Build A Stacey Flat-File CMS Template

I’ve reviewed and created a Zurb Foundation Theme for Kirby CMS. Well, it’s time to go to the cheaper (free) alternative called Stacey. Stacey works on the same principles as Kirby in that it’s a flat-file CMS that’s super-easy to work with. You can read my comparison on Tech.Pro

I recently created a repo for a minimalist stacey theme which you can preview on my self-help blog. It took me next to no time to create and allows me the freedom to replicate the exact setup across many different platforms. Hell, it takes me no time at all to completely remake it.

stacey-blog

Here is what it will look like approximately.

Let’s get started.

Download

Download Preview!

Stacey Installation

Note: I am using the downloadable 2.3.0 version from Stacey’s home page. The version 3.0 available on Stacey’s github is pretty much the same. I’ll have a newer version of my template available at some point.

Installing Stacey is super-simple. Download it, extract it on your server, and you’re ready to go. You may need to change some permissions but that’s simple as hell.

Next, you have two options as far as the theme goes. You can either just follow along and change the default theme or pick up a copy of my own theme. I’d go with the latter choice.

Folder Structure

stacey-folder-structure

Let’s break down the meaning of each one:

  • app holds the power machine of the CMS. That’s all the base code that caches, parses, and displays our code
  • content holds our content. The structure is just like Kirby CMS where you can number your top-level “visible” pages (1.blog, 2.contact, 3.whatever), or use “invisible” pages (index, feed, sitemap) that will not show up in a top-level navigation but are still accessible. A folder can have a sub-folder of sub-pages which works well for a blog where each “post” is pretty much a sub-page.
  • public is where javascript, common image files, and css shows up. You can paste your template’s styles here, your jquery, or whatever else
  • templates is where your template is. Unfortunately, you can’t have several different templates in that folder, so you have to stick to just one at a time. The templates folder also contains partials where you can place your common template files like “header”, “footer”, and code snippets.

Setting Up Content

First, let’s setup our content before we start our template. A common structure may look like so:

  • 1. about
  • 2. contact
  • 3.blog – 1.first-post, 2.second-post

Within each page folder (about, contact), create a page.txt file which will host your content, page title and other miscellaneous data. For each blog type page, create a category.txt file and for each post, create a post.txt file. Simple, right?

The name of the txt file corresponds to which template file we’re asking for. If there is no template file, it’ll default to index. The folder name decides the URL structure on the other hand. So for example, instead of having 1.about, we create a 1.about-web-development, you’ll have a URL of whatever.com/about-web-development (or whatever.com/?/about-web-development without pretty URLs).

 Writing Content

Writing content is another thing. So, Stacey works with markdown and is pretty badass. The setup is quite simple, you define a variable and assign a value to it. Then use said variable in your template. Here is the default setup:

title: Page Title That Shows Up In Menus
- 
date: February 11 2013
-
content:
Our main site content shows up here.

You can create custom variables, as long as they don’t have spaces or illegal PHP characters. I created one called “mainimage” which links to an image within a post and displays it in the theme.

One more thing, if you put your content on a separate line as the variable line, it gets automatically parsed through markdown. Little tricked I found and did not know about from stacey documentation.

Setting Up Theme Files

As I’ve said before, the name you give a .txt file is the name of the template file it uses to parse. I generally keep what Stacey ships with by default such as the feed and sitemaps but I change the rest. So let’s setup the file structure the same way I have.

  • category.html for blog-type pages
  • index.html for default
  • page.html for pages
  • post.html for blog posts

The rest keep in place (feed, json, sitemap), they don’t need any changing. Let’s add a few partials as well to keep clutter out of  our templates. Create the following files in the partials folder:

  • footer.html
  • head.html
  • header.html
  • navigation.html
  • category.html

These will be present on all pages.

Head

Let’s start with the common head file first:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>@title - @name</title>
    <link rel="alternate" type="application/atom+xml" href="@root_path/?/feed/">
    <link rel="stylesheet" href="/public/docs/css/style.css" type="text/css" media="screen">
  </head>
  <body>

Let’s check this out. The @variables will echo out the title of the page and the name of your blog. Now, we’ll be using the variable @root_path so that we can link to the feed. The @root_path will echo out the root of the folder where your site is installed.

The stylesheet is linked from the public folder. Simple, right? :) We’ll open the body tag and close it in the footer.

Header

The “header” is a separate file because it contains our page name and title:

<header>
<div id="logo"><a href="/"><h1>@name</h1></a></div>
<div id="tag-line">Subtitle</div>
</header>

You’re welcome to set a subtitle @ variable in your _shared.txt file in the content folder.

Navigation

Next, let’s create a partial for our navigation:

<nav>
<ul id="navigation">
  foreach $root do
    <li>
      <a href="/@url">@title</a>
      :children
    </li>
  endforeach
</ul>
</nav>

The $root variable holds your root pages (visible ones). The Stacey allows foreach loop in its templating languages but you’ll have to follow your variable by “do”, that’s like opening up the braces and “endforeach” ends the braces. Running the loop allows us to access several different variables such as @url, and @title. We’ll be accessing the :children partial in this loop as well:

