banner
Vinking

Vinking

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

小孩子才做選擇,我全都要!

Note

😫 本文不適合懶得折騰的同學

本文章涉及對主題代碼的更改,會導致每次升級主題後都需要重新按照下面的修改方式修改一遍,否則會沒有效果。所以如你所見,我的主題版本還停留在 20230131 版本。

📦 請務必做好備份

在自己操作前請備份好主題文件以及數據庫文件,避免操作失誤而不知道怎麼恢復到原來的狀態。

🍦 對小白友好

本文章面向代碼小白,將會比較詳細地介紹整個思考流程,如果你有一定代碼水平,可以直接跳過文章的流程部分直接查看代碼。

目前我的博客首頁有普通文章和『說一下』這兩種不同的東西。『說一下』可以很好地處理一些日常吐槽或者沒有必要 懶得 寫成文章的事情。接下來會以 Cuteen 主題為例,讓你能夠給自己的主題加上屬於自己的『說一下』。


你剛完成了一篇簡短文章,但是文章的長度還有類型都似乎和你以前寫過的文章不一樣,這篇文章與其叫文章,更像是朋友圈或者空間的說說。所以你想給博客的首頁新增加一種類型,用來顯示這種別具一格的文章。你理了理思路,知道要做的只有兩件事情,就是怎麼讓 Typecho 能夠知道剛完成的這篇文章究竟是什麼? 還有 怎樣根據文章的類型去渲染不同的樣子?。那就開始吧。

讓 Typecho 能夠知道剛完成的這篇文章究竟是什麼#

剛好 Typecho 提供了這一功能,它叫自定義字段

自定義字段#

在 Typecho 中,自定義字段是官方為用戶自定義留下的一個接口。通過在文章編寫頁面選擇 / 填寫對應的信息,可以使得 Typecho 能夠根據這些信息來決定怎樣去處理這篇文章的某些東西。

文章自定義字段

你覺得這東西簡直就是為你上面的想法量身定做的功能,只需要在發表文章的時候選擇是文章還是說說不就可以讓 Typecho 知道以什麼樣的風格來渲染了嗎。

經過在主題文件夾的一輪尋找,你終於在 core 文件夾下的 Fields.php 找到了 themeFields 函數,這個函數可以給文章添加自定義字段

Note

🔔 請注意:不同主題添加自定義字段文件的位置還有名字都可能不一樣,例如 ** Sunny 主題的 themeFields 函數在 functions.php 文件的第 1292 行 **。這個文件叫什麼在哪裡可以詢問主題的作者。當然你也像我當初一樣根據後台文件編輯器下已有的自定義字段名字去主題文件夾 Ctrl + F 一個一個文件找。

你對函數做出了下面的修改:

/* ... */

function themeFields(Typecho\Widget\Helper\Layout $layout)
{
    $excerpt = new Typecho\Widget\Helper\Form\Element\Textarea('excerpt', null, null, '文章摘要', '輸入自定義摘要。留空自動從文章截取。');
    $layout->addItem($excerpt);
    $imgst = new Typecho\Widget\Helper\Form\Element\Text('imgst', NULL, NULL, _t('文章縮略圖'), _t('在這裡填入一個圖片URL地址, 以在文章列表加上一張圖片'));
    $layout->addItem($imgst);
    $catalog = new Typecho\Widget\Helper\Form\Element\Radio(
        'catalog',
        array(
            true => _t('啟用'),
            false => _t('關閉')
        ),
        false,
        _t('文章目錄'),
        _t('默認關閉,啟用則會在文章內顯示“文章目錄”(自動匹配H1~H6標籤)')
    );
    $layout->addItem($catalog);

    /* 你上面的代碼可能會跟我的不一樣,上面代碼不用動,在函數的末尾追加下面的代碼 */
    $isSpeak=new Typecho_Widget_Helper_Form_Element_Select('isSpeak',['0'=>'哒咩','1'=>'是'],'0','是否是說說');
    $layout->addItem($isSpeak);
}

