Note
😫 This article is not suitable for those who are too lazy to tinker
This article involves modifications to the theme code, which means that you will need to redo the modifications below every time you upgrade the theme, otherwise it will have no effect. So as you can see, my theme version is still at 20230131.
📦 Please make sure to back up
Please back up your theme files and database files before making any changes to avoid any mistakes and not knowing how to restore to the original state.
🍦 Friendly for beginners
This article is aimed at coding beginners and will detail the entire thought process. If you have some coding skills, you can skip the process part of the article and directly check the code.
Currently, my blog homepage has two different types of content: regular articles and "Say Something." "Say Something" can handle daily complaints or things that are not necessary too lazy to write into an article. Next, I will take the Cuteen theme as an example to show you how to add your own "Say Something" to your theme.
You just completed a short article, but the length and type of the article seem different from what you have written before. This article is more like a status update on social media rather than a traditional article. So you want to add a new type to the homepage of your blog to display this unique article. You sorted out your thoughts and realized that there are only two things to do: how to let Typecho know what this newly completed article is? and how to render it differently based on the article type? Let's get started.
Let Typecho know what this newly completed article is#
Fortunately, Typecho provides this functionality, called custom fields.
Custom Fields#
In Typecho, custom fields are an interface left for users to customize by the official team. By selecting or filling in the corresponding information on the article writing page, Typecho can determine how to handle certain aspects of this article based on that information.
You think this feature is tailor-made for your idea above; you just need to choose whether it's an article or a status update when publishing the article to let Typecho know how to render it.
After searching through the theme folder, you finally found the themeFields
function in the Fields.php
file under the core
folder, this function can add custom fields to articles.
Note
🔔 Please note: The location and name of the custom fields file added by different themes may vary. For example, the themeFields
function of the Sunny theme is located at line 1292 of the functions.php
file. You can ask the theme author what this file is called and where it is located. Of course, you can also do as I did and search for existing custom field names in the backend file editor and find them one by one in the theme folder using Ctrl + F.
You made the following modifications to the function:
/* ... */
function themeFields(Typecho\Widget\Helper\Layout $layout)
{
$excerpt = new Typecho\Widget\Helper\Form\Element\Textarea('excerpt', null, null, 'Article Summary', 'Enter a custom summary. Leave blank to automatically extract from the article.');
$layout->addItem($excerpt);
$imgst = new Typecho\Widget\Helper\Form\Element\Text('imgst', NULL, NULL, _t('Article Thumbnail'), _t('Enter an image URL here to add a picture to the article list'));
$layout->addItem($imgst);
$catalog = new Typecho\Widget\Helper\Form\Element\Radio(
'catalog',
array(
true => _t('Enable'),
false => _t('Disable')
),
false,
_t('Article Directory'),
_t('Default is disabled; enabling will display the "Article Directory" (automatically matches H1~H6 tags) within the article')
);
$layout->addItem($catalog);
/* Your code above may differ from mine; do not modify the above code, just append the following code at the end of the function */
$isSpeak=new Typecho_Widget_Helper_Form_Element_Select('isSpeak',['0'=>'Dame','1'=>'Yes'],'0','Is it a status update?');
$layout->addItem($isSpeak);
}
The Typecho_Widget_Helper_Form_Element_Select
class provides a method to create a dropdown selection box. Here, a dropdown selection form field named $isSpeak
is created, with options Dame and Yes, and the initial value is 0, meaning Dame is selected by default. This field will also display the name Is it a status update? in the custom fields of the backend editor.
Note
Please note: It is recommended to set the initial value to 0, meaning the article defaults to a regular article. Otherwise, all previous articles will be changed to status update types.
After adding this, you can see the following custom field in the backend editor:
At this point, you have selected "Yes" for this article. After publishing, Typecho will know that this article should be a status update.
How to render differently based on the article type?#
Next, you need to modify the homepage code to render it differently based on the fields you just defined. You open index.php
and see a piece of code like this:
<?php while ($this->next()): ?>
<?= Context::IndexList($this) ?>
<?php endwhile; ?>
This is a piece of code used to loop through and display the article list, which indicates that calling the Context
class's IndexList
method will return a structure containing the information of the current loop article. The Context
class is located in the core
folder under Context.php
. You need to modify this IndexList
function to add an if
statement to check if it is a status update type article:
public static function IndexList($ctx): string
{
if ($ctx->fields->isSpeak === '1') {
// Status update type; you can modify the structure yourself
$str = "
<article class='article". ($ctx->sequence % 2 == 0 ? ' flex-row-reverse ': ' ') ."speak'>
<a style='width:100%' href='" . $ctx->permalink . "'>
<div class='speakContent'>
<div class='speakNav'>📖 Say Something</div>
<div class='speakDesc'>" . Context::ArticleExcerpt(1000 , $ctx) ."</div>
</div>
</a>
</article>";
}else if ($ctx->fields->isSpeak === '0' || $ctx->fields->isSpeak === null){
# Wrap the original return $str; code here:
# $img = self::ImageEcho($ctx);
# ...
# $str .= '<a class="article-description" href = "' . $ctx->permalink . '" > ' . Context::ArticleExcerpt(100, $ctx) . '</a ></div ></article > ';
}
return $str;
}
Here, Context::ArticleExcerpt(1000 , $ctx)
calls a method from the Cuteen theme to limit the output to a maximum of 1000 characters on the homepage to prevent it from being too long and unattractive. You can modify this value according to your needs.
Note
Please note: For non-Cuteen themes, you need to change all $ctx->
to $this->
(because the Cuteen theme calls Context::IndexList($this)
and passes $this
as an argument to the parameter $ctx
, so you need to use $ctx->
to access the parameters within the method). Similarly, non-Cuteen themes cannot use Context::ArticleExcerpt(1000 , $ctx)
; here you can use mb_substr($this->fields->excerpt, 0, 1000, 'UTF-8')
to output the first 1000 characters of the article.
Can't find while ($this->next())
[Using Sunny theme as an example]#
If you can't find while ($this->next())
in your theme's index.php
, you can try opening F12 to locate the element that wraps the articles, which is <div class="postlist_out ">
, and then search for this class name postlist_out
in index.php
. If you can't find it, continue to find the parent element of this element, which is <main class="main_body">
, and search in index.php
again, and so on.
Here, searching for main_body
successfully found the file article.php
that outputs the article list.
Then enter article.php
, search for while ($this->next())
, and you will find the article structure:
After saving, you will have your own "Say Something." Of course, the current "Say Something" does not have corresponding CSS, so you will need to write the corresponding CSS rules yourself, which will not be covered here.
This article is synchronized and updated to xLog by Mix Space. The original link is https://www.vinking.top/posts/codes/typecho-custom-post-type-tutorial