如何解析WordPress 的古騰堡(Gutenberg)內(nèi)容

Gutenberg 是WordPress的默認(rèn)編輯器。該編輯器可以通過(guò)拖放界面使用文本、圖像、視頻和其他網(wǎng)站元素的離散塊來(lái)制作和設(shè)計(jì)內(nèi)容。這種方法增強(qiáng)了 WordPress 的靈活性和設(shè)計(jì)能力。

圖片[1]-如何解析WordPress 的古騰堡(Gutenberg)內(nèi)容-光子波動(dòng)網(wǎng) | 專業(yè)WordPress修復(fù)服務(wù),全球范圍,快速響應(yīng)

使用 REST API 獲取古騰堡(Gutenberg)內(nèi)容

要以編程方式與 WordPress 網(wǎng)站交互并檢索古騰堡塊中結(jié)構(gòu)化的內(nèi)容,可以使用 WordPress REST API 或WPGraphQL 插件。這些工具能夠讓你以 JSON 格式獲取 WordPress 內(nèi)容。

要通過(guò) REST API 啟用 JSON 數(shù)據(jù)訪問(wèn),請(qǐng)將 WordPress 永久鏈接設(shè)置調(diào)整為遠(yuǎn)離“Plain”。這樣,就能通過(guò)一種特定格式的網(wǎng)址來(lái)訪問(wèn) API 了,如下所示:

https://yoursite.com/wp-json/wp/v2

通過(guò)向此 URL 發(fā)出 API 請(qǐng)求,可以用編程方式檢索各種信息并在 WordPress 網(wǎng)站上執(zhí)行操作。例如,你可以通過(guò)向以下地址發(fā)送 GET 請(qǐng)求來(lái)獲取帖子列表:

https://yoursite.com/wp-json/wp/v2/posts

會(huì)返回一個(gè) JSON 對(duì)象,其中包含有關(guān) WordPress 網(wǎng)站上的帖子的信息,包括標(biāo)題、內(nèi)容、作者詳細(xì)信息等。

圖片[2]-如何解析WordPress 的古騰堡(Gutenberg)內(nèi)容-光子波動(dòng)網(wǎng) | 專業(yè)WordPress修復(fù)服務(wù),全球范圍,快速響應(yīng)

將古騰堡(Gutenberg)塊解析為 HTML

當(dāng)從使用古騰堡編輯器的 WordPress 網(wǎng)站檢索帖子時(shí),數(shù)據(jù)庫(kù)中存儲(chǔ)的內(nèi)容可以混合使用 HTML 和 JSON 元數(shù)據(jù)來(lái)描述各種塊類型,例如引用和圖庫(kù):

<!-- wp:quote {"className":"inspirational-quote","style":{"typography":{"fontSize":"large"}}} -->
<blockquote class="wp-block-quote inspirational-quote has-large-font-size"><p>“The journey of a thousand miles begins with one step.”</p><cite>Lao Tzu</cite></blockquote>
<!-- /wp:quote -->

<!-- wp:gallery {"ids":[34,35],"columns":2,"linkTo":"none","sizeSlug":"medium","className":"custom-gallery"} -->
<ul class="wp-block-gallery columns-2 is-cropped custom-gallery"><li class="blocks-gallery-item"><figure><img src="http://example.com/wp-content/uploads/2021/09/image1-300x200.jpg" alt="A breathtaking view of the mountains" class="wp-image-34"/></figure></li><li class="blocks-gallery-item"><figure><img src="http://example.com/wp-content/uploads/2021/09/image2-300x200.jpg" alt="Serene lakeside at dawn" class="wp-image-35"/></figure></li></ul>
<!-- /wp:gallery -->

該代碼段展示了兩個(gè) Gutenberg 塊:引用和圖庫(kù)。每個(gè)區(qū)塊都有封裝在 HTML 注釋中的 JSON 元數(shù)據(jù)。元數(shù)據(jù)定義了類名、樣式等屬性,以及與區(qū)塊展示相關(guān)的其他配置。

圖片[3]-如何解析WordPress 的古騰堡(Gutenberg)內(nèi)容-光子波動(dòng)網(wǎng) | 專業(yè)WordPress修復(fù)服務(wù),全球范圍,快速響應(yīng)

當(dāng)你通過(guò) WordPress REST API 或 WPGraphQL 獲取這些區(qū)塊時(shí),WordPress 會(huì)對(duì)其進(jìn)行處理,將 HTML 和 JSON 元數(shù)據(jù)的組合轉(zhuǎn)換為完全呈現(xiàn)的 HTML 元素,你可以直接將其整合到網(wǎng)頁(yè)中。上述區(qū)塊轉(zhuǎn)換后的 HTML 顯示如下:

