fragmentary notesITエンジニアの気まぐれメモ

Tumblrブログ カスタマイズTIPS - NPF対応版

2023/08/14 17:17

Introduction

以前、私が運営するTumblrブログのテーマに適用しているカスタマイズロジックについて紹介するエントリを投稿しましたが、最近になりTumblrに大きな仕様変更が入り、対応が必要になりました。

Tumblr側の仕様変更の内容としては、Neue投稿形式(Neue Post Format、以下NPFと記載)の採用に伴い既存の投稿形式の一部置き換え。NPFは従来 投稿したいコンテンツ毎に「テキスト投稿」「画像投稿」etcと別れていたTumblrの投稿形式が1つにまとまり、複数タイプのコンテンツを追加することのできる形式。数年前からベータ版として既存の投稿形式の横にひっそり存在していましたが、iOS・Android版のアプリからの投稿がNPF形式のみ対応の状態を経て、最近 PCからもNPF形式での投稿に切り替わっているようです。それに伴い従来の「画像投稿」等、Legacy Post Formatが使用できなくなりました(泣)

「画像投稿」をメインで使用し、それに特化する形でカスタマイズロジックを組んでいたため、この仕組みが崩壊。NPFはテーマ上は従来の「テキスト投稿」と同じふるまいをすることから、

  • 既存の「テキスト投稿」のエントリを壊さないよう
  • 従来「画像投稿」で実現したことを再現する

ロジックを組む必要がでてしまいました。。。結構しんどい。いろいろ試行錯誤した結果、75点くらいの出来のものができたので、その結果をまとめてみます(まだ改善の余地ありですが)。

実現したいこと

実現したいことは概ねこんな感じ、これまで「画像投稿」でやってきた内容とほぼ同じ。

  1. エントリ本文の1つ目のH1タグをタイトルとする
  2. エントリ本文の1パラグラフを本文概要として一覧ページに表示する
  3. エントリ本文中の画像1枚をアイキャッチとして一覧ページに表示する
  4. 上記以外の本文等は一覧ページには表示せず、個別のページから参照するようにする

実現方法

Tumblrカスタムテーマ開発の基本的なお作法は公式ドキュメント参照(最近 日本語になったんだね、以前は英語だけだった気がする)。またNPFの公式仕様はこちらから(みてもよくわからないけど)。

今回は主に一覧ページ向けのカスタマイズとなるため、{block:IndexPage} {/block:IndexPage} の間に記述していきます。NPFになって大きく変わった点、メリット・デメリットそれぞれを多く抱える部分として、エントリの内容・コンテンツ情報をJSON形式で取得できるようになったこと。これによってフロントでの加工がすごくやりやすくなりました。JSONは独自タグ {NPF} で展開するが可能。そのため今回はこんなイメージでJSONからの情報を加工することにしました。

以下手順、ソースコードは参考用のもので、説明の都合上 簡略化しています。
最初に、NPFのJSONを出力しているDOM情報をname:npfJSON指定で取得します。併せてアイキャッチと記事概要の出力先となるDOM情報も取得しておきます。

const npfJSONnode   = document.getElementsByName("npfJSON")[0];
const eyecatchNode  = document.getElementsByName("eyecatch")[0];
const abstNode      = document.getElementsByName("abst")[0];

次に、JSONをオブジェクトして扱いやすい形にパースします。

const npfData = JSON.parse(npfJSONnode.innerHTML);

このnpfData内のcontentにArray形式で投稿内容が格納されています。ここから「エントリの1つ目のH1タグ」を抜き出します。ループでcontentを回しながら、typeが"text" かつ subtypeが"heading1"の要素を抜き出します。

// タイトル格納用変数
let title = ""

// タイトル走査
for(let i = 0; i < npfData.content.length; i++)
{
  const content = npfData.content[i];

  // タイトル要素を見つけたらループを抜ける
  if(content.type == "text" && content.subtype == "heading1")
  {
    title = content.text;
    break;
  }
}

