Skip to Content

Planet Drupal

Syndicate content
Drupal.org - aggregated feeds in category Planet Drupal
Updated: 1 hour 4 min ago

Chen Hui Jing: Drupal 101: Getting started with Drupal 7 theming

10 August 2015 - 5:00pm

With Drupal 8 just around the corner, it may seem odd that I would write a post about Drupal 7 theming, but I figured it would take some time for Drupal 8 to really become mainstream. Also, when I do write that Drupal 8 theming post (coming soon), we can do some one to one comparisons on the things that have changed. Trust me, there are a lot of differences between the two.

A theme is like the skin for your website. Drupal 7 theming may seem complicated at first. Peeking into a theme folder reveals a bunch of folders littered with PHP files, stylesheets and who knows what else. The easiest way to wrap your head around things is...

Categories: Drupal

Steve Purkiss: What is Drupal?

10 August 2015 - 4:08pm
Tuesday, 11th August 2015What is Drupal?

Drupal is people. Drupal is figuring out people. Drupal is figuring out how to make things better. Drupal is about feeding yourself and your family. Drupal is about feeding other people's families. Drupal is about going to places you'd never considered going to. Drupal is about laying in the lake and watching the stars at night. Drupal is about making money for your business. Drupal is about making things easier. Drupal is about accessiblity for all. Drupal is about opportunity for all. Drupal will tell you what you need to know. Drupal is there for you to tell and show. Drupal is the push and the struggle. Drupal is the hook. Drupal is about taking those moments to really get your teeth into something you're passionate about and feel like you're maybe making a difference. Drupal is about escapism. Drupal is firing up the laptop and tethering before you get on the plane so you can git clone the latest dev release to take a look through the code until you're sleepy just to show off a bit more Drupal to fellow passengers who may take a glance but also learn something at the time. Drupal is about sharing your costs. Drupal is there to learn how to share. Drupal is there to provide a path to follow. Drupal is about sharing your thoughts and visions. Drupal is finding out where the line is when you didn't even know there was a line. Drupal is finding out the magic of everyone. Drupal is about survival. Drupal is tolerance. Drupal is about sustainability. Drupal is opportunity for all. Drupal is forcing you to face up to your conditions. Drupal is understanding. Drupal is a battle, an upheal struggle. Drupal is simple. Drupal is about sharing. Drupal is about caring. Drupal is hugging. Drupal is your voice. Drupal is special. You are special. 

Drupal is your True Pal.

Picture: https://twitter.com/PropagoD8/status/630082554071269376

tags: Drupal PlanetPlanet DrupalWhat is Drupaldrupal
Categories: Drupal

Red Crackle: Creating the simplest headless Drupal 7 site

10 August 2015 - 1:25pm
In What is headless Drupal post, you learned what exactly is headless Drupal. In this post, you will create the simplest headless Drupal application possible in less than 15 minutes. By the end of this post, you will have a simple HTML page. On loading this page, JS will send a request to Drupal. Drupal will generate a random number and send it back to the JS. JS will render it on the HTML page.
Categories: Drupal

Four Kitchens: REST Easy Part 2: Sub Property Boogaloo

10 August 2015 - 1:10pm

This week we’ll continue where we left off after doing the ground work of creating a basic endpoint with the RESTful Drupal module. We skipped one crucial part: the body field. This week’s installment will cover our missing field, which requires extra care when used within a RESTful endpoint.

Categories: Drupal

Promet Source: Feature Branch Workflow the Promet Way

10 August 2015 - 12:50pm

When you’re wrangling a slightly larger team of devs as we do here at Promet, the importance of strict naming conventions becomes apparent pretty quickly. Take the commonly referenced Git workflow from Victor Driessen, for example.

Categories: Drupal

TimOnWeb.com: Happy birthday to me and Devel form debug module to you all

10 August 2015 - 11:06am
I’m turning 32 today. People love birthdays, to me it’s just another line number in a messed stack trace output (philosophy mode enabled).   Two years ago I released a drupal module called Get form id (deprecated from now on) that does one small task - it tells you any form's id ...

Read now

Categories: Drupal

Lullabot: Write Unit Tests for Your Drupal 7 Code (part 2)

10 August 2015 - 10:12am

