Jul 30 2013
joe
Jul 30

It's been a while since I've sat down and tried to write a module from scratch in Drupal 8. I've dabbled here and there in the various already existing modules but there's always something interesting about just trying to write that simple "Hello World" module. Sure, starting from scratch isn't really something we do all that often, but it's nice to to know how it works.

So, as part of our Learning Drupal 8 by Trial and Error blog posts, I set out to write what is probably one of the simplest tasks you could want to do with a custom module. Displaying the text "Hello World" as the primary content of the page. In the process of doing so I learned that while the general concepts are much the same as Drupal 7 — you're simply finding a way to map a URL to some PHP code that gets executed — the mechanics of it are much different in Drupal 8.

Most of the information I used while doing this was found by searching through the change records on drupal.org which provide a list and some basic documentation for most of the big changes between Drupal 7 & 8.

.info files and YAML

First up was the .info file. Which in Drupal 8 is now really a modulename.info.yml YAML file. Asside from the sytax differences between the old .ini style files and the new YAML files things are mostly the same here. Give your module a name, a description, and some other basic metadata that Drupal needs. I mostly read through these examples and looked at the .info.yml files of a few core modules for reference.

Symfony 2 routing

The other big thing for me that I knew existed, but hadn't encountered up until this point, is the new Symfony 2 based routing system. It's basically Drupal 8's version of the routing portion of what hook_menu() in prior versions did. The hook_menu() hook still exists, but it's now exclusively used for defining menu items, not menu items and their routes. You can read more about modulename.routing.yml files and how they work. At the end of the day though you're still just mapping a URL to some PHP that gets executed.

PSR-0

Also worth mentioning is the PSR-0 naming standard which is being used by Drupal 8 to perform autoloading of code on an as-needed basis. In Drupal 7 we have the registry which reads in a list of files[] from your .info file and then parses them to figure out what classes, if any, are defined in those files. Then, when someone instantiates a new object from a given class the file containing that code will be automatically loaded on an as-needed basis. The PSR-0 standard is essentially a different way of doing this same thing but following a practice that a larger portion of the PHP community uses, rather than one that we made up for Drupal.

There's more in the screen cast as well, so have a look at what it takes to write the simplest of Drupal 8 modules.

Note: As of the recording of this video some changes have been made to Drupal 8 that make this code not work. Most notably the ControllerInterface class which I extend in the video has been renamed to ContainerInjectionInterface. More details https://drupal.org/node/2079895.

More Changes: Changes where made in the .routing.yml file recently so that the key 'pattern' is now 'path'. See the change notice here: https://drupal.org/node/2089727

Enjoy.

Apr 17 2013
joe
Apr 17

This week we are kicking off a brand new series, Working with Entities in Drupal 7. Entities were introduced in Drupal 7, and are an extremely useful tool, though they have been somewhat confusing for people to work with. In this series we will start out by explaining what entities are, in addition to things like bundles, fields, and entity types. We then spend time understanding how you can use the Entity API to work with existing Drupal entities in you own custom module work. With that foundation in place, we will create a new custom entity and talk about when and why you may, or may not, want to do that.

To get things started off we will cover some terminology and history, with a free video, and then begin working with entity_load() and the EntityFieldQuery class to work with existing Drupal entities on your system.

This series assumes that you're already familiar with the basic tennents of writing modules for Drupal and makes use of things like hook_menu() without spending time explaining them. If you're not familiar with Drupal module development, you should brush up by watching our Module Development for Drupal 7 first.

Mar 06 2013
Mar 06

There are some times in Drupal 6 where you push the limits of what the blocks interface can do. If you need to display the same block, multiple times on the same page, you will start to see these limitations. An example of where this is useful is a Newsletter signup form. Sometimes a client may want a newsletter signup form to be in the footer of every page, but also displayed more prominently on the contact form page.

You will also run into this issue if you want to output a block in one region on one page and another region on a separate page. An example of this would be to display the newsletter signup form in the header on the front page, but in the footer on every other page of the site.

Both of these examples can easily be achieved using something like Panels or Display Suite, but if you want to stick to the blocks interface, here is a simple way you can solve this by building a custom Drupal 6 module.

The first step is to create a simple Drupal 6 module. After you have the module created, we need to create our own Drupal 6 block. Drop the following code in your .module file. You will need to replace the module name with the name of your module. You will also need to look through the other code replacing text and descriptions as necessary. In my example I will be going through creating a second block for the Drupal 6 Constant Contact module.

/**
 * Implements hook_block().
 */
function MYMODULE_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {
    $blocks[0] = array('info' => t('Constant Contact Block 2'));
 
    return $blocks;
  }
  else if ($op == 'view') {
    switch ($delta) {
      case 0:
        // Your module will need to define this function to render the block.
        $block = array(
          'subject' => t('Title of block #1'), 
          'content' => '',
        );
        break;
    }
    return $block;
  }
}

The next step is to identify the block you want to display. The best way to do this is to figure out which module you need to duplicate the block for. In my example this was the Constant Contact module. Open up the .module file for whichever module you want to duplicate the block for.

Once you have the module file opened, do a search for "_block" or "hook_block". This should get us to the function that has all the details you need to insert the line of code that will print this block. We need to get the module name and the delta value for our block. Here is an example from the constant_contact.module file's hook_block implementation.

/**
 * Enables us to place a signup form into a block
 */
function constant_contact_block($op = 'view', $delta = 0, $edit = array())
{
	switch($op) {
		case 'list':
			$blocks[0] = array(
				'info' => t('Constant Contact Signup Form'),
				'visibility'      => 0,
				'roles'      => array(1),
				'pages'      => 'user*',
			);
		return $blocks;
		case 'configure':
			$form = array();
		return;
		case 'save':
		return;
		case 'view':
			switch ($delta) {
				case 0:
					$block['subject'] = t('Signup');
					$block['content'] = drupal_get_form('constant_contact_signup_form');
				break;
			}
		return $block;
	}
}

I can pull out the module name from the function constant_contact_block and get that "constant_contact" is the module name. You can also take this from whatever is in front of the .module in the constant_contact.module file name.

The next step is to pull out the delta value for the block. This is displayed below the switch ($delta) { line of code. In this "case" we want the number "0". This is pulled from the case 0: line of code. Blocks may have multiple of these case statements, you will need to find the right delta value for the block you want to display. Many times in a Drupal 6 hook_block implementation this will simply be 0.

We now add the following line of code to our modules hook_block function.

$block = module_invoke('MYMODULE', 'block', 'view', [DELTA]);

We replace MyMODULE with the module name, in this case "constant_contact" and we replace [DELTA] with the delta value, in this case 0. Here is what the finished line of code looks like:

$block = module_invoke('constant_contact', 'block', 'view', 0);

You then need to replace this line of code with what would normally be your Drupal 6 block output code. The final version of your Drupal block code should look something like this:

/**
 * Implements hook_block().
 */
function MYMODULE_tweaks_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {
    $blocks[0] = array('info' => t('Constant Contact Block 2'));
 
    return $blocks;
  }
  else if ($op == 'view') {
    switch ($delta) {
      case 0:
        $block = module_invoke('constant_contact', 'block', 'view', 0);
        break;
    }
    return $block;
  }
}

You can now add this block just like you would any other block. It should be an exact duplicate of the other Drupal block.

A couple notes: This approach still has it's limitations so a better solution is using something like Panels or Display Suite. However it works well for one off simple fixes on sites that are already making heavy use of blocks. Also note that if you are displaying the same block multiple times on the same page, everything should work fine, but your CSS may not validate if the block uses the same CSS ID since it will now be in multiple places inside the HTML.

Hope that helps and let me know if you have any questions.

Feb 21 2013
Feb 21

Episode Number: 

113

In the last two episodes, we covered building a basic Drupal 7 module that displayed a JavaScript confirmation before a user leaves a specific page. In this episode we continue where we left off and add the ability to display the JavaScript confirm form on specific content type node edit pages.

In this episode you will learn:

  • How to add a checkbox field on the administration form that displays all the content types on your Drupal site
  • How to verify you are on the node edit page of a specific content type

Thanks to Drupalize.me for sponsoring this episode.

DDoD Video: 

AttachmentSize 1.84 KB
Feb 20 2013
Feb 20

Episode Number: 

112

In this episode you will learn:

  • How to implement hook_menu to add an administrative page to your custom Drupal module
  • How to build a Drupal administrative form
  • How to match page patterns to determine when to display the Javascript confirmation box

Thanks to Drupalize.me for sponsoring this episode of the Daily Dose of Drupal.

DDoD Video: 

AttachmentSize 1.63 KB
Feb 19 2013
Feb 19

Episode Number: 

111

Learning module development in Drupal is not easy, but this Daily Dose of Drupal episode provides a very simple but practical module development video tutorial to use when learning about Drupal Module development. If you have a complex form on your Drupal websites, whether it is a Node creation form or perhaps even a webform, you may want to warn users before they navigate away from the page. This can help inform users that if they navigate away from the page before submitting the form, they may lose the contents of the form.

Note: In the uploaded module I added an extra feature that makes sure the confirmation form does not show up when submitting the form. I did not cover this in the video.

In this episode you will learn:

  • How to create a simple Drupal 7 module
  • How to create a Drupal 7 .info file
  • How to create a Drupal 7 .module file
  • How to use the Drupal 7 hook_init() function
  • How to use the drupal_add_js() function to add inline JavaScript
  • How to use the current_path() function to get the current Drupal system path

Thanks to Drupalize.me for sponsoring this episode.

DDoD Video: 

AttachmentSize 1.07 KB
Jan 31 2013
Jan 31

Replicating module_invoke_all and drupal_alter in Javascript

If you've ever written a Drupal module before you're likely familiar with Drupal's hook system. I'm not going to go in to details about how the hook system works, or why this particular pattern was chosen by Drupal's developers. What's important here is what this systems allows module developers to accomplish.

At its most basic, the hook system is what allows me to write a module that enhances or extends Drupal -- without ever having to modify a line of someone else's code. I can, for example, modify the list of blocks that are available on a given page by simply implementing a "hook" function in PHP that modifies the information that was already set up. This approach is one of the things that makes Drupal incredibly flexible!

When you're writing your own custom modules, it is customary to expose these types of hooks for other modules, too. That way, other developers can come along and make minor modifications or feature enhancements to your module by "piggybacking" on your module's functionality, rather than hacking your code. It also means that you don't have to anticipate every possible use case for your code: by providing these extension points, you allow future developers to extend it.

Drupal makes it really easy for modules developers to do this, and it provides a set of helper functions that allow you to easily broadcast these "I have a hook! Who wants to tie into it?" announcements to the world.

The case for APIs

Now, that's all well and good, but what if the functionality I want people to be able to alter or events I want people to be able to react to are encapsulated in Javascript? This is where Drupal breaks down a bit and we're left to our own devices. Drupal provides a simple mechanism for modules to essentially register a bit of code that they would like to be executed whenever Drupal.attachBehavoirs is called. This happens when the DOM is fully loaded and Drupal's Javascript code has been properly initialized, and anytime new elements have been added to the DOM via AJAX. And that's about it.

For most cases where Javascript needs to interact with Drupal this works just fine. What you're likely really after is some element in the DOM anyway so you can do your sweet web 2.0 fadeIn().

Sometimes, though, your Javascript needs are more complex than adding visual pizzaz. Consider this; You've been asked to write a module that integrates a video player from a third party site into Drupal. The video service offers a straightforward Javascript based embed option. All you have to do is include their Javascript file on the page and call the player.setup() method, passing in an embed code to the player so that it knows which video to play. Easy enough, and a common pattern.

Let's say the setup() method takes not only an embed code but also an array of additional paramaters to configure how the player appears and behaves. Some of those paramaters are callback functions -- the name of an additional Javascript function that should be called when certian things happen. Some examples of this might be 'onCreate' when the player is embeded and ready to start playback, 'onPause' when someone clicks the player's play/pause button, and so on. For our example we'll assume that we're implementing an 'onCreate' callback. It should be triggered by the video player after it's been embedded, and is ready for playback to start. (Another common example of something like this the jQuery.ajax, which can take 'success' and 'error' callbacks. Which one gets called depends on the result of the Ajax request.)

This should be simple, right? Just set the callback to 'Drupal.myModule.onCreate' and write the corresponding function in your mymodule.js file!

Except... Later on in the project, Kyle comes along and is told to implement an unrelated piece of functionality that also fade a DOM element in on the page after the video player has been embeded. Now two different functions both need to fire when the Video player has been created. You can't just pass in a second 'onCreate' callback function to the player.setup() method -- it only allows one value! So now Kyle is stuck trying to jam his unrelated Javascript in to your Drupal.myModule.onCreate function. Blam! You've got a mess of unrelated, hard to maintain code!

A better way of handling this would be for your module to re-broadcast the 'onCreate' callback to give other code a chance to respond to it as well. You could take it one step farther and implement a system that sends out a notification when the 'onCallback' event occurs, and subscribe to it with any functions that need it. That approach would be a lot like the module_invoke_all() function in Drupal's PHP API.

