Razor Templates
This commit is contained in:
		
							
								
								
									
										18
									
								
								WGneu/Documents/BusinessDocument.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								WGneu/Documents/BusinessDocument.cshtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| @using RazorLight | ||||
| @inherits TemplatePage<WGneu.Documents.BusinessDocument> | ||||
| @model WGneu.Documents.BusinessDocument | ||||
| @{ Layout = "Document"; } | ||||
|  | ||||
| <div class="info-wrapper"> | ||||
|     <div class="address-wrapper"> | ||||
|         <div class="sender"> | ||||
|             <div>WG Matzen | Schloßstraße 6 | 2243 Matzen</div> | ||||
|             <div>E Österreichische Post AG Eco Brief</div> | ||||
|         </div> | ||||
|         <address>@Model.Address</address> | ||||
|     </div> | ||||
|     <aside></aside> | ||||
| </div> | ||||
| <main> | ||||
|     @RenderBody() | ||||
| </main> | ||||
							
								
								
									
										24
									
								
								WGneu/Documents/BusinessDocument.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								WGneu/Documents/BusinessDocument.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using WGneu.Models; | ||||
|  | ||||
| namespace WGneu.Documents { | ||||
|     public class BusinessDocument : Document { | ||||
|  | ||||
|         public BusinessDocument(string title, Member m) : base(title) { | ||||
|             Member = m; | ||||
|         } | ||||
|  | ||||
|         public Member Member { get; set; } | ||||
|  | ||||
|         public string Address { | ||||
|             get { | ||||
|                 // TODO Name/Rechnungsadresse | ||||
|                 return $"{Member.GivenName} {Member.FamilyName}\n{Member.Address}"; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										8
									
								
								WGneu/Documents/BusinessLetter.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								WGneu/Documents/BusinessLetter.cshtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| @using RazorLight | ||||
| @inherits TemplatePage<WGneu.Documents.BusinessLetter> | ||||
| @model WGneu.Documents.BusinessLetter | ||||
| @{ Layout = "BusinessDocument"; } | ||||
|  | ||||
| <p>Sehr geehrtes Mitglied,</p> | ||||
| <p>nein.</p> | ||||
| <p>Mit freundlichen Grüßen<br/>Ihre Winzergenossenschaft</p> | ||||
							
								
								
									
										14
									
								
								WGneu/Documents/BusinessLetter.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								WGneu/Documents/BusinessLetter.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using WGneu.Models; | ||||
|  | ||||
| namespace WGneu.Documents { | ||||
|     public class BusinessLetter : BusinessDocument { | ||||
|         public BusinessLetter(string title, Member m) : base(title, m) { | ||||
|  | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										44
									
								
								WGneu/Documents/Document.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								WGneu/Documents/Document.cshtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| @using RazorLight | ||||
| @inherits TemplatePage<WGneu.Documents.Document> | ||||
| @model WGneu.Documents.Document | ||||
|  | ||||
| <!DOCTYPE html> | ||||
| <html lang="de-AT"> | ||||
| <head> | ||||
| 	<title>@Model.Title</title> | ||||
| 	<meta charset="UTF-8"/> | ||||
|     <script> | ||||
|         window.finished = false; | ||||
|         window.PagedConfig = { auto: navigator.webdriver }; | ||||
|         if (!navigator.webdriver) { | ||||
|             window.addEventListener("beforeprint", async () => { | ||||
|                 await window.PagedPolyfill.preview(); | ||||
|                 window.finished = true; | ||||
|             }); | ||||
|             window.addEventListener("afterprint", () => { | ||||
|                 location.reload(); | ||||
|             }); | ||||
|         } | ||||
|     </script> | ||||
|     <!-- TODO store paged.js locally to avoid using the internet --> | ||||
|     <script src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script> | ||||
|     <link rel="stylesheet" href="style.css" type="text/css"/> | ||||
| </head> | ||||
| <body> | ||||
|     <div class="m1"></div> | ||||
|     <div class="m2"></div> | ||||
|     <div class="m3"></div> | ||||
|     <header>@Model.Header</header> | ||||
|     <div class="footer-wrapper"> | ||||
|         <div class="pre-footer"> | ||||
|             <span class="date">@Model.FullDateString</span> | ||||
|             <span class="page"></span> | ||||
|         </div> | ||||
|         <footer>@Model.Footer</footer> | ||||
|     </div> | ||||
|     <div class="spacing"></div> | ||||
|     <div class="main-wrapper"> | ||||
|         @RenderBody() | ||||
|     </div> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										52
									
								
								WGneu/Documents/Document.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								WGneu/Documents/Document.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using System.IO; | ||||
|  | ||||
| namespace WGneu.Documents { | ||||
|     public class Document { | ||||
|  | ||||
|         public Document(string title) { | ||||
|             Title = title; | ||||
|             Header = "Winzergenossenschaft Matzen"; | ||||
|             Footer = "Winzergenossenschaft für Matzen und Umgebung reg. Gen.m.b.H."; | ||||
|             Date = DateTime.Today; | ||||
|         } | ||||
|  | ||||
|         public string Title { get; set; } | ||||
|  | ||||
|         public string Header { get; set; } | ||||
|  | ||||
|         public string Footer { get; set; } | ||||
|  | ||||
|         public string FullDateString { | ||||
|             get { | ||||
|                 return Date.ToString("dddd, d. MMMM yyyy"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public DateTime Date { get; set; } | ||||
|  | ||||
|         private async Task<string> Render() { | ||||
|             if (this is BusinessLetter bl) { | ||||
|                 return await Pdf.CompileRenderAsync("BusinessLetter.cshtml", bl); | ||||
|             } else if (this is BusinessDocument bd) { | ||||
|                 return await Pdf.CompileRenderAsync("BusinessDocument.cshtml", bd); | ||||
|             } else { | ||||
|                 return await Pdf.CompileRenderAsync("Document.cshtml", this); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private async Task<string> SaveHtml() { | ||||
|             await File.WriteAllTextAsync("razor_test.html", await Render()); | ||||
|             return ""; | ||||
|         } | ||||
|  | ||||
|         public async Task<string> Save() { | ||||
|             await SaveHtml(); | ||||
|             return ""; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -9,6 +9,7 @@ using System.Threading.Tasks; | ||||
| using PdfSharp.Pdf.IO; | ||||
| using PuppeteerSharp; | ||||
| using PuppeteerSharp.Media; | ||||
| using RazorLight; | ||||
| using WGneu.Windows; | ||||
|  | ||||
| namespace WGneu.Documents { | ||||
| @@ -16,9 +17,11 @@ namespace WGneu.Documents { | ||||
|  | ||||
|         private static readonly string CHROMIUM = @"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"; | ||||
|         private static IBrowser? _Browser = null; | ||||
|         private static RazorLightEngine? _Engine = null; | ||||
|  | ||||
|         public static void Init() { | ||||
|             var b = Browser; | ||||
|             var e = Engine; | ||||
|         } | ||||
|  | ||||
|         private static IBrowser Browser { | ||||
| @@ -31,6 +34,16 @@ namespace WGneu.Documents { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private static RazorLightEngine Engine { | ||||
|             get { | ||||
|                 _Engine ??= new RazorLightEngineBuilder() | ||||
|                     .UseFileSystemProject(@"C:\Users\Lorenz\source\repos\WGneu\WGneu\Documents") | ||||
|                     .UseMemoryCachingProvider() | ||||
|                     .Build(); | ||||
|                 return _Engine; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public static async Task Convert(string path_html, string path_pdf) { | ||||
|             using var page = await Browser.NewPageAsync(); | ||||
|             await page.GoToAsync("file://" + path_html); | ||||
| @@ -59,5 +72,9 @@ namespace WGneu.Documents { | ||||
|             var w = new DocumentViewerWindow(title, path); | ||||
|             w.Show(); | ||||
|         } | ||||
|  | ||||
|         public static async Task<string> CompileRenderAsync(string key, object model) { | ||||
|             return await Engine.CompileRenderAsync(key, model); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -20,16 +20,8 @@ namespace WGneu.Documents { | ||||
|         } | ||||
|  | ||||
|         public static async void Generate(WgContext c) { | ||||
|             var engine = new RazorLightEngineBuilder() | ||||
|                 .UseFileSystemProject(@"C:\Users\tom\source\repos\wgneu-cs\WGneu\Documents") | ||||
|                 .UseMemoryCachingProvider() | ||||
|                 .Build(); | ||||
|  | ||||
|             var model = new TestTemplateModel(c); | ||||
|  | ||||
|             string result = await engine.CompileRenderAsync("TestTemplate.cshtml", model); | ||||
|  | ||||
|             await File.WriteAllTextAsync(ROOT + "razor_test.html", result); | ||||
|             var letter = new BusinessLetter("Test Dokument", c.Members.First()); | ||||
|             var pdf_path = await letter.Save(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,249 +0,0 @@ | ||||
| @using RazorLight | ||||
| @inherits TemplatePage<WGneu.Documents.TestTemplateModel> | ||||
| @model IQueryable<WGneu.Documents.TestTemplateModel> | ||||
|  | ||||
| <!DOCTYPE html> | ||||
| <html lang="de-AT"> | ||||
| <head> | ||||
|     <title>%SUBJECT%</title> | ||||
|     <!-- TODO store paged.js locally to avoid using the internet --> | ||||
|     <script> | ||||
|         window.finished = false; | ||||
|         window.PagedConfig = {auto: navigator.webdriver, after: () => { window.finished = true; }}; | ||||
|         if (!navigator.webdriver) window.addEventListener("beforeprint", () => { window.PagedPolyfill.preview(); }); | ||||
|     </script> | ||||
|     <script src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script> | ||||
|     <style> | ||||
|         :root { | ||||
|             font-family: "Times New Roman", serif; | ||||
|             line-height: 1; | ||||
|         } | ||||
|         * {box-sizing: border-box;} | ||||
|         body {margin: 0;} | ||||
|         .m1, .m2, .m3 { | ||||
|             height: 0; | ||||
|             width: 1cm; | ||||
|             position: fixed; | ||||
|             left: 0; | ||||
|             border-top: 1pt solid black; | ||||
|         } | ||||
|         .m1 {top: 105mm;} | ||||
|         .m2 {top: 148.5mm;} | ||||
|         .m3 {top: 210mm;} | ||||
|         header { | ||||
|             height: 45mm; | ||||
|             padding: 5mm; | ||||
|             position: absolute; | ||||
|             top: -25mm; | ||||
|             left: 0; | ||||
|             right: 0; | ||||
|             text-align: center; | ||||
|         } | ||||
|         .spacing {height: 20mm;} | ||||
|         .info-wrapper { | ||||
|             width: 100%; | ||||
|             height:45mm; | ||||
|             margin: 0 0 8.46mm 0; | ||||
|             position: relative; | ||||
|         } | ||||
|         .address-wrapper { | ||||
|             height: 45mm; | ||||
|             width: 85mm; | ||||
|             margin: 0; | ||||
|             padding: 5mm; | ||||
|             position: absolute; | ||||
|             left: 20mm; | ||||
|             top: 0; | ||||
|             display: flex; | ||||
|             flex-direction: column; | ||||
|             justify-content: flex-end; | ||||
|         } | ||||
|         .address-wrapper .sender { | ||||
|             flex: 17.7mm 1 1; | ||||
|             font-size: 8pt; | ||||
|             display: flex; | ||||
|             flex-direction: column; | ||||
|             justify-content: flex-end; | ||||
|             padding-bottom: 2mm; | ||||
|         } | ||||
|  | ||||
|         address { | ||||
|             flex: 27.3mm 1 1; | ||||
|             white-space: pre-line; | ||||
|             font-size: 12pt; | ||||
|             font-style: normal; | ||||
|         } | ||||
|  | ||||
|         aside { | ||||
|             height: 40mm; | ||||
|             width: 75mm; | ||||
|             margin: 0; | ||||
|             position: absolute; | ||||
|             left: 125mm; | ||||
|             top: 5mm; | ||||
|         } | ||||
|         main { | ||||
|             margin: 8.46mm 20mm 4.23mm 25mm; | ||||
|         } | ||||
|         main :first-child { | ||||
|             margin-top: 0; | ||||
|         } | ||||
|         main h1, main p { | ||||
|             font-size: 12pt; | ||||
|             margin: 1em 0; | ||||
|             text-align: justify; | ||||
|             widows: 3; | ||||
|             orphans: 3; | ||||
|         } | ||||
|         main .date { | ||||
|             margin-bottom: 2em; | ||||
|             text-align: right; | ||||
|         } | ||||
|         main h1 { | ||||
|             margin-bottom: 2em; | ||||
|         } | ||||
|         .footer-wrapper { | ||||
|             padding: 0 20mm 0 25mm; | ||||
|             position: running(page-footer); | ||||
|             bottom: 0; | ||||
|             left: 0; | ||||
|             right: 0; | ||||
|         } | ||||
|         .pre-footer { | ||||
|             margin: 4.23mm 0; | ||||
|             font-size: 10pt; | ||||
|             display: flex; | ||||
|         } | ||||
|         .pre-footer .date, .pre-footer .page { | ||||
|             flex: 100px 1 1; | ||||
|         } | ||||
|         .pre-footer .date {text-align: left;} | ||||
|         .pre-footer .page {text-align: right;} | ||||
|         .page::after { | ||||
|             content: "Seite 1 von 1"; | ||||
|         } | ||||
|         footer { | ||||
|             font-size: 10pt; | ||||
|             border-top: 1pt solid black; | ||||
|             height: 25mm; | ||||
|             padding-top: 1mm; | ||||
|             text-align: center; | ||||
|         } | ||||
|  | ||||
|         @@page { | ||||
|             size: A4; | ||||
|             margin: 25mm 0 35mm 0; | ||||
|             @@bottom-center { | ||||
|                 content: element(page-footer); | ||||
|             } | ||||
|         } | ||||
|         @@media screen { | ||||
|             body, header, .footer-wrapper { | ||||
|                 width: 210mm; | ||||
|             } | ||||
|             header, .address-wrapper, aside, main { | ||||
|                 border: 1px solid lightgray; | ||||
|             } | ||||
|             .m1, .m2, .m3 {display: none;} | ||||
|             header {top: 0;} | ||||
|             .spacing {height: 45mm;} | ||||
|             .main-wrapper { | ||||
|                 margin-bottom: 40mm; | ||||
|             } | ||||
|             .footer-wrapper { | ||||
|                 position: fixed; | ||||
|                 bottom: 0; | ||||
|                 left: 0; | ||||
|                 right: 0; | ||||
|                 background: white; | ||||
|             } | ||||
|         } | ||||
|         @@media print { | ||||
|             .page::after { | ||||
|                 content: "Seite " counter(page) " von " counter(pages); | ||||
|             } | ||||
|             .footer-wrapper { | ||||
|                 display: none; | ||||
|             } | ||||
|         } | ||||
|     </style> | ||||
| </head> | ||||
| <body> | ||||
| <div class="m1"></div> | ||||
| <div class="m2"></div> | ||||
| <div class="m3"></div> | ||||
| <header> | ||||
|     <h1>Winzergenossenschaft Matzen</h1> | ||||
| </header> | ||||
| <div class="footer-wrapper"> | ||||
|     <div class="pre-footer"> | ||||
|         <span class="date">Samstag, 4. März 2023</span> | ||||
|         <span class="page"></span> | ||||
|     </div> | ||||
|     <footer> | ||||
|         Winzergenossenschaft für Matzen und Umgebung reg. Gen.m.b.H. | ||||
|     </footer> | ||||
| </div> | ||||
| <div class="spacing"></div> | ||||
| <div class="main-wrapper"> | ||||
|     <div class="info-wrapper"> | ||||
|         <div class="address-wrapper"> | ||||
|             <div class="sender"> | ||||
|                 <div>WG Matzen | Schloßstraße 6 | 2243 Matzen</div> | ||||
|                 <div>E Österreichische Post AG Eco Brief</div> | ||||
|             </div> | ||||
|             <address>Maximilian Mustermann | ||||
|             Musterstraße 123 | ||||
|             2222 Musterort | ||||
|             Österreich</address> | ||||
|         </div> | ||||
|         <aside></aside> | ||||
|     </div> | ||||
|     <main> | ||||
|         <div class="date">Matzen, am 04.03.2023</div> | ||||
|         <h1>%SUBJECT%</h1> | ||||
|         <p>Sehr geehrtes Mitglied,</p> | ||||
|  | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|         <p>Ich bin ein langer Paragraph.</p> | ||||
|  | ||||
|         @foreach (var country in Model.Countries) { | ||||
|             <h1>Land:</h1> | ||||
|             <p>@Raw(country.Name)</p> | ||||
|             <p>@country.Alpha2</p> | ||||
|             <p>@country.Alpha3</p>  | ||||
|         } | ||||
|  | ||||
|  | ||||
|  | ||||
|         <p> | ||||
|             Mit freundlichen Grüßen<br/> | ||||
|             Ihre Winzergenossenschaft Matzen | ||||
|         </p> | ||||
|     </main> | ||||
| </div> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,19 +0,0 @@ | ||||
| using Microsoft.AspNetCore.Mvc.RazorPages; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using WGneu.Models; | ||||
|  | ||||
| namespace WGneu.Documents { | ||||
|     public class TestTemplateModel { | ||||
|  | ||||
|         public IQueryable<Country> Countries { get; set; } | ||||
|  | ||||
|         public TestTemplateModel(WgContext c) { | ||||
|             Countries = c.Countries; | ||||
|         } | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										176
									
								
								WGneu/Documents/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								WGneu/Documents/style.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,176 @@ | ||||
|  | ||||
| :root { | ||||
|     font-family: "Times New Roman", serif; | ||||
|     line-height: 1; | ||||
| } | ||||
|  | ||||
| * { | ||||
|     box-sizing: border-box; | ||||
| } | ||||
|  | ||||
| body { | ||||
|     margin: 0; | ||||
| } | ||||
|  | ||||
| .m1, .m2, .m3 { | ||||
|     height: 0; | ||||
|     width: 1cm; | ||||
|     position: fixed; | ||||
|     left: 0; | ||||
|     border-top: 1pt solid black; | ||||
| } | ||||
|  | ||||
| .m1 {top: 105mm;} | ||||
| .m2 {top: 148.5mm;} | ||||
| .m3 {top: 210mm;} | ||||
|  | ||||
| header { | ||||
|     height: 45mm; | ||||
|     padding: 5mm; | ||||
|     position: absolute; | ||||
|     top: -25mm; | ||||
|     left: 0; | ||||
|     right: 0; | ||||
|     text-align: center; | ||||
| } | ||||
| .spacing {height: 20mm;} | ||||
| .info-wrapper { | ||||
|     width: 100%; | ||||
|     height:45mm; | ||||
|     margin: 0 0 8.46mm 0; | ||||
|     position: relative; | ||||
| } | ||||
|  | ||||
| .address-wrapper { | ||||
|     height: 45mm; | ||||
|     width: 85mm; | ||||
|     margin: 0; | ||||
|     padding: 5mm; | ||||
|     position: absolute; | ||||
|     left: 20mm; | ||||
|     top: 0; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     justify-content: flex-end; | ||||
| } | ||||
|  | ||||
| .address-wrapper .sender { | ||||
|     flex: 17.7mm 1 1; | ||||
|     font-size: 8pt; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     justify-content: flex-end; | ||||
|     padding-bottom: 2mm; | ||||
| } | ||||
|  | ||||
| address { | ||||
|     flex: 27.3mm 1 1; | ||||
|     white-space: pre-line; | ||||
|     font-size: 12pt; | ||||
|     font-style: normal; | ||||
| } | ||||
|  | ||||
| aside { | ||||
|     height: 40mm; | ||||
|     width: 75mm; | ||||
|     margin: 0; | ||||
|     position: absolute; | ||||
|     left: 125mm; | ||||
|     top: 5mm; | ||||
| } | ||||
|  | ||||
| main { | ||||
|     margin: 8.46mm 20mm 4.23mm 25mm; | ||||
| } | ||||
|  | ||||
| main :first-child { | ||||
|     margin-top: 0; | ||||
| } | ||||
|  | ||||
| main h1, main p { | ||||
|     font-size: 12pt; | ||||
|     margin: 1em 0; | ||||
|     text-align: justify; | ||||
|     widows: 3; | ||||
|     orphans: 3; | ||||
| } | ||||
|  | ||||
| main .date { | ||||
|     margin-bottom: 2em; | ||||
|     text-align: right; | ||||
| } | ||||
|  | ||||
| main h1 { | ||||
|     margin-bottom: 2em; | ||||
| } | ||||
|  | ||||
| .footer-wrapper { | ||||
|     padding: 0 20mm 0 25mm; | ||||
|     position: running(page-footer); | ||||
|     bottom: 0; | ||||
|     left: 0; | ||||
|     right: 0; | ||||
| } | ||||
|  | ||||
| .pre-footer { | ||||
|     margin: 4.23mm 0; | ||||
|     font-size: 10pt; | ||||
|     display: flex; | ||||
| } | ||||
|  | ||||
| .pre-footer .date, .pre-footer .page { | ||||
|     flex: 100px 1 1; | ||||
| } | ||||
|  | ||||
| .pre-footer .date {text-align: left;} | ||||
| .pre-footer .page {text-align: right;} | ||||
| .page::after { | ||||
|     content: "Seite 1 von 1"; | ||||
| } | ||||
|  | ||||
| footer { | ||||
|     font-size: 10pt; | ||||
|     border-top: 1pt solid black; | ||||
|     height: 25mm; | ||||
|     padding-top: 1mm; | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
| @page { | ||||
|     size: A4; | ||||
|     margin: 25mm 0 35mm 0; | ||||
|     @bottom-center { | ||||
|         content: element(page-footer); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @media screen { | ||||
|     body, header, .footer-wrapper { | ||||
|         width: 210mm; | ||||
|     } | ||||
|     header, .address-wrapper, aside, main { | ||||
|         border: 1px solid lightgray; | ||||
|     } | ||||
|     .m1, .m2, .m3 {display: none;} | ||||
|     header {top: 0;} | ||||
|     .spacing {height: 45mm;} | ||||
|     .main-wrapper { | ||||
|         margin-bottom: 40mm; | ||||
|     } | ||||
|     .footer-wrapper { | ||||
|         position: fixed; | ||||
|         bottom: 0; | ||||
|         left: 0; | ||||
|         right: 0; | ||||
|         background: white; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @media print { | ||||
|     .page::after { | ||||
|         content: "Seite " counter(page) " von " counter(pages); | ||||
|     } | ||||
|     .footer-wrapper { | ||||
|         display: none; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user