Support Center

About Koken

This Help Center provides support for Koken, a free content management system designed for photographers, artists and designers.

Build your first theme - Part three

Build your first theme - Part three

Last Updated: May 20, 2014 02:22PM EDT

So far we've built a basic portfolio theme, then enhanced the theme to include archival pages for viewing content by tag, category or date. This article will continue to enhance our basic theme by incorporating timeline templates. These templates will display all your latest albums, album updates, content and essays as a unified stream sorted by recency. Here are the templates we'll be building in order:

Template Description
timeline.lens Displays a unified stream of all images, albums and essays by date.
date.lens Displays timeline data filtered by day, month or year.
tag.lens Displays timeline data filtered by tag.
category.lens Displays timeline data filtered by category.

timeline.lens

timeline.lens displays all published albums, content and essays by date. Anytime something new is published or updated an "event" is triggered and the timeline publishes that item at the top of its stream. This provides site visitors with a convenient place to see everything that's new on a single page.

Here's the basic starting outline for a timeline.lens template:

<!DOCTYPE html>
<head>
  <koken:meta />
  <koken:title />
  <koken:settings />
</head>
<body>
<koken:load>
  <header>
    <h1>{{ site.title }}</h1>
    <nav>
     <koken:navigation />
    </nav>
  </header>
  <ol class="list">
    <koken:loop>
      <li>
        <h2>
          <koken:link><koken:time /></koken:link>
        </h2>
        <koken:event>
          <koken:event_album>           
          </koken:event_album>
          <koken:event_album_update>
          </koken:event_album_update>
          <koken:event_content>
          </koken:event_content>
          <koken:event_essay>
          </koken:event_essay>
        </koken:event>
      </li>
    </koken:loop>
  </ol>
<koken:else>
  <koken:note>
    No timeline data found. 
  </koken:note>
</koken:load>
</body>
</html>

The meat of the template is the area enclosed by the <koken:event> tag. This tag serves as both a loop and router to the appropriate markup for each event type. Here's a breakdown of each event tag and which action triggers their use:

  • <koken:event_album> — Rendered when a new public album is published.
  • <koken:event_album_update> — Rendered when an existing public album is updated.
  • <koken:event_content> — Rendered when a new image or video is uploaded.
  • <koken:event_essay> — Rendered when a new essay is published.

We recommend adding all four of these events to your timeline.lens markup, but you can leave some out if you'd like. An event will be ignored if Koken isn't able to find the necessary markup for the content being displayed.

Let's now extend this timeline markup with Lens tags and variables to output the data each event contains.

<!DOCTYPE html>
<head>
  <koken:meta />
  <koken:title />
  <koken:settings />
</head>
<body>
<koken:load>
  <header>
    <h1>{{ site.title }}</h1>
    <nav>
     <koken:navigation />
    </nav>
  </header>
  <ol class="list">
    <koken:loop>
      <li>
        <h2>
          <koken:link><koken:time /></koken:link>
        </h2>
        <koken:event>
          <koken:event_album>           
            <koken:link>
              <koken:img />
            </koken:link>
            <h3>
              <koken:link>
                {{ album.title }}
              </koken:link>
            </h3> 
            <p>
              {{ album.summary }}
            </p>
          </koken:event_album>
          <koken:event_album_update>
            <koken:loop>
              <koken:img />
            </koken:loop>
            <h3>{{ album.title }} ({{ content.length }} new items)</h3> 
            <p>
              {{ album.summary }}
            </p>
          </koken:event_album_update>
          <koken:event_content>
            <koken:content_image>
              <koken:link>
                <koken:img />
              </koken:link>
            </koken:content_image>
            <koken:content_video>
              <koken:video />
            </koken:content_video>
            <h3>
              <koken:link>
                {{ content.title | content.filename }}
              </koken:link>
            </h3> 
            <p>
              {{ content.caption }} 
            </p>
          </koken:event_content>
          <koken:event_essay>
              <koken:featured_image>
                <koken:link>
                  <koken:img />
                </koken:link>
              </koken:featured_image>
            <h3>
              <koken:link>
                {{ essay.title }}
              </koken:link>
            </h3> 
            <p>
              {{ essay.excerpt }}
            </p>
          </koken:event_essay>
        </koken:event>
      </li>
    </koken:loop>
  </ol>