Lucky for you, there are all kinds of ways to do this in Javascript! I'll outline two of them below.

The Drupal Way

One way of solving the problem is to replicate the Drupal.behaviors system provided by core. That's actually pretty straightforward. You need to:

  • Create a well known place for someone to register their objects or functions.
  • Write a short snippet of Javascript that will loop through and execute these registered functions.
  • Call this Javascript at the appropriate time.
  • Ensure that your module's Javascript is loaded before that of other modules.

In your javascript code, you'll need to create a standard object that other modules can go to when they register their functions. In core, this is Drupal.behaviors. We'll create our own new object for this example.

var MyModule = MyModule || {};
MyModule.callbacks = {};

Then you'll need an easy way to call and execute any registered callbacks.

MyModule.executeCallbacks = function(data) {
   $.each(MyModule.callbacks, function(key, callback) {
       if ($.isFunction(callback)) {
          callback(data);
       }
   });
}

What this code does is loop over all the functions collected in MyModule.callbacks and executes them. Pretty simple, really! It works well for notifying any code of some "event" as long as you remember to call the MyModule.executeCallbacks() method at the appropriate times.

Now, any other module can register callback functions that will be called by the MyModule.executeCallbacks() method:

MyModule.callbacks.theirModuleOnCreate = function() {
   // Do some sweet Javascript stuff here ...
}

Put it all together by implementing your onCreate callback (the code we wanted to implement at the very beginning of this exercise!) and call the new code.

MyModule.onCreate = function() {
   // Give all modules that have registered a callback a chance to respond.
   MyModule.executeCallbacks();
}

Pretty painless. Just make sure your module's Javascript file is loaded before any others: in Drupal, you can do that by changing the weight of your module to -10, or something similar. If you don't do that, you'll end up with warnings about "MyModule.callbacks being undefined" when someone else's Javascript is loaded first, and tries to register a callback with your object.

This approach is easy to implement, but it still has some problems.

  • It's a major "Drupalism." For anyone familiar with Javascript but not with Drupal's way of doing things, it's a conceptual hurdle that needs to be overcome before understanding how to add a new behavior.
  • If one behavior fails, the execution stops: anything that hasn't be executed will not get called, and you're dependent on others to write code that doesn't fail.
  • There is no easy way to remove a behavior added by someone else's code, or to overwrite the way that Drupal core does something. Don't like the table drag javascript? The only way around it is Monkey Patching.

An alternative way

Another approach that's a bit more "Javascripty" is to use the jQuery.trigger() and jQuery.bind() methods. With them, you can create custom events that other modules can listen for and react too. It's a lot like using jQuery to intercept the 'click' event on a link, perform some custom action, then allowing the link to continue with it's processing. In this case, though, we'll be triggering our own custom event on a DOM element. To do this you need to:

  • Call jQuery.trigger on an object or DOM element in order to broadcast an event.
  • Use jQuery.bind on an object or DOM element to register a listener for an event.
  • Wash, rinse & repeat ...

As usual, the code samples below would go inside of your module's mymodule.js file and be included on the page when necessary via the drupal_add_js() PHP function.

Inside of our module's .onCreate callback, we use the jQuery.trigger() method to trigger our custom event and alert all listeners that they should go ahead and do their thing. It's not necessary to prefix our event names with 'myModule.' but it does lead to cleaner code. (It also makes it easier to unbind all of the events associated with a particular module in one step.) This approach is functionally equivalent to calling the MyModule.executeCallbacks() method from the previous example. We're telling anyone that wants to participate that now is the time to do it!

MyModule.onCreate = function() {
   // Trigger an event on the document object.
   $(document).trigger('myModule.onCreate');
}

The second piece of this puzzle is using the jQuery.bind() method to add an event listener that will be triggered any time our custom event is triggered. Each event listener receives the jQuery.Event object as the first argument. The code below is equivalent to the bit above where we register our callback with MyModule.callbacks.theirModule = {}

$(document).bind('myModule.onCreate', function(event) {
   // Do my fancy sliding effect here ...
});

Any number of modules can bind to the custom event, and respond to the onCreate callback event, without ever having to modify your module's Javascript.

Another technique that I've used in the past is to create a drupal_alter() style functionality in Javascript. This would allow others to modify the parameters that my code passes to a third party's API. It's easy to do, so since you can pass an array of additional arguments to the jQuery.trigger() method. They'll be passed along to any listeners added with jQuery.bind(). And, since complex data types in Javascript are inherently passed by reference, the listener can make changes to the incoming parameters and they'll be reflected upstream. Something like the following would do the trick.

MyModule.createWidget = function() {
  var parameters = {width: 250, height: 100, onCallback: 'MyModule.onCreate'};
  // Allow other modules to alter the parameters.
  $(document).trigger('myModule.alterParameters', [parameters]);
  superAwesomeWidgetAPI().setup(parameters);
}

Then anyone else could bind to the new 'myModule.alterParameters' event and receive the parameters object as an additional argument. The first argument for any function using jQuery.bind() to listen to an event is always the jQuery.event object.

$(document).bind('myModule.alterParameters', function(e, parameters) {
  // Here I can change parameters and it will be reflected in the function that triggered this event.
  parameters.width = 350;
});

While this method isn't perfect either, I like that it's closer to the Javascript programming patterns used in the broader world outside of Drupal. This means it's easier for someone not familiar with Drupal to understand my code and to quickly figure out how to work with it.

It does, however, still exhibit some of the same problems as the Drupal.behaviors method. Notably the fact that if any one listener has code that fails the whole system breaks down. In addition, you have to trigger and bind to events on either a DOM element or other Javascript object.

Summary.

Drupal itself doesn't come with a Javascript equivalent to the module_invoke_all() function, but there are a lot of ways that we can implement a similar system ourselves. When you run in to this problem in your development, I encourage you to use the second approach outlined: it has all the same capabilities of the Drupal.behaviors approach, with less code and a shallower learning curve.

These are by no means the only methods for accomplishing this sort of task in Javascript. Another for example would be the popular publish/suscribe pattern, but we'll wait to explore those in another article! Whichever approach you choose, it's important to build for future flexibility, just as you would with your PHP code.

Dec 05 2012
joe
Dec 05

In this lesson, we’re going to talk about what a Drush command is exactly. We're assuming you’re at least somewhat familiar with Drush and running commands, and general interaction with the terminal. In order to demonstrate both how Drush commands work, and to give a better idea of what we’ll be working towards, we're going to take a look at the Drush command we’re going to write for the Databasics module and explain a bit about arguments and options. We’re going to

  • Run a couple of Drush commands and see the difference between arguments and options in action.
  • Talk about the command that we’re going to learn to write in this series
  • See how to get a list of all the commands Drush knows about and the help text for those commands
  • Learn about the path Drush searches for the commands that it uses
Dec 05 2012
joe
Dec 05

Drush is one of the coolest tools available for Drupal developers. It provides all sorts of commands for assisting in Drupal development, automating workflows and making it easier to script various parts of the drupal workflow. But sometimes the commands that come with drush or those available from other modules just don’t quite cut it. Sometimes we need to automate things that are specific to our own site. Drush commands can also be really useful for quick one-off data migration tasks and other things for which writing a whole module might just be overkill. In this series we’re going to learn about:

  • What a drush command is and where drush finds the commands that it can use
  • How to use hook_drush_command in order to tell drush that we want to provide new commands
  • How to output data from our commands using some of drush's built-in helper functions.
  • Writing our own custom drush commands
  • Passing arguments to a command
  • Passing options to a command
  • How to prompt the user for input while your command is executing
  • Invoking other drush commands from our own
  • Creating make files

This series assumes that you’re already familiar with the basics of drush, that you’ve got it installed on your system and that you’re comfortable with running drush commands provided by core and contrib modules. If you’re not familiar with drush, you might want to start with the Introduction to Drush Series which covers all of the prerequisites for this series.

Nov 28 2012
Nov 28

Welcome to another Daily Dose of Drupal, today we’re on Episode Number 56 and if you didn’t follow yesterday’s episode, we’re learning about the E-mail Field Module and we weren’t only going over with the e-mail field module did, we’re actually going to the code in figuring out why it works the way it does and learning how it interacts with the Field API in Drupal 7 to actually work the way that you know that it works based on the previous episode of the Daily Dose of Drupal Episode Number 42 and probably your uses for the module which I’m guessing you may have had if you worked on a few Drupal websites.

Last time it went a little long so we’ll try to keep it a little shorter this time but we basically got down to this Hook Field Formatter Info and we’re learning about Field Formatters. So we’re going to go ahead and get started; but first you can follow me on Twitter @smthomas3 or you can go over to codekarate.com and sign up for the newsletter if you haven’t already.

Okay so Field Formatters and Hook Field Formatter Info; as we did last time we pulled it up and it exposes Field API Formatter Types. This is displayed in the Manage Display section and as you can see there are three formats here; and as I mentioned before I sometimes like to change code if you’re not sure what it does and that’s a good way to figure out and be able to turn how it’s interacting, you’ll notice nothing changed there.

So we’ll take a look, we’ll refresh again juts to make sure and again; although I did changed the label here for default e-mail link it’s still is not showing up. So the next solution is let’s go ahead and clear the cache, let me go ahead and get to this Drupal site and I’ll use Drush to clear the cache, now if I come back to this page you can see that the asterisk I added are now showing up. Now it’s just a lesson that some things are dependent on the cache, they actually are cache, in this case this Field Formatter Info, this Hook Field Formatter Info information is actually cache.

So by clearing that it was able to show up … it should be able to show up correctly again, you’ll notice it still have the asterisk, go ahead and cleat the cache, refresh the page and it will go away. Okay the next step; let’s actually figure out what these are doing. So this Hook Field Formatter Info; this corresponds with the Hook Field Formatter View.

The Hook Field Formatter Info Hook actually defines which to show in that list so what formatters are available and this Hook Field Formatter View will actually define how to display this by building a renderrable array and you can check out some previous episodes of the Daily Dose of Drupal to learn about renderrable arrays or you can of course find plenty of information on drupal.org.

So as you can see there are three formatters here and one conditional that I talked about last time. Each one of these; for instance e-mail default corresponds to a case statement in this Hook Field Formatter View. So if you selected e-mail default it’s going to use this case statement, if you selected e-mail content or contact we’ll use this one and so on and so forth. Let’s go ahead and give it a try.
So I’m going to go ahead and pull up this piece of content, I’m going to actually add a valid e-mail address here and save it and you will notice that if I go to this page there is … it says contact person by e-mail. And that is because I’m using this e-mail contact form formatter, if I use the default one and go ahead and save it and refresh this page you can see that it creates a mail to link as if you look down at the bottom left corner and that is created by this section right here.

So as you can see it uses this mail to link, we can go ahead and add some extra text here just to make sure that we know how it’s working so I’m just going to add a little bit of text out in front and I’ll refresh it, you can say now it says e-mail ***, I’m going to go ahead and get rid of that, the e-mail contact formatter goes through so all this one does it it sets element delta to a renderrable array of mark-up and then it goes ahead and it returns this elements so it’s returning this renderrable array or render array.

And if you want to look what all these parameters are you can of course hop over to documentation and it’s going to give us some more information. The first is Entity Type which is the actual type of entity, in this case the Use Object Type but it’s the same thing, Display Type is the name of formatter to use so that’s important to know this Display Variable at the end has a type item in the array and this Type Item is going to correspond to one of these Hook Field Formatter Info items what we’ll declare up above.

So we’re going to go ahead and just create a new one just to show how it works and ours is not going to be anything realistic but you’ll probably use an actual module but it’s just going to show an example. So e-mail example; so as you can see I’m just … copied the previous one and I created another item in this Hook Field Formatter Info Array, this formats array that get’s returned, if I save this hop over and clear the cache and I hop back over here, you’ll notice now I have my e-mail example format, I’m going to save that but before anything is going to actually work I’m going to need to define a case statement for that.

So Case E-mail example and I’m going to follow the same format as it show above and I’m basically going to loop through all the various items and for each item; what this allows you to do is it could be multiple … this Delta Value, there could be multiple e-mail addresses for this fields. Some Fields allow you to define multiple items, in this case it’s only one but it could be multiple so you need to be able to handle that option and we’re going to just keep really simple and as I said before this won’t actually to be something you would use but you can really see how it works.

And then we’re going to go ahead and just add that e-mail address so it’s going to be some extra text here, I’m going to go ahead and save that, now I’m going to refresh this page, now it says my example e-mail formatter is and then it has my e-mail address. Like I said before not really a real life use case but you can see how easy it is to add an additional Hook Field Formatter or an additional Field Formatter I guess. The important thing to note is although I just showed you you can do this, this isn’t the correct way to actually add an additional formatter.

You can actually implement your own Hook Field Formatter View and Hook Field Formatter Info in your own module and not actually have to modify the e-mail field module and that is in fact the way you should do it so this code here would actually need to be broken out in its own module just because you don’t want to actually modify contributed modules if there’s easy hooks that allow you to interact with them otherwise you’ll have update problems and it’s just not the best way to do things. However it does show you what the module is doing and how you can interact with it.

