こんにちは。今回はWordPressから取得した投稿にリンクカードを導入する方法を書きます。リンクカードはiframelyを用いて実装します。

iframelyとは

iframelyはリンクをいい感じのデザインにしてくれるサービスです。例えば以下のような感じです。

iframelyにはAPIが用意されていて、プログラムでhtmlを取得することが出来るのでReactに導入するにはぴったりです。

実装方法

今回はWordPress側にPz-LinkCardを導入し、それをGatsbyのビルド時にiframelyが作ってくれたhtmlに差し替えることでGatsby側のサイトにiframelyを導入したいと思います。なので、まずは以下の公式サイトを参考にHeadless CMSのWordPressにプラグイン「Pz-LinkCard」を導入しましょう。

次にGatsby側で記事内のリンクカードをiframelyのリンクカードに差し替えるコードを書きます。GatsbyでWordPressのデータを引っ張るのはgatsby-source-wordpressを使っています。

まずは必要なライブラリをインストールします。

bash
1
npm i --save html-react-parser

https://www.npmjs.com/package/html-react-parser

gatsby-source-wordpressは記事の内容をgraphqlで取得するのですが、string型でしか取得できません。そのためDOM操作が行えないため、一度上記のhtml-react-parserでパースしてからDOM操作を行ってiframelyへの差し替えを行います。

まずはiframelyのスクリプトを導入します。React-Helmetを用いて以下のようなコンポーネントを作成します。

jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import React from 'react'
import Helmet from 'react-helmet'

export default class Iframely extends React.Component {
  componentDidMount() {
    if (window.iframely) {
      window.iframely.load()
    }
  }

  render() {
    return (
      <Helmet>
        <script
          type="text/javascript"
          src="//cdn.iframe.ly/embed.js?api_key=xxxxxxxxxxxxxx"
          charset="utf-8"
        />
      </Helmet>
    )
  }
}

上記のコンポーネントをiframelyを使うページに入れます。基本は投稿の部分やLayout.jsなどに入れます。api_keyの部分は予めiframelyに登録をして取得したものを入力して下さい。次に実際に記事部分を差し替えます。以下のコンポーネントにhtml文字列を渡すことで差し替えたhtmlオブジェクトを返します。

jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import React from 'react'
import parse, { domToReact } from 'html-react-parser'

const ContentParser = ({ content }) => {
  return <div>{parse(content, { replace: replaceCode })}</div>
}

const replaceCode = node => {
  if (node.name === 'div') {
    if (node.attribs.class === 'linkcard') {
      let link = getLinkcard(node)
      return (
        <div className="iframely-embed">
          <div
            className="iframely-responsive"
            style={{
              height: '168px',
              paddingBottom: '0',
              marginBottom: '5px',
            }}
          >
            <a href={link} data-iframely-url={true}></a>
          </div>
        </div>
      )
    }
  } 
}

const getLinkcard = node => {
  if (node.name === 'a') {
    return node.attribs.href
  } else if (node.children != null) {
    for (let index = 0; index < node.children.length; index++) {
      let url = getLinkcard(node.children[index])
      if (url != null) return url
    }
  }
}

export default ContentParser

ReactというかJavascript出来るわけではないのでこれで良いのか微妙ですがこのサイトに導入しているのはこんな感じなので許して下さい!
html-react-parserを用いてパースしたhtml文字列の中でDOM操作をしていきます。その中で特定のhtmlタグがついたものを置き換え出来るので、PzLinkcardで生成されたLinkCardをiframelyで生成したリンクカードに置き換えています。あとは以下のように投稿の内容を渡してあげるだけです

jsx
1
2
<Iframely />
<ContentParser content={content} />

これでWordPressを利用したGatsbyのサイトにリンクカードを導入できます。

参考

https://takumon.com/iframely
https://dimitr.im/adding-syntax-highlighting-wordpress-gatsby


2020.04.07 03:48  2020.10.12 00:44