A better look

Now are site is workig properly but it is really ugly. Let's change this!

CSS

To improve the look of the site we have to use CSS. There are two ways to add CSS to your site: you can link to an external CSS framework or write your own CSS files. Using an external CSS framework like Bootstrap is very easy and can be done just like this

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    {% block title %}
      <title></title>
    {% endblock title %}

  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">

  </head>
  ...

However if you want to customize a little the style you should also write your own css files. To do it first you have to modify the main.py file, and modify it so it looks like this

...

k.miners = [
  miners.DefaultPageMiner(),
  miners.WatchDirectoryMiner(["templates", "static"])
]

k.mappers = [
  mappers.DefaultPageMapper(),
  mappers.DefaultStaticFilesMapper(),
]

k.renderers = [
  renderers.DefaultSiteRenderer(),
  renderers.DefaultStaticFilesRenderer(),
]

...

You can see that we have added two things: a new mapper and a new renderer, DefaultStaticFilesMapper and DefaultStaticFilesRenderer. They are used in combination to copy files from the static directory. It is mainly used for css stylesheets and javascript files. To add these files to our page we have to link them in our template with the url() function, like we did previously

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    {% block title %}
      <title></title>
    {% endblock title %}

    <link rel="stylesheet" href="{{ url('/static/path/to/our/file.css') }}">

  </head>
  ...

Favicon

Now that your site looks better you can add a favicon. The favicon is the little icon you see on the browser address bar. Even if it is very small it is very important because makes your site immediately recognizable among all the other tabs.

To generate a favicon I recommend going to https://favicon.io/. You can create a favicon from test, an image or even emojis. When you have finished click the download button and you should have a zip file. If you open it you can see that there isn't only one image, but there are many images with different formats and sizes, plus a file called site.webmanifest. Copy these files to a directory named root. This directory will contain files that will be placed in the root level of our site, and this is exactly what is needed for the favicons.

Now we need to modify our main.py file again, to tell Kart to render this directory

...

k.miners = [
  miners.DefaultPageMiner(),
  miners.WatchDirectoryMiner(["templates", "static", "root"])
]

k.mappers = [
  mappers.DefaultPageMapper(),
  mappers.DefaultStaticFilesMapper(),
  mappers.DefaultRootDirMapper(),
]

k.renderers = [
  renderers.DefaultSiteRenderer(),
  renderers.DefaultStaticFilesRenderer(),
  renderers.DefaultRootDirRenderer(),
]

...

Like for the static directory, we had to add a mapper and a renderer, DefaultRootDirMapper and DefaultRootDirRenderer in this case. Now if you run main.py again you should see your favicon instead of the ugly default one.

Title

On the right of the favicon on most sites you can see a brief description of the page. On the other hand on our site is written localhost:9000. We can change this by adding a title tag in our html template. Head over to the base.html template and modify it

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    {% block title %}
      <title>{{config.name}}</title>
    {% endblock title %}

...

Now when we go to our site in the browser we should see the name of the site alongside the icon. Still, we can improve this by changing the title to reflect the page content. If we modify our page.html template like this

{% extends "base.html" %}

{% block content %}
<title>{{config.name}} - {{page.title}}</title>
{% endblock content %}

{% block content %}

  {% include 'nav.html' %}

  <h1>{{page.title}}</h1>

  {{page.content|html}}

{% endblock content %}

the title should better reflect the content of the page.

Now we have a beautiful working site, even if very simple. If you don't need to add content very frequently, you probably don't need much more. If that's the case, you can skip the next pages and go to Publishing to learn how to publish your site.

Table of contents