Not another Grid Layouts post

Heads Up!

This article is several years old now, and much has happened since then, so please keep that in mind while reading it.

Since the release of the Grid Layouts property editor with Umbraco 7.2 (released in December 2014) a lot has been written, discussed, criticized and glorified about this subject. So is it really necessary with another blog post about it? Well yes, I think so and and here are some of the reasons why:

  1. Umbraco 7.4 beta was released just a week ago containing a complete overhaul of the editing experience for Grid Layouts.
  2. If you search in the projects section on our.umbraco.org for "grid" you'll find very few, albeit very awesome, packages for it.
  3. I've seen a number of posts on the forum asking various questions regarding the implementation of Grid Layouts and while the discussion, and in many cases the following solutions, are absolutely fantastic there seems to be a disconnect between how we (Umbraco HQ) envisioned the usage of Grid Layouts and the approach a lot of developers are taking.*

My goal with this post is to address the above and to highlight some basic things that can and/or should at least be considered by developers setting up Grid Layouts. All in service of making a meaningful editing experience for the end user (editor) that will be using this to create some hopefully engaging and most certainly responsive content.

The Grid way of thinking

There are three things that are absolutely crucial to acknowledge before implementing Grid Layouts in your project.

First of you have to get to grips with the fact that setting up one or more Grid Layouts for a given website requires a decidedly different approach than the usual separation of data (properties on a Document Type) and rendering in the template. With Grid Layouts it is imperative that you consider (and customise) the rendering of the input and stored content in the Backoffice and the connection between this and the rendered content on the frontend.

Secondly there are limitations to the types of content that is suited for Grid layouts. Antoine Giraud, one of the founding fathers of the property editor (the original uSky editor), describes this very aptly in his Skrift article Ten Grids Later. Basically stating that "Grid-friendly" content is content that inherently belongs to the page on which it is created and is NOT reusable content. This is in part due to the way Grid Layouts stores content, a big ol' and rather "dumb" chunk of JSON, where depending on content located elsewhere in the solution can add a level of complexity that we cannot require our editors to take into account. This can also cause severe headaches for developers when deploying content between environments.

The last but in no way smallest point is that creating content with Grid Layouts requires more of the editor. Grid Layouts is a way of solving the problem that has arisen with the evermore complex structure of frontend HTML and CSS. While the advent of CSS grid frameworks has made our lives (as developers) infinitely easier in many ways, both in terms of development speed and cross platform compatibility. It has also added a layer of abstraction between the data input, more often than not vertically aligned fields containing one or more Rich Text editors (oh the horror), and the output neatly arranged side by side in x number of columns. With Grid Layouts it is possible create content with an approximation of the rendered output thus making the level of abstraction smaller. But this in turn means that the editor has to make decisions when choosing Layouts/Rows/Grid Editors and the more complex the Grid Layout is the more decisions the editor has to make. While a good implementation (read: with appropriate restrictions) can help mitigate this to a large extend, I firmly believe there is no getting around that the editor needs a certain amount of flair for design and storytelling.

To sum up, setting up a Grid Layout is a demanding process where you need to take all of the above into account. There is no two ways about it, to create a good editing experience it is crucial that you tailor Grid Layouts to the content it is meant to create. If you are using Grid Layouts extensively on a site chances are you'll need multiple Grid Layout data types with their own Layouts, Row configuration and custom (and/or customized) Grid editors. I cannot recommend reading the aforementioned article by Antoine enough. It provides great insights, and lists anumber of useful packages as well. This post will be aimed at setting up "vanilla" Grid Layouts.

So where do I start?

As Grid Layouts is a very visual way of dealing with content in the Backoffice you start by working closely with the designer of the frontend and the client/editor that will be using it. That might even be yourself which can make the process easier but also lonelier ;)

It is not just a simple matter (overly reductive, I know) of making sure that headlines, paragraphs, images and whatever else a Rich Text editor can serve up is rendered correctly. You need to carefully plan out the different design scenarios that is needed convey the story (or stories) of the content that is yet to be created.

This is the really tricky part and it is difficult to make meaningful general guidelines for what the specific solution entails, the rest is purely a matter of problem solving (ie development) and something we can talk about in broader terms and give more specific solutions to.

Customising a Grid Layout

Once the design is in place and the content blocks are mapped out it is more or less a matter of following the documentation for Grid Layouts. In the following I'll try to provide a little more context to the examples given in the docs.

