Getting around Prismic's lack of <blockquote> element capability in rich text editor

505 views Asked by At

I started using Prismic as a headless CMS for a previous project, and it worked fine, but on a second project, I ran into a problem that surprised me, and that is Prismic's inability to do a simple blockquote. Considering that this HTML element has been around in HTML for decades, it blows my mind. According to their docs and forum responses, they are considering adding it to their editor, but you have to jump through hoops by using labels and applying them to your text, and this just wraps the text in <span> tag that has a class of your label name. In your front end, you then have to target those spans with CSS.

The problem with this in their Rich Text editor, if you have a multi-paragraph block that you want to quote inside of a larger body of text, the editor treats them as multiple paragraphs, so in your output, instead of one big block - like you would get with a standard <blockquote> tag - you get multiple paragraphs wrapped in individual <span> tags, which is more difficult to make look like one block with just CSS.

<p><span class="my-label">Paragraph 1 text</span></p>
<p><span class="my-label">Paragraph 2 text</span></p>
<p><span class="my-label">Paragraph 3 text</span></p>
<p><span class="my-label">Paragraph 4 text</span></p>

I'm doing this inside a Nuxt app using v-html, and since highlighted text could be anywhere inside a larger body of text, I really don't want to have to do code gymnastics inside an html serializer or the api data to identify the labeled items. I really don't want to have to switch to another CMS or local markdown just to get around this.

When I've tried targeting the tags, it gets challenging trying to do it so that everything looks like one large block.

  1. Does any Prismic user know a way I can actually get a <blockquote> tag in the content in the Prismic editor itself? There's not an option to edit the raw html in their editor, and even with slices, I haven't seen a way to insert a tag in the content.
  2. Is there a simple way with CSS to target those multiple paragraphs so that they look like one block? I'm not a CSS guru, and it looks like it requires some fine tuning with padding and line heights.
1

There are 1 answers

1
lihbr On

Regarding a solution on Prismic's end, using slices the idea would be to use the slice zone to have a simple "RichText" slice for basic text and another "BlockQuote" slice for doing fancy quotes. Slice definition could look like this:

{
  "type": "Slices",
  "fieldset": "Slice zone",
  "config": {
    "labels": {
      "richtext": [],
      "blockquote": []
    },
    "choices": {
      "richtext": {
        "type": "Slice",
        "fieldset": "Rich Text",
        "description": "Rich text slice",
        "icon": "reorder",
        "display": "list",
        "non-repeat": {
          "text": {
            "type": "StructuredText",
            "config": {
              "multi": "paragraph, preformatted, heading1, heading2, heading3, heading4, heading5, heading6, strong, em, hyperlink, image, embed, list-item, o-list-item, rtl",
              "allowTargetBlank": true,
              "label": "Text"
            }
          }
        },
        "repeat": {}
      },
      "blockquote": {
        "type": "Slice",
        "fieldset": "Block Quote",
        "description": "Block Quote slice",
        "icon": "format_quote",
        "display": "list",
        "non-repeat": {
          "text": {
            "type": "StructuredText",
            "config": {
              "multi": "paragraph, preformatted, heading1, heading2, heading3, heading4, heading5, heading6, strong, em, hyperlink, image, embed, list-item, o-list-item, rtl",
              "allowTargetBlank": true,
              "label": "Text"
            }
          }
        },
        "repeat": {}
      }
    }
  }
}

Then it would be just about looping through the array, something in that fashion:

<template>
  <prismic-rich-text v-for="slice in document.data.body" :field="slice.primary.text" :class="slice.slice_type" />
</template>