Skip to main content

🎨 Template Development Guide

emlog allows for easy template changing. Template files are located in the content\templates directory. Each template is a separate folder, named after the template's English alias. Templates installed via the app store or uploaded from the backend are all saved in this directory.

Template File and Directory Description

File NameDescription
cssStores all CSS style files required by the template
jsStores all JS files required by the template
imagesStores image resources like LOGO required by the template
preview.jpgTemplate preview image displayed in the backend template selection interface. Recommended: 500x300 jpg format
header.phpSite header information, generally including page head information, top title, and navigation bar
echo_log.phpArticle detail page, displaying the content of a single article
log_list.phpHomepage, displaying the article list
footer.phpSite footer information, displaying copyright information, etc.
page.phpPage, displaying custom pages
side.phpSidebar. This file is not required if making a single-column template
module.phpFunctional modules: latest articles, comments, categories, tags, etc.
404.phpCustom error page when the 404 page is not found
pw.phpCustom encrypted article password input page. If this file is missing, the system default style is used [Not Required]
user.phpTemplate loaded by route /user, can be used for user center pages, etc. [Not Required]
plugins.phpTemplate system call file. Once the template is enabled, this file will be automatically loaded by the system. Can be used to implement plugin-like functions. [Not Required]
options.phpTemplate settings configuration file, can build richer setting items. [Not Required]
callback.phpTemplate event callback function definition. See the event callback section documentation for details [Not Required]
custom_fields.phpPreset article custom fields required by the template itself [Not Required]

Template Engine

emlog does not use any other third-party template engines. It directly uses native PHP syntax markers to embed HTML to generate dynamic pages. This not only reduces the learning burden for developers but also greatly improves page loading and rendering efficiency.

// Embed variable
<div><?= $value ?></div>

// Loop
<?php foreach ($abc as $v) :?>
<div><?= $v ?></div>
<?php endforeach;?>

// Condition
<?php if($a == 'abc') :?>
<div>hello</div>
<?php endif;?>

Common Code

Prevent Direct Access

The following line of code exists at the beginning of every PHP file in the template directory. Its purpose is to prevent the PHP script where the code is located from being directly accessed and executed. It must be retained.

if(!defined('EMLOG_ROOT')) {exit('error!');}

Or

defined('EMLOG_ROOT') || exit('access denied!');

Reference Template File

The following two lines of code are used to call the code of side.php and footer.php in the template folder to the current position of the current file.

require_once View::getView('side'); 
require_once View::getView('footer');

// View is the template view controller. View::getView('file name', 'file suffix') will return the corresponding file under the current template installation path.
// The second parameter of the getView function is a default parameter. If no value is passed, it will return the file path with .php file suffix by default.

File Description

header.php

Site header information, generally including page head information, top title, and navigation bar.

Header Information

The comment content at the beginning is necessary information for the template, which will be displayed in the backend template management interface. Please make sure to fill it in completely.

/*
Template Name: Default Template
Version: 1.0
Template Url: https://www.emlog.net/template/
Description: The default template of emlog
Author: emlog
Author Url: https://www.emlog.net/author/index/577
*/
tip

For Template URL and Author URL, please use the application link and author page from the official website emlog.net. Other non-official links will not be displayed as hyperlinks in the backend.

Load Template File

require_once View::getView('module'); // Load template common module.

Variables & Constants

Variable & ConstantTypeDescription
$site_titleVariableSite title (affected by backend SEO optimization settings)
$site_keyVariableSite keywords
$site_descriptionVariableOutput site browser description (affected by backend SEO optimization settings)
$blognameVariableSite title
$bloginfoVariableSite subtitle
BLOG_URLConstantURL of the site homepage, output format like https://emlog.net/
TEMPLATE_URLConstantURL of the template folder, used to load CSS, JS, and other content inside the template, output format like http://emlog.net/blog/content/templates/default/

The above variables and constants can be output in the template in the following way:

<?= $page_url ?>
<?= BLOG_URL ?>

footer.php