其中 Typecho_Widget_Helper_Form_Element_Select 類提供了創建下拉選擇框的方法,這裡創建一個名為 $isSpeak下拉選擇框表單字段,選項有 哒咩 兩種,初始值為 0,即默認選中 哒咩,同時會在後台編輯器的自定義字段中顯示該字段的名稱為 是否是說說

Note

請注意:這裡初始值建議選擇為 0,即文章默認為普通文章。否則會將以前的文章全部變成了說說類型。

添加完之後重新進入後台編輯器能看到下面這個自定義字段:

添加的自定義字段

到此,你給這篇文章選擇了『是』這個選項。發表之後 Typecho 就知道你的這篇文章應該是一篇說說了。

怎樣根據文章的類型去渲染不同的樣子?#

接下來你需要對首頁代碼進行修改,讓它能根據剛才定義的字段來作出不同的渲染。你打開 index.php ,看見這樣的一段代碼:

<?php while ($this->next()): ?>
    <?= Context::IndexList($this) ?>
<?php endwhile; ?>

這是一段用於循環顯示文章列表的代碼,由此可知,調用 Context 類的 IndexList 方法會返回帶有本次循環文章信息的結構。而這個 Context 類在 core 文件夾下的 Context.php 中。你需要修改這個 IndexList 函數,給它加上一個 if 來判斷是不是說說類型的文章:

public static function IndexList($ctx): string
{
    if ($ctx->fields->isSpeak === '1') {
        //說說類型,你可以自己修改結構
        $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'>📖 說一下</div>
                    <div class='speakDesc'>" . Context::ArticleExcerpt(1000 , $ctx) ."</div>
                </div>
            </a>
        </article>";
    }else if ($ctx->fields->isSpeak === '0' || $ctx->fields->isSpeak === null){
          # 這裡包裹原來的 return $str; 之前的代碼:
          # $img = self::ImageEcho($ctx);
          # ...
          # $str .= '<a class="article-description" href = "' . $ctx->permalink . '" > ' . Context::ArticleExcerpt(100, $ctx) . '</a ></div ></article > ';
    }
    return $str;
}

其中 Context::ArticleExcerpt(1000 , $ctx) 是調用 Cuteen 主題的一個方法來限制在首頁最多輸出 1000 個字,防止過長而不美觀,你可以按照自己的需求修改這個值。

Note

請注意:非 Cuteen 主題這裡需要將所有$ctx-> 改成 $this->。(因為 Cuteen 主題調用 Context::IndexList($this)$this 作為實參傳給了形參 $ctx,所以在方法內需要使用 $ctx-> 獲取參數)。同樣的非 Cuteen 主題是不能使用 Context::ArticleExcerpt(1000 , $ctx) 的,這裡可以使用 mb_substr($this->fields->excerpt, 0, 1000, 'UTF-8') 輸出文章前 1000 個字符。

找不到 while ($this->next()) 【以 Sunny 主題為例】#

如果你的主題的 index.php 找不到 while ($this->next()) 的話,可以嘗試打開 F12 定位到包裹文章的元素,這裡是 <div class="postlist_out ">,然後在 index.php 裡搜索這個 class 名字 postlist_out。如果找不到就繼續找到這個元素的父元素,即 <main class="main_body">,再在 index.php 裡搜索,以此類推。

定位

這裡搜索 main_body 成功找到了輸出文章列表的文件 article.php

定位 article.php

然後進入 article.php,搜索 while ($this->next()),就可以找到文章結構了:

文章結構


保存之後你便獲得一個屬於你自己的『說一下』了。當然現在的『說一下』因為沒有對應的 CSS,所以需要你自己來編寫對應的 CSS 規則,這裡就不展開了。

此文由 Mix Space 同步更新至 xLog 原始鏈接為 https://www.vinking.top/posts/codes/typecho-custom-post-type-tutorial

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。