So the next step will go ahead and look at Hook Field Widget info and we’ll follow the same pattern as before and look up and see what Hook Field Widget Info does. You can see it exposes Field API Widget Types. That may not exactly tell you what it does but we’ll go ahead and take a look; so this returns and array e-mail_textfield and it gives us a label of text field.

The Field Types that it applies to is e-mail because that’s the e-mail filed that we are creating or that’s created up above and settings is a size of 60. So let’s go ahead and take a look at this; if you come back to Manage Fields you can see this widget shows up as Text Field, if I change this; Text Filed 2 for instance and I refresh you’ll notice that now it says Text Field 2 here and you can of course add additional widget types there just like we added formatter types. So I can create a second one that could do something else for instance.

So you have Text Field 2, it doesn’t seem to want to show multiple for some reason, interesting, go ahead and make sure we clear the cache, maybe that’s the cause of the problem and you’ll notice it of course was, so important note; when in doubt you may want to try clearing the cache. Again we’re not going to modify the original module, just know that you can play around with that and see how that works.

The Settings Form is actually the form that you will see if you go into Field Settings … well actually not Field Settings and go into the Edit and this here corresponds in this Hook Field Widget Settings Form which we’ll take a look at first but it’s going to correspond to this form in some way. So we’ll take a look at Hook Field Widget Settings Form, it says add settings to the Widget Settings Form.

Pretty straight forward answer I guess but it tells you of course the information that api.drupal.org page is for these different hooks. They’re going to be extremely valuable when you’re trying to learn this information. So what this does is it grabs the widget and the settings, it does pull out the settings value that’s set from up here but it allows you to change the size of the text field, it does add a valid date, the valid date is a positive integer.

Let’s go ahead and change the title to size of e-mail text field and we’ll take a look, refresh and you’ll notice now down here it says size of e-mail text field, it does default to 60. I believe if I change this unless I’ve already saved it I’m not positive that this is going to show up but we’ll go ahead and take a look, clear the cache and we’re still set at 60. I’m guessing it’s because I actually had saved this form before so it overwrote that default value but you can of course change the default here, it defaults to 60.

The next is Hook Field Widget Form; now this one is a little different than the Hook Field Widget Settings Form. So even though … there’s a lot of Hooks that are getting thrown around for the Field API and it’s confusing even to me and I’ve worked with them a decent amount so don’t be worried that it might seem a like there’s a lot of hooks that’s going around, you can of course always look them up and you can use other modules as examples when you’re building your own.
So after you’ve seen how a couple of modules work you can go ahead and you can pull those examples up as you need them as you’re working on modules that you may need in order to know how those are set up and how they interact with Drupal core and the Drupal Field API.

So this returns the form for a Single Field Widget and this one is actually not the settings form here but if you go to the actual content type and click Edit it is this text field right here. So as you can see the type is Text Field, it gives it a default value which is going to be pulled in from the items array that is passed in using the correct delta so you can use multiple e-mail fields or multiple instances of one e-mail field and it pulls in the correct size, it gives it a prefix and a suffix as well.
So if we went ahead and for instance commented out the default value then when we refresh this page you can tell that there is no default value here. So although I didn’t go … that’s really it for the Field API stuff and it does some other things with allowing you or with a Hook Menu and the Form API, we’re not going to go through that because it’s already went on for quite a while.

The Field API; as you can tell there’s a lot of Hooks implement however if you look at the amount of code, each Hook does not actually contain a lot of code so you can actually take a look at it, go through it, find out what each line of code is doing. Don’t be afraid to … for instance; in this case if we’re going back to the Widget Type or let’s actually go Manage Display and let’s go to default e-mail link, okay so that is set up right and let’s go to actually view this.

Don’t be afraid to use some print statements or debugging statements to actually … for instance in this case I’m going to display the items, don’t be afraid to go ahead and add your debugging statements and look through what’s getting passed. As you can see there’s one item, it’s an array, the delta of it is 0 and it’s this e-mail address.

So as I said before; don’t be worried about changing the code or playing around with it when you’re learning because that’s just … I’ve found at least personally, that’s the best way that I learned, is actually digging in to the code, changing things, figuring out what I can do to improve the code, what I can do to break the code all different kinds of fun things to really learn how the module is interacting with Drupal.

That’s it for this time, keep in mind as you go through this module and other modules there are issue queues on drupal.org for this module and other modules and maybe you will be able to find the bugs, fixed bugs, post patches and overall just help the Drupal community by promoting better modules and increasing the quality of the code and just all around making modules in Drupal even better.
So keep that in mind as you’re going through this and as you’re learning, it’s never too early to try to contribute and most of the times you’ll find other developers very helpful in helping you get started. If you have any questions as always you can contact me on Twitter, you can use codekarate.com which I urge you to subscribe for the newsletter, you can send me an e-mail, you can see the e-mail right there, go ahead and just send me an e-mail if you have any questions, I’ll try to answer every question that I get, I can’t always do it but I will give it my best attempt and I’ll try to get back to you.

If I don’t get back to you in the first few days don’t worry, sometimes especially around the holiday season and e-commerce shops getting launch, it’s been a little bit hectic but I will get to you, don’t worry and I will talk to you again next time and thank you for watching the Daily Dose of Drupal.

Nov 27 2012
Nov 27

Hello there and welcome to another Daily Dose of Drupal. Today we’re on Episode Number 55, as always; I am Shane, you can follow me on Twitter @smthomas3, also go ahead and go to codekarate.com if you haven’t already and sign up for the newsletter here left. I send out a newsletter every once in a while that has some links to popular articles on my blog, also some other Drupal insights and eventually I’ll be sending out a couple of courses that only people from my newsletter will be able to access so go ahead and get signed up and we’ll go ahead and get started today.

I’m pretty excited about today’s episode; it’s been something I’ve wanted to do for a while, I believed it was originally recommended from the Contact Form on the codekarate.com website but basically I’m going to go ahead and call it a Drupal Module Investigator episode. I found that there’s a disconnect between writing your first module and actually understanding how a more complex module works.

So what I’m going to do is I’m going to take what’s going to start as in simple Drupal modules and I’m going to break them down and go over the code and show you not only how it works but why it works the way it does. And this is hopefully going to fill the gap between if your module developer just starting out and actually being able to build some pretty cool modules so let’s go ahead and get started. I’m going to go over this e-mail field module today and I’m going to look at the code, I’m only going to focus on the field, the API portions on the code mainly because I don’t really have time to go over all f the code but I’ll just go over the portions that I think are important to get started or at least an important portion of the module.

If you haven’t already watched episode number 42 I believed, yes 42, it goes over the e-mail field module and it will show you some of the basic on how the module actually works. Today we’re going to focus on some more on the code behind the e-mail field module and how it works the way it does and how I go about deconstructing a module if you need to figure out why it’s working the way it does or if you need to figure out how you can interact with that module.
So the first thing; let’s go ahead and open up all of the files from this module, you can see it’s the e-mail module, it has … looks like 7 files in it, I’ve went ahead and opened all of them here. The first is the license file that’s added on by Drupal so we’re going to go ahead and ignore that, the next is a read me file; this is an important place to start if you’re looking at module and you’re not sure what it does or how it works. The Read Me file could be very helpful so you could read through that.

This e-mail.feeds.inc; this is a … it just integrates with the Feeds module, we’re not going to go over this part today but you can of course take a look and figure out what it’s doing, also this e-mail.migrate; this is support for the migrate package, I believe this is for migrating from Drupal 6 to Drupal 7, we can ignore that one today as well, we’re going to take a look at the Info file.

The Info file is basically the configuration file for your Drupal module. In this case it says the name is e-mail, it gives it a description, the core is 7.x because it is a Drupal 7 website, it’s a Drupal 7 module intended for use on a Drupal 7 website. You can see the package is fields that will put it in the Fields Set on the modules page and it also includes that migrate.inc file that we’re going to ignore.

So go ahead and close that one out and I’ll show you if you go onto the modules page, into the field section, that’s where that package comes in, you can see the e-mail module has been enabled. We’ll now go to the Install File; we have e-mail field schema and this as you can see this comment is very helpful, it tells you it’s implementing Hook Field Schema.

So we’re going to actually take a look at what that does and this is very helpful when you’re trying to look through and figure out what a module was doing. So I’m just going to Google search that Hook, you can use any search engine you want of course and I’m going to go to the api.drupal.org page on Hook Field Schema. And you can see this defines the Field API Schema for Field Structure.
What this module does … and you can go back and watch the previous video, it creates an e-mail field that you can use inside a content type in Drupal. So in this example I have a content type called Test Fields and one of the fields in there is an e-mail field. So what this does is this defines a way to store that data from the field, you can see that it defines the column as e-mail, the type is a var_char which is a variable character and length of 255 and this actually creates that database table to store this e-mail field data.

So that all that works from the install file, we’ll not take a look at the module file. As I said before; we’re only going to look through about the first 200 lines of it today just to save time but you can of course take a look at the rest.

The first thing is Hook Field Info; we’re going to take a look at that one and you can see this defines Field API field type because the label, description, settings and a couple of other properties for the array that you can return. You can see that the key of this array is e-mail … the label is e-mail and it says … it gives a description; it gives it a default widget, default formatter and the property type.
So let’s go ahead and see how that works out; you can see the field type right there is set as e-mail, if you click this dropdown you see there is an e-mail field type. Let’s go ahead and change this to e-mails just to see how it works. It’s one thing you can do, it’s good to change the code, tweak it a little bit, save it and see how it has an effect because that will allow you to really dig in and find out how that’s working You’ll notice this was changed to e-mails and it says e-mails is now in the dropdown, so that is where that comes into play.

So creating a new field type is as simple as implementing that hook with your own different … based on the types of fields you need, different information. This is the Migrate API information that we’re going to go ahead and ignore, the next is Hook Field Validate.

We’re going to follow the same pattern we have before and go ahead and look that up and see what it does. It says it validates this module’s field data. So it goes ahead and says if there are validation problems it adds to the errors array which is passed by reference, so there is no return value because this is in fact passed by reference. You can see what it’s doing here is it’s looping through this items, all of the items from this content type and if there is an item that is an e-mail type which is what we defined up here then it’s going to try to validate this e-mail address by calling this valid e-mail address function.

If it is valid it’s going to just ignore it but if it’s not valid which is in this case the not valid is going to go ahead and said the message thing this is not a valid e-mail address and it’s going to pass in the error. So we’re going to go ahead and take a look at that, I am going to try to create a simple test fields content type and I’m going to try to create an example or an e-mail example but I’m going to put an invalid e-mail address, you’ll see that it says all the characters I entered is not a valid e-mail address.

I can of course change this; add a couple of exclamation points for instance, try to save it again and you’ll notice my exclamation point has come up so you can interact with the code that way and see how this validated function is working. Hook Field Widget error is another Hook and this does something a little bit different, this one it says flags a field level validation error.

So all these does is set an error on the widget itself I believe so let’s go back to this … on the widget form itself I believe is where this error comes into play but you can see all it’s doing is just setting … if there’s an error message it’s setting on elements. So that is all that is doing. Let’s go ahead and … just because I’m not 100% sure on this I’m just going to check it quick, this shouldn’t do anything in this case because I believe it’s on that widget page.

I haven’t actually looked over this code very much yet so I’m learning just as I’m trying to teach you guys and girls. Alright, so as you can see when I do not have that … so it is in fact using that or when I do not have this getting set, this is just setting this error getting pass through here. So when I comment to that out you’ll notice that what should have been an error was now passed through, if I uncomment that, save it, now the error is showing up.

So that’s … this actually is setting the error so in most cases this is probably pretty much the same thing regardless of what you have in your validated function, it could be different but I’m not exactly sure what cases that might be. I’m sure if you read the documentation on drupal.org it will give you some additional information on what that can do.

The next is this Hook Content is empty and this one we’ll go ahead and take a look, I don’t … I’m not familiar with this one either and you can see it doesn’t look like there’s any documentation for that Hook so I’m not exactly certain. You can see it talks about some CCK so I’m not sure exactly what this does, maybe it has a purpose maybe it does not. You could of course change the code, test it out and see if it has any impact. This could be something legacy from the Drupal 6, it could have a purpose, I’m just not aware of it but go ahead and if you figure it out go ahead and let me know in the comments section.

This Hook Field Formatter Info; let’s take a look at that one, as you can see this process is pretty much the same and if you’re just getting new or getting brought up the speed on building Drupal modules, the process of deconstructing and existing modules pretty much the same. You look through the Hooks, you figure out what they do and then you can of course use those Hooks.

When you want to learn about the Field API you can just do a search for the Field API and learn about the various Hooks that need to be implemented, look at modules like the e-mail or link module and figure out how to create your own fields using the Drupal 7 Field API. So Hook Field Formatter Info exposes Field API format or types. You can see there’s e-mail default, e-mail contact and e-mail plane. Also there’s a conditional formatter; if the module exists which in this case means the module is downloaded and installed and this is the spam span module, it adds another format.