同様にして、「エントリ本文の1パラグラフ」を本文概要として抜き出すためにtypeが"text" かつ subtypeがnullの要素を1件、「エントリ本文中の画像1枚」をアイキャッチ抜き出すためにtypeが"image"の要素を1件 取得します。

取得できたタイトルと本文概要をabstNodeへ追加。

// h1の要素を生成
const h1title = document.createElement("h1");
// 取得したタイトルをh1要素に設定
h1title.innerText = title;
// h1要素をabstNodeへ追加
abstNode.appendChild(h1title);

// 本文概要用のp要素を生成
const abstBody = document.createElement("p");
// 取得した本文概要をp要素に設定
abstBody.innerText = abst;
// p要素をabstNodeへ追加
abstNode.appendChild(abstBody);

次にアイキャッチ画像。type="image"で抽出した要素には、サイズ違いの複数の画像情報をArray形式で格納されているため、そこからwidthが500のものを選んで、画像のurlを取得します(本文中に画像が存在しない場合に備え、別途デフォルトアイキャッチ画像を用意するようにしています)。取得した画像をeyecatchNodeへ追加。

// 画像url格納用変数
let url = 【デフォルトアイキャッチ画像URL】
for(let i = 0; i < npfData.content.length; i++)
{
  const content = npfData.content[i];
  if(content.type == "image")
  {
      for(let j = 0; j < content.media.length; j++)
      {
          const media = content.media[j];
          if(media.width == 500)
          {
              url = media.url;
              break;
          }
      }
      break;
  }
}

// アイキャッチ用img要素を生成
const image = document.createElement("img");
// URLを設定
image.src = url;
// img要素をeyecatchNodeへ追加
eyecatchNode.appendChild(image)

最後に、npfJSONノードを非表示化して(実際は、CSS設定で最初から非表示にしていますが)、完了!!

NPFのデメリット

NPFは、JSON形式でデータが取れるようになったメリットが大きいものの、いくつか個人的には辛いデメリットが。。。

エントリ本文中のコードブロックがサポート対象外に

従来であれば本文中にコードブロックを差し込んで、サンプルソースコード等を投稿できたのですが、現在 NPFエディタではコードブロックが挿入不可になってしまいました。それだけならまだよいのですが。。。過去にLegacy Post Format(LPF)で投稿されたものはこれまで通り表示されるのですが、独自タグ{NPF}はNPFだろうとLPFだろうとお構いなしでJSONを出力しようとします。その結果、LPFで記述されたコードブロック中のダブルクォーテーション等を一切エスケープなしで出力してしまうため、JSONが壊れパースエラーとなってしまうのです。前述のとおり今回のカスタマイズは「テキスト投稿」に対して適用するようにしていて、コードブロックを含む過去エントリも当然「テキスト投稿」。そのため、もれなくプログラムエラーが表示が崩れます。現状 解決策なし。投稿形式からNPF or LPFの判断がつけば、回避策もあるのですが、その識別方法がなく、お手上げ状態。。。結構辛い。

他多数のHTMLタグが使用不可に

上記影響を受け、いろいろ試したところ、そのほか多くのHTMLタグが使用不能になっていることがわかりました。代表的なところでいうと、

  • 箇条書きLv1
    • 箇条書きLv2
      • 箇条書きLv3

のような階層形式の箇条書き、表を記述するためのテーブルタグも使えなくなってしまいました。

このあたりは、Tumblrからこのブログに重きを移そうと決心したきっかけにもなりましたね。

試していないですが、ダブルクォーテーションを含む記述等、エスケープ無だとJSONが壊れるような記述もおそらくNGかと。

終わりに

以上が、NPF化の波にのまれながら、何とかこれまで通りの運用を継続できないか試行錯誤した結果でした。エントリ内容によってロジックが崩壊するという割と致命的な問題は抱えていますが、現状エントリ内容を修正する等の運用回避しか道はなさげ。何かよい方法が見つかればまたアップデートしたいと思います。

  • Home
  • /
  • Posts
  • /
  • Tumblrブログ カスタマイズTIPS - NPF対応版
Tech-TIPS

Comments

© 2024 shunya_wisteria