<blockquote class="wp-block-quote inspirational-quote has-large-font-size"><p>“The journey of a thousand miles begins with one step.”</p><cite>Lao Tzu</cite></blockquote>

<ul class="wp-block-gallery columns-2 is-cropped custom-gallery">
  <li class="blocks-gallery-item"><figure><img loading="lazy" src="http://example.com/wp-content/uploads/2021/09/image1-300x200.jpg" alt="A breathtaking view of the mountains" class="wp-image-34" sizes="(max-width: 300px) 100vw, 300px" /></figure></li>
  <li class="blocks-gallery-item"><figure><img loading="lazy" src="http://example.com/wp-content/uploads/2021/09/image2-300x200.jpg" alt="Serene lakeside at dawn" class="wp-image-35" sizes="(max-width: 300px) 100vw, 300px" /></figure></li>
</ul>

對(duì)于使用 Next.js 等 JavaScript 框架構(gòu)建解耦或應(yīng)用程序的開(kāi)發(fā)人員來(lái)說(shuō),這提供了一種簡(jiǎn)單的方法來(lái)顯示內(nèi)容,即使用屬性將 HTML 直接注入到頁(yè)面中dangerouslySetInnerHTML以呈現(xiàn)標(biāo)記。

<div dangerouslySetInnerHTML={{ __html: <raw_html_string> }} />
圖片[4]-如何解析WordPress 的古騰堡(Gutenberg)內(nèi)容-光子波動(dòng)網(wǎng) | 專業(yè)WordPress修復(fù)服務(wù),全球范圍,快速響應(yīng)

Parse Gutenberg 塊內(nèi)容進(jìn)入 Next.js 靜態(tài)站點(diǎn)

我們將 WordPress 內(nèi)容提取到 Next.js 項(xiàng)目中,然后將 Gutenberg 塊解析為 HTML。

1.首先設(shè)置一個(gè)從 WordPress 網(wǎng)站獲取帖子的函數(shù)。打開(kāi)?項(xiàng)目中的?src/page.js文件并將其內(nèi)容替換為以下代碼片段:

const getWpPosts = async () => {
	const res = await fetch('https://yoursite.com/wp-json/wp/v2/posts');
  	const posts = await res.json();
	return posts;
};

此異步函數(shù)對(duì) WordPress REST API 執(zhí)行 API 請(qǐng)求。它獲取你網(wǎng)站上的所有可用帖子并將它們作為數(shù)組返回。

2.接下來(lái),讓我們通過(guò)將帖子記錄到控制臺(tái)并呈現(xiàn)基本問(wèn)候語(yǔ),在簡(jiǎn)單的 Next.js 頁(yè)面組件中利用獲取的帖子:

