基于Frontity正确显示WordPress文章内容

frontity display contents of post

本篇文章介绍如何对 WordPress 的文章内容做兼容性适配,比如文章中的界面元素、样式、链接等做兼容性处理,主要是保证经过 WordPress 内容编辑器(Gutenberg)生成的文章可以正确地显示在 Frontity 的网站界面中。

在 Frontity 应用里能够正确显示 WordPress 内容编辑器中的各种元素的主要工作包括三个部分,一个是 WordPress Gutenberg 主题样式的移植,第二个是 WordPress 中用户自定义的样式移植,第三个是对 WordPress 文章中的一些特定界面元素做兼容性处理。

一、Gutenberg 主题样式移植

这个比较简单,根据你的 Gutenberg 版本到这个网站找对应的 Style.css 和 Theme.css两个文件,然后拷贝到 Frontity 项目的 assets/gutenberg 目录下,并在 Frontity 应用组件的 index.js 中声明一下即可。

sample-frontity-project/packages/frontity-chakra-theme/src/components/index.js

...
import KflyoIcon from "../assets/kflyo.png";
import gutenbergStyle from "../assets/gutenberg/style.css";
import gutenbergTheme from "../assets/gutenberg/theme.css";
import KflyoOne from "../assets/kflyo-one.css";

// Theme is the root React component of our theme. The one we will export
// in roots.
const Theme = ({ state }) => {
  // Get information about the current URL.
  const data = state.source.get(state.router.link);

  const overrides = extendTheme({
    fonts: {
      heading: "Kelson, system-ui, Helvetica, sans-serif"
    },
    colors: { ...state.theme.colors }
  });

  return (
    <ChakraProvider theme={{ ...overrides }}>
...
      <Global styles={css(gutenbergStyle)} /> {/*Gutenberg 样式*/}
      <Global styles={css(gutenbergTheme)} /> {/*Gutenberg 主题样式*/}
      <Global styles={css(KflyoOne)} /> {/*用户自定义样式*/}
    </ChakraProvider>
  );
};

export default connect(Theme);

更详细的内容,这有一篇文章可以参考。

二、WordPress 用户自定义样式移植

这个跟上面的做法一样,把用户自定义样式拷贝到 Frontity 相应的目录下,然后声明一下即可。

三、WordPress 文章内容元素兼容性适配

这个要用到 Frontity 的 html2react 组件,作用是把 html 元素转换成 react 组件,然后以组件的方式处理 html 元素。

htmltoreact 组件的一个重要的功能是 processor,定义 html 界面元素对应的 React 组件,定义好后,就可以按照 React 的方式处理界面元素了。

比如文章中代码的语法显示部分,对 pre 标签的处理:

sample-frontity-project/packages/frontity-chakra-theme/src/components/styles/ processors.js

import React from "react";
import { Alert, Text, Box, Heading, others } from "@chakra-ui/react";
import Link from "../link";

import PreCode from "../precode";
import { getPostData, formatPostData } from "../helpers";
import post from "../post/post";

/**
 *
 * @param {React.ElementType} tag
 * @param {{props: (nodeProps: Object) => Object, component: React.ComponentType<any>}} options
 */
function makeProcessor(tag, options) {
  return {
    name: tag,
    test: ({ node }) => node.component === tag,
    processor: ({ node, state }) => {
      var isGalleryOrVideo = null;
      if(options.component==PostLink) {
        const postData = getPostData(state);
        const post = formatPostData(state, postData);
        isGalleryOrVideo = (post.format=="gallery" || post.format=="image")?{'data-lightbox': post.format}:(post.format=="video" || node.props.href.endsWith(".gif"))?{'data-videobox': "video"}:null;
      }
      node.component = options.component || node.tag;
      node.props = { ...options.props({ node }), ...node.props, ...isGalleryOrVideo };
      return node;
    },
    // allow for overriding this processors
    priority: 20
  };
}
...
const pre = makeProcessor("pre", {
  props: () => {
    return {
      className: "wp-block-code prettyprint",
    };
  },
  component: PreCode
});

const processors = [blockquote, paragraph, figcaption, h3, a, pre];
export default processors;

sample-frontity-project/packages/frontity-chakra-theme/src/components/precode.js

import { connect } from "frontity";
import React from "react";

const PreCode = ({
    className,
    children,
    ...props
  }) => {console.log(className)
    return (
        <pre className="wp-block-code prettyprint">
            {children}
        </pre>
     );
  };

export default connect(PreCode)

最后,用户在 WordPress 中开发好的 JavaScript 和 Css 代码可以声明并使用。

sample-frontity-project/packages/frontity-chakra-theme/src/components/index.js

// Theme is the root React component of our theme. The one we will export
// in roots.
const Theme = ({ state }) => {
  // Get information about the current URL.
  const data = state.source.get(state.router.link);

  const overrides = extendTheme({
    fonts: {
      heading: "Kelson, system-ui, Helvetica, sans-serif"
    },
    colors: { ...state.theme.colors }
  });

  return (
    <ChakraProvider theme={{ ...overrides }}>
      <FontFace />
      {/* Add some metatags to the <head> of the HTML. */}
      <Title />
      <Head>
        <meta name="description" content={state.frontity.description} />
        <html lang="zh-CN" />
        <link rel="icon" href={KflyoIcon} sizes="32x32"></link>
        <script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
        <script type="text/javascript" src="https://www.kflyo.com/wp-includes/js/jquery/jquery.js?ver=1.12.4"></script>
        <script type="text/javascript" src="https://www.kflyo.com/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.4.1"></script>
        <script type="text/javascript" src="https://www.kflyo.com/wp-content/plugins/kflyo-utility-tools/js/kflyo.js?ver=1.1"></script>
        <link rel="stylesheet" id="kflyo-css" href="https://www.kflyo.com/wp-content/plugins/kflyo-utility-tools/css/kflyo.css?ver=1.1" type="text/css" media="all"></link>
      </Head>

      {/* Add the header of the site. */}
      <Header />

      {/* Add the main section. It renders a different component depending
      on the type of URL we are in. */}
      <Box
        as="main"
        mt={{ base: "40px", md: "70px" }}
        minH="calc(100vh - 320px)"
      >
        <Switch>
          <Loading when={data.isFetching} />
          <SearchResults when={data.isSearch} />
          <Archive when={data.isArchive} />
          <Post when={data.isPostType} />
          <Page404 when={data.is404} />
        </Switch>
      </Box>

      <Footer />
      <Global styles={css(gutenbergStyle)} />
      <Global styles={css(gutenbergTheme)} />
      <Global styles={css(KflyoOne)} />
    </ChakraProvider>
  );
};

export default connect(Theme);
frontity display contents of post
Frontity 显示文章内容

发表评论

邮箱地址不会被公开。 必填项已用*标注