This article is a continuation of Write Unit Tests for Your Drupal 7 Code (part 1), where I wrote about how important it is to have unit tests in your codebase and how you can start writing OOP code in Drupal 7 that can be tested with PHPUnit.

In this article I show you how this can be applied to a real life example.

TL;DR

I encourage you to start testing your code. Here are the most important points of the article:

Dependency Injection and Service Container

Jeremy Miller defines dependency injection as:

[...] In a nutshell, dependency injection just means that a given class or system is no longer responsible for instantiating their own dependencies.

In our MyClass we avoided instantiating CacheController by passing it through the constructor. This is a basic form of dependency injection. Acoording to Martin Fowler:

There are three main styles of dependency injection. The names I'm using for them are Constructor Injection, Setter Injection, and Interface Injection.

As long as you are injecting your dependencies, you will be able to swap those objects out with  their test doubles in your unit tests.

An effective way to pass objects into other objects is by using dependency injection via a service container. The service container will be in charge of giving the receiving class all the needed objects. Then, the receiving object will only need to get the service container. In our System Under Test (SUT), the service container will yield the actual objects, while in the unit test domain it will deliver mocked objects. Using a service container can be a little bit confusing at first, or even daunting, but it makes your API more stable and robust.

Using the service container, our example is changed to:

class MyClass implements MyClassInterface { // ... public function __construct(ContainerInterface $service_container) { $this->cacheController = $service_container->get('cache_controller'); $this->anotherService = $service_container->get('my_services.another_one'); } // ... public function myMethod() { $cache = $this->cacheController->cacheGet('cache_key'); // Here starts the logic we want to test. // ... } // ... }

Note that if you need to use a new service called 'my_services.another_one', the constructor signature remains unchanged. The services need to be declared separately in the service providers.

Dependency injection and service encapsulation is not only useful for mocking purposes, but also to help you to encapsulate your components –and services–. Borrowing, again, Jeremy Miller’s words:

Making sure that any new code that depends on undesirable legacy code uses Dependency Injection leaves an easier migration path to eliminate the legacy code later with all new code.

If you encapsulate your legacy dependencies you can ultimately write a new version and swap them out. Just like you do for your tests, but with the new implementation.

Just like with almost everything, there are several modules that will help you with these tasks:

