mecha notes

this is a 'rolling update' post: the publish date reflects the last time this file was edited. originally published July 25 2020.


Mecha CMS is the software powering this website.

i like it. most of the time.

when i don't like it, however, there has yet to be a problem i couldn't get figured out with a little digging around the codebase.

here is where i'll try to add a little documentation of my own, for anyone who goes googling for things i had issues with.


hardcoded values & strings

<?php if ($site->is('home')): ?>
    <!--<span>--><?= i('home'); ?><!--</span>-->
<?php else: ?>
    <a href="<?= $url; ?>"><?= i('Home'); ?></a>
<?php endif; ?>

configuring Nginx to work with mecha

zardo still runs on Apache2, but when i wanted to get a dev server going at home, i decided to bite the bullet and see how i'd fare with a LE(M)P1 stack.

though beyond my paygrade as far as fixing it, mecha is somewhat unusual in that it seems to have a bit of trouble handling the creation of page slugs, and requires php-fpm and php-mbstring to be installed and configured to begin smoothly handling URL's.

this is fairly straightforward with apache. nginx requires a little bit of code in your website's config file in /etc/nginx/sites-avaliable:

        location ^~ /engine {
        deny all;
        return 404;

        location ~ /lot/x/.*/lot/asset {allow all; }
        location ^~ /lot {
                deny all;
                return 404;

        location ^~ /lot/asset {allow all; }
        location ^~ /lot/layout/asset { allow all; }

        location / { try_files $uri $uri/ @rewrite; }
        # pass PHP scripts to FastCGI server

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
        #       # With php-fpm (or other unix sockets):
                fastcgi_pass unix:/run/php/php7.3-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass;

                location @rewrite {
                        rewrite ^/(.*)$ /index.php?_=$1 last;

there's a bit going on here: this will setup and secure Mecha by disabling access to the engine folder as well as the configurations for extensions. to handle the aforementioned URL rewrites, a small condition @rewrite lets nginx know how to handle the task of creating links from post slugs.

though this is more-or-less a paste-and-go bit of code, pay special attention to the section which tells nginx where to find the php-fpm thread to pass off the @rewrite task among others:

fastcgi_pass unix:/run/php/php7.3-fpm.sock;

by default this is both commented out and configured to use the 7.0 version of this module. most users will likely need to edit this to instead use php7.2-fpm.sock; for my dev server i am using the more recent version 7.3. this little line got me good - everything else seemed to check out, but my website kept breaking and only by pure chance did i happen to glance at this line and realize it was trying to call to a non-existent file.

custom styling for individual pages

for the 'about' section, i wanted to center the screenshot of the Lighthouse audit. the end result was kind of tacky, as it required me to wrap the markdown shortcode in HTML. a slightly less cumbersome alternative was to put the image inside a table, and then style the table with CSS. the issue, however, was how would i style tables in a way that wouldn't break a potential future table on another part of the site, where the content might not need be centered?

Mecha's got you covered. It includes a very useful and powerful feature: by creating a directory with the name name of the page you want to add information and data to, you can add .data files (and more, though beyond this scope) which Mecha will grab and inject into the page as it is built and loaded. Currently this will work for files named css.data and js.data - for CSS and javascript.

in my case i wanted to customize about.page, so I created a directory and named it about. within the about folder I included a file css.data with the following:

tr {
  border: none;

as you might know, this is pretty horrific CSS in almost any case, as it would ruin a vast majority of tables across a website, as well as the styling for them. in this case though, knowing i was only going to need exactly one table on this one page, this proved to be a working fix. while i could have also done a similar workaround by styling the img element, by using tables i leave some room for easy expansion later if i feel compelled to caption the image - by simple adding text to a second row.


config: lot/x/page/state.php

by default, sections are set to organize content by filename, alphabetically. 5 page links at a time are shown on a page.


return [
    // Pre-defined page data
    'page' => [
        'chunk' => 50,
        'deep' => 0,
        'sort' => [1, 'time']

for my notes section i wanted to display all my post links on one page organized by publish date. to do this, i changed the chunk from 5 to 50 - any number over 5, and it'll be awhile before i reach 50. i also changed the sort key, from file to time which tells mecha to sort them by the date set in the YAML frontmatter with the time key:

title: foo
description: bar
author: andrew snow
time: 2020-01-01
format: Markdown

section config

while state.php will allow you to configure the sitewide default to handle pages, you can fine-tune the settings for a specific section as well, by editing the .page file created telling mecha you intend to have a section containing content.

for example, to create the notes section, i simply created a file in the root lot/page folder with the following frontmatter:

title: notes
description: Not quite "writing"
author: andrew snow
type: Markdown
sort: [-1, 'time']

as you can see, one of the allowable options to define is time, which is optional but potentially useful.

header scripts: css, js

when i first went to play with the layout, i was mingboggled: the layout files dont actually have the <script src=""> codes in the <head> element!

i manually added my own in anyways, but it never satisfied me - mainly because it meant i was forced to use the default css file, since there was no way to change the css file it looked for.

i feel pretty dumb for it have taken me to find where this is configured: the index.php page in the root of lot/layout.

// Add CSS file to the `<head>` section…
Asset::set('css/log.min.css', 20);

when adding a css file, it will be inserted into the <head> element at the top of the page. when adding javascript files, they will instead be inserted into the footer.php layout when wrapping content.

  1. i always install a database out of habit, but at this point it's more or less vestigial.