Let’s go ahead and take a look at what that means; so when you come over to the structure content types, I’m going to my content type, I go to Manage Display, you’ll notice there are a couple of different formats here; there’s the default e-mail link, e-mail contact form and e-mail plain text and that corresponds to this Hook or this Hook Field Formatter Info and I’m going to there for today because I don’t want to make this too long but I’m going to finish up the rest of this module or at least through all the Field API types tomorrow.

So I’ll be going over the rest of this tomorrow and I’ll actually go through and I’ll create a new formatter and I’ll show you how that shows up and how that can be used and I’ll also got through what these formatters are doing and how you can of course use this Hook on your own module.

So that’s it for today on the Daily Dose of Drupal, Module Investigator episode of the e-mail field module. We’ll be back again tomorrow and I will finish this up and then we’ll continue on learning other Drupal stuff. So thanks again for watching, as always, I’m Shane, follow me on Twitter if you haven’t already and I will be back again next time. Thanks again, bye.

Nov 27 2012
Nov 27

Hello there everyone and welcome to another exciting episode of the Daily Dose of Drupal. As always; I am Shane, you can follow me on Twitter @smthomas3 or you can go to codekarate.com and sign up for the newsletter which I encourage you to do if you have not already. I will be releasing another issue here the next few days.

So today we’re going to talk about the Ajax Framework in Drupal 7. The documentation is listed here from api.drupal.org and it talks about how you can use Ajax … the Ajax Framework to help you more easily make Ajax Calls to your Drupal website. And this is for Drupal 7 so it’s relatively new in Drupal 7 or it’s quite a bit different than Drupal 6. I found a lot of examples on how to use Ajax within a form, however there was not just a simple straight forward example for how to use it with other types of HTML.

So I wanted to create a simple example of how you use Ajax which is just a simple link, basically you click a link, it makes an Ajax Call out to the server, it does a little bit of processing and sends you back something to put on your HTML page or your Drupal page.

So a few days ago and this is episode 54, that will be coming out shortly but a few days ago I created a blog post called Drupal 7, Java Script, Ajax Framework example from a link and this is basically what I’m going to be going over today but I wanted to put in a video format so I could explain it a little bit better and show a demo. But all the code is there so you can definitely take a look in code if you don’t want to follow along with this video but this video is going to show you how it works and walk through how the code is actually doing what it’s doing.
So here’s my example; just a very simple page, all it does is that when you click this link it goes out to the server, it returns the current time as you can see after a little bit it goes away and it replaces the link back again so can notice that the time has changed, it’ll go away in a few seconds and basically; what that’s doing is just making a very simple Ajax Callout to the server, it’s returning a response and then it’s doing some processing. You can go ahead and take a look at the network tab here and you can see it’s making a call to ajax/myajaxtest or myajaxtest/ajax actually, if you hover over this link you’ll look down here and you’ll notice it’s making a call to my-ajax-test/nojs.

So what this does is when you click this link it actually replaces the nojs portion of this path, you can notice if I open this in a new window it actually gives me a formatted page, notice the title is different where it has nojs in the URL but if you use the Ajax format which when you click this link, the Java Script replaces this nojs with Ajax, it gives you a different result.

You’ll notice it’s Jason data and then that will get processed. So let’s go ahead and take a look at the code and see how it’s doing that and what is it doing and how it works. Go ahead and start … it’s a very simple module, it’s called Ajax Link, it has three files; the first one is ajaxlink.info which is just your simple Drupal 7 module info file.

You’ll notice it does include a scripts file for ajax_link.jas. Let’s go ahead and take a look at the ajaxlink.module file; so it’s only about 79 lines so it’s not too long.

The first is it implements Hook Menu and the first item in Hook Menu is just ajax-test and this is just our ajax-test page. All it has in this page is just an Ajax link. So it calls this Ajax Link Page Callback which this returns a renderable array which if you’re not sure what a renderable array is, look at some of my previous Daily Dose of Drupal videos, I talked about them briefly and it returns a … basically what happens is this gets rendered and created into a link.

So it’s a type of link, the title is Ajax Link which is the title right here, the H Ref is what you see when you hover over it is my-ajax-test/nojs as you can see down here, I also add a prefix and a suffix onto this and you’ll notice I wrap the link inside in ajax-linkdiv but I also put a div after this and it’s just set up to be empty.

So if I look at this you’ll notice … let me go ahead and refresh this page, there is a link right here; ajax-display. So I have my ajax-link div which wraps this link and I also have this ajax-display div which is empty right now. You’ll notice when I click on the link this ajax-display gets the data that’s pass back from the server and it gets put inside that div. So that’s all put into the prefix and suffix, I mean this is a renderable arrays or somewhat similar to Form Arrays if you’re familiar with Drupal 6 Form Arrays. The important part is this part right here; this Ajax property of this array.

All it’s telling you to do is use Ajax which is going to make sure it switches this nojs to Ajax when it makes the Ajax Call, I’m using an effect fade, you can look inside the Ajax Framework documentation for a whole bunch of other options for what you can do with this, a lot of these are use within Drupal forms like I said so they’re not all needed and this was basically what I can stripped it down to and still have it work.

Now let’s look at this other menu item; my-ajax-test, you’ll notice there’s a % sign here and this is so we can take argument or either it’s going to be nojs or it’s going to be /ajax. So it’s going to pass in that page argument to this Ajax link Callback function which if we go down here you’ll notice I have the function and I just pass the variable that get’s called in, this is either going to be set to like I said, nojs or Ajax and it’s going to be a string.

So the first thing I do and this is where you do any of your database queries, your processing, anything like that, I just go ahead and get the current time using the PHP date function then I do the IF statement, I basically say if it’s Ajax that was passed in here I’m going to run some Ajax commands otherwise I’m just going to return a renderable array with the mark-up of this time variable that we previously created. So let’s look at this Ajax piece and unpack it a little bit; I basically set up a commands array, I run one command that’s going to do a replace so it’s going to look for this ID of ajax/display, it’s going to replace that entire div with this HTML right here.

So this is going to be a div with the same ID but it’s going to have this time variable that I created up above. The second one we’re going to do is its Ajax command to change, that is going to just mark this ajax-display with a change indicator and I’ll show you what that does in a second.

So we’ll go ahead and take a look … you’ll notice when I come to the page originally and I go to Ajax link you’ll notice there’s just div ID, ajax –display. As soon as I click that you’ll notice that there’s a new class added; ajax-change and what that allows you to do is it allows you to react on items that have actually been changed.

Now what I also needed to do I needed to run some Java Script after this Ajax Call went through and the easiest way I could find to do that was to create a very simple J query plug-in.

So what this does is it calls Ajax command invoke and it calls my J query plug-in which we’ll show you in a second, that’s just called Ajax Link and it executes that code. And then what it does is it wraps it all into renderable array type format and returns t using this Ajax delivers function and that’s how it works. Let’s go ahead and look at the Java Script which is just a few simple lines of code.

Basically this right here creates a new J query plug-in called ajax_link, all this does is it hides this ajax-link div which is a wrap around this link so you can see it hides it that’s why it goes away.

The Java Script or the Ajax from here, these two lines or this line specifically is what adds this to the page and then in the Java Script I proceed to set a timeout of 5 seconds or 5,000 mili seconds which basically will fade out this ajax-display, set the HTML to nothing so we’ll get rid of the contents and then re-show it so it’s there for the next time then I’ll also fade in this Ajax link so it comes back. And that’s all there is to it to making this happen, see it disappears, this is going to fade out and then be removed and it’s going to fade this one back in.

Very simple, it took me a while to figure it out and get it working because like I said there wasn’t a lot of examples of Ajax … using the Ajax Framework for simple links and there are probably multiple ways to do this, this is just one way, you can always add just a use-ajax class to a link and it will start using Ajax, there’s a whole bunch of different things you can read up on on the Ajax Framework, I just wanted to show you one example and explain how it worked so you can start using Ajax in your own modules and on your own Drupal 7 websites.

That’s it for this time on the Daily Dose of Drupal, check back in again for another exciting episode and we’ll be back again soon. Thanks for watching.

Nov 23 2012
Nov 23

Drupal 7 Ajax Framework Example

For a Daily Dose of Drupal episode that covers this blog post topic as well, take a look at Drupal 7 Ajax Framework Link Example.

After struggling to find documentation on how to take advantage of the Drupal Ajax Framework with just a simple HTML link I decided to provide an example to anyone else who might be struggling with the same problem. The documentation on drupal.org is very detailed, however most of the documentation centers around using the Drupal 7 Ajax Framework with forms. In this case I just want to use the Drupal 7 Ajax Framework with a simple link.

I am going to start by creating a simple module that will provide an example. First we create the ajax_link.info file:


name = "Ajax Link Test"
description = "A simple Ajax link example"
core = 7.x

The next step is to create the ajax_link.module file. In this module file we start with the hook_menu implementation. We will first just create the hook_menu implementation for a very simple page.

/**
 * Implements hook_menu().
 */
function ajax_link_menu() {
  $items = array();
 
  $items['ajax-test'] = array(
    'title' => 'Ajax Test',
    'type' => MENU_NORMAL_ITEM,
    'page callback' => 'ajax_link_page',
    'access arguments' => array('access content'),
  );
 
  return $items;
}

Next we create the page callback for our hook_menu implementation. This page just displays a simple link that will load additional HTML to the page using Ajax when clicked.

/**
 * Callback function that displays a simple Ajax powered link.
 */
function ajax_link_page() {
  return array(
    '#type' => 'link',
    '#title' => t('Ajax Link'),
    '#href' => 'my-ajax-test/nojs',
    '#prefix' => '<div id="ajax-link">',
    '#suffix' => '</div><div id="ajax-display"></div>',
    '#ajax' => array(
      'effect' => 'fade',
    ),
  );
}

Now we save everything, clear the cache and take a look at the page.

Drupal 7 Ajax Framework test page

It is not working yet, we need to create the hook_menu item for the Ajax callback. Our hook_menu implementation now looks like:

/**
 * Implements hook_menu().
 */
function ajax_link_menu() {
  $items = array();
 
  $items['ajax-test'] = array(
    'title' => 'Ajax Test',
    'type' => MENU_NORMAL_ITEM,
    'page callback' => 'ajax_link_page',
    'access arguments' => array('access content'),
  );
 
  $items['my-ajax-test/%'] = array(
    'title' => 'Ajax test callback',
    'type' => MENU_CALLBACK,
    'page callback' => 'ajax_link_callback',
    'page arguments' => array(1),
    'access arguments' => array('access content'),
  );
 
  return $items;
}

We now create the Ajax callback. We build this out to handle both Ajax calls and requests with no Javascript. The Ajax framework will replace the "nojs" part of the path with "ajax" when the link is clicked.

/**
 * Ajax callback to display the current time.
 */
function ajax_link_callback($ajax) {
  // Do any database queries, processing, etc.
  $time = t('The current time is: !time', array('!time' => date('Y-m-d H:i:s')));
 
  if ($ajax == 'ajax') {
    $commands = array();
    // Ajax command to replace the #ajax-display element with the current time.
    $commands[] = ajax_command_replace('#ajax-display', "<div id='ajax-display'>" . $time . "</div>");
    // Add a visual "changed" marker to the '#ajax-display' element.
    $commands[] = ajax_command_changed('#ajax-display');
    // Menu 'page callback' and #ajax['callback'] functions are supposed to
    // return render arrays. If returning an Ajax commands array, it must be
    // encapsulated in a render array structure.
    ajax_deliver(array('#type' => 'ajax', '#commands' => $commands));
  }
  else {
    // No ajax, just display the time on a page using renderable array.
    return array(
      '#markup' => $time,
    );
  }
}

We now have everything we need for a simple example. The comments in the code examples should help explain what is going on. Lets look at a screenshot of what it looks like after the link is clicked.

Drupal 7 Ajax Framework response

The last step was one that took me awhile to figure out. What if you want to execute or trigger some extra JavaScript/Jquery after the Ajax call is complete. Perhaps you need to manipulate other things on the page, or need to modify the html that was just loaded through the Drupal 7 Ajax Framework. In this case the easiest way I found is to build a simple Jquery plugin and call that plugin using the ajax_command_invoke function.

The first step is to create the JavaScript file, we will call it ajax_link.js. In this example I simply hide the Ajax link, set a timeout to remove the loaded content after 5 seconds, and then re-display the Ajax link. You could of course do anything you needed to in the JavaScript file. Below is my jQuery plugin.

(function($) {
  $.fn.ajax_link = function() {
    $('#ajax-link').hide();
    setTimeout(function() {
      $('#ajax-display').fadeOut().html("").show();
      $('#ajax-link').fadeIn();
    }, 5000)
  }
})(jQuery);

We need to modify the info file to make sure this Javascript file is added on every page.


name = "Ajax Test"
description = "A simple Ajax link example"
core = 7.x
scripts[] = ajax_link.js

The last step is to add the ajax_command_invoke function call to our Ajax callback in our module file.

/**
 * Ajax callback to display the current time.
 */