const page = async () => {
  const posts = await getWpPosts();
  console.log(posts);
  
  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

export default page;

    當(dāng)你使用運(yùn)行項(xiàng)目時(shí)npm run dev,它會(huì)顯示“Hello World”消息并將獲取的帖子記錄到終端。

    [
      {
        "_links" : {
          "about" : [...],
          "author" : [...],
          "collection" : [...],
          "curies" : [...],
          "predecessor-version" : [...],
          "replies" : [...],
          "self" : [...],
          "version-history" : [...],
          "wp:attachment" : [...],
          "wp:term" : [...]
        },
        "author" : 1,
        "categories" : [...],
        "comment_status" : "open",
        "content" : {
          "protected" : false,
          "rendered" : "\n<p>Fire, a primal force, captivates with its <strong>flickering flames</strong>, evoking both awe and caution. Its <quote>dance</quote> symbolizes destruction and renewal, consuming the old to make way for the new. While it warms our homes and hearts, fire demands respect for its power to devastate.</p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"250\" height=\"148\" src=\"https://img.example.com/wp-content/uploads/2024/02/burningbuilding.jpg\" alt=\"\" class=\"wp-image-14\"/></figure>\n\n\n\n<p>In ancient times, fire was a beacon of light and warmth, essential for survival. Today, it remains a symbol of human ingenuity and danger. From the comforting glow of a hearth to the destructive fury of wildfires, fire’s dual nature reminds us of our fragile relationship with the elements.</p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https://img.example.com/premium-photo/painting-burning-building-illuminated-by-bright-flames-night_168058-249.jpg?w=1380\" alt=\"\"/></figure>\n\n\n\n<p>You can check out other articles on our blog:</p>\n\n\n\n<ul>\n<li><a href=\"https://yoursite.com/?p=6\">Lorem Ipsum: Beginnings</a></li>\n\n\n\n<li><a href=\"https://yoursite.com/?p=9\">Lorem Ipsum: Act 2</a></li>\n\n\n\n<li><a href=\"https://yoursite.com/?p=11\">Lorem Ipsum: Act 3</a></li>\n</ul>\n"
        },
        "date" : "2024-02-27T12:08:30",
        "date_gmt" : "2024-02-27T12:08:30",
        "excerpt" : {
          "protected" : false,
          "rendered" : "<p>Fire, a primal force, captivates with its flickering flames, evoking both awe and caution. Its dance symbolizes destruction and renewal, consuming the old to make way for the new. While it warms our homes and hearts, fire demands respect for its power to devastate. In ancient times, fire was a beacon of light and warmth, […]</p>\n"
        },
        "featured_media" : 0,
        "format" : "standard",
        "guid" : {
          "rendered" : "https://yoursite.com/?p=13"
        },
        "id" : 13,
        "link" : "https://yoursite.com/?p=13",
        "meta" : {
          "footnotes" : ""
        },
        "modified" : "2024-02-29T16:45:36",
        "modified_gmt" : "2024-02-29T16:45:36",
        "ping_status" : "open",
        "slug" : "fire-fire",
        "status" : "publish",
        "sticky" : false,
        "tags" : [],
        "template" : "",
        "title" : {
          "rendered" : "Fire"
        },
        "type" : "post"
       },
      },
      ...
    ]

    表示各個(gè)古騰堡帖子數(shù)據(jù)的 JSON 對(duì)象包括各種字段,其中內(nèi)容和摘錄字段作為解析為 HTML 字符串的古騰堡塊返回。

    3.在 Next.js 中正確渲染此 HTML 內(nèi)容,我們使用dangerouslySetInnerHTML屬性:

    const page = async () => {
      const posts = await getWpPosts();
    
      return (
        <>
          <h1> Headless Blog </h1>
    
          <div>
            {posts.map((post) => (
              <Link href={'/blog/' + post.id} key={post.id}>
                <h2>
                  {post.title.rendered} <span>-></span>
                </h2>
                <div dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} />
              </Link>
            ))}
          </div>
        </>
      );
    };
    
    export default page;

      在更新的組件中,我們映射獲取的帖子數(shù)組以生成帖子摘錄列表。每個(gè)摘錄都包含在一個(gè)Link用于導(dǎo)航的組件中,顯示帖子標(biāo)題及其內(nèi)容片段。

      dangerouslySetInnerHTML屬性用于解析和呈現(xiàn)excerpt.rendered字段中包含的 HTML 內(nèi)容。

      4.接下來(lái),在應(yīng)用程序目錄?中創(chuàng)建文件blog/[id]/page.js??。可以使用文件夾來(lái)定義路線。因此,通過(guò)創(chuàng)建博客?文件夾,可以定義博客?路線。可以將其與動(dòng)態(tài)路由結(jié)合起來(lái)?,為每個(gè)帖子生成路徑。

      5.每個(gè)帖子都有一個(gè) ID。可以使用此 ID/blog/{post_id}在應(yīng)用程序中生成其唯一的路徑。添加以下代碼:

      import Link from 'next/link';
      
      export async function generateStaticParams() {
          const res = await fetch('https://yoursite.com/wp-json/wp/v2/posts');
          const posts = await res.json();
          return posts.map((post) => {
              return {
                  params: {
                      id: post.id.toString(),
                  },
              };
          });
      }
      
      export async function getPost(id) {
          const response = await fetch('https://yoursite.com/wp-json/wp/v2/posts/' + id);
          const post = await response.json();
          return post;
      }

        generateStaticParams()?函數(shù)根據(jù)每個(gè)帖子返回的相應(yīng) ID 在構(gòu)建時(shí)靜態(tài)生成路徑。該getPost()函數(shù)使用傳遞的 ID 從 REST API 獲取帖子的古騰堡數(shù)據(jù)。

        前面的部分顯示了從帖子的 REST API 返回的已解析古騰堡數(shù)據(jù)示例。目前,我們只關(guān)心該content.rendered?領(lǐng)域:

        [
          {
            ...
            "content": {
              "rendered" : "\n<p>Fire, a primal force, captivates with its <strong>flickering flames</strong>, evoking both awe and caution. Its <quote>dance</quote> symbolizes destruction and renewal, consuming the old to make way for the new. While it warms our homes and hearts, fire demands respect for its power to devastate.</p>\n\n\n\n<figure> class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"250\" height=\"148\" src=\"https://img.example.com/wp-content/uploads/2024/02/burningbuilding.jpg\" alt=\"\" class=\"wp-image-14\"/></figure>\n\n\n\n<p>In ancient times, fire was a beacon of light and warmth, essential for survival. Today, it remains a symbol of human ingenuity and danger. From the comforting glow of a hearth to the destructive fury of wildfires, fire’s dual nature reminds us of our fragile relationship with the elements.</p>\n\n\n\n<figure> class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https://img.example.com/premium-photo/painting-burning-building-illuminated-by-bright-flames-night_168058-249.jpg?w=1380\" alt=\"\"/></figure>\n\n\n\n<p>You can check out other articles on our blog:</p>\n\n\n\n<ul>\n<li><a> href=\"https://yoursite.com/?p=6\">Lorem Ipsum: Beginnings</a></li>\n\n\n\n<li><a> href=\"https://yoursite.com/?p=9\">Lorem Ipsum: Act 2</a></li>\n\n\n\n<li><a> href=\"https://yoursite.com/?p=11\">Lorem Ipsum: Act 3</a></li>\n</ul>\n"
            },
            ...
          }
        ]

        該字段包含帖子的原始 HTML。它可以直接使用dangerouslySetInnerHTML?像這樣的屬性來(lái)渲染<div dangerouslySetInnerHTML={{ __html: <raw_html_string> }} />

        6.接下來(lái),可以通過(guò)解析內(nèi)部鏈接和調(diào)整圖像大小來(lái)處理數(shù)據(jù)。安裝該html-react-parser?包以簡(jiǎn)化解析標(biāo)簽的過(guò)程:

        npm install html-react-parser --save

          7.將以下代碼添加到blog/[id]/page.js?文件中:

          import parse, { domToReact } from "html-react-parser";
          
          /*
           * We use a regular expression (pattern) to match the specific URL you want to replace.
           * The (\d+) part captures the numeric ID after ?p=.
           * Then, we use the replacement string 'data-internal-link="true" href="/blog/$1"',
           * where $1 is a placeholder for the captured ID.
           */
          export function fixInternalLinks(html_string) {
            const pattern = /href="https:\/\/yoursite.com\/\?p=(\d+)"/g;
            const replacement = 'data-internal-link="true" href="/blog/$1"';
          
            return html_string.replace(pattern, replacement);
          }
          
          export function parseHtml(html) {
            // Replace 2+ sequences of '\n' with a single '<br />' tag
            const _content = html.replace(/\n{2,}/g, '<br />');
            const content = fixInternalLinks(_content);
          
            const options = {
              replace: ({ name, attribs, children }) => {
                // Convert internal links to Next.js Link components.
                const isInternalLink =
                  name === "a" && attribs["data-internal-link"] === "true";
          
                if (isInternalLink) {
                  return (
                    <Link href={attribs.href} {...attribs}>
                      {domToReact(children, options)}
                    </Link>
              	  );
                } else if (name === "img") {
                  attribs["width"] = "250";
                  attribs["height"] = "150";
                  return (
                    <img {...attribs}/>
                  );
                }
              },
            };
          
            return parse(content, options);
          }

          fixInternalLinks()?函數(shù)使用正則表達(dá)式從 HTML 字符串中查找 WordPress 網(wǎng)站中帖子的鏈接。在原始 HTML 中,可以看到該帖子包含一個(gè)List標(biāo)簽,其中包含指向網(wǎng)站上其他帖子的鏈接,并將這些鏈接替換為指向靜態(tài)網(wǎng)站中的路徑的內(nèi)部鏈接。

          parseHTML()?函數(shù)找到多個(gè)多余換行符序列,n并用標(biāo)簽替換它們<br />?。它還查找內(nèi)部鏈接并將錨標(biāo)記轉(zhuǎn)換為鏈接標(biāo)記。然后,該函數(shù)使用標(biāo)簽屬性調(diào)整圖像大小。

          8.要為每個(gè)動(dòng)態(tài)路徑生成主 UI,請(qǐng)?zhí)砑右韵麓a:

          export default async function Post({ params }) {
            const post = await getPost(params.id);
          
            const content = parseHtml(post.content.rendered);
          
            return (
              <>
                <h1>
                  {post.title.rendered}
                </h1>
           	 
                <div>{content}</div>
              </>
            );
          }

          從古騰堡數(shù)據(jù)解析原始 HTML 后,代碼返回表示頁(yè)面格式化 UI 的 JSX。

            最后,運(yùn)行項(xiàng)目時(shí),主頁(yè)將顯示 WordPress 上的帖子列表。此外,當(dāng)你單擊各個(gè)帖子時(shí),將看到解析后的古騰堡內(nèi)容正確呈現(xiàn)。


            聯(lián)系我們
            教程看不懂?聯(lián)系我們?yōu)槟赓M(fèi)解答!免費(fèi)助力個(gè)人,小企站點(diǎn)!
            客服微信
            客服微信
            電話:020-2206-9892
            QQ咨詢:1025174874
            郵件:info@361sale.com
            工作時(shí)間:周一至周五,9:30-18:30,節(jié)假日休息
            ? 轉(zhuǎn)載聲明
            本文作者:Harry
            THE END
            喜歡就支持一下吧
            點(diǎn)贊0 分享
            評(píng)論 搶沙發(fā)

            請(qǐng)登錄后發(fā)表評(píng)論

              暫無(wú)評(píng)論內(nèi)容