🎨 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 Name | Description |
|---|---|
| css | Stores all CSS style files required by the template |
| js | Stores all JS files required by the template |
| images | Stores image resources like LOGO required by the template |
| preview.jpg | Template preview image displayed in the backend template selection interface. Recommended: 500x300 jpg format |
| header.php | Site header information, generally including page head information, top title, and navigation bar |
| echo_log.php | Article detail page, displaying the content of a single article |
| log_list.php | Homepage, displaying the article list |
| footer.php | Site footer information, displaying copyright information, etc. |
| page.php | Page, displaying custom pages |
| side.php | Sidebar. This file is not required if making a single-column template |
| module.php | Functional modules: latest articles, comments, categories, tags, etc. |
| 404.php | Custom error page when the 404 page is not found |
| pw.php | Custom encrypted article password input page. If this file is missing, the system default style is used [Not Required] |
| user.php | Template loaded by route /user, can be used for user center pages, etc. [Not Required] |
| plugins.php | Template 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.php | Template settings configuration file, can build richer setting items. [Not Required] |
| callback.php | Template event callback function definition. See the event callback section documentation for details [Not Required] |
| custom_fields.php | Preset 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
*/
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 & Constant | Type | Description |
|---|---|---|
| $site_title | Variable | Site title (affected by backend SEO optimization settings) |
| $site_key | Variable | Site keywords |
| $site_description | Variable | Output site browser description (affected by backend SEO optimization settings) |
| $blogname | Variable | Site title |
| $bloginfo | Variable | Site subtitle |
| BLOG_URL | Constant | URL of the site homepage, output format like https://emlog.net/ |
| TEMPLATE_URL | Constant | URL 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, Constant | Type | Description |
|---|---|---|
| $icp | Variable | ICP filing number set in the backend |
| $footer_info | Variable | Page footer information set in the backend |
| Option::EMLOG_VERSION | Constant | Current emlog version number |
log_list.php
Homepage template, displaying the article list.
Variables & Methods
| Variable, Constant, Method | Type | Description |
|---|---|---|
| $value['log_cover'] | Variable | Article cover image URL |
| $value['logid'] | Variable | ID of the current article |
| $value['log_url'] | Variable | Article address URL |
| $value['log_title'] | Variable | Article title |
| date('Y-n-j', $value['date']) | Variable | Article publication time, parameter 'Y-n-j G:i l' is used to define the date format |
| $value['log_description'] | Variable | Article excerpt (outputs full text if there is no excerpt) |
| $value['comnum'] | Variable | Number of comments for the current article |
| $value['views'] | Variable | Number of views for the current article |
| $value['fields'] | Variable | Custom fields, array type, see example below for reading method |
| editflg($value['logid'],$value['author']) | Variable | Displays "Edit" link when administrator or author is logged in |
| topflg($value['top']) | Variable | Displays sticky mark, this function is located in template module.php |
| $page_url | Variable | Displays pagination function for the current list page |
| blog_sort($value['logid']) | Method | Displays the category the article belongs to |
| blog_author($value['author']) | Method | Displays the author of the article |
| blog_tag($value['logid']) | Method | Displays 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, Method | Type | Description |
|---|---|---|
| $logid | Variable | ID of the current article |
| $log_title | Variable | Article title |
| $log_cover | Variable | Cover image URL |
| date('Y-n-j', $date) | Variable | Publication time, parameter 'Y-n-j G:i l' is used to define the date format |
| $log_content | Variable | Article content |
| $excerpt | Variable | Article excerpt |
| $comnum | Variable | Number of comments for the current article |
| $views | Variable | Number of views for the current article |
| $fields | Variable | Custom fields, array type, see example below for reading method |
| $page_url | Variable | Displays pagination function for the current list page |
| topflg($top) | Method | Displays sticky mark |
| blog_tag($logid) | Method | Tags |
| blog_author($author) | Method | Author |
| blog_sort($logid) | Method | Category it belongs to |
| editflg($logid,$author) | Method | Displays "Edit" link when administrator or author is logged in. |
| neighbor_log($neighborLog) | Method | Neighboring articles, i.e., previous post, next post. |
| blog_comments($comments) | Method | Comment list |
| blog_comments_post($logid,$ckname,$ckmail,$ckurl,$verifyCode,$allow_remark) | Method | Post 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') ?>
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 Point | Belonging File | Mounting Point Description | Example |
|---|---|---|---|
| doAction('index_head') | header.php | Site head tag mounting point, used to mount js or css style files | |
| doAction('index_footer') | footer.php | Footer bottom mounting point, used to mount footer information display plugins | |
| doAction('index_loglist_top') | log_list.php | Homepage article list top mounting point, recommended to add below the homepage navigation bar | |
| doAction('log_related', $logData) | echo_log.php | Related 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.
| Event | Trigger Function |
|---|---|
| Enable Template | callback_init() |
| Delete Template | callback_rm() |
| Update Template | callback_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
defaultattribute is used to specify the default value. Whendefaultis not specified, the first value invaluesis used. If none are specified, a default value will be used. - For
radioandcheckboxtypes, thevaluesattribute is used to set the value and display name of each button. - Except for
sort,dependcan be specified assort, indicating that this option can set different values according to different categories. Whendependis specified assort, theunsortedattribute is optional. When true, it means including uncategorized; when false, it does not include. The default is true. - Except for
tag,dependcan be specified astag, indicating that this option can set different values according to different tags, such as adding icons to tags. - For
sortandpage, themultiattribute can be set to true, indicating multi-selection. - The
descriptionattribute is used to describe the option (optional). - If
typeistext, themultiattribute can be set to true, indicating multi-line text. - Optional attribute
richis 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,
typeis stilltext, and you can set thepatternattribute tonum. You can specifymax,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,
typeis stilltext, just set thedateattribute totrue. - If
typeissort,page, ortag, 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
patternattribute 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
patternattribute is optional. If thepatternattribute is not set, the default content is text. Themultiattribute can be set to true, indicating multi-line text. Setting thepatternattribute toimageallows 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 typepage, the page id will be obtained; for typesort, the category id will be obtained; for typetag, 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:
$keyis the same as the parameter provided by the_g()method$typeis the data type of the multi-content block, divided intotitleandcontent. This parameter can be omitted, andcontentwill be obtained by default.titleis the title filled in the multi-content block.contentis 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, Constant | Type | Description |
|---|---|---|
| Option::EMLOG_VERSION | Constant | Get current emlog version number |
| ROLE | Constant | Current user role (user group): admin, writer, visitor |
| ROLE_ADMIN | Constant | admin |
| ROLE_WRITER | Constant | writer |
| ROLE_VISITOR | Constant | visitor |
| UID | Constant | Current user UID |
| BLOG_URL | Constant | Site URL |
| ISLOGIN | Constant | Login status, true for logged in, false for not logged in |
| TEMPLATE_URL | Constant | Current template URL eg: http://localhost:8080/content/templates/default/ |
| TEMPLATE_PATH | Constant | Absolute 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 Item | Get Example |
|---|---|
| Site Title | Option::get('blogname') |
| Site Subtitle | Option::get('bloginfo') |
| Site Meta Info: title | Option::get('site_title') |
| Site Meta Info: description | Option::get('site_description') |
| Site Meta Info: keyword | Option::get('site_key') |
| Site URL | Option::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.
- Packaging: Go to the
content\templatesdirectory, 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 asdefault.zip - 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.```