Site footer information, displaying copyright, ICP filing, and other information.

Variables & Constants

Variable, ConstantTypeDescription
$icpVariableICP filing number set in the backend
$footer_infoVariablePage footer information set in the backend
Option::EMLOG_VERSIONConstantCurrent emlog version number

log_list.php

Homepage template, displaying the article list.

Variables & Methods

Variable, Constant, MethodTypeDescription
$value['log_cover']VariableArticle cover image URL
$value['logid']VariableID of the current article
$value['log_url']VariableArticle address URL
$value['log_title']VariableArticle title
date('Y-n-j', $value['date'])VariableArticle publication time, parameter 'Y-n-j G:i l' is used to define the date format
$value['log_description']VariableArticle excerpt (outputs full text if there is no excerpt)
$value['comnum']VariableNumber of comments for the current article
$value['views']VariableNumber of views for the current article
$value['fields']VariableCustom fields, array type, see example below for reading method
editflg($value['logid'],$value['author'])VariableDisplays "Edit" link when administrator or author is logged in
topflg($value['top'])VariableDisplays sticky mark, this function is located in template module.php
$page_urlVariableDisplays pagination function for the current list page
blog_sort($value['logid'])MethodDisplays the category the article belongs to
blog_author($value['author'])MethodDisplays the author of the article
blog_tag($value['logid'])MethodDisplays the tags of the article

The above variables and methods can be output in the template in the following way:

<?= $value['logid'] ?>
<?= blog_author($value['author']) ?>

// Read custom fields, where index abcd is the custom field name
if (isset($value['fields']['abcd'])) {
echo $value['fields']['abcd']; // Output the value of the custom field named abcd
}

echo_log.php

Article detail page template, displaying the content of a single article.

Variables & Methods

Variable, Constant, MethodTypeDescription
$logidVariableID of the current article
$log_titleVariableArticle title
$log_coverVariableCover image URL
date('Y-n-j', $date)VariablePublication time, parameter 'Y-n-j G:i l' is used to define the date format
$log_contentVariableArticle content
$excerptVariableArticle excerpt
$comnumVariableNumber of comments for the current article
$viewsVariableNumber of views for the current article
$fieldsVariableCustom fields, array type, see example below for reading method
$page_urlVariableDisplays pagination function for the current list page
topflg($top)MethodDisplays sticky mark
blog_tag($logid)MethodTags
blog_author($author)MethodAuthor
blog_sort($logid)MethodCategory it belongs to
editflg($logid,$author)MethodDisplays "Edit" link when administrator or author is logged in.
neighbor_log($neighborLog)MethodNeighboring articles, i.e., previous post, next post.
blog_comments($comments)MethodComment list
blog_comments_post($logid,$ckname,$ckmail,$ckurl,$verifyCode,$allow_remark)MethodPost comment box
// Output title in template
<?= $log_title ?>

// Read custom fields, where index abcd is the custom field name
if (isset($fields['abcd'])) {
echo $fields['abcd']; // Output the value of the custom field named abcd
}

page.php

Page, displaying custom pages. Variable definitions etc. are the same as echo_log.php.

side.php

Sidebar, mainly responsible for outputting sidebar content based on backend widgets settings. It is recommended to keep the code in this file unchanged.

module.php

Template common code, including sidebar widgets, comments, quotes, editing, etc.

This file is composed of several functions, called by template files. Custom functions can be defined within it to implement more functions.

For example, when calling emlog cache in a custom function, assuming reading user cache information: global $CACHE; $user_cache = $CACHE->readCache('user');

If database operation is needed: $DB = MySql::getInstance(); $res = $DB->query($sql);

404.php

Template used for custom 404 pages.

pw.php

Used for custom encrypted article password input page. If this template file does not exist, the system default style will be used, without affecting the normal use of password input function. Please refer to the default template for template content.

user.php

User center template, can be used for themes to build their own user center. The user center URL routing rules are as follows, where xxx is the custom route name, for example: /user/profile or /?uc=profile etc. If this template file does not exist, accessing it will prompt 404.

  • Route Rule 1 (Pseudo-static needs to be enabled): /user/xxx
  • Route Rule 2: /?uc=xxx

