Render Snippets in Front Matter

Background
I created an editorial component that allows editors to add free-form content to sections via a rich text editor. I made a snippet for a button that will allow editors to simply add buttons. When I saved the page my front matter looked like this:

- _bookshop_name: editorial
    content: >-
      ## Some Content

      Here's a paragraph
      
      {% bookshop 'snippets/button' text: "Click Me"
      button_link: "#" button_color: "primary" button_size: "lg" %}

Here’s my bookshop component code:

<section class="editorial {{ section_theme }}">
  <div class="max-w-section">
    {{ content | markdownify }}
  </div>
</section>

What I expect to see
My button rendered and looking nice and clickable:

<h2>Some content</h2>
<p>Here's a paragraph</p>
<a class="btn btn--large btn--primary" href="#">Click me</a>

What I saw
My bookshop component stringified :frowning:

<h2>Some content</h2>
<p>Here's a paragraph</p>
<p>{% bookshop 'snippets/button' text: "Click Me"
      button_link: "#" button_color: "primary" button_size: "lg" %}</p>

Next Steps
I attempted to just use pure HTML but no dice on that either. It seems nothing gets rendered in the frontmatter. I recall jekyll having a plugin that made this happen but not sure if 11ty has something as well.

I think the other path might be to create a nested component section where I can add buttons, rich text, and other components editors might need separately.

1 Like

I ran into and addressed this exact same issue when building my template. I ended up creating my own filter that rendered the bookshop components, it was a pain to get right.

However, this was before 11ty came out with render which should be a pretty straight forward drop in replacement. What you are looking for is the renderContent filter

What I recommend you try doing after adding the render plugin

<section class="editorial {{ section_theme }}">
  <div class="max-w-section">
    {{ content | renderContent | markdownify }}
  </div>
</section>

Here is what I did for mine:

{% if text and env_bookshop_live %}
    <div class="c-textBlock">    
        {{ text | markdownify  }}
    </div>
{% elsif text %}
<div class="c-textBlock">    
        {{ text | evalLiquid | markdownify  }}
    </div>
{% endif %}

Note: This is using my own filter. I for some reason you want to implement your own, take a look at this

I hope this helps :slightly_smiling_face:

2 Likes

I’ll try that out. Still getting my sea legs with 11ty, it requires WAY more finesse than Jekyll where I would just plop a plugin and use a liquid tag/filter.

My other thought was nesting components where I would make a Gutenberg-style editorial area since my snippets sit on their own line. Though I’m not really sure if you can do that with snippets and CloudCannon’s docs are unclear to say the least.

@Gio There’s a lot of issues here so hopefully you can fill in the gaps of this rest of the owl documentation.

I’m working off of the Eleventy CloudCannon Starter template which doesn’t use async in the configs so I can’t even install the plugin. This guy uses a different installation method which works, but then renderContent is not a recognized filter and my site refuses to build again :upside_down_face:.

Oy…I see the issue now. This template is on v2, not v3. So these were the relevant docs, but rendercontent was not included in this version. Updated to v3 and it worked as intended:

Here’s my code so this isn’t wisdom of the ancients:

<section class="editorial {{ section_theme }}">
  <div class="max-w-section">
    {{ content | renderContent }}
  </div>
</section>

I’ll need to see if anything else broke, but I think the big idea here is that the Eleventy CloudCannon Starter is a terrible starting place.

Not a dig a cloudcannon, but there existing 11ty starter template didn’t work for me and I couldn’t get it to build locally when I did try to mess around with it. I recommend using their 11ty based venture template instead, that is what I used to learn how to use bookshop within 11ty and eventually create my own based on what I learned from there. You could also gather information from my own template, but I haven’t done any developer focused documentation, sorry.

If you ever encounter any other snags feel free to @ me. I’ve worked pretty extensively with 11ty.

1 Like

Yup, I peeped the venture template too. Much more simple and actual functioning template. The starter has some functional issues with the CMS as well. I was banging my head against a wall with the icon selector until I made a site with starter and saw it had the same issue. Still not sure why

