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

Build your first theme

Last Updated: Oct 16, 2014 04:48PM EDT

This is the first in a multi-part series of articles explaining the basics of Koken theme creation. If you're a beginner, you're in the right place. We're going to keep it simple and construct a theme one template at a time. The theme won't be pretty, but will provide you with enough foundation to start flying on your own.

Note: you'll need to understand the basics of editing HTML and be comfortable uploading files to a web server in order to follow along.

Create files

First step is to create a theme package. Every theme needs the following:

folder

Create a folder on your desktop and name it after your theme.

info.json

Create an empty text document and save it to your folder as "info.json". This will hold configuration info for your theme.

preview.jpg

Create a preview image that is 260px wide by 167px high and save it as "preview.jpg". to your theme's folder. This will be displayed in the Site console.

css/settings.css.lens

This will be your theme's CSS file. You can load other CSS files as well, but this one is parsed by Koken to publish dynamic theme setting values.

Edit info.json

Open the info.json you created and copy/paste the following:

{
  "name": "Theme name",
  "version": "1.0",
  "description": "Brief description of this theme",
  "demo": "http://yoursite.com/demo",
  "author": {
    "name": "Your name",
    "link": "http://yoursite.com"
  }
}

Replace the values to the right of each property with anything you like. This data will be used when the theme appears in the Site console. All are required with the exception of "demo", which publishes a link to an outside theme demonstration. Save and close the info.json file when complete.

Create template files

Now let's talk about templates. Koken has a defined set of templates that are used to render content. You don't have to include each one, but we recommend including at least those in the table below. Create separate documents for each of the following (using the same file names) and save each to your theme folder.

Template Description
album.lens Displays a single album.
albums.lens Displays a list of public albums.
content.lens Displays a single image or video.
contents.lens Displays a list of public images and videos.
essay.lens Displays a single published essay.
essays.lens Displays a list of published essays.
index.lens Displays featured content.
page.lens Displays a custom page.

Add HTML markup

Lens templates are marked up with your own HTML plus Lens template tags for publishing content. Here's some basic markup that can be used in any template:

<!DOCTYPE html>
  <head>
    <koken:meta />
    <koken:title />
    <koken:settings />
  </head>
  <body>
    <header>
      <h1>{{ site.title }}</h1>
      <nav>
       <koken:navigation />
      </nav>
    </header>
    <koken:load>
      <!-- insert Lens template tags here -->
    <koken:else>
     <koken:note>No data found</koken:note>
    </koken:load>
    <footer>
      {{ site.copyright }}
    </footer>
  </body>
</html>

In the above, Koken fills in the template's <head> region with metadata from Koken's Settings, <koken:title /> to output a dynamic title element for each page, plus <koken:settings /> to load the CSS document saved to css/settings.css.lens. Inside the body's header Koken displays the title of your site plus your primary site navigation. After that <koken:load> is used to load the template's data. And finally a footer is added to display your site copyright.

Install and assign theme

To make sure everything is setup right, let's install what you have so far. Connect via FTP to the server where Koken is setup and open the koken/storage/themes folder. Upload to /themes your theme folder. When complete, open your web browser and sign-in to Koken. Click on Site in the top navigation, then click on "Themes" in the bottom row. You should see your theme in the list of installed themes. Click on your theme to preview, then click the "Use theme" button to make your theme the current draft.

Tip: For performance, template markup on your live site is cached by default. Templates loaded in Draft are never cached. If the theme you are developing is used by your live site, and you want to see markup edits there, click on Settings in the main console navigation, then > Publishing and uncheck "Cache all site templates". We recommend turning this back on when edits are finished and your site is live.

Edit and preview templates

Your theme may be just a bunch of blank pages, but great progress has been made! All the basics are now in place to move on to bigger things. We're now going to use one of our templates (album.lens) to explain how template tags are added, how content is previewed, then provide tips for formatting content.

album.lens

album.lens is used to display a single public or unlisted album. Check the Library to ensure you have at least one album with media in it before moving forward. Once you've confirmed that, edit the album.lens template to use the basic markup from above plus the album's title and content.

