# 緣起
當初在瀏覽網頁時意外看到如下面這張示意圖的頁面
就想說剛好可以拿來使用,但去查詢了一下後,發現是適合 Butterfly
主題的外掛,雖然我的 shoka
也可以安裝,但是怕會衝到一些依賴外掛,所以索性直接拿原碼來實現。
碰巧之前在 hexo 官方文檔有看到自製 tag plugin
的介紹,覺得頗有料,於是就著手把兩者結合起來啦!
最後經過一番修改,改成了還算符合我期望的樣子😎 讚讚_
下面會附上最後的程式碼做個紀錄~~
# 使用方法
在 此頁面 中照著填寫已下的結構即可,注意最少要填必填的那兩項,其餘的沒有填會有預設值。
用 {% animeinfo %}` 和 `{% endanimeinfo %}
包住以下
- name: (必填) | |
img: (nullable) | |
date: #eg: 2023 十月 (nullable) | |
metaColor: #eg: `#2fd8d8`, mark 特別喜歡的已看者 (Default, nullable) | |
totalcount: #eg: 全 x 話 (nullable) | |
progress: #eg: 進度 y 話 (nullable) | |
type: #eg: 動漫 or 電影 (d = 動漫,nullable) | |
area: # 國家 (d=Japan, nullable) | |
cvs: # 重點聲優 (nullable) | |
link: (必填) | |
des: (nullable) |
# Javascript
若未顯示,則重整一次網頁即可顯示~
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const fs = require('fs'); | |
const path = require('path'); | |
const yaml = require('js-yaml'); | |
const url = require('url'); | |
function animeVideoGrid(args, content) { | |
const theme = hexo.theme.config; | |
if(!args[0] && !content) {return;} | |
if(args[0]) { | |
const filepath = path.join(hexo.source_dir, args[0]); | |
if(fs.existsSync(filepath)) { | |
content = fs.readFileSync(filepath); | |
} | |
} | |
if(!content) {return;} | |
const list = yaml.load(content); | |
var result = '' | |
list.forEach(item => { | |
if(!item.name || !item.link) { // 必填項目 0.name | |
return; | |
} | |
// 1.img | |
var item_image = item.img || theme.images + '/404.png'; // or default img | |
if (!item_image.startsWith('//') && !item_image.startsWith('http')) { // 非外部則找內部 | |
item_image = theme.statics + item_image; | |
} | |
// 2.date | |
var item_date = item.date || '暫未填寫'; | |
// 3.metaColor | |
var item_metaColor = item.metaColor ? ` style="color: ${item.metaColor}"` : ''; | |
// 4.totalcount | |
var item_total = item.totalcount ? `全 ${item.totalcount} 話` : '-'; | |
// 5.progress | |
var item_progress = item.progress ? `第 ${item.progress} 話` : "尚未開始看"; | |
if(item.totalcount && item.progress) { | |
if(item.progress === item.totalcount) {item_progress = "已看完";} | |
} | |
// 6.type | |
var item_type = item.type || "動漫"; | |
// 7.area | |
var item_area = item.area || "日本"; | |
// 8.cvs | |
var csvArray = []; | |
if(item.cvs) { | |
if(item.cvs === 0) | |
csvArray.push('-'); | |
else | |
csvArray = item.cvs.split(','); | |
} | |
// 9.link (必填) | |
// 10.des | |
var item_des = item.des || "暫無簡介"; | |
// write result html | |
result += ` | |
<div class="aniinf-item"> | |
<div class="aniinf-img"><img src="${item_image}" referrerPolicy="no-referrer" /></div> | |
<div class="aniinf-info"> | |
<div class="aniinf-name">${item.name}</div> | |
<div class="aniinf-meta"> | |
<span class="aniinf-meta-items"${item_metaColor}> | |
<span class="aniinf-meta-item aniinf-date"> | |
<span class="aniinf-meta-label">推出時間</span> <em>${item_date}</em> | |
</span> | |
<span class="aniinf-meta-item aniinf-meta-tot"> | |
<span class="aniinf-total">${item_total}</span><em class="aniinf-meta-label-em">0</em> | |
</span> | |
<span class="aniinf-meta-item aniinf-progress"> | |
<span class="aniinf-meta-label">觀看進度</span> <em>${item_progress}</em> | |
</span> | |
<span class="aniinf-meta-item aniinf-type"> | |
<span class="aniinf-meta-label">類別</span> <em>${item_type}</em> | |
</span> | |
<span class="aniinf-meta-item aniinf-cvs"> | |
<span class="aniinf-meta-label">主要 CV</span> <em class="aniinf-cvs">`; | |
if(csvArray.length === 0) { | |
result += "暫未填寫"; | |
} else { | |
csvArray.forEach((csvitem, idx) => { | |
result += csvitem; | |
if(idx !== csvArray.length - 1) {result += `<br/>`;} | |
}); | |
} | |
result += ` </em> </span> | |
<span class="aniinf-meta-item aniinf-area"> | |
<span class="aniinf-meta-label">出版國家</span> <em>${item_area}</em> | |
</span> | |
<span class="aniinf-meta-item aniinf-meta-right"> | |
<span class="aniinf-link"><a target="_blank" href="${item.link}">觀看連結</a></span><em class="aniinf-meta-label-em">0</em> | |
</span> | |
</span> | |
</div> | |
<div class="aniinf-des">簡介:${item_des}</div> | |
</div> | |
</div>`; | |
}); | |
return `<div class="animeinfo">${result}</div>`; | |
} | |
hexo.extend.tag.register('animeinfo', animeVideoGrid, {ends: true}); |
# CSS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.aniinf-item { | |
position relative | |
clear both | |
padding 10px 0 | |
border-bottom 1px solid #ddd | |
min-height 180px | |
} | |
@media screen and (max-width:600px) { | |
.aniinf-item { | |
width 100% | |
} | |
} | |
.aniinf-img { | |
position absolute | |
left 0 | |
top 10px | |
width 110px | |
img { | |
margin 20px auto | |
width 110px | |
max-height 149px | |
} | |
} | |
.aniinf-info { | |
padding-left 120px | |
margin-top 10px | |
} | |
.aniinf-name { | |
font-size 18px | |
} | |
.aniinf-meta { | |
font-size 12px | |
padding-right 10px | |
height 45px | |
} | |
.aniinf-meta-items { | |
font-size 12px | |
color #2fd8d8 | |
padding-top 10px | |
line-height 1 | |
float left | |
width 100% | |
} | |
.aniinf-meta-item { | |
display inline-block | |
width 13% | |
border-right 1px solid #2fd8d8 | |
text-align center | |
height 34px | |
em { | |
display block | |
padding-top 6px | |
line-height 17px | |
font-style normal | |
font-weight 700 | |
} | |
} | |
.aniinf-meta-label { | |
display block | |
line-height 12px | |
} | |
// only one | |
.aniinf-total, .aniinf-link { | |
padding-top 11px | |
display block | |
line-height 12px | |
font-weight 700 | |
} | |
.aniinf-meta-label-em { | |
color transparent | |
opacity 0 | |
visibility hidden | |
line-height 6px !important | |
padding 0 !important | |
} | |
// responsible | |
@media (max-width:650px) { | |
.aniinf-cvs { | |
display none | |
} | |
.aniinf-meta-item { | |
width 16% | |
} | |
} | |
@media (max-width:590px) { | |
.aniinf-type { | |
display none | |
} | |
.aniinf-meta-item { | |
width 19% | |
} | |
} | |
@media (max-width:520px) { | |
.aniinf-area { | |
display none | |
} | |
.aniinf-meta-item { | |
width 24% | |
} | |
} | |
@media (max-width:480px) { | |
.aniinf-date { | |
display none | |
} | |
.aniinf-meta-item { | |
width 30% | |
} | |
} | |
@media (max-width:400px) { | |
.aniinf-meta-tot { | |
display none | |
} | |
.aniinf-meta-item { | |
width 45% | |
} | |
} |
# 參考資料
- 官方 source code
- 官方 認識標籤外掛
- 非官方 Hexo 新增自定義標籤外掛
- 非官方 成果示意