function ajax_link_callback($ajax) {
  // Do any database queries, processing, etc.
  $time = t('The current time is: !time', array('!time' => date('Y-m-d H:i:s')));
 
  if ($ajax == 'ajax') {
    $commands = array();
    // Ajax command to replace the #ajax-display element with the current time.
    $commands[] = ajax_command_replace('#ajax-display', "<div id='ajax-display'>" . $time . "</div>");
    // Add a visual "changed" marker to the '#ajax-display' element.
    $commands[] = ajax_command_changed('#ajax-display');
    // Trigger our ajax_link jQuery plugin.
    $commands[] = ajax_command_invoke(NULL, "ajax_link");
 
    // Menu 'page callback' and #ajax['callback'] functions are supposed to
    // return render arrays. If returning an Ajax commands array, it must be
    // encapsulated in a render array structure.
    ajax_deliver(array('#type' => 'ajax', '#commands' => $commands));
  }
  else {
    // No ajax, just display the time on a page using renderable array.
    return array(
      '#markup' => $time,
    );
  }

That is it. You can now test out a working example of loading content through the Drupal 7 Ajax Framework using a link. After the link loads the Ajax content, you trigger additional JavaScript to be run on the page. Simple as that!

Let me know if you have other ways of doing something like this in the comments below.

Nov 15 2012
Nov 15

Hello there everyone and welcome to another episode of the Daily Dose of Drupal. We have a big one today; we’re on Episode Number 50. Today we’re going to be talking about the Module Builder module but before we get started, if you haven’t signed up for the Code Karate newsletter you should do that now and you should also follow me on Twitter if you haven’t already, I’m Shane, you can follow me @smthomas3 but let’s go ahead and get started; the Module Builder module; this is a tool you can use when you’re trying to either maybe you’re just getting started in building modules or maybe you just want to not have to type up the same comments and the same Hook definitions in every module that you create.

What this does is it allows you build out the Boiler Plate Hook Definitions in your module file and Hook Codes so you don’t have to type all that stuff out every time. So as you can see it says that it builds out that skeleton or scaffolding for the module.

There are two different ways you can use this module; you can download it just as you would in a traditional module and use the Drupal UI; in this case that’s a point and click interface where it will allow you to create that basic module code that will get you started and of course the module is not going to do anything on its own but it’s going to give you examples of that code so you just have to fill in the pieces, it saves you time and just saves you a lot of typing.

The other way and this is the one I’m going to go over today quickly is the Drush Plug-in and this is a little more confusing because you have to know a little bit more about the command line a little bit more about what the module can do. So we’ll go ahead and we’ll go over some of these options; the first thing you’re going to do is you’ll need to install it as a Drush Plug-in which in this case we just need to go to our command lie, go to our home directory and look for the Drush … the .drush folder, I’m just going to download this file here and unpack it and now you can look if I go in there it has those files for the Module Builder module, you can of course download this as you normally would into a Drupal website but in this case we want it to be available through Drush.

I’m going to go ahead and go to a working Drupal website just so I can use the Drush commands and I’m going to start going through this list of commands on the documentation page, you can get to that by going here and clicking on Read Documentation on the Module Builder project page and this is going to go through some of the features on how to install and configure the UI and just how to use some of the Drush commands.

So we’re going to go ahead and get started; you first have to start by downloading the Hook database, this is going to make all those Hooks available for you, it says Hook files have been downloaded.

The next is to run mb-list and one thing to keep in mind is that this module is in the development stage so I’ve notice there’s a few things that don’t seem to work quite right all the time but you got to keep in mind what this is meant for and this is meant for use when you’re developing, it’s just a handy tool to help you build modules more quickly, it’s not something you’re going to use on a live Drupal website that’s in a production.

So if you run that command it gives you a list of all of these Hooks that it has definitions for. This allows you to get that Boiler Plate or structure of that code into a module really easily.

So you can also see that there’s some presents here, I don’t generally use those but you can try those out and see if you have any luck with getting those to work. Next thing we’re going to do is go ahead and run this simple command here; and you’re going to notice that it’s going to ask you some questions.

Some of these aren’t necessarily going to be irrelevant all the time but it goes through all the steps anyway so we don’t want to use any presets, we can give it readable name, a description if we want, give it a help text if we want some dependencies, the package you’ll notice that a lot of those are information that would go into the Info file.

Since we didn’t tell it to build an Info file it just spits out the code for any of the Hooks that we told it to. In this case we did Drush Module Builder which is the MB and we said we want to create My Module … my_module and we want to use Hook Menu and Hook Cron.

So you can see it also of course takes in the help text that we created so it implements Hook Help, implements Hook Menu and implements Hook Cron. It doesn’t actually create the Info File in this case. If you want to just create the Info File we’ll go ahead and we’ll run this command which goes into a little bit more detail, this one is only going to output the Info File.

Keep in mind that this is not actually creating the module, its’ just giving you the code at this point that you can drop into a module. So the first thing on this is going to do a Drush MB for that Module Builder, my_module, we can give it a name so we don’t have to answer the question for entering the name, so - - name and then we’re going to call it My Module.

If you want to enter the dependencies this way you can do - - DEP, in this case we’ll use Views and we only want to build the Info File. So it’s going to ask us presets, it’s going to ask us for Hooks, again; since we’re only building the Info File that’s not going to do anything and you can add a description package for the module and you’ll see it gives you the proposed to My Module Info, it gives you the name, the description, dependencies, package and you can just drop that in and create that .info file for your module.

The next step is we’re actually going to create the entire module because it’s nice getting the code but what about if we actually want to have this Drush command create the module for us, no reason to have to do that manually so I’ll run through this here.

Drush MB for Module Builder, my_module, we want Hook Cron … I’m going to go ahead and leave this out, I’m going to define a few here; I’m going to name it My Module, we’ll say we’ll use views as a dependency in this - - write, that’s actually going to force the module to be created.

We’re not going to use any presets, we’re going to use Cron Menu, permission, mail and any other Hooks you might want to add in there, add a quick description, help text, we’ll give it a package and you can see it does. In this case I’ve already created this so I’m just going to overwrite this, I was testing it earlier but you can see it actually does still spit out the code for you so you can copy and create it yourself but now if we go into the modules and you look and you can see that My Module has been created.

We’ll go ahead and we’ll open these files up and you can see we have our Info file that was created and we have Help, Hook Menu, Hook Permission, Hook Cron, Hook Form Alter and Hook Mail along with sample code that you can then strip out and use. You can see it use my_module to create it using for the Hooks.

So really simple and it just makes things extremely easy, you can also … let’s say you forgot … you went ahead and say you forgot a Hook that you want it to add in, after we create it we can run this command and let’s say we want to add to My Module, we want to add Hook in it, no presets, let’s see if this actually works; and so we’ll take a look; I’m not sure if this is actually going to work or not but we’ll go ahead reopen it and just see … okay in that case it does not look like that one was working.

As I said; I don’t use it too often, I use it just to get the basic starting point of the module. In some cases I just started using it a little more frequently. It’s a nice little Drush Plug-in to have especially if you are familiar which is the basic commands in just running your Module Builder with your default Hooks that you generally use when creating a module, it just saves you a lot of time, it makes things easy for you to get up and running quickly when building modules.

So go ahead and give it a try and see what you think and let me know. Thanks for watching the Daily Dose of Drupal and we’ll be back again next time.

Oct 31 2012
Oct 31

Episode Number: 

40

Learn how to add theme functions and template files to you Drupal 7 module. This episode builds upon the my_example module created in the last episode and adds in a hook_theme implementation along with simple examples on how to create a theme function and template file in your module.

In this episode you will learn:

  • How to add a hook_theme implementation to you your Drupal 7 module
  • How to add a theme function in your Drupal 7 module
  • How to create a theme template file (.tpl.php file) in your Drupal 7 module

DDoD Video: 

Oct 30 2012
Oct 30

Episode Number: 

39

Printing out straight HTML in your custom modules was so Drupal 6. Learn all about Renderable Arrays in Drupal 7 to make your Drupal 7 pages even more flexible.

In this episode you will learn:

  • The basics of Drupal 7 Renderable Arrays
  • How to implement a simple Renderable Array Drupal 7 example

DDoD Video: 

Oct 08 2012
Oct 08

Posted Oct 8, 2012 // 0 comments

In the Drupal community, you see caching discussions related to pages, blocks, reverse-proxies, opcodes, and everything in between. These are often tied to render- and database-intensive optimizations to decrease the load on a server and increase throughput. However, there is another form of caching that can have a huge impact on your site’s performance – module level data caching. This article explores Drupal 7 core caching mechanisms that modules can take advantage of.

When?

Not all modules require data caching, and in some cases due to “real-time” requirements it might not be an option. However, here are some questions to ask yourself to determine if module-level data caching can help you out:

  • Does the module make queries to an external data provider (e.g. web service API) that returns large datasets?
  • If the module pulls data from an external source, is it a slow or unreliable connection?
  • If calling a web service, are there limits to the number of calls the module can make (hourly, daily, monthly, etc.)? Also, if it is a pay service, is it a variable cost based on number of calls?
  • Does the hosting provider have penalties for large amounts of inbound data?
  • Does the data my module handles require significant processing (e.g. heavy XML parsing)?
  • Is the data the module loads from an external source relatively stable and not change rapidly?

If you answered, “yes,” to more than a third of the questions above, module-level data caching can probably help your module’s performance by providing the following features:

  • Decrease external bandwidth
  • Decrease page load times
  • Reduce load on the site’s server
  • Provide reliable data services

Where?

OK, so you’ve decided your module could probably benefit from some form of module-level data caching. The next thing to determine is where to store it. You can always use some form of file-based caching, but to implement that with the proper abstractions to run on a variety of servers requires calls through the Drupal core File APIs, which can be a bit convoluted at times. File-based caching mechanisms also cannot take advantage of scalable performance solutions like memcache or multiple database server configurations that might be changed at any time.

Luckily, Drupal core provides a cache mechanism available to any module using the cache_get and cache_set functions, fully documented on http://api.drupal.org:

<?php
cache_get
($cid, $bin = 'cache')
cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT)
?>

By default, these functions will work with the core cache bin called simply “cache.” This is the main dumping ground for Drupal core for data that can persist in the system for a length of time beyond the one page call, and are not tied to a session. However, many modules define their own cache bins so they can provide their own cache management processes. A few core module ones are:

  • cache_block
  • cache_field
  • cache_filter
  • cache_form
  • cache_menu
  • cache_page

Seeing as how several core Drupal modules implement their own cache bins, the next questions for your new module are:

  • Does the module need to manage its cache in a manner that is not consistent with the main cache bin?
  • Will its cache need to be flushed independently of the main cache at any time, or have some other expiration logic assigned to it that falls outside of the core cron cache clear calls?

If the answer to either of these questions is, “yes,” then a dedicated cache bin is probably a wise idea.

Cache bin management is abstracted in the Drupal system via classes implementing DrupalCacheInterface. The core codebase provides a default database-driven cache mechanism via DrupalDatabaseCache that is used for any cache bin type that has not been overridden with a custom class (see the documentation on DrupalCacheInterface for details on how to do that) and has a table in the database named the same as the bin. This table conforms to the same schema as the core cache tables. For reference, this is the core cache table schema in MySQL that we will use as the base for our module’s cache bin:

+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| cid        | varchar(255) | NO   | PRI |         |       |
| data       | longblob     | YES  |     | NULL    |       |
| expire     | int(11)      | NO   | MUL | 0       |       |
| created    | int(11)      | NO   |     | 0       |       |
| serialized | smallint(6)  | NO   |     | 0       |       |
+------------+--------------+------+-----+---------+-------+

How?

For the sake of simplicity, we will assume that our module is fine with using the default cache mechanism and database schema. As an exercise, we will also assume that we meet the criteria for defining our own cache bin so we can explore all the hooks required to implement a complete custom bin leveraging the default cache implementation. The sample module is called cachemod, and the cache bin name is cache_cachemod.

Define the cache bin schema

In order to add a table with the correct schema to the system, we borrow from some code found in the block module that copies the schema from the core cache table and add this to our install hooks in cachemod.install:

<?php
/**
* Implements hook_schema
*/
function cachemod_schema() {
 
// Create new cache table using core cache schema
 
$schema['cache_cachemod'] = drupal_get_schema_unprocessed('system', 'cache');
 
$schema['cache_cachemod']['description'] = 'Cache bin for the cachemod module';  return $schema;
}
?>

Now that we have defined a table for our cache bin that replicates the schema of the core cache table, we can make basic set and get calls using the following:

<?php
cache_get
($cid, 'cache_cachemod');
cache_set($cid, $data, 'cache_cachemod');
?>

Using our new cache bin

Notice the CID (cache ID) parameter. This will need to be unique to the data being stored, so in the case of something like a web service, the CID might be built from the arguments being passed to the service and the data will be the returned data. One way to abstract this so you get consistent CID values for calls to cache_get and cache_set is to build a helper function. This sample assumes our service call takes an array of key-value pairs:

<?php
/**
* Util function to generate cid from service call args
*/
function _cachemod_cid($args) {
 
// Make sure we have a valid set of args
 
if (empty($args)) {
    return
NULL;
  } 
// Make sure we are consistently operating on an array
 
If (!is_array($args)) {
   
$args = array($args);
  } 
// Sort the array by key, serialize it, and calc the hash
 
ksort($args);
 
$cid = md5(serialize($args));
  return
$cid;
}
?>