<!DOCTYPE html>
<head>
  <koken:meta />
  <koken:title />
  <koken:settings />
</head>
<body>
<header>
  <h1>{{ site.title }}</h1> 
  <nav>
    <koken:navigation />
  </nav>
</header>
<koken:load>
  <h2>{{ album.title }}</h2>
  {{ album.description paragraphs="true" }} 
  <p>
  <koken:time />
  </p>
  <ol class="grid">
    <koken:loop>
      <li>
        <koken:link>
          <koken:img />
        </koken:link>
      </li>
    </koken:loop>
  </ol>
<koken:else>
  <koken:note>
    No album data found 
  </koken:note>
</koken:load>
<footer>
  {{ site.copyright }} 
</footer>
</body>
</html>

In the above we print the album's title then loop over each item inside. Inside that loop we use <koken:img /> to render an image. If the item is a video, a keyframe from the video will be displayed (assuming ffmpeg is supported on your server). That image is wrapped with <koken:link>, which will load the image/video using the content.lens template, which we'll create a little later.

So how do we preview this template to make sure it works? We do that in the Site interface.

Add site link

With at least one public album containing content available, enter Site and click "Add links" in the left column. A sheet will appear containing linkable content. Click the "Add" button next to any album to toggle its visibility (to "Added"). When finished click "Done". A link to your album will appear in the left column. Click that album link, and you will see the album's content displayed using album.lens in the main preview area. Should appear something like this:

Image formatting

You'll notice that the page contains a bunch of really big images that increase/decrease in size when the browser window is resized. That's because Koken publishes "responsive" images by default, which is a fancy way of describing images that scale to their surroundings. Koken automatically increases and decreases every image dimension for use in responsive page layouts that adapt to smaller and larger screen sizes.

Image size can be controlled by applying a width to an image's container (in this case the <li>) or by adding fixed dimensions to the <koken:img /> tag.

Let's start with responsive images. Our album images are already in an ordered list, so we can tap into that by adding some style markup to settings.css.lens. Here's some example code:

img {
  width:100%;
  max-width:100%;
  height:auto;
}

ol.grid li {
  list-style:none;
  display:inline-block;
  margin:0 10px 10px 0;
  width:15%;
}

These styles will apply to each <li> and <img> included in the list. The <li> has a fluid width of 15% and is displayed as an inline-block to render them side by side. We also apply some sizing markup to <img> to make it scale more fluidly. Here's what it looks like now:

Expand and contract your browser. Every image will scale to its container, and Koken will work behind-the-scenes dynamically swapping each image with larger/smaller versions to accommodate when necessary. This fluidity provides site designers with the best possible image quality and file sizes across every screen size.

If you're not interested in designing a responsive site, and would rather display images at fixed dimensions, you can do that as well. Edit your <koken:img /> tag to look like this:

<koken:img width="125" height="125" />

Refresh the template and custom images will be generated using your maximum width and height.

Moving on

There are more formatting options for images, but the above should be enough to get you started. Check out our <koken:img /> documentation for more formatting options. For now let's get back to templates.

albums.lens

Now let's edit your albums.lens template. This template displays a list of all your public albums. Open albums.lens in your text editor and add the following:

<!DOCTYPE html>
<head>
  <koken:meta />
  <koken:title />
  <koken:settings />
</head>
<body>
<header>
  <h1>{{ site.title }}</h1> 
  <nav>
    <koken:navigation />
  </nav>
</header>
<koken:load>
  <ol class="grid">
    <koken:loop>
      <li>
        <koken:link>
          <koken:img size="3:2" />
        </koken:link>
        <h2> 
          <koken:link>
            {{ album.title }} 
          </koken:link>
        </h2> 
      </li>
    </koken:loop>
  </ol>
<koken:else>
  <koken:note>
    No public albums found 
  </koken:note>
</koken:load>
<footer>
  {{ site.copyright }} 
</footer>
</body>
</html>