My next snag is getting the content to render in bookshop:


The content renders on build but not within bookshop. Other CMSs like sanity offer a local dev mode so I can see what the issue is before building and I’m running out of build time so if you got a fix, I’m all ears.

1 Like

If you started off originally basing your project off the 11y starter template, I fear you may be fighting an uphill battle since its hasn’t been kept up to date.

Using venture as your starting point could save you time in the long run.

Are you building a site for a client and is that why you are running out of build minutes? What I do is build the client account in my agencies org, and then just connect it to the client org once I’m ready for hand off. This applies if your main organization account is on the standard plan or above. If you are on the lite plan, I don’t have a work around.

Back to your question. Is there a way you can share your repo so I can take a look?

Based on the image alone, there are too many unknowns.

Note:
I didn’t take the time to figure out how to render snippets within text blocks in the live editor. I just explain the limitation to my clients and they are fine with it. The rest of the markdown does render though.

Here is an 11ty specific guide for bookshop incase you haven’t seen it yet

Here is my textblock, maybe you are doing something different?

Right on about the Eleventy Starter. I’m working on modernizing everything now. I ripped out a bunch of stuff as well so I’m not really losing anything.

I have indeed been referencing the guide as I’m developing. I think I really just need to sit down and learn it really well before moving forward in finetuning the CMS.

As for the render, I’m not sure why a markdownify filter works but not the renderContent filter. I’ll ping support with that issue.

Says it right here in the docs. Only liquid filters get processed. So I just gotta tell them to close their eyes and imagine the button.

I think a nested component might be a better way that will allow editors to create sections. I do this with one of my Hubspot CMS clients currently. You drop in a section and then add the modules (eg a 3 column blog post card grid). I can also pre-make the sections with the modules included. It’s a more adaptable system and our content editors don’t have to use their imagination.

I think I understand what you mean. You may already figured it out, but sounds like you are looking to create an array of a structure.

blueprint:
  content:
    sectionId:
    editorial: [bookshop:structure:editorialBlocks]
  styles:
    color_group: primary
{% for block in content.editorial %}
      <div class="mt-4">{% bookshop "{{block._bookshop_name}}" bind: block %}</div>
    {% endfor %}

Once you get that up and running perhaps you can showcase it here in the community? :eyes: I’d be interested in seeing what you came up with.

1 Like

Hi Ed,

Sorry you had a disappointing experience with the Eleventy Starter! We’ll do what we can to go through and update the starter to a more useful condition, in particular updating it up to use Eleventy 3, and using the new 11ty filter renderContent where we can.

I think one of the main problems here is that we haven’t made it clear that snippets in markdown fields in the visual editor won’t work without significant custom implementation.

The issue is that rendering Snippets/Shortcodes is usually the responsibility of 11ty (or whatever SSG you are using). When 11ty runs a build it parses your markdown body content, and renders any shortcodes amongst that body content.

A markdown field in frontmatter getting run through Bookshop does not get run through 11ty (at least not in the visual editor). Instead it would usually get parsed into html through a markdown library, eg. markdown-it. 11ty will also be doing this under the hood (but also more - like resolving your shortcodes into html) when it parses the markdown in the body content of your pages. Bookshop doesn’t run any part of Eleventy proper in the browser, it just runs the liquidjs engine, so anything to support a specific Eleventy non-liquid feature like renderContent has to be emulated in a custom Bookshop plugin.

When we update to the latest version of 11ty we do gain access to the renderContent filter, which renders markdown and snippets unlike just pumping the content through a standalone markdown library. This is probably where you noticed that, although your shortcode will render during local development and on your real site, Bookshop doesn’t know anything about the renderContent function (remembering it is an 11ty fn not a Bookshop one). This means it cannot render shortcodes in the same way as would happen during the build. To use renderContent with Bookshop, you’d need to add a custom plugin that does the same thing as renderContent, to tell Bookshop what the markdown field would look like if it did get processed through an 11ty build, and therefore the renderContent filter. This ensures the visual editor can reflect what your changes would actually look like if you were to save and build.