Now we can implement a basic public web service function leveraging our cache like this:

<?php
/**
* Public function to execute web service call
*/
function cachemod_call($args) {
 
// Create our cid from args
 
$cid = _cachemod_cid($args);  // See if we have cached data already
 
$data = cache_get($cid, 'cache_cachemod')
  if (!
$data) {
   
// No such luck, go try to pull it from the web service
   
$data = _cachemod_call_service($args);
    if (
$data) {
     
// Great, we have data!  Store it off in the cache
     
cache_set($cid, $data, 'cache_cachemod');
    }
  }  return
$data;
}
?>

Note that there are several values for the optional expire parameter to the cache_set call that are fully documented in the API docs.

Hooking into the core cache management system

If you want your module’s cache bin to clear out when Drupal executes a cache wipe during cron runs or a general cache_clear_all, set the expire parameter in your cache_set call above to either CACHE_TEMPORARY or a Unix timestamp to expire after, and add the following hook to your module:

<?php
/**
* Implements hook_flush_caches
*/
function cachemod_flush_caches() {
 
$bins = array('cache_cachemod');
  return
$bins;
}
?>

This will add your cache bin to the list of bins that Drupal’s cron task will empty.

Additionally, if you would like to add your cache bin to the list of caches that drush can selectively clear, add the following to your module in a file named cachemod.drush.inc:

<?php
// Implements hook_drush_cache_clear
function cachemod_drush_cache_clear(&$types) {
 
$types['cachemod'] = '_cachemod_cache_clear';
}
// Util function to clear the cachemod bin
function _cachemod_cache_clear() {
 
cache_clear_all('*', 'cache_cachemod', true);
}
?>

Note that if you set the expiration of the cache item to CACHE_PERMANENT (the default), only an explicit call to cache_clear_all with the item’s CID will remove it from the cache.

Conclusion

Sometimes it makes sense to have a module cache data for its own use, and even possibly in its own cache bin to maintain a finer-grained control of the data and cache management if something beyond the core cache management is required. Utilizing the cache abstraction built into Drupal 7 core and some custom classes, hooks, and drush callbacks can give your module a range of options for reducing data calls, processing overhead, and bandwidth consumption. For more detailed info, check out the API pages at http://api.drupal.org for the functions, classes and hooks mentioned above.

As a Senior Developer at Phase2, Robert Bates is able to pursue his interests in solving complex multi-tier integration challenges with elegant solutions. He has experience not only in traditional web programming languages such as PHP and ...

Oct 05 2012
Oct 05

Episode Number: 

22

Continued from the last episode of the Daily Dose of Drupal, this episode continues Drupal 7 module development work with the Database API to pull data from the database and display it on a page.

In this episode you will learn:

  • How to pull data from the Drupal database using the Drupal 7 db_query function
  • How to use db_select and the Database API's dynamic query building to pull data from the database
  • How to display data using a theme function to output data as a table
  • How to sanitize user entered data for display using the Drupal check_plain and check_markup functions

DDoD Video: 

Oct 03 2012
Oct 03

Episode Number: 

21

This episode works off the the previous episode to create a custom Drupal 7 form using the Drupal Form API, and then looks at how to submit data from the Drupal form into a Drupal database table.

In this episode you will learn:

  • How to use hook_menu, hook_permission, and drupal_get_form to create a custom Drupal form page
  • How to create a custom Drupal 7 form using the Drupal Form API
  • How to add a validation function to the Drupal 7 form
  • How to add a submit function the Drupal 7 form
  • How to insert form data into a database table using the Drupal 7 Database API

DDoD Video: 

Oct 02 2012
Oct 02

Episode Number: 

20

In this example we create a new Drupal 7 module with the purpose of creating a database table inside our Drupal 7 module. We look at hook_schema and the Drupal Schema API to create a new database table.

In this episode you will learn:

  • How to create a Drupal 7 module with an .install file
  • What hook_install, hook_uninstall, and other various installation hooks do inside your .install file
  • How to implement hook_schema in your Drupal 7 module
  • How to use the Schema API for create Drupal database tables

DDoD Video: 

Oct 02 2012
Oct 02

Episode Number: 

19

This continues on the module we started last time and shows how to implement hook_cron to run periodic tasks on your Drupal website. Also goes over hook_mail and the drupal_mail function for creating and sending email messages within your Drupal 7 module.

In this episode you will learn:

  • How to implement hook_cron in a Drupal 7 module
  • How to implement hook_mail to set up email messages in your Drupal 7 module
  • How to trigger the sending of email in a Drupal 7 module with the drupal_mail function
  • How to retrieve Drupal variables using the Drupal variable_get function

DDoD Video: 

Oct 02 2012
Oct 02

Episode Number: 

19

This continues on the module we started last time and shows how to implement hook_cron to run periodic tasks on your Drupal website. Also goes over hook_mail and the drupal_mail function for creating and sending email messages within your Drupal 7 module.

In this episode you will learn:

  • How to implement hook_cron in a Drupal 7 module
  • How to implement hook_mail to set up email messages in your Drupal 7 module
  • How to trigger the sending of email in a Drupal 7 module with the drupal_mail function
  • How to retrieve Drupal variables using the Drupal variable_get function

DDoD Video: 

Sep 28 2012
Sep 28

Welcome to another Daily Dose of Drupal, this is Episode Number 18. Today we’re going to continue on our Drupal Module Development learning and we’re going to focus on building a brand new Drupal module from scratch. This Drupal module is going to be a little bit trivial and not necessarily a practical use case I guess but it’s going to show you a couple of different things.

The module is essentially going to monitor every time that Cron is run on your Drupal site and it’s going to send you an e-mail, very simple but it’s going to go over how to build an Administration form in a Drupal module, how to use hook_cron to do things periodically on your site when Cron is run and it’s going to talk about how to send e-mails from your Drupal module.

And today’s episode we’re just going to cover the Administration form and next time we will cover hook_cron and the sending of the e-mails. So we’re going to get started; we have our test site here and inside of it we’re going to create a new module, we’re going to call this cron_monitor. Inside there I’m going to create a cron_monitor.info file and a cron_monitor.module file, I’m going to hop over to my Code Editor and open these files up and our .info file we’re going to give this a name, okay in the description we’re going to say that we want it to be 7.x module, we’ll give it a version and we’re also going to give it a configuration page and this is going to be important and I’ll show you why in a little bit but we want this configuration or administration form to be accessed to admin/config/cron_monitor, so we save this and the Info file should be good to go.

The next step is to start on the Drupal module file. So in order to do that we’ll just go ahead and open up the Page View tag; we obviously could add a little file header here but I’m just going to start with implementing hook_menu.

So we’re going to come out with documentation for hook_menu for Drupal 7 and just like last time we’re going to go ahead and grab a copy of … an example of hook_menu to get it started and if you also come back to hook_menu documentation you can see down a ways.

They have an example of setting up an administration configuration page or series of configuration pages with the multiple tabs. So this is important if you want to create or if you need to configure multiple different types of things inside one module. We’re only going to care about this first one here because we don’t need multiple administration pages in our example, we’re going to change the Hook part to cron_monitor which is the name of our module, we’re going to create the URL at admin/config/cron_monitor which of course should match up with this.
The title is going to be Cron Monitor Settings, we’re going to give it a Page Callback and in this example we’re going to be creating an administration form. The Page Callback for that is drupal_get_form and you can read about that here in the API documentation. It basically takes a form ID as the parameter and it will go ahead and it will give you that form.

So you can read about that on the api.drupal.org site and we need to pass in the form ID or the function name for that form as an argument, we can call this whatever we want; I’m going to call it Cron Monitor Admin Form and then we also need to give it an Access Argument.

In this case we’re going to create our own permission called Administer Cron Monitor. So in order to create our own permission just like we did in a previous episode of Daily Dose of Drupal we look up hook_permission, we can come down here and just copy this code over, replace Hook with cron_monitor.

We want this to be the same as what we listed down here below so Administer Cron Monitor, give it a title and we can give it a description Perform Administration Task for Cron Monitor. Now that we have that set up; been pretty basic so far, nothing really new but this is where it get’s a little interesting.
For now we’re going to create our form function and this is going to be pulled right here from the argument that we’re passing in to Drupal Get Form. In the first parameter it’s going to be a Form Variable and the second parameter is going to be form_state and the form_state is always going to be passed by reference you want to make sure that that is there and your Form Variable is going to be pass into that so that’s where you can add your Form Items.

We’re going to … at the end of this; Return system_settings_form and pass in our Form Variable and I’ll go through what some of this is going to mean. The first thing is the Drupal Form API; if you’re not familiar with it and you want to learn to build Drupal modules you will want to take a look at the Form API Quick Start Guide for creating forms and also the Form API Reference Guide which is probably something you’ll either should keep handy or bookmark or maybe even memorize it … I don’t know if I go that far but you get the picture.

It’s very important and it will help you anytime you need to build Forms, Alter Forms inside your Drupal module. So the first thing that we’re going to do is in our Administration Form we want two things; we want a checkbox to either turn the monitoring on or off and we also want the message that can be sent with each e-mail that’s going to get triggered, we’re going to create two Form Fields for that; the first one is going to be the Checkbox and the next one is going to be a Text area.

Because it’s an administration settings page we’re going to make use of the Drupal Variables table so there are few variable functions that will write and read information from that Drupal Variables Database Table. The first thing we’re going to do is click on checkbox here; it’s going to give you a little example of a Checkbox Form Item. Go ahead and copy that in just to give us a good starting point, here we give it a name and this should … in an Admin Form corresponds to what you want to call your Variable. We’re going to call your Variable cron_monitor_enable.
It’s a checkbox and we want the title to be Enable Cron Monitor, we also need to now add a default value and this is where the variable Table and Variable functions are going to come in. We do a variable_get which you can read the documentation right here, it’s going to return a Variable and we go ahead and do cron_monitor_enable because that’s what we want to call our Variable, this is how it’s going to be stored in the Variable’s table and next we give it a default as you can see here.

This is what the variable is going to default … it’s the default value that use a variable has never been set so this is brand new. We want to default this to 0 which is going to be disabled, we could default it to one which would default it to enabled but in this case we’ll default it to 0. And the reason we … the system_settings_form; let’s take a look at that; System Settings Form is great for Administration Forms, it goes ahead and it adds a default buttons to a form, it sets it’s prefix and it does … a lot of the standard stuff that you’d have to do on a typical Drupal Form. In this case it’s an Administration Form, it’s relatively straight forward.

All we want to do is when you click the Save button we wanted to go to this variable, that’s in the Variable’s table and write out the value depending on if we check the box or we don’t check the box. The next time you refresh the Form page it’s going to load the default value. So if everything goes through it and it’s set then it’s going to go ahead and pull out the current state of that checkbox, so we’ll save this, we’ll come to our test site now, click on the module’s page and search for Cron Monitor, you can see that it’s down here; notice that there’s nothing here for operations, has our description, everything looks good, we’re going to save this.

Now if you come back to Cron Monitor you can see there’s the Permission’s page and the Configure option and this is Configure option is courtesy of this line that we put in our Info file so that’s why that is important to just make it easy to get to the Administration page, you’ll notice we now have a checkbox, notice how it defaults to Unchecked which is 0, if we check it then hit Save; it says the Configuration Options have been saved and now notice that it’s checked.

I can come back to this page and refresh and it’s still going to be check so it’s perfect. We’re almost done; the only thing that we’re going to do left … the only thing we have left to is we’re going to go ahead and add a Text area and do the same thing; as you can see we have a Text area here; this is an example, we’re just going to pull through the same as we did before, we’ll drop this in right after our enable checkbox here, you got to do a little bit of clean up and we’re not going to need this longer descriptions so we’ll go ahead and bring that down and the default value is of course going to change.

So let’s start with what we’re going to save this as a Variable. We’re going to save this Cron Monitor … it’s a good rule of thumb to use the module name of your module in the Variable and the actual Variable name.

So we’re going to do cron_monitor_email_text or it could be whatever we want. Type as a Text area and then we have to set our default value which we’re going to take the same idea from up here and apply it down here, we’re going to change this to our variable name which is e-mail text and instead of defaulting to 0 we’re going to default it to an empty string, and go ahead and save this, if we come back to our administration page you’ll see we now have a text area, has our title on it, has our description, notice there’s nothing in here by default, we enter some text here, hit Save and you’ll notice that the text is still there and that’s it, we now have the Administration Form on our Drupal site that is setting variables in the Drupal Variable Database Table and if you have the ability to look at the database I urge you to do that, look at how these values are stored, they’re stored in a serialized PHP Variable.

So it’s a little bit different, it’s going to look a little odd when the first time you look at it but it’s a good idea to just to take a look at how these … how your actions in code actually affect the Database. So that’s it for this time, next time we’ll cover hook_cron and how to send e-mail from your Drupal module, until next time, thanks for watching the Daily Dose of Drupal.

Sep 28 2012
Sep 28

