Creating custom content blocks
Making content blocks simpler with use of SimplyEdit
Wordpress 5.0 is out and with it Gutenberg, a modern inline WYSIWYG editor. There’s a good article on Smashing Magazine that shows how to do extend Gutenberg with custom content blocks. Sanity, a different CMS system, took the opportunity to show how simple their CMS handles custom content blocks in comparison to Gutenberg. So ofcourse I’d like to show you how SimplyEdit makes it even simpler.
Where Gutenberg requires a 10 step tutorial, with a mix of PHP, javascript, JSON, HTML and CSS, Sanity requires just a JSON content model and a React component. SimplyEdit just requires HTML and CSS.
Carousel components
The Gutenberg demo uses the Carousel component from Sanity uses the deprecated marquee tag to simplify the code. So check out the marquee approach first:
The HTML for the marquee tag, as used in the Sanity article looks like this:
Now the SimplyEdit version. I’ve moved the CSS to separate classes as well.
This allows you to add and edit slides in the slideshow, but the slideshow itself is not yet something you can add to a page. So here is a page that has two content blocks; “Marquee” and “Content”:
And you can see the whole thing in action in this codepen: https://codepen.io/poef/pen/KJEPJw
However, SimplyEdit can handle even a much more complex piece of code, like the Bootstrap Carousel. And it does it with a lot less code as well. You will need some understanding of Javascript to follow this though.
The HTML for the Carousel looks like this:
The original Gutenberg example adds a lot of HTML to make it a true testimonial slider, but we’ll just focus on the basic principles here. The code above is a direct copy of the HTML from the Bootstrap Carousel page. So you cannot edit anything or add or remove slides. Let’s start with that:
Syncing the numbers with the indicators
We’ve added a data-simply-list=”slides”
and data-simply-sortable
. We’ve removed all the slides except the first and put that one in a template.
There are two problems here: all the slides you add will be active
, while there can be only one active slide at a time. And the carousel indicators are not synced with the number of slides. Let’s fix that one first:
Now we have the same number of slides as indicators, but the indicators all point to the first slide. We can fix this at the same time as we fix the active
slides problem. What we need is a way to only add the active
class to the first slide and the first indicator. The simplest way would be something like this:
And skip the active
class in the templates, but we must make sure that the slides list is applied before we do this. SimplyEdit has an event for that:
We’re using the databind:elementresolved
event here to be sure that all changes to the list have been rendered before we change the DOM. If you used the simply-data-applied
event, then you might trigger before the updates to the DOM have all been rendered.
Pointing to the correct slide
The next problem is to make the indicators point to the correct slide. For that we need the index of the list item stored as the data-slide-to
attribute. We can just calculate this in the javascript method above, like this with javascript:
And now we add the index
to the carousel indicators as the data-slide-to
attribute in HTML:
Because the template defines the index
field as an attributes list, we can’t just assign it a number in the javascript, we have to specify the attribute name as well. That is why we use an object with the property data-slide-to
. SimplyEdit allows for more than one attribute in a single field.
Making it editable
All that’s left to do is to make the contents of the slides editable with SimplyEdit, in HTML it will be:
And we’re done. You can now add slides, edit the image and captions and save the changes. Except for one thing, the carousel now works with SimplyEdit and is editable, but it isn’t a custom content type yet, you can’t insert it. It has to be part of the page template. So let’s turn it into a content slice you can select and insert into a page (with HTML):
Now you can select the carousel as a custom content type in the <main>
section. In fact, it is currently the only content type, since SimplyEdit doesn’t provide you with a default set, you must create your own.
Using a transform function
There is still a problem though, the carousel relies on a specific id
to link the controls to this specific carousel. If we insert the carousel like this, only the first one will work correctly. What we need is a way to specify a unique id
for each carousel.
One way of achieving this is to use a transform function. Something like this (javascript):
And then add the random id
in the carousel (HTML):
What happens here: is that the transformer method randomId
is called when the carousel is rendered. This transformer adds the id
and href
properties to the carousel
field. This field is re-used in the carousel controls, which are anchors, so SimplyEdit fills the href
attribute from the new href
property in the carousel
field.
See the complete running demo here at my Codepen.
A bit too complex
The Bootstrap Carousel component is actually quite a bit more complex than is really needed. There shouldn’t be a need to specify one slide as active, the component could just as easily assume the first element is active unless another one was specified. In addition, the carousel indicators shouldn’t have to specify which slide they reference, this could just as easily be inferred from the order of the indicators.
Finally, it would be easier if the indicators and previous and next buttons did not have to reference the carousel by ID. All these links are inside the DOM element that is referenced by them anyway so a simple default that searches for a parent element with class carousel
would work just as well.
If all these changes were implemented, you wouldn’t need javascript at all. I’ve made a simple slideshow that even does away with a separate list for the navigation (indicators), as an example of what is possible. The navigation dots even allow you to drag and drop slides in edit mode.
This blog is written by Auke van Slooten, our senior developer.
Connect with us at GitHub, on social media, or leave a comment below.