  • Registry autoload will help you to structure your object oriented code by giving you autoloading if you follow the PSR-0 or PSR-4 standards.
  • Service container will provide you with a service container, with the added benefit that is very similar to the one that Drupal 8 will ship with.
  • XAutoload will give you both autoloading and a dependency injection container.

With these strategies, you will write code that can have it’s dependencies mocked. In the previous article I showed how to use fake classes or dummies for that. Now I want to show you how you can simplify that by using Mockery.

Mock your objects

Mockery is geared towards providing even more flexibility when creating mocks. Mockery is not tied to any test framework which makes it useful even if you decided to move away from PHPUnit.
In our previous example the test case would be:

// Called from the test case. $fake_cache_response = (object) array('data' => 1234); $cache_controller_fake = \Mockery::mock('CacheControllerInterface'); $cache_controller_fake->shouldReceive('cacheGet')->andReturn($fake_cache_response); $object = new MyClass($cache_controller_fake); $object->myMethod();

Here, I did not need to write a CacheControllerFake only for our test, I used Mockery instead.
PHPUnit comes with a great mock builder as well. Check its documentation to explore the possibilities. Sometimes you will want to use one or the other depending on how you want to mock your dependency, and the tools both frameworks offer. See the same example using PHPUnit instead of Mockery:

// Called from the test case. $fake_cache_response = (object) array('data' => 1234); $cache_controller_fake = $this ->getMockBuilder('CacheControllerInterface') ->getMock(); $cache_controller_fake->method('cacheGet')->willReturn($fake_cache_response); $object = new MyClass($cache_controller_fake); $object->myMethod();

Mocking your dependencies can be hard –but valuable– work. An alternative is to include the real dependency, if it does not break the test runner. The next section explains how to save some time using Drupal Unit Autoload.

Cutting corners

Sometimes writing tests for your code makes you realize that you need to use a class from another Drupal module. The first instinct would be, «no problem, let’s create a mock and inject it in place of the real object». That is a very good approach. However, it can be tedious to create and maintain all these mocks, especially for classes that don’t depend on a bootstrap. That code could just be required in your test case.

Since your unit test can be considered a standalone PHP script that executes some code –and makes some assertions– you could just use the require_once statement. This would include the code that contains the class definitions that your code needs. However, a better way of achieving this is by using Composer’s autoloader. An example composer.json in your tests directory would be:

{ "require-dev": { "phpunit/phpunit": "4.7.*", "mockery/mockery": "0.9.*" }, "autoload": { "psr-0": { "Drupal\\Component\\": "lib/" }, "psr-4": { "Drupal\\typed_entity\\": "../src/" } } }

With the previous example, your unit test script would know how to load any class in the Drupal\Component and Drupal\typed_entity namespaces. This will save you from writing test doubles for classes that you don’t have to mock.

At this point, you will be tempted to add classes from your module’s dependencies. The big problem is that every drupal module can be installed in a different location, so a simple ../../contrib/modulename will not do. That would only work for your installation, but not for others. This is one of the reasons why I wrote with Christian Lopez (penyaskito) the Drupal Unit Autoload. By adding Drupal Unit Autoload to your composer.json you can add references to Drupal core and other contributed modules. The following example speaks for itself:

{ "require-dev": { "phpunit/phpunit": "4.7.*", "mockery/mockery": "0.9.*", "mateu-aguilo-bosch/drupal-unit-autoload": "0.1.*" }, "autoload": { "psr-0": { "Drupal\\Component\\": "lib/", "Symfony\\": ["DRUPAL_CONTRIB<service_container>/lib"] }, "psr-4": { "Drupal\\typed_entity\\": "../src/", "Drupal\\service_container\\": ["DRUPAL_CONTRIB<service_container>/src"] }, "class-location": { "\\DrupalCacheInterface": "DRUPAL_ROOT/includes/cache.inc", "\\ServiceContainer": "DRUPAL_CONTRIB<service_container>/lib/ServiceContainer.php" } } }

We added mateu-aguilo-bosch/drupal-unit-autoload to the testing setup, so we can include Drupal aware autoloading options to our composer.json.

Striving for the green

One of the most interesting possibilities that PHPUnit offers is code coverage. Code coverage is a measure used to describe the degree to which the methods are tested. Having a high coverage reduces the number of bugs in your code greatly. Moreover, adding new code with test coverage will help you ensure that you are not introducing any bugs along with the new code.

PhpStorm coverage integration.

A test harness with coverage information is a valuable tool to include in your CI tool. One way to execute all your PHPUnit cases is by adding a phpunit.xml file describing where the tests are located and other integrations. Running the phpunit command in that folder will execute all the tests.

Another good 3rd party service is coveralls. It will tell your CI tool how the coverage of your code will change with the pull request –or patch– in question; since Coveralls knows about most of the major CI tools almost no configuration is needed. Coveralls also provides a web UI to see what parts of the code are covered and the ones that are not.

Coveralls.io dashboard.

Write tests until you get 100% test coverage, or a satisfactory number. The higher the number the higher the confidence that the code is bug free.

Read the next section to see all these tools in action in contributed Drupal 7 module.

A real life example

I applied the tips of this article to the TypedEntity module. TypedEntity is a nice little module that helps you get your code organized around your Drupal entities and bundles, as first class PHP objects. This module will help you to change your mindset.
Make sure to check the contents of the tests/ directory. In there you will see real life examples of a composer.json and test cases. To run the tests follow these steps:

