Friday 17 April 2020

Creating a Slider in Umbraco

Umbraco offers an incredibly flexible grid editor and when paired with Doc Type Grid Editor and Nested Content, it makes for a beautiful developing experience. We'll be going through the creation of a Swiper carousel in Umbraco.
The tutorial starts from a fresh installation of Umbraco 7.7.6 with the default starter kit installed. This means that some steps may be quite specific but hopefully the instructions will be easy enough to follow that you can tweak this for your individual setup.

1. Setup Models Builder

In the interest of teaching the best practices, we'll be making use of the Models Builder to keep your views clean. There's a little set up required but it pays off and I'd urge you to check out the Models Builder documentation to discover all of the options available to you. Let's get started.
In Visual Studio, open up your ~/Web.config file and change the following line from:
<add key="Umbraco.ModelsBuilder.ModelsMode" value="PureLive" />
To:
<add key="Umbraco.ModelsBuilder.ModelsMode" value="Dll" />
The models builder automatically builds models based on your document types, changing it to Dll generates a dll file that we'll need to include in our project.
In Umbraco, go to Developer -> Models Builder and hit the Generate models button.
This will generate a file located at ~/bin/Umbraco.Web.PublishedContentModels.dll, right-click this in your Visual Studio Solution Explorer and Include in Project. The next time you generate models, this dll will get updated and you'll have access to them throughout the project.

2. Install Plugins

For this tutorial, we'll be making use of a couple of plugins, the first is required, the second however depends on your version of Umbraco. If you're running 7.7 or later, you can skip the Nested Content install.

Doc Type Grid Editor

Doc Type Grid Editor is an advanced grid editor for the new Umbraco Grid, offering similar functionality as the macro grid editor but using the full power of the doc type editor and data types.
To get setup, in Visual Studio, install the Doc Type Grid Editor package. The quickest way is to simply open up the Package Manager Console and type run the following code:
install-package our.umbraco.doctypegrideditor

Nested Content

Nested Content is a new list editing property editor for Umbraco 7+, similar to likes of Embedded Content and Archetype, however Nested Content uses the power of doc types to define the list item blue prints. By using doc types, we get the benefit of an easy / reusable UI we are all familiar with and also get to re-use all the standard data types as our field editors rather than being limited to a subset of “allowed” types.
As mentioned above, you can safely skip this step if your version of Umbraco is 7.7 or higher. Otherwise, open up your package manager console again but this time run the following:
install-package our.umbraco.nestedcontent
Once these are both installed, be sure to build your project.

3. Create Image Picker Data Type

To keep things nice and simple of your CMS users, we're going to create a new data type which allows the editor to choose just one image. Umbraco only has a picker available for multiple files (of any type) so it's always a good step to create a 'Single Image Picker'. To do so:
  1. Go to the Developer Section and create a new Data Type. Call it Single Image Picker.
  2. Choose Media Picker in the Property Editor dropdown.
  3. Check the Pick only images checkbox to ensure that your editors can't choose the wrong file type (we'll use this picker for a slider image later so it's important that only images are allowed).
  4. Click Save

4. Create 'Slide' Document Type

Now we'll create the 'Slide' document type, this will consist of the fields we need to display as part of the slider. We'll use it later to tell Umbraco that this will be repeatable field. Here's how we do it:
  1. Go to the Settings section in Umbraco and in the Document Types folder, create a new folder called Nested Content.
  2. In the new folder, create a new Document Type without template called Slide.
  3. Click Add new tab and call the tab Slide.
  4. Click Add property, put Image into the Enter a name... field.
  5. Click Add editor and choose the Single Image Picker data type that we created earlier.
  6. Click Submit.
  7. Click Save.
This document type will act as a repeatable field where we can set multiple images. You could alternatively choose a multiple image picker here but this way makes it easier to add extra fields later down the line, you may want a 'Text' field for example so that user can specify some text to each image/slide.

5. Create `Slides` Data Type

Now that we've created the 'Slide' document type, we need to create a 'Nested Content' data type that makes use of it.
  1. In the Developer section of Umbraco, create a new 'Data Type' called Slides.
  2. Choose Nested Content in the Property editor dropdown box.
  3. In the Document Type dropdown that is now displayed, choose the Slide document type that we created in the last step.
  4. Choose Slide for the Tab dropdown and hit Save.

6. Create `Slider` Document Type

Now to create the 'Slider' document type which we will use as the grid editor itself.
  1. Go to the Settings section in Umbraco and in the Document Types folder, create a new folder called Grid Editors
  2. In the new folder, create a new Document Type without template called Slider.
  3. Click Add new tab and call it Slider.
  4. Click Add property.
  5. Type Slides into the Enter a name... field.
  6. Click Add editor and use the new Slides data type that we just created.
  7. Click Submit.
  8. Click Save.

7. Setup Doc Type Grid Editor

