The Principle of Emptiness
It is the developer’s right to improve the CMS feature.
I really need to update the documentation about future layout API, but to give a general picture for beginners, I decided to publish this article. I guess you never know that you can make parts of the layout to be specifically loaded only on certain pages. That’s reasonable, because until now I still don’t have the opportunity to document it.
The most basic specification of the layout files loading system is dependent on page.php
and pages.php
files only. We, in fact don’t even need the index.php
file. The index.php
file is basically just a free space to make it easier for developers to add layout features without having to touch the core CMS feature. Because in principle, our web pages only consist of two forms: item and items. And here, we call item as page and items as pages.
The following is the most minimal layout file structure you can make:
.\
└── lot\
└── layout\
├── page.php
└── pages.php
Yep. That is all. The before.php
, after.php
and nav.php
files, for example, they are actually just additional files that are not mandatory and are only made to help us reduce in writing the same code over and over again. We usually use before.php
file to display the top of the page that doesn’t change everywhere such as page header and page navigation, and then we will use after.php
file to display the bottom of the page that doesn’t change like footnotes and copyright statements:
.\
└── lot\
└── layout\
├── after.php
├── before.php
├── page.php
└── pages.php
Inside page.php
and/or pages.php
files, we include those parts like this:
<?= Layout::get('before'); ?>
<!-- Your content goes here -->
<?= Layout::get('after'); ?>
Good news for future Mecha CMS users! Because you can call layout parts in a neater way. As layout files are called inside a class method, then we can actually call other parts of it using the generic self
and static
keyword. Just think of that files as part of the class method:
<?= self::get('before'); ?>
<!-- Your content goes here -->
<?= self::get('after'); ?>
But wait! We can even simplify it like this:
<?= self::before(); ?>
<!-- Your content goes here -->
<?= self::after(); ?>
Mecha uses PHP’s __callStatic
magic method to add that default behavior, that is, to load before.php
and after.php
files if exists, as long as you haven’t created custom methods named before
and after
through the Genome
class feature.
That means you can call any method through it without having to worry about error messages that will appear as when you declare a function that never existed. That’s the reason I prefer classes with a bunch of static methods rather than static functions like layout_before()
and layout_after()
. Mecha will try to find foo.php
file when you declare self::foo()
, and if the file does not exist, nothing will be returned. As simple as creating a widget.php
file, we have added widget
method to the system automatically!
<?= self::widget(); ?>
The next advantage is the namespace. self::before()
and self::get('before')
will try to load before.php
file, but with namespace defined in the first argument, we can load other files located in the before
folder. For example, if we declare self::before('art')
or self::get('before/art')
, then we will get .\lot\layout\before\art.php
loaded into the page if we have it, otherwise, it will load the before.php
file, otherwise, it will return nothing:
<?= self::before('art'); ?>
<!-- Your content goes here -->
<?= self::after(); ?>
.\
└── lot\
└── layout\
├── before\
│ └── art.php
├── after.php
├── before.php
├── page.php
└── pages.php
These capabilities are unlimited, and the system will prioritize the longest namespace to load. With page extension, this feature is also available automatically for the current page based on the URL path. For example, we can create a special home page layout by creating an index.php
file in the page
folder (because the default home page layout is constructed via index.page
file). Or, we can also create special articles layout by creating article.php
file in the pages
folder:
.\
└── lot\
└── layout\
├── before\
│ └── art.php
├── page\
│ └── index.php
├── pages\
│ └── article.php
├── after.php
├── before.php
├── page.php
└── pages.php
The next advantage is the Genome
feature itself. We can change the way self::before()
works simply by creating a new method called before
to the Layout
class:
Layout::_('before', function(array $lot = []) {
return 'Custom layout start!';
});
We can also add certain features that you can use in the layout with this capability. In index.php
file, we add this declaration:
Layout::_('hasExtension', function(string $name) {
return null !== State::get('x.' . $name);
});
And in the layout file, we could call it this way:
<?php if (self::hasExtension('comment')): ?>
<?= self::comments(); ?>
<?php endif; ?>