Layouts and Row configurations

Setting up the overall layout (Layout in Grid terms) is usually a matter of deciding whether the content created with Grid Layouts is full width or not. If for some reason multiple Layouts is required it is important to restrict which Row configurations are available to the user. If you only have a single layout for the data type this will be the default and no choice will be presented to the editor in the Content section.

You are almost certainly going to need multiple Row configurations. A row configuration consists of a number of cells (that corresponds to columns in the CSS framework) and inside these cells the actual Grid Editors will be available. Again it is imperative that you remember to restrict which editor are available in the different cells. You can have a large number of Grid Editors in your solution but try to limit the choice on individual cells as much as possible as this will help guide the user to creating the content. As with Layouts, if only one Grid Editor is allowed in a cell this will be inserted by default which means you can actually present a sort of finished template.

Read the documentation

Settings and Styles 

Settings and Styles are great tools to allow your editor some control of the rendering of rows and cells. This means you can let them add CSS classes, data attributes, inline styling and so forth to the rendered HTML. Here we have a coupling between the frontend rendering and the content editing and if used correctly it can empower to the user to create very diverse pieces of content but always try to keep simplicity in mind. Make sure to restrict settings and styles to rows or cells so the options are presented only where they make sense.

Read the documentation

Grid Editors 

And now for the really fun part! Customising Grid Editors to suit your solution. When you create a new Grid Layout data type in a blank Umbraco installation, there is a number of "default" Grid Editors already available (6 to be specific). These should really be seen as examples of the choices you can give your user. Or rather examples of how you can use the Grid property editors that come with Umbraco. We have made it quite easy to customise these (especially the textstring input which is used for the Headline and Quote Grid Editors).

A good approach is to think of Grid Layouts as a sort of Rich Text editor replacement. Let's say the Grid Layout data type we are setting up (or rather the content we are designing for) can have three different headlines, we can fairly quickly set up three different Grid Editors to handle this.

Read the documentation

Enter the package.manifest

We'll create our three customised headlines in a package.manifest file placed in /App_Plugins/clever-name/

{
    "gridEditors": [
        {
            "name": "H1",
            "alias": "headline1",
            "view": "textstring",
            "icon": "icon-coin",
            "config": {
                "style": "font-size: 36px; line-height: 45px; font-weight: bold",
                "markup": "<h1>#value#</h1>"
            }
        },
        {
             "name": "H2",
             "alias": "headline2",
             "view": "textstring",
             "icon": "icon-coin",
             "config": {
                 "style": "font-size: 28px; line-height: 45px; font-weight: bold",
                 "markup": "<h2>#value#</h2>"
             }
         },
         {
             "name": "H3",
             "alias": "headline3",
             "view": "textstring",
             "icon": "icon-coin",
             "config": {
                 "style": "font-size: 22px; line-height: 45px; font-weight: bold",
                 "markup": "<h3>#value#</h3>"
             }
         }
    ]
}

This will make three new Grid Editors available to add to the cells where they are relevant. The really interesting part here is the config object where style injects CSS to the backoffice input and markup wraps the input value #value# in the desired html. You can also add a class attribute (or other html attributes) to target the output more specifically with your frontend CSS and JavaScript.

A good starting point for customising Grid editors is to take a look at the config file /config/grid.editors.config in your Umbraco installation. This is essentially the same as we added in the gridEditors array in our package manifest.

PRO TIP: Do not add custom Grid Editors to the config file as this will be overwritten when upgrading your Umbraco installation. Always use a package manifest.

An RTE replacement with an RTE inside, what gives?

It is hard to completely get the rid of the Rich Text editor as it does handle things like links and alignment well but limiting the options in the RTE to the absolute minimum (you see a trend here ?) is again highly recommended.

Limiting the RTE

This is also be done when setting up the Grid Layout data type and then we can use the RTE for paragraphs where more options than a simple textarea can give us is warranted.

Limited RTE

If you do not want to use the RTE for paragraphs in your Grid Layout it is quite easy to create your own:

 