<koken:else>
  <koken:note>
    No timeline data found. 
  </koken:note>
</koken:load>
</body>
</html>

As you can see, applicable Lens tags and variables were added to each of the events to render their particular type of content. If some of this markup looks familiar, it should — we used these Lens tags and variables for some of the templates in our first theme design tutorial.

See those <koken:link> tags inside each event? Each of those links the event to the appropriate content page to see more. Album events link to album.lens, individual images/videos link to content.lens, and essays link to essay.lens.

If all you want is a single timeline view for your site, you can stop here. If however you'd like to offer timeline views filtered by date, tag or category, read on!

date.lens

The date.lens template extends timeline.lens by displaying all events from a particular day, month or year. You can design the page however you want, but chances are you'll probably want it to look like timeline.lens, so we'll re-use and enhance its markup. Here's example code:

<!DOCTYPE html>
<head>
  <koken:meta />
  <koken:title />
  <koken:settings />
</head>
<body>
<koken:load>
  <header>
    <h1>{{ site.title }}</h1>
    <nav>
     <koken:navigation />
    </nav>
  </header>
  <koken:breadcrumbs />
  <h1>All content published in <koken:time /></h1>
  <ol class="list"> 
    <koken:loop>
      <!-- insert same koken:event code from timeline.lens -->
    </koken:loop>
  </ol>
<koken:else>
  <koken:note>
    No timeline data found. 
  </koken:note>
</koken:load>
</body>
</html>

This will look pretty much the same as timeline.lens but we'll preface the events with <koken:breadcrumbs /> to output a hierarchical list of navigation links so the site visitor knows where they are, plus a header that includes {{ event.title }} to display the date being viewed.

So now you may be wondering how someone would get to date.lens when navigating your site. To do that we need to update timeline.lens with date archive links.

To display a drop-down of all timeline months, add a <koken:select> tag. When a user selects a month, date.lens loads and displays all timeline events that occurred within that time frame. You could add this select to both timeline.lens and date.lens to display archive links in both templates.

<koken:load source="timeline" filter:scope="month">
  <koken:select label="Select month" />
</koken:load>

If you'd prefer something more basic you could link to date.lens by wrapping the <koken:time /> tag outside of <koken:event> with <koken:link>, like so:

<koken:link>
  <koken:time />
<koken:link>

If you include <koken:time /> inside an event, add to="date" so Koken knows you want date.lens and not the content page for the event.

<koken:link to="date">
  <koken:time />
<koken:link>

tag.lens

tag.lens is just like date.lens except its filter criteria is by tag. We'll use the exact same markup date.lens uses but modify the header to acknowledge that only events with content assigned a particular tag are showing. Again, you're free to make the design of tag.lens completely different if you'd like to. But this'll do for today:

<!DOCTYPE html>
  <head>
    <koken:meta />
    <koken:title />
    <koken:settings />
  </head>
  <body>
    <koken:load>
      <nav>
        <koken:navigation />
      </nav>
      <koken:breadcrumbs />
      <h1>You are viewing all content tagged #{{ event.title }}</h1>
      <koken:loop>
        <koken:time />
        <!-- insert same koken:event code from timeline.lens -->
      </koken:loop>
    <koken:else>
      <koken:note>
        No timeline data found.
      </koken:note>
    </koken:load>
  </body>
</html>

Now let's talk about how someone would view tag.lens. Like our earlier date.lens template, we need to provide links. You can do that here by adding the <koken:tags> tag to timeline.lens to output a list of all tags. Tag order is automatically sorted by how many times they've been used. We'll then wrap each tag with <koken:link> to view timeline data by tag. Here's example markup you could add anywhere outside <koken:event> in timeline.lens:

modified timeline.lens

<koken:tags>
  <p>
    <strong>Filter by tag:</strong>
    <koken:loop>
      <koken:link>
        #{{ tag.title }}
      </koken:link>
    </koken:loop>
  </p>