In this markup, <koken:loop> loops over each public album, prints its title, followed by an image (the album's primary cover).

Image formatting

Alright, so now we need to decide how to format the images. Most designers prefer a uniform size for album covers. You do that by assigning size to <koken:img> as illustrated above. This property accepts aspect ratios, so if 3:2 isn't your thing, change it to whatever you want.

You'll also notice that each album cover and title is wrapped with <koken:link>. These create hyperlinks that link to album.lens, which we added a template for earlier.

Save the template, refresh the browser, then click "Albums" in the navigation or in the left column of Site. The albums.lens template will load and display each album title plus its primary cover published. Expand and contract your browser, and (just like our album.lens example) each cropped image will be dynamically swapped with optimized versions at every dimension.

contents.lens

contents.lens displays all your uploaded (public) images and videos from the Library. Here's some example markup:

<!DOCTYPE html>
  <head>
    <koken:meta />
    <koken:title />
    <koken:settings />
  </head>
  <body>
    <header>
      <h1>{{ site.title }}</h1>
      <nav>
       <koken:navigation />
      </nav>
    </header>
    <koken:load>
      <h2>Latest uploads</h2>
      <ol class="grid">
        <koken:loop>
          <li>
            <koken:link>
              <koken:img />
            </koken:link>
            <koken:link>
              {{ content.title | content.filename }}
            </koken:link>
          </li>
        </koken:loop>
      </ol>
    <koken:else>
      <koken:note>
        No images or videos found
      </koken:note>
    </koken:load>
    <footer>
      {{ site.copyright }}
    </footer>
  </body>
</html>

So by now this should start looking familiar to you. Just like we did earlier in albums.lens, contents.lens loops over content and prints titles as well as timestamps through <koken:time>. You'll also notice a <koken:link> tag wrapping <koken:img />. This will publish hyperlinks to the content.lens template for each image (which we'll create next). Another detail you may notice — the content title. Lens variables can fallback to other variables if the first value is empty. So here we first try to publish the image/video's title, and if that's not available we use the filename instead.

Save contents.lens, refresh your browser, then click on "Content" in the navigation or left column. This will load contents.lens in the main area. Clicking each thumbnail or title will load that item using content.lens, which we'll add markup to next.

content.lens

content.lens is used to view a single image or video from the Library. Think of it as the permalink page for everything you upload. Let's start with some basic template markup:

<!DOCTYPE html>
<head>
  <koken:meta />
  <koken:title />
  <koken:settings />
</head>
<body>
<header>
  <h1>{{ site.title }}</h1> 
  <nav>
    <koken:navigation />
  </nav>
</header>
<koken:load>
  <h2> {{ content.title | content.filename }} </h2> 
  <koken:content_image>
    <koken:img />
  </koken:content_image>
  <koken:content_video>
    <koken:video />
  </koken:content_video>
  {{ content.caption paragraphs="true" }} 
<koken:else>
  <koken:note>
    No image or video found 
  </koken:note>
</koken:load>
<footer>
  {{ site.copyright }} 
</footer>
</body>
</html>

Here we print the content's title or filename if a title doesn't exist. We then check to see what kind of content it is (image or video) using the <koken:content_image> and <koken:content_video> tags. If an image, we render it using <koken:img />. If a video, we render it using <koken:video />. Finally, we display the content caption with paragraphs set to "true" so that it's wrapped with <p> tags.

Save content.lens and refresh your browser. To preview your markup, click on "Content" in the navigation or left column, then click any image/video to view it in content.lens.

essays.lens

essays.lens is for displaying all published essays. Here's some example markup:

<!DOCTYPE html>
<head>
  <koken:meta />
  <koken:title />
  <koken:settings />
</head>
<body>
<header>
  <h1>{{ site.title }}</h1> 
  <nav>
    <koken:navigation />
  </nav>
</header>
<koken:load>
  <ol class="list">
    <koken:loop>
      <li>
        <article>
          <h2> 
            <koken:link>
              {{ essay.title }} 
            </koken:link>
          </h2>
          {{ essay.content paragraphs="true" }} 
        </article>
      </li>
    </koken:loop>
  </ol>
<koken:else>
  <koken:note>
    No published essays found 
  </koken:note>
</koken:load>
<footer>
  {{ site.copyright }} 
</footer>
</body>
</html>

Here we loop over every published essay and create an article containing the title and content for each. We also wrap each title with <koken:link> to link each essay to essay.lens to create a permalink for it.

