larablog 建構日誌:UX 改進其之一

larablog 建構日誌:UX 改進其之一

網頁路徑

  網頁路徑,或稱麵包屑(breadcrumbs)是標示頁面位於網站文件結構何處的一串訊息,協助網站瀏覽者理解當前頁面相對於網站結構的位置,我透過安裝套件的方式建立此功能。

套件下載

composer require diglactic/laravel-breadcrumbs

定義網頁路徑

  建立 /routes/breadcrumbs.php 檔案定義網頁路徑

<?php // routes/breadcrumbs.php
use App\Models\Post;
use App\Models\Category;
use App\Models\Tag;
use Diglactic\Breadcrumbs\Breadcrumbs;
use Diglactic\Breadcrumbs\Generator as BreadcrumbTrail;

// Home
Breadcrumbs::for('home', function (BreadcrumbTrail $trail) {
    $trail->push('首頁', route('home'));
});

// Home > Blog
Breadcrumbs::for('blog', function (BreadcrumbTrail $trail) {
    $trail->parent('home');
    $trail->push('建置日誌', route('blog'));
});

// Home > Blog > Post title
Breadcrumbs::for('post', function (BreadcrumbTrail $trail, Post $post) {
    $trail->parent('blog');
    $trail->push($post->title, route('post', $post));
});

// Home > Single article
Breadcrumbs::for('single', function (BreadcrumbTrail $trail, Post $post) {
    $trail->parent('home');
    $trail->push($post->title, route('single', $post));
});

發佈設定檔案

php artisan vendor:publish --tag=breadcrumbs-config

  執行後會建立 /config/breadcrumbs.php檔案,可編輯像是顯示樣式的進一步設定。

Blade template 修正

  Moderna 提供的網頁路徑範例 HTML 碼是這樣的:

<section class="breadcrumbs">
      <div class="container">
        <div class="d-flex justify-content-between align-items-center">
          <h2>Blog</h2>

          <ol>
            <li><a href="index.html">Home</a></li>
            <li><a href="blog.html">Blog</a></li>
            <li>Dolorum optio tempore voluptas dignissimos cumque fuga qui quibusdam quia reiciendis</li>
          </ol>
        </div>
      </div>
    </section>

  透過套件運作後是這樣:

<section class="breadcrumbs">
        <div class="container">
            <div class="d-flex justify-content-between align-items-center">
                <h2>建置日誌</h2>
                <ol>
                    {{ Breadcrumbs::render('post', $post) }}
                </ol>
            </div>
        </div>
    </section>

套件輸出的網頁路徑

文章目次

  文章目次(table of contents aka TOC)是瀏覽長篇文章時需要的功能,瀏覽者可透過頁面提供的目次清單跳轉至想要觀看的段落,透過 Google 老師我找到合適的套件安裝應用。

套件下載

composer require caseyamcl/toc

  套件提供兩個類別建立文章目次資料,分別是:

  • TOC\MarkupFixer:為 heading 標籤(H1 ~ H6)標記 ID。
  • TOC\TocGenerator:以 HTML 格式建立目次結構

PostController 修改

  原先我是在 Blade template 進行 markdown 文章的格式轉換,因為套件是透過整理文章 HTML 碼建立目次結構的關係,轉換步驟改在 PostController 進行,Blade template 的轉換敘述移除。

  PostController 引入命名空間:

use Illuminate\Support\Str;
use TOC\TocGenerator;
use TOC\MarkupFixer;

  將 markdown 格式文章轉譯為 HTML 格式:

$post->content = Str::markdown($post->content);

  產生 markupFixertocGenerator 物件後透過 fix 方法為文章內的 heading 標籤加上 id 屬性,接著 透過 $toc 變數儲存目次結構及賦予連接標籤:我的設定是從 H2 開始的兩階,也就是收錄 H2 與 H3。

$markupFixer  = new MarkupFixer();
$tocGenerator = new TocGenerator();
$post->content = "<div class='content'>" . $markupFixer->fix($post->content) . "</div>";
$toc = "<div class='toc'>" . $tocGenerator->getHtmlMenu($post->content, 2, 2) . "</div>";

  回傳給 Blade template 的變數敘述改為:

return view('blog_page', $bindings,  compact('post', 'toc', 'with_comments'));

Blade template 的變動

  原先顯示文章內容的程式碼(顯示前將 markdown 格式內容轉譯成 HTML格式)是:

// /resources/views/blog_page.blade.php

<div class="entry-content">
    {!! \Illuminate\Support\Str::markdown($post->content) !!}
</div>

  在因應目次套件先行轉換的情況下改為:

