Thursday, November 21

Developing With Automad

Selecting the right CMS for a blog or website can be difficult. Every web project has its own needs and requirements, meaning one CMS may be a better fit for one site but not so much for a different site. Simple solutions might be lacking some essential features, while more complex systems can create easily overhead for a given task.

I want to cover Automad, a CMS that is less-known than, say, a behemoth like WordPress, but still offers some powerful features like it while maintaining the nimbleness of smaller, simpler solutions, like static site generators.

 

Specifically, Automad fills a gap between larger and smaller offerings in a few key ways:

  • It is file-based, but does not require a database. This ensures quick setup, portability, security, speed, and easy deployment.
  • Even without a database, it offers database features like searching, tagging, filtering, and sorting.
  • A multi-layer caching engine caches content stored in the file system efficiently.
  • The browser-based dashboard and the in-page (“live”) edit mode allows for intuitive content management.

But what makes Automad really different, is its integrated template engine. Templating is a core requirement for may CMSs because it creates and sets the base for a site’s visual display. Since Automad’s template engine is so close to the core, it allows you to create templates with complex navigations and to batch process images using a clean and short syntax. You’ll feel the difference once you get your hands on it, and we’ll walk through an example together in just a bit.

But first, a quick overview of templating

As a designer or a developer, you’re probably curious about how to develop themes and templates for Automad. I mean, it’s the crux for why any of us really use a CMS in the first place. If you’ve done any level of theming with WordPress, then working with Automad will feel vaguely familiar, and perhaps even easier.

The minimal requirement for creating an Automad theme is a single .php file and a theme.json file bundled together in a subdirectory you create inside the top-level /packages directory in a default Automad installation:

packages/
  yourTheme/
    yourTemplate.php
    theme.json

The tutorial package shipped with Automad provides a good starting point for understanding the basic concepts of themes.

A look at the syntax used in Automad templates

While it is possible to write templates in plain PHP, it is not required and actually not recommended. The reason is that Automad’s own template syntax is shorter, more readable, and integrates well with the user interface by automatically listing all of the used variables in the dashboard. It can be seamlessly mixed into HTML markup.

Basically, the syntax can be split into two groups:

  1. Echoing content: @{ variable }
  2. Statements, like functions, loops and conditionals: <@ function @> or <@ statement @>…<@ end @>

Echo content

Let’s say we want to pull the body content for a post into a template and we have a variable set up for that called text. In WordPress, this would be a global variable (the_content) that is called in PHP:

<?php the_content(); ?>

In Automad, we can do the same without PHP:

<p>@{ text }</p>

It is possible to manipulate the output of variables by passing the value to a function using the pipe (|) operator. The following example shows how to shorten a given text to a maximum of 100 characters without cutting words:

@{ text | shorten (100) }

This would be the same of thing you might do to define the excerpt of a post in WordPress using a function:

/* Limit excerpt to 20 words */
function my_custom_excerpt_length( $length ) {
    return 20;
}
add_filter( 'excerpt_length', 'wpdocs_custom_excerpt_length', 999 )
}

One of the key benefits of some CMS solutions, like Jeykll, is that using Markdown to create site content is a native feature. Automad can do the same. Let’s say we want to convert Markdown text to HTML. It’s pretty darn simple (and efficient) using the pipe operator:

@{ text | markdown }

Using statements

Statements are a handy way to define content and display it conditionally. Unlike variables, statements are wrapped in <@ … @> delimiters. The following example can be used to create a simple top level menu by using the nav function:

<@ nav { context: "/", class: "nav" } @>

Let’s say you want to display your post content by default but display a fallback if that content does not exist for some reason. That’s where we can put conditional statements and control structures to use:

<# If the post content exists then display... #>
<@ if @{ text } @>
  <p>...</p>

<# Otherwise, display this... #>
<@ else @>
  <p>Sorry, no content here!</p>

<# OK, no more conditions. #>
<@ end @>

Want to create a loop? This is where display a list of posts or any repeatable content that matches a condition is super useful. We can do that in Automad by providing one or more glob patterns in a foreach loop.

For example, let’s display all JPG and PNG images for a post cropped at 400x300 with their captions:

<@ foreach in "*.jpg, *.png" { width: 400, height: 300, crop: true } @>
  <img src="@{:fileResized}" width="@{:widthResized}" height="@{:heightResized}">
  <p>@{:caption}</p>
<@ end @>

Did you catch that?! As shown by this example, a remarkable Automad feature is the ability to embed resizing options for each matching file inside the loop statement. No more complicated functions to register sizes that then need to be called in the template!

