Starting Page Templating with TYPO3 🛠️✨
Kicking off the basics of page templating! Since I’m working with TYPO3, the core code will be based on Fluid templates (it’s like HTML but with some extra power). For CSS, I’m going with Tailwind, and my favorite JS library, Alpine.js, will handle the interactivity. Let’s get started!
First, I used TypoScript to set up the page object to use Fluid templates and defined the paths for templates, layouts, and partials. My usual page structure looks like this:
<body>
<header></header>
<main></main>
<footer></footer>
</body>
Pretty simple, right? Since I'm using Tailwind (which I’ll set up soon), it’s easy to keep the footer at the bottom of the page. I just add these classes:
<body class="flex flex-col min-h-screen">
<main class="flex-grow">
This setup ensures the main section stretches to fill the height, so the header, main, and footer always cover the full screen. In the Fluid template, I added a note to use the "DefaultPage" layout. The layout file handles the header, main content, and footer by using partials and sections. Why layouts? It simplifies template reuse, like if I want to switch between different navigation styles (e.g., top or left).
Moving on to the Frontend: CSS and JavaScript
Since most modern libraries can be installed via npm, I’m using it for this project too. I created a "Build" folder in my Resources/Private directory to store all the npm settings, and the built output will go into Resources/Public. Then, I’ll include the CSS and JS files in TYPO3 using the includeJS or includeCSS functions in TypoScript. For JS, I add the defer attribute, so scripts don’t run immediately but wait until the rest of the page is ready—one of Alpine.js’ perks!
Next up, I added the first meta tag, the viewport tag, to make sure text isn’t tiny on mobile devices. Here’s the TypoScript code for that:
page.meta.viewport = width=device-width, initial-scale=1
This generates the following HTML: <meta name="viewport" content="width=device-width, initial-scale=1">
.
Building the Page Header
Here’s a little side tip: when setting content widths in TYPO3, I like to create a partial called ContentWidth.html with multiple sections for different widths. Here’s an example:
<f:section name="wide">
w-full max-w-[1440px] mx-auto
</f:section>
<f:section name="wideXspacing">
<f:render section="wide" /> px-6
</f:section>
<f:section name="slim">
w-full max-w-[724px] mx-auto
</f:section>
<f:section name="slimXspacing">
<f:render section="slim" /> px-6
</f:section>
With this setup, I can easily control the width of the content. Here’s how I apply it in the header:
<header>
<div class="{f:render(section: 'wideXspacing', partial: 'ContentWidth')}">
HEADER CONTENT
</div>
</header>
Handling Errors
For easier future changes, I use constants to set main paths and page IDs in TypoScript. For example, I can link to the homepage like this:
<f:link.typolink parameter="{f:cObject(typoscriptObjectPath: 'lib.pids.home')}">Home</f:link.typolink>
But I ran into a frontend error that wasn’t very readable. To display full error messages (only on staging or local environments, not on production), I added this TypoScript:
config.contentObjectExceptionHandler = 0
Accessibility Tip
Some users rely on screen readers, so a well-structured page is essential. One handy feature is a "skip to content" link, allowing users to bypass navigation. Just place an anchor at the top of the page, but be mindful of search engines. Here’s an example:
<a href="#skip" aria-label="Skip to content" title="Skip to content"></a>
This way, the link is accessible but doesn’t mess with your SEO.
What is NPM?
npm (Node Package Manager) is a tool for managing JavaScript packages and dependencies. It’s commonly used with Node.js to install, update, and manage libraries or frameworks required in web development. npm enables developers to quickly add functionality to their projects through reusable packages from a vast registry. It's also useful for handling version control, automating tasks, and managing project configurations across development environments.