<div class="entry-content">
    {!! $post->content !!}
</div>

  在側邊欄的位置增加文章目次敘述:

<div class="col-lg-4">
    <div class="sidebar">
        <h3 class="sidebar-title">文章目次</h3>
        {!! $toc !!}
    </div>
    <div class="sidebar">

文章目次的呈現

頁尾導覽條

  放置在文章底部的頁尾導覽條提供當前文章前一篇或下一篇的閱讀連結(或按鈕),這個功能不需安裝套件,只要一點點資料庫知識及 Eloquent 語法。

PostController 改動

  在 renderBlogPage 方法的 $bindings 陣列增加「前一篇文章」與「後一篇文章」兩個變數,以當前文章 id 值「前一」及「後一」指定:

'previous_post' => Post::where('status', 'published')->where('featured', 'yes')->where('id', '<', $post->id)->orderBy('id', 'desc')->first(),
'next_post' => Post::where('status', 'published')->where('featured', 'yes')->where('id', '>', $post->id)->orderBy('id', 'asc')->first(),

  Blade template 部分借鏡網頁路徑樣式做出左右對稱顯示

<!-- 前後頁導覽條 -->
<div class="entry">
    <div class="d-flex justify-content-between align-items-center">
        @if(!isset($previous_post))
            &nbsp;
        @else
            <a href="/blog/{{ $previous_post->slug }}">< {{ $previous_post->title }}</a>
        @endif
        @if(!isset($next_post))
            &nbsp;
        @else
            <a href="/blog/{{ $next_post->slug }}">{{ $next_post->title }} ></a>
        @endif
    </div>
</div>
<!-- 前後頁導覽條 -->

文章尾端導覽條

程式碼高亮度

  在解釋部落格建置流程時我張貼了大量的程式碼段落,也因此程式碼內容好不好閱讀對於整篇文章的閱讀體驗影響甚大。程式碼高亮度顯示(code highlight)能將程式碼內容以不同顏色及亮度標示,讓閱讀者能更容易閱讀,這裡匯入著名網站:highlight.js 提供的資源落實。

引入資源

  在負責頁面顯示的主版:/resource/views/layout/master.blade.php 匯入 highlight.js 運作用的 CSS 及 JavaScript 檔案,我使用 highlight.js 提供的 CDN 資源,然後加上 <script>hljs.highlightAll();</script> 啟動。

  在引入 CSS 樣式的位置加入:

<!-- Highlight.js CSS File -->
    <link rel="stylesheet" href="https://unpkg.com/@highlightjs/cdn-assets@11.2.0/styles/monokai-sublime.min.css">

  在引入 JavaScript 檔案的位置加入:

<!-- Highlight.js JS File -->
    <script src="https://unpkg.com/@highlightjs/cdn-assets@11.2.0/highlight.min.js"></script>
    <script>hljs.highlightAll();</script>

  下圖是尚未套用 highlight.js 資源前的文章內容,程式碼段落與文字敘述的差異不大。

套用 highlight.js 前的程式碼段落,與文字敘述的差異不大

  下圖是套用 highlight.js 資源後的文章內容,以黑底顯示的程式碼段落是不是更容易閱讀了?

套用 highlight.js 資源後程式碼段落與文字敘述有明顯區分

結語

  網頁路徑套件協助開發者建立網頁路徑資訊,在內容結構不複雜時也可不透過套件完成,取決於專案的情況。

  文章目次套件協助我為文章內容產生目次清單,在製作時因為忽略 markdown 格式轉換是在 Blade template 進行,未移除轉換程式碼的結果就是文章的程式碼區塊顯示嚴重跑版,找了半天才發現是自己沒注意到...

  在運作上美中不足的部分,是因為能力不足無法將目次清單區塊不隨頁面捲動固定顯示,推測可透過 CSS 與 JavaScript 完成。

  在製作頁尾導覽條時讓我重新整理 Eloquent 語法的認知,程式碼高亮度的引進讓程式碼閱讀變得更方便,也讓我再一次體會到用 Notion 寫技術筆記的方便之處。

  使用者體驗的精進尚未結束,下期繼續。

文章作者:A-Bo Lee
作者大頭照

居住在臺灣的 Joomler,期望以程式設計、開放原碼推廣活動收入養活一家老小。
35 歲後改姓李,id 作為曾為郭姓的證明。
FFXI:Abokuo@Sylph鯖、よろしくです。

看完文章有什麼想法嗎?利用下面表單告訴作者吧

請先閱讀
服務條款隱私權政策,送出回應意即同意前述文件。標記 * 欄位請務必填寫,電子郵件信箱僅作驗證使用,不會顯示在回應中。