It’s worth noting that foreach loops can also be used to iterate over objects. Automad knows multiple types of objects. One of the most important objects is pagelist because of its ability to output all of the pages on the site, like you might want to do when building navigation. When iterating a pagelist, the context changes with every iteration to the current page in the loop. That way, it is possible to use page variables within the loop’s code block.

To configure the pagelist, we can use the newPagelist function like this:

<@ newPagelist { context: "/", type: "children" } @>
<ul>
  <@ foreach in pagelist @>
    <li><a href="@{ url }">@{ title }</a></li>
  <@ end @>
</ul>

A sneak peek behind the scenes for you super geeks ?

Automad’s template interpreter is written in pure PHP and it processes templates on the fly. Therefore, no extra build process is required at all. The list of system requirements is also rather short. A web server (Apache or Nginx) and PHP 5.4+ is already enough to run a site. Pages are only rendered when content has changed or after system updates.

Automad’s multi-layer caching engine stores the rendered pages in separate .html files as well as all crawled data in the file system as a kind of content object. That object is also used to speed up page searching and filtering.

Due to that mechanism, it is possible to either edit the content of a site directly in production online using the browser-based dashboard or edit a site locally and deploy it via Git or plain rsync.

Let’s write some code!

The best way to get acquainted with anything on the web is to just build websites. Here are some examples of how we’d get started with that using Automad.

Example 1: Recursive navigation

Creating a site-tree navigation is a good example for using recursion in templates. Conceptually, creating such a recursive navigation can be split into three steps:

  1. Defining a reusable snippet of code to create a single branch of the site-tree which calls itself conditionally
  2. Configuring a dynamic pagelist which automatically only contains children of its current context
  3. Defining the root page of the site-tree (for instance the homepage) and call the recursive snippet initially

Let’s break those steps down into greater detail…

Defining a reusable snippet of code

In Automad, blocks of code can be defined to be reused at a later point by using the snippet keyword. Regarding this example, the following snippet will call itself conditionally when looping through a pagelist and the active page of the current iteration itself has children pages:

<@ snippet navigation @>  
  <ul class="menu-list">       
    <@ foreach in pagelist @>
      <li>
        <a href="@{ url }">@{ title }</a>
        <# Call snippet recursively. #>
        <@ navigation @>
      </li>
    <@ end @>
  </ul>
<@ end @>
Configuring a dynamic pagelist

The pagelist has to be configured a children type. The context (or parent page) will always change recursively within the snippet defined above in that way. The pagelist will automatically only contain children pages of the currently processed page.

<@ newPagelist { 
  type: 'children'
} @>
Defining the root page

In the last step, the root context of the navigation tree has to be defined and the snippet has to be called once to initiate the recursion. The with statement is used here to change the context to the homepage.

<div class="menu">
  <@ with '/' @>
    <@ navigation @>
  <@ end @>
</div>

A complete working tutorial template is already included in Automad.

Example 2: Working with files

Since images are super important for content management, working with them should be as easy and intuitive as possible. Automad’s template language provides handy methods for basic image processing, like resizing and cropping. When using a single image or iterating a set of images, resizing options can be passed to a with statement or foreach loop. Check out the <a href=”https://dev.automad.org/tutorials/working-with-images”Working with Images tutorial that ships with Automad to get started quickly.

<@ foreach in '*.jpg, *.png' { width: 400, height: 300, crop: true } @>
  <# Code to be used for each image in the filelist. #>
  <img 
  src="@{ :fileResized }" 
  alt="@{ :basename }"
  title="@{ :file }"
  width="@{ :widthResized }"
  height="@{ :heightResized }"
  >
  <p>@{ :caption | markdown }</p>
<@ else @>
  <# Code to be used when the list of images is empty. #>
<@ end @>

Instead of using a glob pattern in the foreach loop, it is also possible to use the filelist object.

If you look at the example code above, you will notice the use of certain runtime variables to access image properties within a code block. While the :file variable represents the original file, :fileResized refers to path of the resized and cached version. The :caption variable enables you to get the caption text stored along with the file.


What will you build?

We merely scratched the surface of Automad here, but hopefully everything we covered gives you a good idea of the possibilities it provides for content management. While there is no one-size-fits-all mold in the CMS world, there will likely be scenarios where a CMS that sits somewhere between the robust and slimmed-down options will come in handy.

Additional Resources

 

Source: CSS-tricks.com

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x