Using October without a database

Tutorial 13

Here's how OctoberCMS can function as a flat-file CMS, meaning with no database. It's a pretty popular concept, there are a few CMS' that do this already, but none quite like October.

The flat-file approach quickly hits limitations with larger sites, so October optionally supports a database. For smaller sites, this is an awesome new tool that you should find pretty interesting.

Quick start October installation

Start in an empty public web directory (wwwroot).

Run this command in console:

php -r "eval('?>'.file_get_contents('https://octobercms.com/api/installer'));"

Test that October is working, if your web address is localhost, then open

http://localhost/

Create a theme

Add a new theme directory in themes/ called website.

Change the config value activeTheme in config/cms.php to website.

Build a page

Create a new directory in themes/website/ called pages.

Create a new file in that directory index.htm.

title = "Homepage"
url = "/"
==
<h1>Hello world!</h1>

You might be familiar with this type of template if you have seen static site generators. The configuration and markup are separated by the == characters.

Now at your web address you should see the "Hello world!" message.

Build a 404 page

Create another new file in the pages/ directory called 404.htm.

title = "Page not found"
url = "/404"
==
<h1>Yikes... do you know where the page went?</h1>

Open a non-existant web address, to see the 404 page, for example:

http://localhost/yay

Create a layout

Create a new directory in themes/website/ called layouts.

Create a new file in that directory default.htm.

<html>
    <head>
        <title>{{ this.page.title }}</title>
        <style>
            body { border: 30px solid orange; padding: 20px; }
        </style>
    </head>
    <body>
        {% page %}
    </body>
</html>

Add a new configuration entry in index.htm and 404.htm files to assign the layout.

layout = "default"

The template system is Twig and the page properties are available via this.page. Look in the browser to see the page contents appears at the {% page %} Twig tag.

Include the assets

Create a new directory in themes/website/ called assets.

Create a new file in that directory styles.css.

body { border: 30px solid orange; padding: 20px; }

Add a link to the stylesheet in the default.htm layout.

<html>
    <head>
        <title>{{ this.page.title }}</title>
        <link href="{{ 'assets/styles.css'|theme }}" rel="stylesheet">
    </head>
    <body>
        {% page %}
    </body>
</html>

The |theme Twig filter makes it relative to the active theme. There is also |app for relative to the application.

Create another new asset file font.css.

body { font-family: sans-serif; }

We can also combine two assets by passing an array of files.

<link href="{{ ['assets/styles.css', 'assets/font.css']|theme }}" rel="stylesheet">

Check the page source to see the two files are now combined!

Pass data to the page

In the index.htm page include a PHP code section.

title = "Homepage"
url = "/"
layout = "default"
==
function onStart()
{
    $this['name'] = 'Jimmy Fallon';
}
==
<h1>Hello {{ name }}!</h1>

The <? ?> tags are optional for syntax highlighting.

Most of the time you will like to keep your PHP code separate from your view content. It is more common that we use components and the page will look like this:

title = "Homepage"
url = "/"

[user]
==
<h1>Hello {{ name }}!</h1>

Don't be too concerned about this, it is a story for another time. For now we will keep it simple, all in one template.

Include a partial

Create a new directory in themes/website/ called partials.

Create a new file in that directory footer.htm.

Thanks for visiting {{ name }}! Like us on facebook...

Partials the same as PHP includes, include it on the default.htm layout.

<html>
    <head>
        <title>{{ this.page.title }}</title>
        <link href="{{ ['assets/styles.css', 'assets/font.css']|theme }}" rel="stylesheet">
    </head>
    <body>
        {% page %}
        <hr />
        {% partial 'footer' %}
    </body>
</html>

You can pass variables to the {% partial %} tag.

{% partial 'footer' name='Joey Salads' %}

Include some content

Create a new directory in themes/website/ called content.

Create a new file in that directory welcome.md.

You know what I like more than *material things?*

### Knowledge!

+ You must have enough fuel units
+ You must construct additional pylons

The file contains the Markdown syntax because it uses the md file extension. Extensions htm or txt can also be used.

Create a new page file called about.htm

url = "/about"
layout = "default"
==
{% content 'welcome.md' %}

Open the web address to see the content.

http://localhost/about

Add page parameters

Change the configuration entry to include a :filename parameter.

url = "/about/:filename"

Now the /about web address will return 404 because it expects a filename. We can make it optional with a question mark.

url = "/about/:filename?"

The value can be accessed in the code by calling this.param.

{{ this.param.filename }}

We could even pass it to the content tag to make it dynamic.

url = "/about/:filename?"
layout = "default"
==
{% content this.param.filename ~ '.md' %}

Of course it would be a good idea to santise the value in PHP code. We can pass a default value and make it lower case.

url = "/about/:filename?"
layout = "default"
==
function onStart()
{
    $filename = $this->param('filename', 'welcome');
    $this['filename'] = strtolower($filename);
}
==
{% content filename ~ '.md' %}

The code section controls the page life cycle, there are other methods like onInit and onEnd too. If a value is returned from these methods, it is considered a response.

url = "/about/:filename?"
layout = "default"
==
function onStart()
{
    $filename = $this->param('filename', 'welcome');

    if ($filename !== 'welcome') {
        return 'Not found!';
    }

    $this['filename'] = $filename;
}
==
{% content filename ~ '.md' %}

Now to open the page without a welcome filename and it returns "Not found!" directly to the browser.

http://localhost/about/yay

A better idea can be to return a redirect instead

if ($filename !== 'welcome') {
    return Redirect::to('/404');
}

Linking to pages

In the footer.htm partial include some links.

Thanks for visiting {{ name }}! Like us on facebook...

<a href="{{ 'index'|page }}">Return home</a>, or
<a href="{{ 'about'|page }}">learn about us</a>

The |page filter accepts the file name as the value and outputs the page URL.

Change the configuration entry in index.htm to a different URL.

url = "/october"

Now the homepage is gone but at the same time, the link is preserved. See the footer link for "Return home" has changed.

http://localhost/october

Linking can also support passing parameters.

<a href="{{ 'about'|page({ filename: 'welcome' }) }}">learn about us</a>

See the footer link for "learn about us" now includes the welcome parameter.

http://localhost/about/welcome

Wrap up

October finds the nice balance between using a heavy system like WordPress, which you may not always need, versus creating a site in just HTML.

All of the Twig tags we used here can be found in the documentation by selecting the Markup guide.

Be sure to watch the other screencasts that cover the other modules, such as creating back-end interfaces and using the AJAX framework.

comments powered by Disqus