Example as follows:

<?php
/**
* Frontend User Center
*/
defined('EMLOG_ROOT') || exit('access denied!');


// Check if logged in
if (ISLOGIN) {
//do something
}

// Get current logged-in user info
$avatar = $userData['photo']
$name = $userData['nickname']
$bio = $userData['description']
$email = $userData['email']

// Get current route path
// Variable $routerPath stores the current request's route path, e.g., /user/profile, $routerPath value is profile
// Include header template file (can determine whether to include based on route)
if (in_array($routerPath, ['', 'order', 'account', 'profile', 'weiyu'])) {
include View::getView('header');
}

// Implement route corresponding function
if ($routerPath === 'profile') {
include View::getView('user_xxxx') // Can load other template files
} elseif ($routerPath === 'weiyu') {
// Show weiyu page
} elseif ($routerPath === 'order_calback') {
// Handle payment callback logic
} else {
show_404_page();
}

// Include footer template file
include View::getView('footer')

custom_fields.php

Preset article custom fields required by the template itself. Adding custom fields in the backend article editing page supports drop-down selection of these preset fields. Configuration content reference as follows:

<?php
/**
* Template preset article custom fields
*/

defined('EMLOG_ROOT') || exit('access denied!');

$custom_fields = [
'price' => [
'type' => 'text',
'name' => 'Price',
'description' => 'e.g., 9.99',
'default' => ''
],
'need_vip' => [
'type' => 'radio',
'name' => 'Need VIP',
'values' => [
'0' => 'No',
'1' => 'Yes'
],
'description' => '1 for Yes, 0 for No',
'default' => '0'
],
];

plugins.php

The template's system call file. Once the template is enabled, this file will be automatically loaded by the system. It can be used to implement plugin-like functions.

Sometimes templates also hope to customize some functions in the system, including mounting functions at plugin mounting points for functional expansion. This file gives the template this ability, so that the template does not need to install additional supporting plugins to achieve richer functions.

<?php
/**
* Template system call file
* Once the template is enabled, this file will be automatically loaded by the system. It can be used to implement plugin-like functions.
*/

if (!defined('EMLOG_ROOT')) {
exit('error!');
}

/* eg:

function sameFunc() {
echo "xxxx";
}

addAction('adm_head', 'sameFunc');

*/

options.php

Template settings configuration file, see the Enable Template Settings section below.

Custom Templates

Articles, categories, pages: support custom templates. Users can select custom templates supported by the template theme when creating categories, pages, and articles, thereby achieving richer page display.

Naming Rules for Custom Template Files

  • Category: Filename starts with log_list_, e.g., log_list_abc.php
  • Article: Filename starts with echo_log_, e.g., echo_log_abc.php
  • Page: Filename starts with page_, e.g., page_abc.php

Comment Rules for Custom Template Files

<?php
/*@name Custom Template Name*/

The content of this comment will appear as the custom template name in the drop-down selection box. Custom templates that meet the above specifications will appear in the drop-down selection box in the scenarios of adding categories and creating pages, facilitating user selection.

Template Mounting Points

The following code format is the plugin mounting point in the template. Please refer to the default template and keep it, do not delete it.

<?php doAction('xxx') ?>
danger

Note: Be sure to refer to the default template to retain the following mounting points when developing templates to facilitate compatibility with other plugins.

Mounting PointBelonging FileMounting Point DescriptionExample
doAction('index_head')header.phpSite head tag mounting point, used to mount js or css style files
doAction('index_footer')footer.phpFooter bottom mounting point, used to mount footer information display plugins
doAction('index_loglist_top')log_list.phpHomepage article list top mounting point, recommended to add below the homepage navigation bar
doAction('log_related', $logData)echo_log.phpRelated article mounting point, added between article content and comments

Event Callbacks

