banner
Vinking

Vinking

你写下的每一个BUG 都是人类反抗被人工智能统治的一颗子弹

Only children make choices; I want them all!

Note

😫 This article is not suitable for those who are too lazy to tinker

This article involves changes to the theme code, which means that you will need to modify it again according to the methods below after each theme upgrade, 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 not knowing how to restore to the original state due to operational errors.

🍦 Friendly for beginners

This article is aimed at coding beginners and will introduce the entire thought process in detail. If you have a certain level of coding skills, you can skip the process part of the article and directly view the code.

Currently, my blog homepage has two different types of content: regular articles and "Say Something." "Say Something" can effectively handle daily complaints or things that are unnecessary too lazy to write as articles. 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 its length and type seem different from the articles you have written before. This article is more like a post 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/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.

Article Custom Fields

You think this feature is tailor-made for your idea above; you just need to choose whether it's an article or a post when publishing the article, and Typecho will know how to render it.

After a round of searching in 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 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('Disabled by default, enabling will display the "Article Directory" in the article (automatically matches H1~H6 tags)')
    );
    $layout->addItem($catalog);

    /* Your code above may differ from mine, do not modify the above code, append the code below at the end of the function */
    $isSpeak=new Typecho_Widget_Helper_Form_Element_Select('isSpeak',['0'=>'Dame','1'=>'Yes'],'0','Is it a post');
    $layout->addItem($isSpeak);
}

The Typecho_Widget_Helper_Form_Element_Select class provides a method to create a dropdown selection box. Here, a dropdown selection field named $isSpeak is created with options Dame and Yes, with the initial value set to 0, meaning Dame is selected by default, and this field will be displayed in the backend editor's custom fields with the name Is it a post.

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 post type.

After adding it, you can see the following custom field in the backend editor:

Added Custom Field

At this point, you have selected "Yes" for this article. After publishing, Typecho will know that this article should be a post.

How to render differently based on the article type?#

Next, you need to modify the homepage code to render it differently based on the field 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 post type article:

public static function IndexList($ctx): string
{
    if ($ctx->fields->isSpeak === '1') {
        // Post 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) is a method from the Cuteen theme that limits 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()) [Taking 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, and so on.

Locate

Here, searching for main_body successfully found the file article.php that outputs the article list.

Locate article.php

Then enter article.php, search for while ($this->next()), and you can find the article structure:

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

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.