At this point, we still haven't actually done anything with Doc Type Grid Editor. So, back in Visual Studio, find the ~/config/grid.editors.config file in your solution explorer. Put the default doc type grid editor code into this file:
{
    "name": "Doc Type",
    "alias": "docType",
    "view": "/App_Plugins/DocTypeGridEditor/Views/doctypegrideditor.html",
    "render": "/App_Plugins/DocTypeGridEditor/Render/DocTypeGridEditor.cshtml",
    "icon": "icon-item-arrangement",
    "config": {
        "allowedDocTypes": [],
        "nameTemplate": "",
        "enablePreview": true,
        "viewPath": "/Views/Partials/Grid/Editors/DocTypeGridEditor/",
        "previewViewPath": "/Views/Partials/Grid/Editors/DocTypeGridEditor/Previews/",
        "previewCssFilePath": "",
        "previewJsFilePath": ""
    }
}
If you're following along exactly, the full file should now look like this:
[{
    "name": "Rich text editor",
    "alias": "rte",
    "view": "rte",
    "icon": "icon-article"
},
{
    "name": "Image",
    "alias": "media",
    "view": "media",
    "icon": "icon-picture"
},
{
    "name": "Macro",
    "alias": "macro",
    "view": "macro",
    "icon": "icon-settings-alt"
},
{
    "name": "Embed",
    "alias": "embed",
    "view": "embed",
    "icon": "icon-movie-alt"
},
{
    "name": "Headline",
    "alias": "headline",
    "view": "textstring",
    "icon": "icon-coin",
    "config": {
        "style": "font-size: 36px; line-height: 45px; font-weight: bold",
        "markup": "<h1>#value#</h1>"
    }
},
{
    "name": "Quote",
    "alias": "quote",
    "view": "textstring",
    "icon": "icon-quote",
    "config": {
        "style": "border-left: 3px solid #ccc; padding: 10px; color: #ccc; font-family: serif; font-style: italic; font-size: 18px",
        "markup": "<blockquote>#value#</blockquote>"
    }
},
{
    "name": "Doc Type",
    "alias": "docType",
    "view": "/App_Plugins/DocTypeGridEditor/Views/doctypegrideditor.html",
    "render": "/App_Plugins/DocTypeGridEditor/Render/DocTypeGridEditor.cshtml",
    "icon": "icon-item-arrangement",
    "config": {
        "allowedDocTypes": [],
        "nameTemplate": "",
        "enablePreview": true,
        "viewPath": "/Views/Partials/Grid/Editors/DocTypeGridEditor/",
        "previewViewPath": "/Views/Partials/Grid/Editors/DocTypeGridEditor/Previews/",
        "previewCssFilePath": "",
        "previewJsFilePath": ""
    }
}]
The only change we need for the purpose of this tutorial is to add slider to the allowedDocTypes array. To do that, change the following line from:
"allowedDocTypes": [],
to:
"allowedDocTypes": ["slider"],
This registers the new set of editors with Umbraco.

8. Add Editors to Grid Data Type

Now that the new editors (or technically, just editor in our case) are registered, we need to enable them in our grid data type:
  1. Go to the Developer section in Umbraco and edit the Content Base - Content - Grid layout data type.
  2. Click on Full Width.
  3. Click the row layout.
  4. Check the Doc Type checkbox.
  5. Click Submit.
  6. Click Save.
NB: These instructions are very specific for the Umbraco starter kit - your grid setup may be different, just be sure to enabled the Doc Type for it.

9. Generate Models

We've created a handful of new document types so we need to regenerate our models so that we can use them in our views. To do this, go to the Developer -> Models Builder section in Umbraco and hit the Generate models button.

10. Setup 'Slider' Partial

At this point, we've finished creating our data types, document types and we've rebuilt our models. Now it's time to setup the view that will render our slider on the frontend.
Create a new file at ~/Views/Partials/Grid/Editors/DocTypeGridEditor/Slider.cshtml. Doc Type Grid Editor, by default will search the ~/Views/Partials/Grid/Editors/DocTypeGridEditor folder for it's views, the view name itself - Slider.cshtml in this case - should match the alias of your grid editor document type (the document type we created in step 6).
@inherits UmbracoViewPage

@{
    Slider slider = new Slider(Model);
}

@if (slider.Slides != null && slider.Slides.Any())
{
    <div class="swiper-container">
        <div class="swiper-wrapper">
            @foreach (Slide slide in slider.Slides.Select(x => new Slide(x)))
            {
                <div class="swiper-slide"><img src="@slide.Image.Url" /></div>
            }
        </div>

        <div class="swiper-pagination"></div>

        <div class="swiper-button-prev"></div>
        <div class="swiper-button-next"></div>

        <div class="swiper-scrollbar"></div>
    </div>
}
There are a couple of things to note with the above code that might not be immediately obvious so here's a breakdown of those parts:
Slider slider = new Slider(Model);
By default, the views that are rendered by Doc Type Grid Editor are pass an IPublishedContent rather than a strongly typed view. As such, getting property values can be a pain. Instead, we simply create a new model using the models that Umbraco have handily generated for us.
@foreach (Slide slide in slider.Slides.Select(x => new Slide(x)))
Much like the previous point, we want to make use of the generated models whenever possible. Again, by default the 'Slides' property we set up will return as a list of IPublishedContent and, again, they can be a little cumbersome to deal with. To get around that we use Select to instantiate a new 'Slide' instead. Clean code makes for happy developers!

11. Build!

Now build your project in Visual Studio otherwise, the site will error when looking for our generated models.

12. Add Slider to Page

Edit the About Us page - again, this is a very specific step for those of your following along, starting with the default starter kit. Editing any page with your grid data type setup should be just fine here.
Add a new Full width row and click Add content, choose Doc Type as the editor. In the pane that slides out from the right, choose Slider from the dropdown and fill out the fields. Save and publish the page.
This doesn't look so pretty now but we'll implement the front end next.

13. Add Frontend Assets

In ~/Views/Master.cshtml file add the following line in the <head> section.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.0.7/css/swiper.min.css">
In the same file, put the following line just before the closing </body> tag.
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.0.7/js/swiper.min.js"></script>
This will import the Swiper scripts and styles to enable the slider.
Just below that, drop the following script tag in place:
<script>
    var mySwiper = new Swiper('.swiper-container', {
        autoplay: {
            delay: 2000,
        },
    });
</script>
This code initialises Swiper. Be sure to check out theSwiper documentation if you want to understand what's going on here.

No comments:

Post a Comment