Feed aggregator

Microserve: Getting Bootstrap Grid Classes Into Drupal 7 CMS Markup

Planet Drupal - Mon, 10/08/2015 - 10:10

Bootstrap is wonderfully useful and robust, mobile first framework for creating fully responsive, grid based web layouts.

The application of the Bootstrap framework relies on the principle of applying existing Bootstrap CSS classes to HTML mark-up, which in turn harness a suite of existing,  integrated LESS classes, mixins and variables as well as some useful, included JavaScript plugins to create Bootstrap layout.

When building HTML from scratch, the principle and practice is pretty straight forward. Once your Bootstrap library files are in the right place and working, you simply need to add Bootstrap classes to your mark-up as you go.

When developing with Drupal, it can be a challenge to 'crowbar' in the Bootstrap classes you need.

When developing with Drupal, things are not quite so straight forward out-of-the-box and it can be quite a challenge trying to 'get at' all of the code where you would need to crowbar in the Bootstrap classes you need.

Luckily there a number of ways to tackle this challenge, four of which are listed below. I've kept the neatest, life changing trick till last, because it's important to understand your options. (There's a time and place for all these approaches.)

1. PHP Templating


So tactic number 1 shouldn't come as massive surprise to most Drupal front enders and that is of course to harness the existing Drupal templating system to create templates containing Bootstrap specific mark-up.

The most obvious example of this (and the bare minimum required to even begin utilising the Bootstrap grid system) is good old page.tpl.php.  Here you'll most likely want to be applying Bootstrap classes to Drupal regions like the main content area and sidebars, so that they respond to screen size and probably 'stack' on top of each other at a smaller sizes.

Of course the above 'regions' example is a simple scenario (and If you're using the Drupal Bootstrap starter theme (https://www.drupal.org/project/bootstrap) a lot of this basic, mark-up will already be in place.) but things will no doubt have to get a lot more fine grain than this and at some point It's a distinct possibility you'll also want to inject Bootstrap column classes into node templates, views templates etc. 

2. Helper Modules

One of my favourite 'helper modules' is Views Responsive Grid.

As the name suggests this module helps create responsive (div based) grid layouts for your views. By itself the module doesn't do anything to auto-magically  'Bootstrapize' your views, rather it gives you an extra view format (Responsive Grid) which at odds with the default Drupal, table based grid format, produces a simple set of nested divs and the ability to assign your own responsive classes to the view wrapper, rows and columns, all through the admin interface, without need for template editing.

In our case we'd use it to add Bootstrap classes, but because it's framework agnostic, you could just as easily use it on sites using omega or foundation themes or your own bespoke responsive approach.

3. Display Suite

Display Suite can be found here.

To people who are already advocates of Display Suite, this one should be a no-brainer.

The Display Suite module (DS) is the ultimate tool in customising Drupal layout through the front end admin interface.  Again no need for editing PHP templates directly.

If like me, you haven't used DS a massive amount in the past, Bootstrap presents a pretty good case for further investigation. 

Simply put, DS presents to you through the Drupal admin interface, every default and custom field of a content type, stripped of mark-up and allows you to create multiple view modes where you can choose to show or hide specific fields, re-arrange their order, group them together, create custom page regions, wrappers and assign custom classes, IDs and various other formatting options to each of these elements.  For all intents and purposes it lets you create complex node templates without necessarily writing a line of code.

So, say we have a 'case study' content type, for example, we could create a node view mode for presenting a single case study article, a teaser view mode to use in views listings where results should appear in a grid layout, and a second teaser view mode to use in views where results appear in a simple list format. We can show/hide whichever fields we like per view mode, group them together any way we choose and more importantly for us, we can use this method to insert all the Bootstrap mark-up and/or classes we require.

4. Bootstrap's Default Mixins

I said at the beginning of this blog, that I was saving the best till last and here it is.

This won't be news to everyone, but I'm willing to bet there are going to be a pretty large portion of bootstrap users, who, even though they have studied the Bootstrap documentation available on the getbootstrap site will have missed this nifty feature.

If you visit the CSS page of the Bootstrap site and specifically the 'grid' section, you will no doubt be familiar with the explanation and examples of the grid system itself and which classes to use where, but right at the bottom of this section (just before the section on 'Typography'), there's a sub-section on LESS mixins.

Now, far be it from me to advise Bootstrap on how to write their documentation, but this section seems to me to be ordered in a quite counter-intuitive manner.  There's a large section of very over complicated example code, showing mixins being used in conjunction with various media queries and LESS variables without seemingly explaining what any of the individual lines of code actually mean. Complicated and confusing enough for may visitors to give up trawling through before reaching the end of the section. And this is the crime, because here, right at the end of the section under the heading 'Example usage',  in one short example piece of code, the keys to the Bootstrap kingdom are presented:

.wrapper { .make-row(); } .content-main { .make-lg-column(8); } .content-secondary { .make-lg-column(3); .make-lg-column-offset(1); } <div class="wrapper"> <div class="content-main">...</div> <div class="content-secondary">...</div> </div> What does this mean?

Well it means, with a little thoughtful coding, you can create an entire Bootstrap layout without needing to physically insert classes into your HTML mark-up at all. You could in theory use just LESS mixins to style existing, non-Bootstrap markup elements to appear as if they had certain Bootstrap classes, without having to edit their HTML output directly.

The example code above would produce layout equivelent to the following HTML mark-up:

<div class="wrapper row"> <div class="content-main col-lg-8">...</div> <div class="content-secondary col-lg-3 col-lg-offset-1">...</div> </div> Further examples

For instance you have a wrapper div, which contains 6 child divs and you want those 6 children to appear as if they were 6 Bootstrap columns with a class of .col-sm-4. They should have a width of 100% on mobile and stack above each other and then at the 'sm' breakpoint of 768px screen width and above, each of the 6 columns should float left in  2 rows of 3 and have a width of 33.33333333%, or in other words ocuppy 4 of the default 12 Bootstrap columns.

*The below layout examples are best viewed on larger screens, so that you can  see the layout change as you resize the browser. (on mobile, layouts will all appear stacked at 100% as no 'xs' breakpoint has been declared.)

Col 1 Col 2 Col 3 Col 4 Col 5 Col 6

If you were editing the HTML directly, you would need to give the wrapper div a class of 'row' and each child div a class of '.col-sm-4'. Using the mixins available to Bootstrap you could do this indirectly, assigning the mixin .make-row(); to your wrapper and then the mixin of .make-sm-column(4); to each of the children. Bingo Bootstrap will now take care of the rest. 

div.wrapper { .make-row(); } div.child { .make-sm-column(4); }

You can also stack Bootstrap classes just like in HTML like so:

div.child { .make-sm-column(4); .make-md-column(6); }

Resulting in:

Col 1 Col 2 Col 3 Col 4 Col 5 Col 6

*Each child div will be 4 columns (33.33333333%) at the 'sm' breakpoint and above, until the 'md' breakpoint when each child div will be 6 columns (50%) wide. Because we haven't decared a specific number of columns at 'xs' (below the 'sm' breakpoint), the divs will revert to their 100% wide default and stack one on top of each other.

You can even add offsets like so:

div.child { .make-sm-column(4); .make-md-column(6); } div.thisclass { .make-sm-column-offset(4); .make-md-column-offset(6); } Col 1 Col 2 Col 3 Col 4 Col 5 Offset on larger screens

*In this example, at the 'md' breakpoint each div occupies 5 columns with an empty column to it's left. (5+1 = 6 cols - or 50% in total).


So there you go, there's my 4 favourite ways of getting Bootstrap into Drupal. You could exclusively use tactics 1,3 or 4 in isolation (2 is more of a 'bolt-on' to be harnessed by the others), depending on your preferred work flow and how much you want to 'get your hands dirty' by digging down into the code of Drupal, but in practice all methods should be viewed as complimentary tools available in a themer's toolbox, each with it own advantages and disadvantages in any one given situation.

Martin White
Categories: Elsewhere

Web Omelette: New contrib module: Info Plugins

Planet Drupal - Mon, 10/08/2015 - 09:02

Today I would like to introduce a new module that I released for the Drupal (developer) community to use and share: Info Plugins. This is for developers who are tired of implementing a bunch of messy _info hooks (and their corresponding callbacks), lumping together functionality that frankly shouldn't even touch. I'm talking about those ugly switch statements in which we have cases for the various extensions we provide. Don't get me wrong Drupal, I love your hook system.

With Info Plugins, much (and progressively more and more) of this becomes cleaner by exposing all those extension points to the cTools plugin system. What I mean by this is that using this module you will be able to declare things like Drupal blocks, filters, field formatters and more, as cTools plugins. This way, all the logic related to one plugin (block, filter or field formatter to continue with the above examples) resides neatly within one single plugin include file.

Let us look at an example a bit more in depth: the Drupal block. Instead of implementing up to 4 hooks (_info, _view, _configure and _save) to manage your blocks, you can now define a new core_block plugin within your cTools plugins folder like so:

$plugin = array( 'title' => t('Example block'), // Your own callback for building the display of the block (called by `hook_block_view()`) // Leaving this empty, the function name would default to `my_module_example_block_view()` 'view' => 'my_module_render_example_block', // Your own callback for building the config form for the block (called by `hook_block_configure()`) // Leaving this empty, the function name would default to `my_module_example_block_configure()` 'configure' => 'my_module_configure_example_block', // Your own callback for saving the config for the block (called by `hook_block_saved()`) // Leaving this empty, the function name would default to `my_module_example_block_save()` 'save' => 'my_module_save_example_block', // ... all other options you may want to pass to `hook_block_info()` ); /** * Returns a renderable array that represents the block content, i.e. * the same as you would return from `hook_block_view()`. * * @param $delta * The block delta */ function my_module_render_example_block($delta) { return array( '#type' => 'markup', '#markup' => 'My custom example block' ); } /** * Returns a form to be used as the block configuration form, i.e. the same * as you would return from `hook_block_configure()` * * @param $delta * The block delta */ function my_module_configure_example_block($delta) { $form = array(); $form['my_custom_field'] = array( '#type' => 'textfield', '#title' => t('My custom block field'), '#default_value' => variable_get($delta, '') ); return $form; } /** * Saves the block configuration, i.e. the same as you would do inside * `hook_block_save()` * * @param $block * An array of values representing the block with it's configuration, i.e. the * `$edit` array passed to `hook_block_save()` */ function my_module_save_example_block($block) { variable_set($block['delta'], $block['my_custom_field']); }

So as you can see, your block definition, render and configuration resides in one file. If you need more blocks, you just define more plugins and you are good to go. There is such a documentation oriented example inside the plugin_examples folder of the module for each available plugin type. Plus, don't forget the README.md file.

Once you install the module, you will have only one administration screen at admin/config/info-plugins where you'll be able to select which plugin types you need. For example, if you need to define a custom block, enable the Core Block plugin type. If you need others, enable them as well. But I recommend you keep them disabled if you don't use them so that their logic doesn't get included in memory (all the relevant hooks and what not). My goal here is to keep a very low foot print.

To see which plugin types are available to use, please consult the project page. And keep checking back because I will add more. And if you want to contribute, please don't hesitate. Take it out for a spin, give it a test and please open issues to let me know of any bugs you find. I will be active on this for a while and want to hammer out all the potential problems before creating a stable release.


In Drupal var switchTo5x = true;stLight.options({"publisher":"dr-8de6c3c4-3462-9715-caaf-ce2c161a50c"});
Categories: Elsewhere


Subscribe to jfhovinne aggregator