In the Appearance - Template Management page of the emlog backend, users can enable, delete, and update templates. These operations will trigger corresponding callback functions. Developers can add a callback.php file to the template and define callback functions for specific events to implement operations such as template initialization, data cleanup, and data structure updates.

EventTrigger Function
Enable Templatecallback_init()
Delete Templatecallback_rm()
Update Templatecallback_up()

Example: (Please refer to callback.php in the default theme directory)

Template Settings

Templates support custom settings functions to provide richer configuration features for templates.

Place an options.php file in the template directory. The content format is as follows. You can add setting items arbitrarily. The starting comment cannot be deleted or changed. Reference as follows:

<?php
/*@support tpl_options*/

!defined('EMLOG_ROOT') && exit('access denied!');

$options = [
/** This item must exist */
'TplOptionsNavi' => [
'type' => 'radio',
'name' => 'Define Setting Tab Name',
'values' => [
'tpl-head' => 'Header Settings',
],
'icons' => array(
'tpl-head' => 'ri-home-line',
),
'description' => '<p>Template: Morning <br>Welcome to use this simple template, currently only supports setting header logo</p>'
],
'sale_qq' => [
'labels' => 'tpl-head',
'type' => 'text',
'name' => 'QQ Consultation',
'multi' => 'true',
'values' => ['12345678'],
],
'logotype' => [
'labels' => 'tpl-head',
'type' => 'radio',
'name' => 'LOGO Display Mode',
'values' => [
'1' => 'Text',
'0' => 'Image',
],
'default' => '1',
],
'appearance-color' => [
'labels' => 'tpl-appearance',
'type' => 'color',
'name' => 'Website Main Color',
'description' => '',
'values' => array('#006fff'),
],
'logoimg' => [
'labels' => 'tpl-head',
'type' => 'image',
'name' => 'LOGO Upload',
'values' => [
TEMPLATE_URL . 'images/logo.png',
],
'description' => 'Upload LOGO image.'
],
'index_sort_list' => [
'labels' => 'modules',
'type' => 'sort',
'name' => 'Category Multi-select',
'multi' => 'true',
'description' => ''
],
'index_page_list' => [
'labels' => 'modules',
'type' => 'page',
'name' => 'Page Multi-select',
'multi' => 'true',
'description' => ''
],
'styles-lazyopts' => [
'labels' => 'styles',
'type' => 'checkbox',
'name' => 'Image Asynchronous Lazy Load',
'values' => [
'view' => 'Views',
'comnum' => 'Comments',
'agree' => 'Likes',
],
'default' => array('view', 'comnum'),
'description' => '',
],
'index_tag' => [
'labels' => 'tpl-head',
'type' => 'checkon',
'name' => 'Show Tag List on Homepage',
'values' => ['1' => 'Enable'],
'default' => '1',
'description' => ''
],
'index_post_list' => [
'labels' => 'tpl-head',
'type' => 'select',
'name' => 'Search Articles',
'new' => 'NEW',
'pattern' => 'post',
'description' => ''
],
'index_cate_list' => [
'labels' => 'tpl-head',
'type' => 'select',
'name' => 'Search Categories',
'new' => 'NEW',
'pattern' => 'cate',
'description' => ''
],
'index_page_list' => [
'labels' => 'tpl-head',
'type' => 'select',
'name' => 'Search Pages',
'new' => 'NEW',
'pattern' => 'page',
'description' => ''
],
'index_block_list' => [
'labels' => 'tpl-head',
'type' => 'block',
'name' => 'Drag Multi-content Block',
'new' => 'NEW',
'description' => ''
],
'index-image_list' => [
'labels' => 'tpl-head',
'type' => 'block',
'name' => 'Drag Multi-image Content Block',
'new' => 'NEW',
'pattern' => 'image',
'description' => ''
],
'index-num_text' => [
'labels' => 'tpl-head',
'type' => 'text',
'name' => 'Number Text Box',
'new' => 'NEW',
'pattern' => 'num',
'unit' => 'Seconds',
'max' => '10',
'min' => '1',
'description' => ''
],
'index-date_text' => [
'labels' => 'tpl-head',
'type' => 'text',
'name' => 'Date Text Box',
'new' => 'NEW',
'date' => 'true',
'description' => ''
],
];