Welcome to another Daily Dose of Drupal, this is Shane and this Episode number 17. Today we’re going to be continuing on the Drupal 7 Module Development basics we went over yesterday and looking at hook_menu and hook_permission or Hooks for Drupal and of course we have our Drupal 7 module here, yesterday we created called My Block.

If you did not follow along with yesterday’s example you may want to go back and look at that or if you have any custom module or you’re familiar with creating at least the basics of a custom module you can go ahead and do that and you can probably follow along without much difficulty.

So hook_menu; what is it and why do we need to use it? Anytime you want to define a Menu Item or a Page Callback inside your Drupal module you’ll need to use hook_menu. This is important for Administration Pages for example or if you have a custom form that you want to build on a custom page and you’ll use this for Ajax Callbacks potentially depending on how you set it up of course or any type of … any setting where you need to access something or some resource from your website from a specific URL.

So for instance if I want to get to a specific URL on a page and I don’t want to use the traditional Content Type to do that I can define something in a Custom Drupal Module and it’s really pretty basic and pretty straight forward but there’s a couple of caveats to hook_menu. A couple of things that you’re going to need is an example; we’ll go ahead and just grab this very first example here; so if we go ahead and inside of our module I’m just going to drop it at the top, add my comment to it and fix the indenting a little bit and let’s go over on what this is doing. In this case we’re defining a URL structure of ABC/DEF and we’re making a Page Callback call to this function so this would be a function we’re going to need to define and we can pass in specific arguments.

For this example; we’re not going to be passing any arguments into our functions so we’re going to get rid of that, we’re going to give it a title which is the actual title of our page, we’ll just call this My Page, for the URL we’re going to access it through My Page, I’ll lower case and for the Page Callback we’ll use myblock_mypage and keep in mind that myblock is just the name of my module so I of course have to change that here and obviously it might not be the best name in this case but this could be whatever your module name is and so generally you’d want to name your functions that you’re creating with myblock or your module name whatever it is, Underscore something so you’ll know how to … where it’s at and how to access that Callback function.

You can define specific types of Menu Items and I encourage you to read the documentation on drupal.org for hook_menu because it’s going to tell you what these different types means … what these different types of menu of definitions mean, Menu normal item, Menu Callback is one that get’s use often.

If you want to integrate within the Drupal Tab system you can have local tasks and a whole bunch of other things and these are defined right down here, talks about Menu Normal Item, Menu Default Local Task, Menu Local Task and it gives you an example that you can take in and use for how that can be useful.
Inside hook_menu on api.drupal.org you’ll see it talks about all the different things that you can add into this array for the specific Menu Item, there’s Title, Title Callback and on down the list. The other one we’re going to look at and you can see there’s a whole bunch … not all of them get used that often but there’s a lot of things there.

The other thing we’re going to add is access argument and you can define a simple array here that’s going to look at the permissions of the current user and see if they have this permission. In this case we’re going to say “can they access content on the website?” So we’re going to go ahead and open up another browser here, get all of this stuff and go to the test website.

So now I’m logged in as anonymous user and as the admin user. So before I can see this page I have to actually create that function, add a simple description there and notice since we didn’t have any page arguments, this is going to be empty. If we had Page Arguments we would have variables in there and here you can just return any HTML you want to be rendered on your page. In this case we’re just going to output some very simple HTML, also we’ll be focusing in a future episode on renderable arrays as that’s kind of the … a new way you should be doing it in Drupal 7 but to keep things simple we’re just going to output straight HTML here. Now if we save this and we come up here to My Page you’ll notice it is not going to work.

You’ll see the requested page cannot be found. The trick here is anytime you change something at hook_menu you need to clear out the Menu cache so I’m going to do this through Drush and in this case the selection is 3, you can also go to Configuration → Performance and clear the cache that way.

Now if I come back to this page you’ll see that I’m able to get to my page, I had this block here which I’m just going to come to my blocks and hide that for now since just kind of getting in the way and now if I come back you can see the title is My Page, it’s also up here and there is my text.

So very simple, the only other thing we’re going to do is implement hook_permission to create our own Permission. And we will go ahead and copy this simple example here, I’m going to paste this at the top, there’s really no specific order you have to implement these Hooks in, it’s more or less however you see it fit but there’s … I have a kind of a general order that I follow for the most part but as long as you’re consistent across your modules that will be easy for you to go ahead and find out or easily locate these different functions.
So I replaced the Hook Text with the name of my module and we get to define our permissions so I’m going to say “access mypage” you can give it a title. So you can give it a title on the Description and that’s all really all there is to it. We can go ahead and save this and obviously you can have multiple here, you can add another one right below here and define a bunch of permissions inside of your module, we’re going to define the 1 and now if we come back here and we go to People and Permissions you’ll notice that if we search for My Page and My Block module there’s now a Permission called Access MyPage.

If we don’t want to go back to this My Page you’ll noticed that it still works because I’m logged in as user 1and make sure of course to actually change the Access Argument here to use your new Permission. Before I forget; so access My Page. Let’s save it and hop over to Drush to clear the Menu cache again I changed that menu Item so I need to make sure that I clear the cache, if I refresh I’m still able to access because I’m logged in as user 1. However; I come over here and I am not logged in I get an Access Denied.

Lets’ go ahead and change that so anonymous users can access that page; we come in to Permissions, find the Permission and we’re going to give access to anonymous and authenticated users, scroll all the way down to the bottom, hit Save. Now if I hop back over here and refresh I can get to the page.

As simple as that. Obviously there’s a lot more to hook_menu and I just encourage you look over that documentation on api.drupal.org on hook_menu as that will be very valuable when you’re trying to learn all the in’s and out’s of what you can do. That’s it for this time; tomorrow we’re probably going to focus on some more Drupal Module Development Hooks and just a little work away through most of the basics.

So if you have any questions or if you want to see anything specific on future episode of the Daily Dose of Drupal go ahead and contact me via Twitter or on codekarate.com, follow me @smthomas3 or sign up for my codekarate.com newsletter. Thanks for watching the Daily Dose of Drupal.

Sep 27 2012
Sep 27

This is Shane with another episode of the Daily Dose of Drupal, this is Episode 16 and this is brought to you by codekarate.com. Today we’re going to do something a little bit different and we’re going to look at some Drupal 7 module development basics.

I’m going to go through the very basics of building your own module and in this example all we’re going to do is build a simple module from scratch that outputs a Custom Block right in here somewhere and this Custom Block right now will just be Static Content but you’ll learn going through this video the basics of what is involved in creating a Drupal module and how it can be use to extend the functionality of your Drupal website and we’re doing this is Drupal 7.

I have a Drupal 7 test site up right now with just some basic content and a few Content Types and other modules installed but one of the things that you’re first going to have to do is when creating a Drupal 7 module is you’re going to have to come in to your Module’s directory which I have up here and we’re going to create a new folder; I’m just going to call this myblock because I’m just going to create a simple Block in this module.

So now I have folder called myblock and generally the folder name is the same as whatever module file name you’re going to have, it doesn’t have to be and we’re going to create an empty file called myblock.module and we’re also going to create an empty file called myblock.info. The Info file is basically … you can think of it as a configuration file. It tells Drupal about your module and it gives Drupal the information that needs to know in order to install the module onto the Drupal website.

Everything in the .module file is the code that actually runs that module and if you look at other modules and that may have download there can be ton of other files in here but this is the structure of what you’ll need to create a module and we will go ahead and open this up now; we just have this empty files here, go ahead and I’ll open this up and we’ll start with the Info file.

The first thing you’ll need is a name; we’re just going to call it My Block module, you can then add description if you want; the Core is the version of Drupal you’re using; in this case it’s a Drupal 7 site. You can specify a minimum PHP version that’s required for your module; in this case I’ll put 5.2.4, you can specify a version of your module; so for instance you may start at 7.x-1.0 and the next time you make a change you can change at to 7.x-1.1 and go up increment a leap from there, you can also add dependencies of other modules that you may need.
So let’s say we also needed the Date module; we could add that there just like that or if you needed the ctools module or the Views module you would add the Dependencies just like that. I’ll go ahead and leave that out because it’s not really required for this very simple module. So I’ll save that and now I have an Info file.
For the myblock.module file we’re just going to start out with a simple file header and this is just a comment that I like to do at the top of my files that basically can be use with certain different documentations, systems like doxygen or other things and it can actually load in some information about your module if you use a system like that but you can also add a description up here or just leave it out if you don’t need it.

Now once we got this far; the next step is learning how to interact with the Drupal API and Drupal is set up to be extremely flexible; it’s set up with something called Hooks which are basically functions that you can implement in your module to interact with the Drupal website.

So this could be interacting by adding a page on your site using a hook called hook_menu or it could be running something periodically on your site, maybe it’s a process that has to run every so often, you could use something called hook_cron for that but one of the things that’s going to be invaluable along with just the standard Drupal documentation which you can find on drupal.org is the api.drupal.org website and I pulled up two hooks here that’s going to let us create this Custom Block.

The first one is hook_block_info, you can read about it here but it allows you to define blocks within your module and that is essentially what we need to do is define a block within our new module. So you can see down here there’s always some example code; when you first start you maybe want to just grab this code, copy it and paste it in and the first thing we’re going to do with this hook_block_info function is change the word hook to myblock because that is the name of your module; it’s myblock.module so you’ll change Hook to My Block.

In this example; in this myblock.info function there’s two block examples that are defined; the first on is called Syndicate; tells you the information about it and then it tells you that it’s going to use the cache called Drupal_No_Cache which in this case isn’t going to cache the block and this one there is no cache so Drupal cache per role is assumed which means that the caching is based on the user’s role on the site. We’ll go ahead and not worry about caching right now; this is just a really simple example so let’s get rid of this and we’re going to call this My Block and for the Info we will do My Custom Block, we’ll save this and now we should have everything we need to at least install the Drupal module and get started.

So we’ll come over to Modules page, scroll down into the Other section, you’ll see the Other fieldset and we’ll click on My Block Module which is what we created, here’s the description, here’s the version that we said that we wanted to use and you’ll see that there’s a whole bunch of different field sets for different types of modules and you can define where your module falls using package, defining the package in the Info file.

In this case we didn’t define one so it defaults to falling into the Other Fieldset on the Modules page, we’ll go ahead and save this, and now that it is saved we’ll come over to Structure, click on Blocks. If we scroll all the way down to bottom we’ll be able to see My Custom Block somewhere in there, here it is; we’re going to go ahead and in my case I’m going to add it to my sidebar first and I’ll go ahead and I’ll drop it all the way at the top and I will click Save.

Now if I go to Homepage I still don’t see anything. That’s because we just defined the Block, we haven’t actually told the block what to display yet. So in order to display what should be viewed for that Block you need to define hook_block_view and you can of course read the information here about hook_block_view but what I’m going to do is I’m going to copy this in; so I’m going to take the example code and I will droop it right into our .module file, of course change Hook to the name of our Module so I’ll call it myblock and you’ll see there’s one parameter here and the parameter is Delta and what that’s going to do is this function is going to be called and the Delta value is going to be passed in; so if I have 3 or 4 different custom Drupal blocks one called My Block1, My Block2, My Block3, however I wanted to call that then when My Block 1 needed to be rendered it would pass in with a Delta value of My Block 1.

So in this case you’ll see we do a switch statement on that Delta value. All we care about is My Block, in this case we don’t really care about anything else because our module doesn’t define the others but if you have other blocks you would of course add additional case statements to this Switch Statement.

So if it’s My Block we have a subject of … we’ll call it this is my custom block for this subject and what you’ll see here for the content; this is an array and what this is called is this is a renderable array. Basically; Drupal knows how to render this. What Drupal is going to do is it’s going to call a specific theme function, you can give it a specific title but in this example we don’t really want to go into all of the details of the renderable array so we’ll leave that for another episode.

You can also go ahead just define a straight … string of HTML here. The preferred way is of course to use that renderable array but for this example we’re just going to go through it with just HTML. So if we save that now and we come over to our page, refresh, you’ll see our custom block now shows up.

One thing to keep in mind with this; this is example is just creating basic content within the block. So if that’s all you needed to do you can easily come into structure in the blocks and add a custom block this way but the reason I’m going through it building a custom module is because there maybe times when you need to be able to deploy the block in multiple sites and having in the module that makes it easier or being able to have the block in code or there maybe more things like a form or a view or like something else inside of the block that you need to actually customized.

In this case of course we’re just going through this simple example. One thing I’m going to do is I’m going to add some simple comments here; generally when you’re building a module file you want to tell anyone who’d be reading it what Hook this implements. So if you’re reading it later or someone else is reading it or you need to quickly search through your module you would be able to determine which hook functions you’re implementing.

So that’s generally the standard; it just implements whatever the function name for the hook you’re implementing and it ended with a period. So we’ll save that and I’ll show you now that you can add some HTML in here, now if we save that and refresh you can see it’s now changed, you can see that the HTML is taking effect and we have a custom block that we can now turn on on any site and to drop it into any different section inside of our blocks that we want and everything will work out great. You’ve created your first Drupal module.

