【问题标题】:Text highlight is not being applied at front-end in Sanity CMS文本突出显示未在 Sanity CMS 的前端应用
【发布时间】:2021-06-30 17:49:15
【问题描述】:

我正在尝试使用 Sanity Headless CMS 和 React 作为前端创建博客。

我制作了一个装饰器来突出显示文本。如下图所示,在编辑器中,突出显示的文本具有黄色背景色。 但是,我的 React 前端没有看到黄色突出显示。

我错过了什么?

sn-ps的代码如下: sanityblog/schemas/blockContent.js

import React from "react";

/**
 * This is the schema definition for the rich text fields used for
 * for this blog studio. When you import it in schemas.js it can be
 * reused in other parts of the studio with:
 *  {
 *    name: 'someName',
 *    title: 'Some title',
 *    type: 'blockContent'
 *  }
 */

const highlightRender = (props) => (
  <span style={{ backgroundColor: "yellow" }}>{props.children}</span>
);

export default {
  title: "Block Content",
  name: "blockContent",
  type: "array",
  of: [
    {
      title: "Block",
      type: "block",
      // Styles let you set what your user can mark up blocks with. These
      // correspond with HTML tags, but you can set any title or value
      // you want and decide how you want to deal with it where you want to
      // use your content.
      styles: [
        { title: "Normal", value: "normal" },
        { title: "H1", value: "h1" },
        { title: "H2", value: "h2" },
        { title: "H3", value: "h3" },
        { title: "H4", value: "h4" },
        { title: "Quote", value: "blockquote" },
      ],
      lists: [{ title: "Bullet", value: "bullet" }],
      // Marks let you mark up inline text in the block editor.
      marks: {
        // Decorators usually describe a single property – e.g. a typographic
        // preference or highlighting by editors.
        decorators: [
          { title: "Strong", value: "strong" },
          { title: "Emphasis", value: "em" },
          {
            title: "Highlight",
            value: "highlight",
            blockEditor: {
              icon: () => "H",
              render: highlightRender,
            },
          },
        ],
        // Annotations can be any object structure – e.g. a link or a footnote.
        annotations: [
          {
            title: "URL",
            name: "link",
            type: "object",
            fields: [
              {
                title: "URL",
                name: "href",
                type: "url",
              },
              {
                title: "Open in new tab",
                name: "blank",
                description: "Read https://css-tricks.com/use-target_blank/",
                type: "boolean",
              },
            ],
          },
        ],
      },
    },
    // You can add additional types here. Note that you can't use
    // primitive types such as 'string' and 'number' in the same array
    // as a block type.
    {
      type: "image",
      options: { hotspot: true },
    },

    {
      type: "code",
    },
  ],
};

src/components/OnePost.js OnePost.js 负责渲染单个博文。

import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import sanityClient from "../client.js";
import BlockContent from "@sanity/block-content-to-react";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { coldarkDark } from "react-syntax-highlighter/dist/esm/styles/prism";

export default function OnePost() {
  const [postData, setPostData] = useState(null);
  const { slug } = useParams();

  const serializers = {
    types: {
      code: (props) => (
        <SyntaxHighlighter
          language={props.node.language}
          style={coldarkDark}
          showLineNumbers
          lineNumberStyle={{
            padding: "0 5px 0 0",
            fontSize: 14,
            borderRight: "1.5px solid darkgray",
            marginRight: "10px",
          }}
        >
          {props.node.code}
        </SyntaxHighlighter>
      ),
    },
  };

  useEffect(() => {
    sanityClient
      .fetch(
        `*[slug.current == $slug]{
          title,
          slug,
          mainImage{
            asset->{
              _id,
              url
             }
           },
         body,
        "name": author->name,
        "authorImage": author->image
       }`,
        { slug }
      )
      .then((data) => setPostData(data[0]))
      .catch(console.error);
  }, [slug]);

  if (!postData) return <div>Loading...</div>;

  return (
    <div className="col-11 col-sm-10 col-md-6 mx-auto mt-5">
      <div>
        <h1 className="font-weight-bold">{postData.title}</h1>
        <div>
          <h6 className="text-secondary">{postData.name}</h6>
        </div>
      </div>
      <div className="text-muted">
        <BlockContent
          blocks={postData.body}
          projectId={sanityClient.projectId}
          dataset={sanityClient.dataset}
          serializers={serializers}
        />
      </div>
    </div>
  );
}

【问题讨论】:

    标签: content-management-system sanity headless-cms


    【解决方案1】:

    你需要序列化数据。

    您已经为代码编辑器窗口执行了此操作,在您当前的序列化程序中您说“如果类型是代码,则运行此组件”。

    你也需要为语法高亮做这个,也许这样的东西可以工作(没有测试过)

    marks: {
      highlight: ({ children }) => {
        return <HighLightComponent children={children} />;
      },
    },
    

    【讨论】:

    • 需要序列化数据。这是什么意思?另外,这个Highlight 组件是什么,我该如何使用它?
    • 高亮组件只是我自己编的一个mock组件。在那里,您可以运行需要突出显示的代码。如果您愿意,也可以只使用 HTML 标记 。 “序列化”数据基本上只是意味着将其转换为您想要的格式。 Sanity 只提供 JSON,不提供 HTML。所以你必须说“如果理智返回突出显示,把它放在这个 HTML 中”。如果您在 Sanity Studio 中运行 GROQ 查询,您可以看到结构。在这里查看我的一个序列化程序,也许它可以给你一些灵感:) pastebin.com/KC19EWkH
    • 非常感谢山姆。你让我今天一整天都感觉很好。这几天我一直在为此苦苦挣扎。我发现 Sanity 文档令人困惑。我会回来找你帮忙的。我正在使用 Sanity 和 React 前端制作博客。再次感谢。
    猜你喜欢
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 2015-05-29
    相关资源
    最近更新 更多