What to write in each element in options.php?

As shown above, in the $options array, the key is the id of the setting item, and the value is an array containing several elements. Among them, type and name attributes are required. name is the name of the setting item, and type is used to specify the type of the setting item.

Supported types for setting items:

  • radio: Radio button
  • checkbox: Checkbox
  • checkon: Switch
  • text: Text
  • image: Image
  • page: Page
  • sort: Category
  • tag: Tag
  • select: Search selection
  • block: Multi-content block
  • color: Color selection

Setting Item Description

  • For all types, the default attribute is used to specify the default value. When default is not specified, the first value in values is used. If none are specified, a default value will be used.
  • For radio and checkbox types, the values attribute is used to set the value and display name of each button.
  • Except for sort, depend can be specified as sort, indicating that this option can set different values according to different categories. When depend is specified as sort, the unsorted attribute is optional. When true, it means including uncategorized; when false, it does not include. The default is true.
  • Except for tag, depend can be specified as tag, indicating that this option can set different values according to different tags, such as adding icons to tags.
  • For sort and page, the multi attribute can be set to true, indicating multi-selection.
  • The description attribute is used to describe the option (optional).
  • If type is text, the multi attribute can be set to true, indicating multi-line text.
  • Optional attribute rich is used to support rich text. If this value is set, the editor will be loaded (deprecated, not supported in pro series versions).
  • If you want to use a number text box, type is still text, and you can set the pattern attribute to num. You can specify max, min, unit, i.e., limit the maximum value, minimum value, and unit of quantity. You can set the minimum or maximum value separately. For example, if only the minimum value is set, the maximum value will not restrict input. The unit of measurement will be displayed on the far right of the text box.
  • If using a date text box, type is still text, just set the date attribute to true.
  • If type is sort, page, or tag, and multi-selection is set, the default value will be empty, otherwise it will be the first value of that type.
  • For type select, the pattern attribute is required. You can fill in: (1). post (2). cate (3). page. Corresponding to articles, categories, and pages respectively. This functional module may query slowly when the data is very large. The array content obtained using built-in functions is the ID of the setting type, for example, getting a group of article gids.
  • (Optional) All the above types support the new attribute, which will display a reminder badge after the setting item name, the effect can be seen in the default template. This attribute value can be filled in arbitrarily, such as: NEW, etc. If empty or not filled, it will not be displayed.
  • For type block, the pattern attribute is optional. If the pattern attribute is not set, the default content is text. The multi attribute can be set to true, indicating multi-line text. Setting the pattern attribute to image allows using multi-image content blocks.

Adding icons to the settings menu

You can add an icons array within the TplOptionsNavi item to add an icon before the parent setting name of your theme settings sidebar menu. The key names of the icons array are consistent with the values array of the TplOptionsNavi item. Using Remixicon, find a suitable icon on the icon site and copy the attribute value in its class, for example class="ri-home-line", just copy ri-home-line. In addition, you need to add the following code to the template plugins.php to introduce icon CSS.

function optionIconFont() {
echo sprintf('<link rel="stylesheet" href="%s">', 'https://cdn.bootcdn.net/ajax/libs/remixicon/3.5.0/remixicon.min.css?ver=' . Option::EMLOG_VERSION_TIMESTAMP);
}
addAction('adm_head', 'optionIconFont');

How to call setting items in the template

The plugin provides a simple method _g($key) or _em($key) to get settings. Taking _g($key) as an example:

  • Use _g('sidebar') to get the sidebar setting. The value obtained will be 0 or 1.
  • Use _g('sortIcon') to get all settings of category icons, an array with category id as the key.
  • Use _g('sortIcon.1') to get the sortIcon with category id 1 (if it exists). Note that for type page, the page id will be obtained; for type sort, the category id will be obtained; for type tag, the tag name will be obtained.