So that’s all there is this time, now next time we’ll be going over different topic, hopefully you learn a little bit about building and developing a custom module in Drupal and how you can create a custom block within that module. Until next time, this is Shane with the Daily Dose of Drupal; you can follow me on Twitter @smthomas3, thanks for watching.

Sep 26 2012
Sep 26

If you need to make price increases when specific attributes or options are selected on products, hook_cart_item() may be able to help you out.

My Drupal 6 Ubercart Dilemma

In a recent situation I needed to create an attribute that contained a price. The trick here is that the price increase needed to be added based on the value selected in another corresponding attribute.

In this example I had one Drupal 6 Ubercart select attribute that was essentially serving the role of a quantity option (I had the traditional Ubercart quantity field disabled). The reason this was set up this way was because this product basically came in packages of select quantities. So the Ubercart attribute had dropdown options of lets say 10, 25, 50, 100, etc.

I had another Ubercart attribute that was created as a single checkbox with a price increase of $0.50. The trick here, was this price increase needed to be based on the quantity dropdown of the number of items in the package.

Drupal Ubercart Attribute Example

This might be a little confusing so I will try to explain it in an example.

  • User goes to the product page
  • User selects quantity if 25, the price of this is $50
  • User selects the single checkbox to trigger the $0.50 price increase per item, the price is now $62.50 ($0.50 x 25 items in the package plus the original $50)

The hook_cart_item implementation

In this example I am just using hard-coded attribute values and option values. Keep in mind this should probably be avoided if possible, but because this was such a unique situation that only occurred for these attributes, I used the hard-coded values for simplicity. This could easily be abstracted into a separate module with an administration interface.

/**
 * Implements hook_cart_item().
 */
function MYMODULE_cart_item($op, &$item) {
  switch ($op) {
    // We only care about the "load" operation, in which a cart item is 
    // being loaded.
    case 'load':
 
      // Here is where I set the hard-coded values for the attribute 
      // and option ids. These values can be pulled from the 
      // Ubercart attribute database tables or from the URLS in the 
      // Ubercart attribute administration pages.
      $quantity_aid = 13;
      $checkbox_aid = 12;
      $checkbox_oid = 50;
 
      // A variable to keep track of the price increases.
      $price_increase = 0;
 
      // Add price increases for my attribute (aid=12, oid=50).
      if (isset($item->data['attributes'][$checkbox_aid][$checkbox_oid])) {
        // Load the attribute so we can determine the price per item that 
        // should be added.
	$checkbox_attr = uc_attribute_load($checkbox_aid);
 
        // Pull the price value (in this case $0.50) from the attribute.
	$price = $checkbox_attr->options[$checkbox_oid]->price;
 
        // Check if the quantity attribute has a selected option value.
        if (is_numeric($item->data['attributes'][$quantity_aid])) {
          $oid = $item->data['attributes'][$quantity_aid];
 
          // Load the attribute so we can pull out the quantity value of 
          // the dropdown.
          $attribute = uc_attribute_load($quantity_aid);
          $quantity = $attribute->options[$oid]->name;
 
          // Make sure the quantity is in fact a numeric value.
          if (is_numeric($quantity)) {
            $price_increase += $price * $quantity;
 
            // Because Ubercart will automatically add the original 
            // attribute price to the total, we need to then subtract out 
            // the original added price.
            $price_increase -= $price;
          }
        }
      }
 
      // Add the price increase to the cart item.
      $item->price += $price_increase;
      break;
  }
}

In the example above, you will need to replace the attribute ids (aid's) and the option id (oid) based on your attributes. You will also need to replace "MYMODULE" with the name of the module you are placing this code in.

Hope this helps someone in a similar situation. If you have any questions or know of a different way to do this, let me know in the comments.

Sep 19 2012
Sep 19

To get things started, in this lesson we'll create a new module, and use hook_views_api() to let Views know we want to use its API.

Sep 12 2012
Sep 12

This lesson gives an overall summary of the entire Coding for Views series. We explain the basic knowledge that each chapter will cover and what you can expect to learn from watching this entire series.

Sep 07 2012
Sep 07

Ever need to output a Drupal 7 view in your code? If so the views_embed_view function is an easy way to do this. One thing you may not have known, is that you can also use it to pass values into your views contextual filters (what the Drupal views module used to call "arguments").

Here is a quick example of how to output a view in code using the views_embed_view function:

print views_embed_view('VIEWS_MACHINE_NAME', 'DISPLAY_ID');

You can get the VIEWS_MACHINE_NAME by going to the main views listing and hovering over the Drupal 7 View you are trying to output programmtically. This should give you a tooltip with the Views machine name.

You can get the display_id by editing that view and hovering over the tab that you want to display. In the URL that is generally displayed on the bottom left of most browser you will see something like this:

In this example, the display id is "block_2" and the machine name is "my_test_view".

If you want to send an argument into the views contextual filter, simply add another argument to the views_embed_view function.

$my_arg = 1;
print views_embed_view('my_test_view', 'block_2', $my_arg);

Side Note: If you are using a date as a contextual filter (as I was in my case), the format of the date is YYYY-MM-DD. So an example would be:

$my_date = "2012-09-07";
print views_embed_view('my_test_view', 'block_2', $my_date);

What do you think? Let me know in the comments below.

Jun 07 2012
Jun 07

Posted Jun 7, 2012 // 0 comments

For some years now, Google has been providing users, webmasters and web developers with some nice and useful web related tools. Some of them are better known than others, and some are not in use anymore. But having your site’s content translated has always been a top necessity, especially if your site targets a multicultural audience. One of Google's recently improved tools, from their content translation tools, is Website Translator. This tool’s engine is based in their Google Translator Toolkit, which uses translation memory (TM) to significantly improve the quality of the translation. It also provides a way to manage your own set of translation content.

When you are a Drupal site manager and/or developer, having a quick way of providing the visiting user with a preset of available languages and quality translations is always a plus. For this reason, we wrote this small module to allow Drupal web administrators to quickly set and customize Google’s website translator in their systems. The module essentially provides an administration UI to define certain parameters needed to build the javascript code that, otherwise would have to be regenerated every time a change was needed. See below a sample screenshot of an admin UI:

Once your configuration is ready, the administrator user can expose the language selector through a menu link . Setting up the menu link is as easy as adding a new link item to one of the site’s menus and setting it's path to: <google-translate>. Once the page is rendered the module’s javascript part will take care of inserting all the code needed to achieve the proper behavior and presentation. We considered other ways of presenting the language selector, but we decided to use a menu link to allow site administrator to optionally expose a disclaimer dialog to the visitor. In this way it could be used to, for example: warn the visitor that the translation services provided were not originated by the site itself, rather that it is a third party service. You can disable this functionality by leaving the disclaimer textarea option in blank in the administration UI.

Using this tool has several advantages. For one, the quality of the translation, I can speak for the spanish versions I’ve seen, they are pretty accurate and refreshingly not “robot-ish”, and that’s one of the other advantages: the use of the translation memories (TM), that allows for more fine tuned translations. Another advantage is the replacement of text happens really fast, of course this depend on the amount of text to process, and the client computing power, but with today’s equipment it should provide an instant seamless translated version. Although the module is in use in a couple of sites now, it is still a sandbox in drupal.org @ http://drupal.org/sandbox/fxarte/1473726 If you like it and find any issues or think a new feature may be a good addition please go to its issue queue.

Felix Silberstein, developer, has been doing software development since high school (a common refrain among Phase2 developers)! And for the last 4 years, Felix has been focusing his attention on developing his capabilities in Drupal and ...

Apr 30 2012
Apr 30

I often get asked what is the best way to go about learning Drupal or the best way to get started with website development. Because of these questions, I decided to put together a list of things I wish I would have done first, when I started to teach myself Drupal.

Learning Drupal Tip #1 - Getting Started

The first step to getting started with Drupal is to first figure out where you are at. If you are a web developer transitioning from another CMS or system like Wordpress, Joomla, etc, you will probably need to start in a different place than someone completely new to the subject.

You also need to do a little self reflection and figure out how you learn best. There are many methods to learning Drupal, and you will need to figure out what works best for you. This may be in the form of reading books, watching videos, or through trial and error (which is probably the way to learn the quickest).

Learning Drupal Tip #2 - Drupal.org

No matter how you decide you want to learn Drupal, you should definitely start with setting up an account on http://drupal.org. There are many pages on Drupal.org that will help you get started. The Drupal documentation page is a good starting point.

You may also want to look into IRC or the Drupal forums as a possibility to get quick support if you get stuck on something. Sometimes it is good to know you are not fighting the Drupal learning curve alone.

Learing Drupal Tip #3 - Videos

If learning by watching is your preferred learning method, here are some links that you may want to look into.

  • Daily Dose of Drupal - This is a self promotion for my Daily Dose of Drupal videos. I record a Drupal related video based on a variety of Drupal topics every weekday and post it here.
  • Drupalize.me - This is a great starting point for learning Drupal. I was a subscriber in the past and Lullabot puts together some well produced videos to help you get started in all aspects of Drupal website development.
  • Learn By The Drop - This is another place with some good videos for learning Drupal. They have a good free video series, as well as a video on installing Drupal 7.
  • Mustardseed Media Podcast - I was an avid viewer of the Mustardseed Media Podcast when I first started learning Drupal. The videos really provide an in depth look at various modules you can use to help you in developing Drupal websites.
  • Drupal Therapy - Another site with some good quality screencasts
  • Youtube - It also never hurts to look around Youtube for videos on Drupal.
  • Sign up for the CodeKarate newsletter or subscribe to my RSS feed. I plan on adding some Drupal videos in the near future.

Learning Drupal Tip #4 - Books

I have read my fair share of Drupal books, or at least large parts of quite a few. However, most of the Drupal books I have read were for Drupal 6. I have listed some Drupal books that I liked, as well as some Drupal 7 books that I would likely purchase if I was to learn Drupal all over again.

  • Using Drupal - A great reference for those just getting started as well as experienced developers who want to brush up on their skills. Focuses mainly on building Drupal through the admin interface without the need to dive into the code.
  • Drupal's Building Blocks - Book is focused more on Drupal 6, but covers the concepts of CCK, Views, and Panels
  • Pro Drupal Development - Although I have not read this book, I have read some of the Drupal 6 version. If you are looking to build modules/themes in Drupal, this will be a great resource.

Google, Bing, DuckDuckGo, or whatever your search engine of choice may be, will definitely aid you in your Drupal learning curve. There are many blogs and websites like CodeKarate that are here to help.

Learning Drupal Tip #6 - Make your own path

Truth is, there is no "right way" to learn Drupal. There is only "your way" or the way that will work best for you. If you have questions, don't be afraid to ask for help using some of the methods above. Also, feel free to drop questions in the comments below or contact me.

Generally Drupal developers enjoy helping out when they can. One thing to keep in mind is to make sure you do adequate research about your question beforehand if you want a Drupal developer to spend the time to help you.

I know I did not hit on everything, so if you are an experienced Drupal developer, let me know what I am missing in the comments below.

Tips from the comments

  • Contributing to Drupal - If you know how to code you could consider contributing to existing projects. You can also contribute directly to Drupal core. If you are the type that is great at explaining how things work, you can always contribute documentation. There are many ways to get involved and doing so will help you climb the Drupal learning curve even faster.
Apr 06 2012
Apr 06
Lullabot logo

Lullabot has trained thousands of Drupal developers & guided the development of some of the largest Drupal websites.

Apr 06 2012
Apr 06

This screencast shows how to:

  • Invoke a Rules event
  • Send parameter data to a Rules event

This is shown by an event triggered every time a view is being rendered, sending the name of the view as a parameter.

Apr 06 2012
Apr 06

This screencast shows how to:

  • Declare a Rules event
  • Declare the data provided by the event
  • Use that data in a rule

The example used creates an event "View is being rendered", passing along information about which view is being used.

Apr 06 2012
Apr 06

This screencast shows how to create a condition plugin for Rules:

  • How to declare new conditions for Rules
  • How to provide the condition callbacks with parameters to act on
  • The big similarities and the few differences between actions and conditions

In the example, a condition is built to check which view type a provided view has.

Apr 06 2012
Apr 06
Lullabot logo

Lullabot has trained thousands of Drupal developers & guided the development of some of the largest Drupal websites.

Mar 30 2012
Mar 30
Lullabot logo

Lullabot has trained thousands of Drupal developers & guided the development of some of the largest Drupal websites.

Mar 30 2012
Mar 30

This screencast shows how to add parameters to your actions, for example to allow site builders to select which user object an action should work with.

Mar 30 2012
Mar 30
Lullabot logo

Lullabot has trained thousands of Drupal developers & guided the development of some of the largest Drupal websites.

Mar 30 2012
Mar 30

This intro chapter contains a quick presentation of the Rules module from a conceptual perspective. It includes:

  • Actions, conditions, events
  • Data types: the importance of entities, relationships and tokens
  • Lists and loops
  • Components and parameters
  • Some words about the Rules user interface

If you would like to see more about configuring Rules before continuing this series on writing code to integrate with the Rules module, you can watch the Learning the Rules Framework series.

Pages

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web