-
Notifications
You must be signed in to change notification settings - Fork 5
Theme Engine
Engrave integrates custom theme engine to be able to create different but powerful themes for each blog / website. It uses PugJS syntax with server-side rendering and client-site javascript for interaction.
Each theme should contain two directories: public
and theme
. Public
contains all files that can and should be accessible from the web. For example all CSS files and images. Theme
directory contains theme's files with pugjs syntax that need to be interpreted by the renderer and may contain some sensitive data. They are not accessible other than by pug renderer.
Default and minimal theme structure looks as follow:
|--public
|--css
|--js
|--theme
|--website.pug
|--index.pug
|--single.pug
|--category.pug
|--404.pug
|--error.pug
File with website.pug
name is actually not used by the rendered but all other top-level files should expand that file. It should contain website base structure. Themes can contain other directories and files. It's a good idea to divide theme into small, separate files dedicated for example for footer, header and other website components.
Theme Engine provides lot of backend data to theme renderer. Some variables are accesible global, but most of them depends on current subpage.
Those variables are accesible on every subpage and can be used in every file.
blog: {
title: string // blog title
slogan: string // blog slogan
domain: string // blog domain without http:// prefix
link_facebook: string // facebook fanpage url (full)
link_twitter: string // twitter account url (full)
link_twitter: string // twitter account url (full)
link_linkedin: string // linkedin account url (full)
link_instagram: string // instagram account url (full)
logo_url: string // blog logo url (full)
opengraph_default_image_url: string
opengraph_default_description: string
categories: [
{
name: string
slug: string
abstract: string // category description (may be used on category page)
}
]
}
Specific fields may not exists or be empty strings so it's necessary to check those both cases before using it.
if blog.slogan && blog.slogan != ''
p= blog.slogan
article: {
title: string,
permlink: string,
username: string,
body: string,
abstract: string, // trimmed body without html and markdown syntax
created: string (Date),
tags: string[];
thumbnail: string; // thumbnail url
votes_count: number,
value: number, // float but should be fixed to 2 digits on page
comments: number, // number of comments
categories: {
name: string,
slug: string,
abstract: string, // category description
}
}
featured: [
// array of article objects
]
Body
field is a valid html code and could be displayed without escaping: Same for abstract (otherwise it will display html-encoded quote characters etc).
div#article-container
div!= article.body
latest: [
// array of latest article objects
]
featured: [
// array of featured article objects
]
To display titles of every article in latest array on main page:
each article in latest
h1= article.title
category: {
name: string,
slug: string,
abstract: string // category long description
}
latest: [
// array of latest article objects per specific category
]
featured: [
// array of featured article objects
]
error
- error message. It's not necessary to display it. Page can be customized
error
- error message. Should be displayed in preformatted text
Engrave backend provides endpoint for fetching comments for specific post. It's crucial to understand that on Steem blockchain, every user comment and article are the same thing - article is just a top-level comment (without parent). In order to get comments you need to provide author
and permlink
. This is a jQuery example:
function getContentReplies(author, permlink, callback) {
$.ajax({
type: "POST",
url: "/comments",
data: {
author: author,
permlink: permlink
},
success: function (data) {
callback(null, data);
},
error: function (data) {
callback(data, null);
}
});
}
In an example above, data
would be a comments array. Every object will contain lot of additional blockchain-related fields but most important one are those:
data: [
{
created: string // Date
rendered: string // ready to display, rendered html code
value: number // reward value, should be fixed to 2 digits manually
children: number // children comments quantity, should be used to optionally fetch children comments to build comments tree
}
]
In order to enable Single Sign-On on your theme, you need to include file provided by Engrave Auth service. Add following file in your theme header:
script(src='https://auth.engrave.website/sslo.js')
After that, you need to create three javascript functions that are called right after specific events:
- onLoad()
- onIdentification(operation)
- onLogout()
Invoked when the script finishes loading the SSO. It is always after onIdentification but should be used to hide JWT token provided by Auth service (it's passed as a query parameter) and to authenticate
Example:
function onLoad(){
const urlParams = new URLSearchParams(window.location.search);
const token = urlParams.get('jwt');
if(token) {
sslssso.login(token); // try to identificate with received token
var url = [location.protocol, '//', location.host, location.pathname].join('');
window.location.replace(url); // redirect to hide query parameter
}
}
Invoked after page load if you have a valid token or after new JWT correct identification (if page is still loaded). If you do not have identification token, this function is not executed. You probably want to save received token in localStorage or cookies if you want to use it in different file (it's necessary to provide JWT token as a header for some operations like comment or vote).
function onIdentification(operation){
const username = operation.payload.data.username;
const jwt = operation.jwt;
localStorage.setItem('aMZr1grXqFXbiRzmOGRM', jwt); // identificator might be random but you need it to get this again from different file
// interact with some UI elements to mark logged user
document.getElementById("nav-login").innerText = "Logout, @" + username;
document.getElementById("nav-login").href = "javascript:sslssso.logout();";
document.getElementById("login-box").style.display = "none";
document.getElementById("comment-form-modal").style.display = "block";
}
Invoked when user logs out, should be used to remove stored token and mark that no user is logged in.
function onLogout(){
document.getElementById("nav-login").innerText = "Login";
document.getElementById("nav-login").href = "/login";
document.getElementById("login-box").style.display = "block";
document.getElementById("comment-form-modal").style.display = "none";
localStorage.removeItem('aMZr1grXqFXbiRzmOGRM');
}
From now on, you should be able to log in and out using Steemconnect. Just redirect user to /login
endpoint and after successful login, it should redirect you to previous location with jwt
token as a query parameter. Use it in onLoad() function and execute sslssso.login(token);
as in provided example. To logout, execute sslssso.logout();
.