  1. Download the latest version of the module in your Drupal site.
  2. Navigate to the typed_entity module directory.
  3. Execute tests/run-tests.sh in your terminal. You will need to have composer installed to run them.

This module executes both PHPUnit and Simpletest tests on every commit using Travis CI configured through .travis.yml and phpunit.xml.

Another great example, this one with a very high test coverage, is the Amazon S3 module. A new release of this useful module was created recently by fellow Lullabot Andrew Berry, and he added unit tests!

Do you do things differently in your Drupal 7 modules? Leave your thoughts in the comments!

Categories: Drupal

SitePoint PHP Drupal: Drupal 8 Theming Revamped – Updates and New Features

10 August 2015 - 9:00am

If you are a Drupal developer who has dabbled in theming older versions of Drupal (5, 6, 7) you understand why frustration is the trusty companion of any Drupal themer. Luckily, though, Drupal 8 promises so many improvements that even the Angry Themer is happy for a change. It is only natural we jump in […]

Continue reading %Drupal 8 Theming Revamped – Updates and New Features%

Categories: Drupal

Appnovation Technologies: Overriding queue classes used in the Batch API in Drupal 7

10 August 2015 - 8:04am
There are lots of benefits in working with a platform such as Drupal, that come packed full of goodies for developers like myself and my colleagues, that enable us to build intelligent and innovative solutions.
Categories: Drupal

Nuvole: Drupal 8 Configuration Management: beware of pitfalls

10 August 2015 - 7:35am
Nuvole's Configuration Management workshop at Drupalaton 2015 in Hungary

Drupalaton in Hungary last weekend gave the opportunity for a 90 minutes workshop about Configuration Management (CMI) and how it changes a Drupal developers work flow with the coming Drupal 8.

CMI allows you to have the whole site configuration under control and that is a great improvement. But it also comes with its pitfalls. Developers have to be more vigilant when sharing configuration with each other: mindless exporting configuration may override the configuration shared by others, mindless importing may override one's own work and forgetting to import merged configuration leads to ignoring the work of your co-developers at a later stage.

CMI, while it is much more awesome than anything we have in Drupal 7, is also much more unforgiving. So it would be all too easy to not use it properly and what it was designed for and then wonder why you can't have nice things.

Fortunately, a methodical git workflow can help recover from mistakes (except importing configuration before exporting it first). So don't forget the order of the steps:

  1. config export
  2. git commit
  3. git merge
  4. config import

And do it often to keep the merges and failures simple and easy to resolve.

Please find the full Drupalaton 2015 workshop slides attached below.

Tags: Drupal PlanetDrupal 8Attachments:  CMI presentation Drupalaton 2015
Categories: Drupal

KnackForge: Solr Streaming Expressions

10 August 2015 - 4:12am

Solr 5.1 introduced a revolutionary Streaming API. With Solr 5.2, you get Streaming Expressions on top of it. Ever wondered on how to run nested queries in SOLR or running parallel computing capabilities, this could be the answer. 

Streaming Expressions provide a simple query language for SolrCloud that merges search with parallel computing. Under the covers Streaming Expressions are backed by a java Streaming API that provides a fast map/reduce implementation for SolrCloud. Streaming Expressions are composed of functions. All functions behave like Streams, which means that they don't hold all the data in memory at once. Read more about the basics here https://cwiki.apache.org/confluence/display/solr/Streaming+Expressions

Setup:

Assuming a debian based system, say Ubuntu 12.04 or 14.04. If you have not installed Solr 5.2, go grap latest codebase (For eg http://apache.mirror1.spango.com/lucene/solr/5.2.1/), extract it. 

Setup Solr in cloud mode.

Cloud mode lets you create collection and nodes. See https://cwiki.apache.org/confluence/display/solr/Getting+Started+with+SolrCloud for more details. bin/solr -e cloud Enter the port and other details.

To start a single node, use,

bin/solr start -cloud -s example/cloud/node1/solr -p 8983

Streaming API:

Now comes the interesting part. We have the following streaming API functions, 

Categories: Drupal

Tim Millwood: Composer in contrib: Step 2

10 August 2015 - 1:45am
Now that we have an initiative to get get a composer.json file in each contrib module, we cal start...
Categories: Drupal

Microserve: Getting Bootstrap Grid Classes Into Drupal 7 CMS Markup

10 August 2015 - 1:10am

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

https://api.drupal.org/api/drupal/modules!system!page.tpl.php/7

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).

Conclusion

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: Drupal

Web Omelette: New contrib module: Info Plugins

10 August 2015 - 12:02am

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.

Cheers!

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

DrupalCon News: Drupal Business Summit: The Next Generation

8 August 2015 - 10:00pm

What do the businesses in the Drupal community need to do to survive and grow in the next three years?

Drupal 8 will attract a new wave of agencies to compete in the market, and will also enable Drupal businesses to compete at a higher level. A time of big change and competition is coming, and it will no longer be enough just to say you 'do Drupal' and then sit back and watch sales roll in.

Categories: Drupal

Chen Hui Jing: Drupal 101: Starting Drupal development

8 August 2015 - 5:00pm

I recently moved from an agency specialising in building Drupal sites to one which is platform-agnostic, and uses all variety of technologies. As my team was not very familiar with Drupal, I started writing some documentation on setting up locally, installing Drush and commonly used modules, and some other stuff so everyone could get up and running quickly. I’ve modified it to be even more beginner-friendly, for people who’ve never built websites before. This is sort of opinionated so feel free not to follow along exactly.

The basic technology stack

As with most content management systems, Drupal has some system requirements in order to run, commonly known as a technology stack. This simply means you have to install...

Categories: Drupal

Drupal Watchdog: Drupal Should Use an External Front End Framework

7 August 2015 - 1:15pm
Preface

The purpose of this blog post is intended to be a comprehensive analysis and response to:
#2289619: [meta] Add a new framework base theme to Drupal core; to encapsulate how I believe core should move forward with a default theme. For brevity, the term "framework" in this post will always refer to "front end framework".

The Problem

Core has always provided its own themes, however the benefit of sustaining this model is becoming increasingly difficult to justify.

Fast Moving Front End Technologies

In regards to the front end, core has historically been more reactive than proactive. This isn’t all that surprising, nor a bad approach, when you take into account what core originally had to deal with.

Now consider for a moment, all the different technologies and techniques that are used on the front end today and compare that with when Bartik was created ~6 years ago. Things have changed rather drastically with the advent of Responsive Web Design, HTML5 and CSS preprocessors like SASS and LESS.

Web Components are possibly the next major milestone in front end development with an impact potentially just as large, if not larger, than that of HTML5 and Responsive Web Design. While the concept isn't necessarily new (frameworks have had "components" for years), it is definitely being sought to become a "web standard" with Google leading the way. Web Components are an encapsulation of multiple front end technologies supported directly by the browser. This could also likely be the future of what we now consider "frameworks" today: a consolidation of web components. Perhaps the web as a whole, only time can tell.

Video:
2015 DrupalCon Los Angeles Session: Drupal 9 Components Library: The next theme system

The 1% of the 1%

Generally known as the 1% rule, only ~1% of any given internet community is responsible for creation. In regards to Drupal, this figure is actually even more drastic with only about 0.02% that are core developers.

This fact is what makes core developers a "rare commodity". I would, however, like to take this a step further. Of that 0.02%, how many of those core developers are front end developers? I’m sure no one knows the exact ratio, but it is commonly accepted that core front end developers are an even "rarer commodity".

Back end developers are the majority. They have little to no interest in current front end technologies, techniques or "Best Practices™". I'm not discounting the fact that there are back end developers that cross over or vice versa, but there are just a handful of "unicorns" .

Without enough of a front end ratio in core development, it is impractical and unfair for everyone involved to expect any sort of "solid theme" from core. It is because of this fact that not having an external framework is actually hurting us from a community, development and maintainability standpoint.

"Getting off the Island"

Core has already adopted the "Proudly Found Elsewhere" mentality for a lot of its back end architecture. The benefits that this approach has brought to our community has proven predominantly fruitful. The front end should be no different.

Core really hasn't accepted this direction for front end themes, but doing so would allow core development to focus solely on the integration of an external framework. This would reduce a lot of the technical debt required to sustain the design and implementation of CSS and JS in a core theme.

Video:
Keynote: Angela Byron — Drupal 8: A Story of Growing Up and Getting Off the Island — php[world] 2014

Automated testing

While the automated testing infrastructure (DrupalCI) is definitely improving, it is still primarily focused on the back end side of things.

Core has wonderful unit testing. These unit tests include and ensure that a theme can implement the necessary hooks available to it via the theme system APIs. It is also great at ensuring that a theme's markup is correctly generated.

However, that is where the benefits of automated testing of core themes ends. Any patch that affects CSS or JS must undergo a very manual process which requires contributors to physically apply patches and "test" changes in multiple browsers. This often results in bucket loads of before and after screenshots on an issue. This is hardly ideal.

The reason many front end oriented projects live on GitHub is because of their ability to integrate amazing automated tests through tools like Travis CI and Sauce Labs. Being on GitHub allows front end projects to rigorously test around the specific areas for which their technologies implement and leads to the stability of their codebase.

Perhaps one day the core and contrib themes could leverage the same type of abilities on drupal.org, perhaps not.

Regardless, testing is just as paramount to the front end as it is for the back end.

Unless the testing infrastructure is willing to entertain the possibility of theme-based CSS and JS testing, an external framework is really our only alternative for stable front end code. At the very least, implementing an external framework allows us to defer this decision.

Popular Drupal-grown base themes

There will always be use cases for the popular Drupal-grown base themes. It really just depends on the project and capabilities of a front end developer. There's nothing wrong with them and I have used them all. They are without a doubt a very powerful and necessary part of our ecosystem.

There is often a lot of misunderstanding around what these base themes actually are, though. Many of them started out simply as a way to "reset" core. Over time, many have added structural components (grid systems), useful UI toggle and other tools. However, the foundation for many of them is simply to provide a starting point to create a completely custom sub-theme. Intended or not, they are essentially by front end Drupal developers for front end Drupal developers.

The priority for these base themes is not "out-of-the-box" visual consumption, but rather providing a blank canvas supported by a well groomed toolset. It is because of this "bare nature" that they can actually become more of an obstacle than a benefit for most. They essentially require an individual to possess knowledge of CSS or more, to get even the most basic of themes up and running.

Their target audience is not the other 99.9998% and not viable for core.

The Solution

Due to the complexity of the theme system, the work with Twig has been a daunting task. This alone has pushed a lot of what we thought we would "get to" into even later stages. I propose that the next stage for a default core theme is to think long term: adoption of an external framework.

Proudly Found Elsewhere

Core cannot continue to support in-house theme development, at least until there is a higher ratio of core front end developers. External frameworks live outside of Drupal and helps ensure fewer "Drupalisms" are added to our codebase. It also allows Drupal to engage more with the front end community on a level it never has before.

Vast and Thriving Ecosystems

Because frameworks typically live outside of larger projects, they usually have a vast and thriving ecosystem of their own. These often produce a flurry of additional and invaluable resources like: documentation, blog posts, in-depth how-to articles, specific Q&A sites, support sites, template sites, forums, custom plugins/enhancements. Drupal would instantly benefit from these existing resources and allow our community to offset some of the learning curves.

Back end developer friendly

These resources also allow a back end developer to focus more on how to implement existing patterns than worrying about having to create new ones. This would allow core developers to focus solely on the theme system itself and providing the necessary APIs for theme integration, rather than the more complicated front end CSS or JS implementations.

Why Bootstrap?

There are many frameworks out there and, quite frankly, attempting to find the one that is "better" than the other is futile; frameworks are simply opinionated "standards". You may agree with one’s opinion or you may not. It does not change the fact that they all work.

The question that remains is: Which framework do we put in in core?

I strongly believe that it should be Bootstrap. A lot of individuals, including myself, have already put in a great deal of time and effort in contrib to solve this exact issue: how to use an external framework with Drupal.

Another advantage of using Bootstrap is that it is already backed by a massive external community.

The main strength of Bootstrap is its huge popularity. Technically, it’s not necessarily better than the others in the list, but it offers many more resources (articles and tutorials, third-party plug-ins and extensions, theme builders, and so on) than the other four frameworks combined. In short, Bootstrap is everywhere. And this is the main reason people continue to choose it. Ivaylo Gerchev

In just two and half years, the Drupal Bootstrap base theme has grown exponentially at a whopping 2596.67% (based on 7.x installs from: 1,070 on January 6, 2013 to: 70,531 on July 12, 2015*) and has become the third top most installed Drupal theme on drupal.org.
*Note: I have chosen to exclude the past two weeks of statistics as I believe they are in error due to #2509574: Project usage stats have probably gone bad (again).

While I cannot attest to the exact reason this rapid adoption has occurred, here is an educated guess: it's what the people want. I purposefully made something that was easy to install and worked right "out-of-the-box". Ensuring that the focus of the project was on the other 99.9998%.

No other Drupal project that implements an external framework can claim this or even come close to it.

Ease of use is paramount and often overlooked by developers. This "philosophy" is what has allowed sites like Dreditor to be born and this one, Drupal Watchdog, to be redesigned given some rather severe time constraints.

Conclusion: Drupal 8, 9, 10...

Adopting an external framework is just the logical next step in core's "Proudly Found Elsewhere" mission on the front end. Regardless of which framework is ultimately chosen, I think it is more important to see why Drupal needs an external framework.

We already have too many issues and tempers flaring around even the smallest of details on the front end. By outsourcing a theme's design (CSS & JS), we would allow our community to instead focus on the integrations of themes, like the future of components and much larger issues.

While this issue isn't about trying to add a framework to core just yet, I think it is very important to have this discussion early on. I do think that ultimately, a framework based theme in core should replace Bartik, but that won't and should not happen until D9.

Since adding an external framework base theme would be purely an API addition, there isn't anything that would prevent us from adding it in an 8.Y.0 release (solely opt-in, of course). In fact, I would strongly recommend that we add one before D9 so we can smooth out any remaining details before tackling something as gigantic as #1843798: [meta] Refactor Render API to be OO.

I have a feeling that D9 will be "the year(s) of the front end". While yes, Twig is awesome, the fact remains that the underlying theme system (and default theme) itself hasn't changed all that much and needs some serious tough love.

I believe integrating an external framework is an excellent way for us to, not only reduce both our technical debt and maintenance burden, but also focus how we should be developing our theme system. We have an opportunity to transform the first visual impression of Drupal.

Let's do it for the 99.9998%.

Tags:  Drupal 8 Drupal 9 Proudly Found Elsewhere Themes Theming Community Front End Framework Bootstrap
Categories: Drupal

Drupal Watchdog: Got Game?

7 August 2015 - 9:16am
Feature

This is not an article about gamification. Unless your website is devoted to dragons, adding quests and hit points won’t improve your users’ engagement with your content. (If your website is devoted to dragons, well that’s just awesome.)

Content – be it text, images, video, data, or a combination of mediums – is the reason we build websites in the first place. It’s right there in the acronym: CMS. Drupal is a system – or more accurately, a framework – for managing content. We strongly believe that all website features, layout, and design choices must support the goal of serving your target audiences with the critical information – the content – they need to engage meaningfully with your organization.

Your content is the connection between your organizational goals and your audiences’ motivations. There’s usually a reason a piece of content is added to a website; somebody, at some point, thought it would be useful. Unless that content has meaning to your users, however, it has little value to your organization. Without a strategy guiding the creation and governance of that content, your quest, noble though it may be, is almost doomed to fail.

Fortunately, it’s not hard to start creating a strategy. We believe you can learn the foundations of content strategy for Drupal websites by breaking down what the team at BioWare did in creating Dragon Age: Inquisition.

Goals and Audiences

You have to start with goals.

BioWare’s basic goal is easy to suss out: they want to make money. To support such a massive undertaking – creating Inquisition involved programmers, writers, producers, graphic artists, vocal talent, project management, and more – the end result had to be a game that would appeal to enough people not only to pay for expenses, but to turn a profit. (We have a strong suspicion the team also wanted to turn around the negative reception Dragon Age 2 met by releasing something that would blow more than a few minds.)

Categories: Drupal

Drupal core announcements: Recording from Aug 7th 2015 Drupal 8 critical issues discussion

7 August 2015 - 5:00am

We met again today to discuss critical issues blocking Drupal 8's release (candidate). (See all prior recordings). Here is the recording of the meeting video and chat from today in the hope that it helps more than just those who were on the meeting:

If you also have significant time to work on critical issues in Drupal 8 and we did not include you, let me know as soon as possible.

The meeting log is as follows (all times are GMT real time at the meeting):


10:10 WimLeers https://www.drupal.org/node/2543332
10:10 Druplicon https://www.drupal.org/node/2543332 => Auto-placeholdering for #lazy_builder without bubbling [#2543332] => 40 comments, 8 IRC mentions

10:11 WimLeers https://www.drupal.org/node/2503963
10:11 Druplicon https://www.drupal.org/node/2503963 => XSS in Quick Edit: entity title is not safely encoded [#2503963] => 27 comments, 2 IRC mentions

10:12 plach https://www.drupal.org/node/2544954
10:12 Druplicon https://www.drupal.org/node/2544954 => SqlContentEntityStorageSchema does not detect column-level schema changes in non-base-fields [#2544954] => 16 comments, 1 IRC mention

10:12 plach https://www.drupal.org/node/2542748
10:12 Druplicon https://www.drupal.org/node/2542748 => Automatic entity updates are not safe to run on update.php by default [#2542748] => 60 comments, 14 IRC mentions

10:14 dawehner https://www.drupal.org/node/2540416
10:14 Druplicon https://www.drupal.org/node/2540416 => Decide whether we need hook_upgrade_N()/upgrade.php front controller [#2540416] => 43 comments, 11 IRC mentions

10:17 webchick https://assoc.drupal.org/d8accelerate

10:17 webchick https://www.drupal.org/node/2485119
10:17 Druplicon https://www.drupal.org/node/2485119 => [meta] The Drupal 8.0.0-rc1 Release Checklist [#2485119] => 32 comments, 11 IRC mentions

10:17 webchick https://www.drupal.org/node/2042447
10:17 Druplicon https://www.drupal.org/node/2042447 => Install a module user interface does not install modules (or themes) [#2042447] => 178 comments, 25 IRC mentions

10:18 webchick https://www.drupal.org/node/2267715
10:18 Druplicon https://www.drupal.org/node/2267715 => [meta] Drupal.org (websites/infra) blockers to a Drupal 8 release [#2267715] => 53 comments, 17 IRC mentions

10:19 alexpott https://www.drupal.org/node/2280965
10:19 Druplicon https://www.drupal.org/node/2280965 => [meta] Remove or document every SafeMarkup::set() call [#2280965] => 109 comments, 24 IRC mentions

10:19 alexpott
https://docs.google.com/document/d/1wBSwpCa0tm_CKAV1_R0xTAdKZSsVSUc2fQuS...

10:21 dawehner https://www.drupal.org/node/2503963
10:21 Druplicon https://www.drupal.org/node/2503963 => XSS in Quick Edit: entity title is not safely encoded [#2503963] => 27 comments, 3 IRC mentions

10:23 WimLeers dawehner: catch: alexpott: https://www.drupal.org/node/2547127#comment-10194525
10:23 Druplicon https://www.drupal.org/node/2547127 => [regression] Empty messages container appearing when a Notice occurs [#2547127] => 19 comments, 4 IRC mentions

10:37 alexpott https://www.drupal.org/node/2527360
10:37 Druplicon https://www.drupal.org/node/2527360 => Review all usages of Xss::filter(), Xss::filterAdmin(), SafeMarkup::checkPlain() and SafeMarkup::escape() [#2527360] => 0 comments, 2 IRC mentions

10:38 alexpott https://www.drupal.org/node/2546232
10:38 Druplicon https://www.drupal.org/node/2546232 => Remove SafeMarkup::checkPlain() from UrlHelper [
#2546232] => 3 comments, 1 IRC mention

10:40 dawehner https://www.drupal.org/node/2540416
10:40 Druplicon https://www.drupal.org/node/2540416 => Decide whether we need hook_upgrade_N()/upgrade.php front controller [#2540416] => 43 comments, 12 IRC mentions

10:55 webchick https://www.drupal.org/node/2542748
10:55 Druplicon https://www.drupal.org/node/2542748 => Automatic entity updates are not safe to run on update.php by default [#2542748] => 60 comments, 15 IRC mentions

10:58 alexpott https://www.drupal.org/node/2544932
10:58 dawehner https://www.drupal.org/node/2497243
10:58 Druplicon https://www.drupal.org/node/2544932 => Do not rely on loading php from shared file system [#2544932] => 6 comments, 2 IRC mentions
10:58 Druplicon https://www.drupal.org/node/2497243 => Rebuilding service container results in endless stampede [#2497243] => 208 comments, 48 IRC mentions

11:02 webchick Ok. Time to pass out. ;)

Thanks to @alexpott for the video and log.

Categories: Drupal


Google+
about seo