Theming Nikola ============== :Version: 5 :Author: Roberto Alsina .. class:: alert alert-info pull-right .. contents:: The Structure ------------- Themes are located in the ``themes`` folder where Nikola is installed, one folder per theme. The folder name is the theme name. A Nikola theme consists of three folders: assets This is where you would put your CSS, Javascript and image files. It will be copied into ``output/assets`` when you build the site, and the templates will contain references to them. The included themes use `Bootstrap `_ and `Colorbox `_ so they are in assets, along with CSS files for syntax highligting and reStructuredText, and a minified copy of jQuery. If you want to base your theme on other frameworks (or on no framework at all) just remember to put there everything you need for deployment. templates This contains the templates used to generate the pages. While Nikola will use a certain set of template names by default, you can add others for specific parts of your site. messages Nikola tries to be multilingual. This is where you put the strings for your theme so that it can be translated into other languages. And these optional files: parent A text file that, on its first line, contains the name of the **parent theme**. Any resources missing on this theme, will be looked up in the parent theme (and then in the grandparent, etc). The ``parent`` is so you don't have to create a full theme each time: just create an empty theme, set the parent, and add the bits you want modified. engine A text file which, on the first line, contains the name of the template engine this theme needs. Currently supported values are "mako" and "jinja". If this file is not given, "mako" is assumed. bundles A text file containing a list of files to be turned into bundles using WebAssets. For example:: assets/css/all.css=bootstrap.css,bootstrap-responsive.css,rst.css,code.css,colorbox.css,custom.css This creates a file called "assets/css/all.css" in your output that is the combination of all the other file paths, relative to the output file. This makes the page much more efficient because it avoids multiple connections to the server, at the cost of some extra difficult debugging. WebAssets supports bundling CSS and JS files. Templates should use either the bundle or the individual files based on the ``use_bundles`` variable, which in turn is set by the ``USE_BUNDLES`` option. Creating a New Theme -------------------- In your site's folder, create a ``themes`` folder. Choose a theme to start from, and create ``themes/yourthemename/parent`` as a file containing the parent theme's name. There, you just created a new theme. Of course it looks exactly like the other one, so let's customize it. Templates --------- In templates there is a number of files whose name ends in ``.tmpl``. Those are the theme's page templates. They are done usig the `Mako `_ template language. If you want to do a theme, you should learn the Mako syntax first. Mako has a nifty concept of template inheritance. That means that, a template can inherit from another and only change small bits of the output. For example, ``base.tmpl`` defines the whole layout for a page but has only a placeholder for content so ``post.tmpl`` only define the content, and the layout is inherited from ``base.tmpl``. These are the templates that come with the included themes: base.tmpl This template defines the basic page layout for the site. It's mostly plain HTML but defines a few blocks that can be re-defined by inheriting templates: * ``extra_head`` is a block that is added before ````, (ex: for adding extra CSS) * ``belowtitle`` is used by default to display a list of translations but you can put anything there. * ``content`` is where the inheriting templates will place the main content of the page. * ``permalink`` is an absolute path to the page (ex: "/archive/index.html") This template always receives the following variables you can use: * ``lang`` is the laguage for this page. * ``title`` is the page's title. * ``description`` is the page's description. * ``blog_title`` is the blog's title. * ``blog_author`` is the blog's author. * ``messages`` contains the theme's strings and translations. * ``_link`` is an utility function to create links to other pages in the site. It takes three arguments, kind, name, lang: kind is one of: * tag_index (name is ignored) * tag (and name is the tag name) * tag_rss (name is the tag name) * archive (and name is the year, or None for the main archive index) * index (name is the number in index-number) * rss (name is ignored) * gallery (name is the gallery name) The returned value is always an absolute path, like "/archive/index.html". * ``rel_link`` converts absolute paths to relative ones. You can use it with ``_link`` and ``permalink`` to create relative links, which makes the site able to work when moved inside the server. Example: ``rel_link(permalink, url)`` * Anything you put in your ``GLOBAL_CONTEXT`` option in ``dodo.py``. This usually includes ``sidebar_links``, ``search_form``, and others. The included themes use at least these: * ``rss_link`` a link to custom RSS feed, although it may be empty) * ``blog_url`` the URL for your site * ``blog_title`` the name of your site * ``content_footer`` things like copyright notices, disclaimers, etc. * ``license`` a larger license badge * ``analytics`` google scripts, or any JS you want to tack at the end of the body of the page. * ``disqus_forum``: a `Disqus `_ ID you can use to enable comments. It's probably a bad idea to do a theme that *requires* more than this (please put a ``README`` in it saying what the user should add in its ``dodo.py``), but there is no problem in requiring less. post.tmpl Template used for blog posts. Can use everything ``base.tmpl`` uses, plus: * ``post``: a Post object. This has a number of members: * ``post.title(language)``: returns a localized title * ``post.date`` * ``post.tags``: A list of tags * ``post.text(language)``: the translated text of the post * ``post.permalink(language, absolute)``: Link to the post in that language. If ``absolute`` is ``True`` the link contains the full URL. This is useful for things like Disqus comment forms. * ``post.next_post`` is None or a Post object that is next newest in the timeline. * ``post.prev_post`` is None or a Post object that is next oldest in the timeline. story.tmpl Used for pages that are not part of a blog, usually a cleaner, less intrusive layout than ``post.tmpl``, but same parameters. gallery.tmpl Template used for image galleries. Can use everything ``base.tmpl`` uses, plus: * ``text``: A descriptive text for the gallery. * ``images``: A list of (thumbnail, image) paths. index.tmpl Template used to render the multipost indexes. Can use everything ``base.tmpl`` uses, plus: * ``posts``: a list of Post objects, as described above. * ``prevlink``: a link to a previous page * ``nextlink``: a link to the next page list.tmpl Template used to display generic lists of links. Can use everything ``base.tmpl`` uses, plus: * ``items``: a list of (text, link) elements. You can add other templates for specific pages, which the user can the use in his ``post_pages`` option in ``dodo.py``. Also, keep in mind that your theme is yours, there is no reason why you would need to maintain the inheritance as it is, or not require whatever data you want. Messages and Translations ------------------------- When you modify templates, you may want to add text in them (for example: "About Me"). Instead of adding the text directly, which makes it impossible to translate to other languages, add it like this:: ${messages[lang]["About Me"]} Then, in ``messages/en.py`` add it along the other strings:: MESSAGES = [ u"Posts for year %s", u"Archive", u"Posts about %s:", u"Tags", u"Also available in: ", u"More posts about", u"Posted:", u"Original site", u"Read in english", u"About Me", ] Then, when I want to use your theme in spanish, all I have to do is add a line in ``messages/es.py``:: MESSAGES = { u"LANGUAGE": u"Español", u"Posts for year %s": u"Posts del año %s", u"Archive": u"Archivo", u"Posts about %s:": u"Posts sobre %s", u"Tags": u"Tags", u"Also available in: ": u"También disponible en: ", u"More posts about": u"Más posts sobre", u"Posted:": u"Publicado:", u"Original site": u"Sitio original", u"Read in english": u"Leer en español", u"About Me": u"Acerca del autor", } And voilá, your theme works in spanish. Don't remove strings from these files even if it seems your theme is not using them. Some are used internally in Nikola to generate titles and similar things. To create a new translation, just copy one of the existing ones, translate the right side of every string to your language, save it and send it to me, I will add it to Nikola!