Skip to content

How to create a custom theme

叡山电车 edited this page Dec 3, 2021 · 10 revisions

Before you start to create custom theme, I recommend strongly to read the tutorial in User Guide to know what Joplin Pages Publisher can do.

Learn By Doing

Step 0: Create theme directory and files

Create a directory named my-beautiful-theme(or whatever you like) under themes directory(you can find its path in "How to create custom theme?" modal), and create a config.json file there.

Step 1: Define some pages

In config.json, add a pages field, and define some pages. For example:

{
  "pages": {
    "index" : [],
    "article: [],
    "archives: [],
    "about": []
  }
}

This tells Joplin Pages Publisher that there are 4 types of pages in our site.

Here are explanation of concepts:

  • There should be a field named pages in config.json. pages are a object, whose keys are all Page Name (So in example above, index / article / archives / about are Page Name(s))
  • Any string except for those starts with _ is acceptable as a page name
  • Each page name should hold a array value which represents customizable(in Page panel of Joplin Pages Publisher's UI) field of this page(in example above, they are all empty array, which means no customizable fields). Basically, if you are not going to share your theme to others, no customizable field is needed.

Step 2: Write templates for pages

Create a directory named templates, where we will place our ejs templates.

For example, we create a index.ejs(index is one of the Page Names).

index.ejs:

<html>
  <head>
    <meta charset="UTF-8" />
    <title>Homepage</title>
  </head>
  <body>
    <h1>Hello, Welcome to my site.</h1>
    <ul>
      <!-- $link is a object that contains url of each page -->
      <li><a href="<%= $link.archives %>">Archives</a></li>
      <li><a href="<%= $link.about %>">About</a></li>Then create four template file there:
    <ul>
  </body>
</html>

Here are explanation of concepts:

  • Every Page defined in config.js should has a corresponding ejs template(with the same name)
  • Some env variables(listed in appendix) will be injected for ejs templates rendering(for example, $link).
  • Any ejs syntaxes is available, such as include
  • Assets(.js file / .css file / images etc.) of pages should be placed in _assets directory under my-beautiful-theme

Step 3: Select your custom theme in UI, and generate

Open Site panel, and select your theme to take effect.

Click generate button to see final result.

Reference

Default theme is a good reference. There are not differences between Default theme and your custom theme in mechanism

Appendix

Env variables for a page

interface PageEnv {
  $page: {
    // Custom field and its value of a this page
    [customizableFieldName: string]: unknown;
  };
  // Information of this site
  $site: {
    // All articles of this site(sort by created time)
    articles: Article[];
    // Site generated time(Unix timestamp)
    generatedAt: number;
    [customizableFieldName: string]: unknown;
  };
  // Information of a article. Only injected for page whose name is "article"
  $article?: Article;
  // URL of each page
  $link: {
    rss: string; // will be empty string if RSS is disabled
    [pageName: string]: string;
  };

  // lodash utils
  // https://lodash.com/
  _: typeof lodash;

  // moment utils
  // https://momentjs.com/docs
  moment: typeof moment;
}

interface Article {
  noteId: string;
  // URL of this article page. No `/` in the start!
  fullUrl: string;
  // raw Markdown text
  content: string;
  // rendered HTML text
  htmlContent: string;
  title: string;

  // Unix timestamp
  createdAt: number;
  updatedAt: number;

  // front matter of this article
  meta: Record<string, any>;
  tags: string[];
}