I’m doing some experimenting to see if there’s any way we can implement the same logic that renderContent uses under the hood in a custom Bookshop plugin, but so far it does seem like quite a large piece of 11ty to try to recreate in a plugin.

We’d like to offer this workflow if we can work out how, but currently its not possible. I think the approach you’ve settled on of nesting components inside of other components is the best way forward for now, as you’ve said in your last couple of replies. Hopefully that should still offer your editors enough flexibility with page building/editing. This could also mean reverting to use a markdown library for markdown inputs in Bookshop (which is nice an easy to emulate in a custom plugin) and removing the option for editors to add snippets in those inputs. Although you can’t use a markdown input with Bookshop to add components (snippets) throughout that content, it could still be handy to allow editors basic markdown formatting like bold, italics and links.

Again, my sincere apologies that you had a round-about frustrating experience getting to that point. If you have any questions, or further feedback on how we could better communicate this in future to avoid others having to face the same frustration you had did, we’d love to hear.

Thanks to both of you - Ed and Gio - for being such active community members - it really is appreciated and helps us out a lot!

Best wishes,
Tom

2 Likes

@Tom_Richardson Thanks for that thorough response. I think I will go with the nested component structure. I believe that will work better for content editors wanting to add buttons and embeds to pages while giving them the preview function. I’m in my throwing science at the wall phase of development so I’m stumbling now but eventually I’ll get into a groove.

My goal is to make my template as stock as possible so other developers can be easily onboarded and we can increase the adoption rate of the platform/framework/doohickey/whatever you wanna call cloudcannon.

My other goal is to make this a better alternative to Worpdress. I’m basically making a Gutenburg-style editor that does everything Wordpress can with a simpler code base that’s cheaper to host and requires 0 maintenance or developer support. I soft-pitched a wordpress site owner at the prospect of simply creating landing pages from existing components on my phone at the bar we were talking at. The other value prop is that wordpress “developers” (eg elementor drag and droppers) create websites for $500-$2000 dollars then hold their clients hostage with maintenance contracts core/plugin updates and doing basic content updates because they didn’t build anything properly or write docs. My build will be higher upfront cost but no maintenance and if they want to engage me on a retainer, we can do SEO and CRO instead of fixing buttons and forms.

3 Likes

@Gio I have a rudimentary module/section system cookin:


So right now I have a section that I drop into the page then you can plop down modules like buttons and rich text. Here’s the structure:

components/sections/1-col/1-col.bookshop.yml

spec:
  structures:
    - content_blocks
  label: "1-col"
  description: 
  icon:
  tags: []


blueprint:
  section_title: 'Section Title'
  modules: [bookshop:structure:modules] #looks for any bookshop component with modues in the structures array
  section_theme: 'section-white'

components/modules/button.yml

spec:
  structures:
  - modules #added the modules definition so that the 1-col section component will list it. 
  label: "Button"
  description:
  icon: touch_app
  tags: []

components/sections/1-col.eleventy.liquid

<section class="{{  section_theme }}">
    <div class="max-w-section">
        <h2>{{ section_title }}</h2>
        {% for module in modules %}
            <div>
            {% bookshop "{{module._bookshop_name}}" bind: module %}
            </div>
        {% endfor %}
    </div>
</section>

collections/pages/test-section.md

---
_schema: default
title: Test Section
layout: layouts/component-page.html
eleventyExcludeFromCollections: false
permalink: /test-section/
content_blocks:
  - _bookshop_name: sections/1-col
    section_title: "Test Section"
    section_theme: "section-white"
    modules: 
    - _bookshop_name: modules/rich-text
      text: >-
        ### Rich text

        I'm text with a whole lotta money. I struck oil in Text-as, ha! 
    - _bookshop_name: modules/button
      text: "I'm a button"
      button_color: "primary"
      button_size: "lg"
---
2 Likes