if $children do
  <ol class="children">
  foreach $children do
    <li>
      <a href="@url">@page_name</a>
      :children
    </li>
  endforeach
  </ol>
endif

This little file is located in the navigation folder in partials. Let’s move onto the next partial.

Footer

Let’s finish up the footer partial so we can get to our template files:

    <footer>
        <hr />
      <p id="footer">&copy; Copyright <strong>@name</strong> @current_year <a class="atom-rss" href="@root_path/?/feed/">RSS</a></p>
        </footer>

I don’t think this needs any explanations really. The @name variable is again, the name of the blog, @current_year is a global variable that show you the current year.

Category-lists

Category lists is the main loop we’ll be using to view all blog posts

foreach $root do
  if $children do
    <ul class="posts">
      foreach $children do
        <li>
        if @thumb do <img src="@thumb" class="project-thumb" alt=""> endif
          <h2>            
            <a href="@url">@title</a> - <small>@date</small>
          </h2>
        </li>
      endforeach
    </ul>
  endif
endforeach

This will list ALL child pages. In our current setup, we only have posts as children but you can easily change the loop to show current page children by removing the “foreach $root do” and “endforeach” at the end. I don’t plan to use child pages so I’ll be skipping that.

Templates

Now that we have all our “common” partials, let’s start with the pages. The best part of creating partials is that we basically dealt with the main structure of a page. What’s left is the main content.

Category.html & Index.html

The category html page is more of a “list all sub-pages” page based on the original stacey theme. Here’s what it looks like (with partials included):

:head
:header
:navigation

<div id="main-content">
<div id="post-content">
      <div id="content">
        :category-lists
      </div>
</div>
</div>
:footer
  </body>
</html>

See how simple this looks? We are playing with several different partials that end up creating almost the entire page for us. I purposely did not add the end body and html tags in the “footer” partial so that we can take out the footer whenever we want to.

Now, the index.html is the same for me; however, you can change this page to resemble the page.html file. Let’s look over that so you can make your decision :)

Page.html

The page template file will determine our page, non-post pages.

:head
:header
:navigation

<div id="main-content">
<div id="main-image">if @mainimage do @mainimage endif

 if !@mainimage do <img src="#" alt="empty" class="empty-image"> endif</div>
<div id="main-title"><h1>@title</h1></div>
<div id="post-content">
      <div id="content">
          @content
      </div>
</div>
</div>
:footer
  </body>
</html>

I added some extra markup for a few features I decided to add to my pages, namely the @mainimage variable. Here’s what the result (with CSS) looks like:

main-image

The addition of a “well, what if mainimage doesn’t exist?” loop ensures that SOMETHING shows up. Currently, I don’t have a backup image but in the second loop, you’d add the URL to the img tag. Here’s what the mainimage variable looks like in our content:

mainimage: <img src="@pathmainimage.png">

or

mainimage:
![main image alt tag](@pathmainimage.png)

Inline will show up as straight html. By adding a break, you’ll be able to use markdown. You can use the @path variable wherever you want to but make sure you follow it by your image name without adding a slash or a space.

Anyways, the rest of the page makes sense, right? Use the @title and @content variables to print exactly that!

Post.html

:head
:header
:navigation

<div id="main-content" class="post">
<div id="main-image">if @mainimage do @mainimage endif

 if !@mainimage do <img src="#" alt="empty" class="empty-image"> endif</div>
<div id="main-title"><h1>@title</h1></div>
<div id="post-content">
    <div id="main-meta">@date</div>
      <div id="content">
       @content
      </div>
</div>
</div>
:footer
  </body>
</html>

Looks the same so why have a different template? Well, check out my site and you’ll see. My post page uses Disqus for commenting, so here’s what you’d add after your content div:

      <hr />
      <div id="comments">
          <div id="disqus_thread"></div>
    <script type="text/javascript">
        /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
        var disqus_shortname = ''; // required: replace example with your forum shortname

        /* * * DON'T EDIT BELOW THIS LINE * * */
        (function() {
            var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
            dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
            (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
        })();
    </script>
    <noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
    <a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>

    </div>

Obviously, replace with your own disqus code or at least ad your disqus_shortname! I purposely didn’t add this to the github repo since everyone uses a different system. I don’t want to intrude!

Optionals

There are some optional partials I decided to create for your use.

Ads

So, I’m sure you use ads, so here’s how to add them. Create an ad_whatever.html file in your partials. I created several:

  • ad_footer
  • ad_affiliate
  • ad_affiliate2
  • ad_adsense

You can include your ad code into each of these (along with necessary markup such anchors and divs). You can THEN include those in your markdown!

content:
Content goes here. Use markdown like so **markdown** and whoops, let's add a partial :ad_affiliate

Perfect for manual ad placement.

CSS

I created a css file to style everything very nicely, you’re welcome download it and use it!
CSS File

Download

Download Preview!

Comments

  1. This was very helpful! Thanks!

  2. Wow! Great tutorial :)

Add Your Comment