Save the template, refresh the browser, then click "Essays" in the navigation or left column of Site. The essays.lens template will load and display all published essays.

essay.lens

essay.lens is used to view a single published essay. Its example markup is nearly identical to essays.lens, but because we're only loading a single essay a loop isn't needed. Here's the example:

<!DOCTYPE html>
<head>
  <koken:meta />
  <koken:title />
  <koken:settings />
</head>
<body>
<header>
  <h1>{{ site.title }}</h1> 
  <nav>
    <koken:navigation />
  </nav>
</header>
<koken:load>
  <article>
    <h2> 
      <koken:link>
        {{ essay.title }} 
      </koken:link>
    </h2> 
    <p>
      <koken:time />
    </p>
    {{ essay.content paragraphs="true" }} 
  </article>
<koken:else>
  <koken:note>
    No published essay found 
  </koken:note>
</koken:load>
<footer>
  {{ site.copyright }} 
</footer>
</body>
</html>

Save the template, refresh the browser, then click "Essays" in the navigation or left column of Site. Click on any of the essay titles to view essay.lens.

index.lens

index.lens is the template used for the front page of your site. It is setup to automatically load featured content as its data source. In the example below we show featured content, but because its markup is nearly the same as our earlier contents.lens example we're going to mix things up a bit and load some additional content: featured albums. Here it is:

<!DOCTYPE html>
  <head>
    <koken:meta />
    <koken:title />
    <koken:settings />
  </head>
  <body>
    <header>
      <h1>{{ site.title }}</h1>
      <nav>
       <koken:navigation />
      </nav>
    </header>
    <koken:load>
      <h1>Featured content</h1>
      <ul>
        <koken:loop>
          <li>
            <koken:link>
              <koken:img />
            </koken:link>
            <koken:link>
              {{ content.title | content.filename }}
            </koken:link>
          </li>
        </koken:loop>
      </ul>
    <koken:else>
       <koken:note>
        No featured content found
     </koken:note>
    </koken:load>
    <koken:load source="featured_albums">
      <h1>Featured albums</h1>
      <ol>
        <koken:loop>
          <li>
            <koken:link>
             <koken:img size="3:2" />
            </koken:link>
            <koken:link>
              {{ album.title }}
            </koken:link>
          </li>
        </koken:loop>
      </ol>
     <koken:else>
       <koken:note>
        No featured albums found
     </koken:note>
    </koken:load>
    <footer>
      {{ site.copyright }}
    </footer>
  </body>
</html>

Here's what's going on above. The first <koken:load> loads data for index.lens (featured content) which we then loop over and output titles and thumbnails just like we did in contents.lens. Thereafter we add another <koken:load> tag that requests featured albums data. Then as we did before we loop over that data and output the title and thumbnail of each featured album.

Save the index.lens template, refresh your web browser, and click "Home" in the left column of Site. Assuming you have both featured content and albums assigned in the Library, you should see the title and thumbnail image for both sets of data.

If you want to dive a little deeper into other data you may request with <koken:load>, click here to read more.

Does index.lens have to be the front page?

Nope! Your site's front page may use a different template than index.lens. You do so by defining a different template in your info.json file with the default_front_page property. Add it like so, then assign the name of the template you want to use with no file suffix.

{
  "name": "Theme name",
  "version": "1.0",
  "description": "Brief description of this theme",
  "demo": "http://yoursite.com/demo",
  "author": {
    "name": "Your name",
    "link": "http://yoursite.com"
  }

  "default_front_page": "contents",

  ...
}

Additionally, a publisher may assign their own front page by editing their navigation in Site.

page.lens

Alright, final template!

page.lens is used to publish custom pages created in Text. Pages are similar to essays, but are standalone pages instead of entries as part of a feed. Because the publisher can input their own HTML, template markup for page.lens is simple, as shown below.