</koken:tags>

If you'd prefer not to display all tags but rather the tags assigned the content inside each event, use the same <koken:tags> markup but edit <koken:link> to include to="tag" to direct it toward tag.lens. Like so:

modified timeline.lens

<koken:event>
  <koken:event_album>
    <-- album template tags and variables from earlier -->
    <koken:tags>
      <koken:loop>
        <koken:link to="tag">
          {{ tag.title }}
        </koken:link>
      </koken:loop>
    </koken:tags>
  </koken:event_album>
</koken:event>

As a footnote, if you left out to="tag" the links would request instead the content's archive template. So using our markup above as an example, each tag would request archive.albums.lens to view only albums assigned that tagged.

category.lens

Will probably come as no surprise to hear that, yes, category.lens can also share the same timline markup. Here's example code with a modified header:

<!DOCTYPE html>
<head>
  <koken:meta />
  <koken:title />
  <koken:settings />
</head>
<body>
<koken:load>
  <header>
    <h1>{{ site.title }}</h1>
    <nav>
     <koken:navigation />
    </nav>
  </header>
  <koken:breadcrumbs />
  <h1>Most recent content tagged {{ category.title }}</h1>
  <ol class="list">
    <koken:loop>
      <li>
        <!-- insert same koken:event code from timeline.lens -->
      </li>
    </koken:loop>
  </ol>
<koken:else>
  <koken:note>
    No timeline data found. 
  </koken:note>
</koken:load>
</body>
</html>

Now let's do the same thing we did with tags by adding categories to timeline.lens. If you wanted to display all categories, add <koken:categories> outside of <koken:event>, like so:

modified timeline.lens

<koken:categories>
  <strong>Filter by category:</strong>
  <koken:loop>
    <koken:link>
      {{ category.title }}
    </koken:link>
  </koken:loop>
</koken:categories>

If you insert the same markup inside an event, only the categories assigned to each event would be displayed. Here again you'd need to edit <koken:link> to include to="category" to use the category.lens template. If not included the appropriate archive.*.lens would load instead.

modified timeline.lens

<koken:event>
  <koken:event_album>
    <-- album template tags and variables from earlier -->
    <koken:categories>
      <ul>
        <koken:loop>
          <li>
            <koken:link to="category">
              <{{ category.title }}>
            </koken:link>
          </li>
        <koken:loop>
      </ul>
    </koken:categories>
  </koken:event_album>
</koken:event>

Create a new album in the Library, add some content to it, then assign some categories. Your timeline should display the album plus category links.

Extra credit: substitute tag.lens and category.lens for archive.*.lens

Here's a little tip. Now that you have category.lens and tag.lens in your theme, do you need the archive.albums.lens, archive.contents.lens and archive.essays.lens templates created in our first theme building article? Answer: no. If you'd prefer to keep things simpler and not offer individual archive pages for each content type and archive pages that display everything, simply remove any of the archive.*.lens templates from your theme. Any tag or category links that would normally point to those templates will now load tag.lens and category.lens using the same criteria.

Source files

Click the button below to download all the templates covered in this article. We also recommend checking out our Blueprint theme, which is a bare bones, skeleton theme that also demonstrates many of the topics covered here.

Download example templates

Where to from here

We covered a lot of ground here. By now you should at least have a timeline.lens template loading all your latest stuff. Or perhaps you went all-the-way and added tag.lens, category.lens and date.lens to view archival timeline data as well. Whatever you decided to add, the basic theme you started with can now do a whole lot more.

So, what's next? One last article before we call it a day. We're going to show you how to add tags.lens and categories.lens templates to display — you guessed it — all the tags and categories created in Koken. These tags and category indexes will then link to tag.lens and category.lens, as well show after the jump. Click the link below to learn more.

support@koken.me
http://assets3.desk.com/
false
koken
Loading
seconds ago
a minute ago
minutes ago
an hour ago
hours ago
a day ago
days ago
about
false
Invalid characters found
/customer/en/portal/articles/autocomplete