If no parameters are passed, i.e., using _g() method, all setting items will be obtained. For templates migrated from old ones, you can use extract(_g()); to replace the original loading of the option file.

Example: Configuration from the default theme setting site logo


<?php if (_g('logotype') == 1): ?>
<a class="blog-header-title" href="<?= BLOG_URL ?>"><?= $blogname ?></a>
<div class="blog-header-subtitle subtitle-overflow" title="<?= $bloginfo ?>"><?= $bloginfo ?></div>
<?php else: ?>
<a href="<?php echo BLOG_URL; ?>" title="<?php echo $bloginfo; ?>"><img src="<?php echo _g('logoimg'); ?>" alt="<?php echo $blogname; ?>"/></a>
<?php endif; ?>

If you need to get data from multi-content blocks, provide the _getBlock($key, $type) method to get it:

  • $key is the same as the parameter provided by the _g() method
  • $type is the data type of the multi-content block, divided into title and content. This parameter can be omitted, and content will be obtained by default. title is the title filled in the multi-content block. content is the content. Using this built-in function, you can get the text of the text type multi-content block or the image URL set by the image type multi-content block.
  • Return value type is array

Use case:

_getBlock('image-block', 'content')

Directly Usable Constants

Variable, ConstantTypeDescription
Option::EMLOG_VERSIONConstantGet current emlog version number
ROLEConstantCurrent user role (user group): admin, writer, visitor
ROLE_ADMINConstantadmin
ROLE_WRITERConstantwriter
ROLE_VISITORConstantvisitor
UIDConstantCurrent user UID
BLOG_URLConstantSite URL
ISLOGINConstantLogin status, true for logged in, false for not logged in
TEMPLATE_URLConstantCurrent template URL eg: http://localhost:8080/content/templates/default/
TEMPLATE_PATHConstantAbsolute path of current template eg:/www/emlog/content/templates/default/

The above constants can be used in the template in the following way:

// Output current site URL
<?= BLOG_URL ?>

Common Configuration Information Retrieval

Configuration ItemGet Example
Site TitleOption::get('blogname')
Site SubtitleOption::get('bloginfo')
Site Meta Info: titleOption::get('site_title')
Site Meta Info: descriptionOption::get('site_description')
Site Meta Info: keywordOption::get('site_key')
Site URLOption::get('blogurl')

Usage Example:

// Output current site name
<?= Option::get('blogname')?>

Common Methods & Functions

Directly usable methods and functions: Common Methods and Functions

Asynchronous Requests

The Pro version supports ajax asynchronous requests and returns json format information, facilitating users to build friendlier frontend interaction experiences such as comments, popup login, registration, and password retrieval.

Post Comment

User Login

User Registration

Retrieve Password

Article Search

Search route: https://yoursite_domain/?keyword=emlog&sid=1

  • keyword: Search keyword
  • sid: Category id, optional. If filled, only search articles under this category. Themes can implement search by category themselves.

Comment UBB Support

emlog comments support UBB tag shortcode parsing. Users can use UBB tags in comments to format comment content, such as bold, color, images, links. Developers can develop comment input boxes that support inserting UBB codes to provide a richer comment experience.

Currently supported UBB tag shortcodes are as follows: bold, color, link, image:

[b]text[/b]
[color=red]text[/color]
[url]http://example.com[/url]
[img]http://example.com/xxx.jpg[/img]

Reference Demo

The default theme that comes with the emlog system is the best demo. You can modify it based on this theme to develop your own theme, or refer to some elements and files of this theme. Default template directory: content/templates/default

Open Source Release

If the template you developed is open sourced on Github, please add the topic to the repository: emlog-template

Publish to App Store

The finished theme, after testing, can be packaged and published to the official app store.

  1. Packaging: Go to the content\templates directory, find the template folder, and directly use the zip compression tool to package this folder (note: do not enter the folder to package), and name the packaged compressed package as: template English alias.zip, such as default.zip
  2. Publish: Log in to the official website emlog.net - My - App Development - Publish Template, fill in the necessary information according to the prompts to publish, and wait for review.```