<!DOCTYPE html>
  <head>
    <koken:meta />
    <koken:title />
    <koken:settings />
  </head>
  <body>
    <header>
      <h1>{{ site.title }}</h1>
      <nav>
       <koken:navigation />
      </nav>
    </header>
    <koken:load>
      <h1>{{ page.title }}</h1>
      {{ page.content }}
    <koken:else>
     <koken:note>
       No page found
      </koken:note>
    </koken:load>
    <footer>
      {{ site.copyright }}
    </footer>
  </body>
</html>

Save the page.lens template, refresh your web browser, then click "Edit links" in the left column of Site. In the sheet that appears, scroll down until you see a "Custom pages" section. Click the "Hidden" button next to any page to show it. Click "Done" when finished, then click on the page link in the left column to preview page.lens.

If you don't see a "Custom pages" section in the sheet, you probably haven't created any pages. Click over to Text then click the plus button at bottom left to create a temporary page to test with.

Pagination

Now that you have your baseline templates in place there's one last thing to talk about — pagination. Koken's API returns a maximum of 100 items anytime data is requested with <koken:load>. If you don't plan on displaying more than 100 items on any page, then you don't need to bother with this. If you do, then you will need to implement pagination so that all your content can be viewed. There are two types of pagination you can use: infinite and linked.

Infinite pagination

Infinite pagination dynamically requests additional data when a user scrolls their web browser to the bottom of the displayed data. The next 100 items are loaded, looped, and output just the same as the initial batch. To use this style of pagination, simply add infinite="true" to any native <koken:load> tag, like so:

<koken:load infinite="true">

Save the template you added infinite to, then (assuming more than 100 items are available) you should see additional content loading.

Note: Infinite pagination is only possible with native template data loaded by <koken:load>. It's not possible to infinitely load data that is requested directly using source in <koken:load>.

Linked pagination

Linked pagination is the more traditional of the two pagination methods. It publishes a list of numerical page links to jump forward and backward across all loaded data. Because contents.lens typically displays the most content, we're going to add pagination to it. Here's the updated markup from earlier:

updated contents.lens

<!DOCTYPE html>
  <head>
    <koken:meta />
    <koken:title />
    <koken:settings />
  </head>
  <body>
    <header>
      <h1>{{ site.title }}</h1>
      <nav>
       <koken:navigation />
      </nav>
    </header>
    <koken:load>
      <h2>Latest uploads</h2>
      <ol class="grid">
        <koken:loop>
          <li>
            <koken:link>
              <koken:img />
            </koken:link>
            <koken:link>
              {{ content.title | content.filename }}
            </koken:link>
          </li>
        </koken:loop>
      </ol>
      <koken:pagination limit="20">
        <koken:pagination_previous>
          <koken:link title="Previous">
            ←
          </koken:link>
        </koken:pagination_previous>
        <koken:pagination_limited_previous>
          <koken:link>...</koken:link>
        </koken:pagination_limited_previous>
        <koken:loop>
          <koken:link class="{{ is_current }}" title="{{ number }}">
            {{ number }}
          </koken:link>
        </koken:loop>
        <koken:pagination_limited_next>
          <koken:link>...</koken:link>
        </koken:pagination_limited_next>
        <koken:pagination_next>
          <koken:link title="Next">
            →
          </koken:link>
        </koken:pagination_next>
      </koken:pagination>
    <koken:else>
      <koken:note>
        No images or videos found
      </koken:note>
    </koken:load>
    <footer>
      {{ site.copyright }}
    </footer>
  </body>
</html>

So as you can see, <koken:pagination> now appears after the ordered list and contains a series of Lens tags that handle paginated links. The limit="20" you see limits the number of page links to 20, after which time the limited tags display elipsis to skip forward and backward to other page sets.

Go ahead and save contents.lens and load it in Site. If you have more than 100 uploads you should see the pagination links at the bottom. You would then need to add pagination to any other list-based template, including albums.lens and essays.lens

Finished!

You made it all the way to the end of our beginners walkthrough. You now know enough to begin styling and enhancing your theme. If you have questions, head over to our discussions area and fire away.

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 isn't pretty, but demonstrates how to do many of the things covered here (and more).

Download example templates

Where to from here

You now know all the basics of theme creation. Keep going by mixing in more of your own HTML and CSS markup to make the theme really shine. Ready to add more templates? Here are your next steps:

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