{
    "gridEditors": [
        {
            "name": "Paragraph",
            "alias": "paragraph",
            "view": "textstring",
            "icon": "icon-font",
            "config": {
                "style": "font-size: 16px; line-height: 45px; font-weight: normal",
                "markup": "<p>#value#</p>"
            }
        },
        {
            "name": "Paragraph centered",
            "alias": "paragraphCentered",
            "view": "textstring",
            "icon": "icon-font",
            "config": {
                "style": "font-size: 16px; line-height: 45px; font-weight: normal, text-align: center",
                "markup": "<p class='text-center'>#value#</p>"
            }
        }
    ]
}

Creating your own Grid Editors

In addition to just customising the default Grid Editors you can also extend them further by adding your own views (for the Backoffice input and if needed add a custom Angular controller) and/or your own renderers (for frontend rendering). There are examples of this in the documentation. You can mix and match the various parts to your fit your needs so you don't have to build every editor from the ground up. Ie. you can use the default  textstring view for input and then add a custom renderer.

If you are familiar with developing property editors for Umbraco it should be fairly easy to get start on a custom Grid property editor as they rely on the same basic concepts. If not, an easy way to get the hang of things is to copy one of the default editors and start hacking away at it. The views are located in /Umbraco/Views/propertyeditors/grid/editors/ and the rendering files in /Views/Partials/Grid/Editors/.

A package manifest for a custom editor with it's own Angular controller and CSS file would look something like this:

{
    "gridEditors": [
        {
            "name": "My Grid Editor",
            "alias": "myGridEditor",
            "view": "/App_plugins/MyGridEditor/myGridEditor.html",
            "icon": "icon-paint-roller"
        }
    ],
    "javascript": [
        "/App_Plugins/MyGridEditor/myGridEditor.controller.js"
    ],
    "css": [
        "/App_Plugins/MyGridEditor/myGridEditor.css"
    ]
}

Rendering Grid Layouts

The same goes for rendering Grid Layouts. The default renderers that come with Umbraco, located in /Views/Partials/Grid/, are for Bootstrap 2 and 3. These are perfectly servicable for some cases but also easily customised. If you are using Bootstrap 3 but want to render using the .sm instead of .md, simply copy the renderer, rename it, change the class names and call it in your template.

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = "Master.cshtml";
}

<div class="gridCSS">
   @CurrentPage.GetGridHtml("bodyText", "myCustomRenderer")
</div>

This is a very simple example but you can manipulate the output in any way you want. For some inspiration take a look at this package, Umbraco Grid Renderers, that enables the use of other popular CSS grid frameworks.

Sharing is caring

You might very well end up with a bunch of editors and renderers that you'll want to use on other projects. You might have them in a repository chock full Grid goodies you and your colleagues can pick and choose from. But going back to one of the reasons for doing this post (the somewhat lackluster results when searching for "grid" projects on Our) you can also share them with the community. This can easily be done by packaging them up in the Developer section of the Backoffice. Simply right click "Created Packages", choose create package and then you can add the files and/or folders that you think might be beneficial to others, "download zip" and upload it to your profile on our.umbraco.org.

I think there is a ton of potential in Grid Layouts that we can tap into and there is no better way than by sharing ideas and code. If you are really lucky you might even get some feedback or help for future improvements.

Famous last words

As I briefly mentioned in the beginning Umbraco 7.4 beta is out and we've given the content editing experience in Grid Layouts a much needed overhaul. You can read about why in this blogpost and see an example of it in action in the beta release post (7.4 has a ton of other cool stuff as well). We would love to get your feedback on the changes we have made. We REALLY love when you log issues on the issue tracker, tweet at us and write forum or blog posts. 

If you have made it this far, I thank you for your patience, and sincerely hope this post has helped clarify a few things for grid veterans and made it a tad more approachable for newcomers. If you want more information on Grid Layouts I highly recommend Mark Stöckers talk from UK festival and the video tutorials on Umbraco.tv. There is also a post on using macros in Grid Layouts from last years 24 days in Umbraco by Antoine.

Also a big HIGH FIVE, YOU ROCK to Blake, Jan and Chriztian for making 24 days in Umbraco and to all the Umbracians who contribute to this great tradition!

On a personal note I'll just say that 2015 as been absolutely fantastic. My first full year at HQ, it is truly humbling to be a part of a community this engaged and vibrant.

Happy holidays to all, see you in the new year :)

*Important to note that this is said with humility. The onus of imparting the "right approach" is on Umbraco HQ by providing sufficient documentation and examples.

Rune Hem Strand

Rune is on Twitter as