Theming a menu

Menus are a familiar fixture in Drupal. In fact, once Drupal is installed, one of the first things we do is use the menu. It looks like this If you quickly scan through the templates included in Bluemarine (or Garland, or any of the default themes), you won't find the template that generates this menu. Why not That's because it comes from a set of theming functions buried deep in Drupal's includes menu.inc file. The main menu function is menu_tree_output(), which is not actually a theming...

Search

Note the grey circle near the end of the search box. That is the location of the throbber icon. When the autocompletion AJAX script is running, the throbber icon will be displayed as a spinning circle. Let's now turn to the anonymous function that is run inside the each function .each function var newld this .attr 'id' '-autocomplete' var newElement ' lt input type hidden gt ' .addClass 'autocomplete' .attr 'id', newId .attr 'disabled','disabled' .attr 'value', SearchAutocomplete.url In a...

The Drupalt function

As with all of core Drupal JavaScript functions, this function uses the Drupal namespace. The t function is a member of the Drupal library. This function's job is to take a string and perform any translation actions on it. Here's a simple example of this In this case, the translation function would check the language database for the user's preferred language and see if there was a translation available. If there is, then the function will return the translated string. If not, then hello world...

Project weekend countdown

The project that we will create in this chapter is a simple weekend countdown tool. This will display a little piece of text that indicates the current day of the week, and then says how many days are left until the weekend. The main point of this application will be to make practical use of the translation system that we saw earlier. For that reason, we will first write some code, and then do a little translation. While we will consistently use the Drupal.t function in this book, I this is the...

Managing cookies

There are still two more functions in our CommentWatcher tool. These are CommentWatcher.getLastID and CommentWatcher.setLastID . These two functions provide a mechanism for tracking the last comment ID. This is necessary if we want our tool to only show new comments. We could store this information in a local variable. In that case, for any given page view, the user would see a comment no more than once. Let's think about a situation we would like to avoid. No new comments are posted, but the...

The Sticky Rotate functions

We are going to continue building on the frobnitz theme we created in the previous chapter. To start off, we are going to create a new JavaScript file called sticky_rotate.js. As usual, this will go in the sites all themes frobnitz directory. And once again we will have to edit the frobnitz.info file in that directory. description Table-based multi-column theme with JavaScript stylesheets all frobnitz.css scripts printer_tool.js scripts sticky_rotate.js Only that last highlighted line is new....

Creating a theme

As we saw in Chapter 1, Drupal separates layout and styling information from processing code. HTML is usually stored in templates or theme functions. The CSS along with other styling information including some images are also stored separately from the functional code. A theme is a collection of resources, usually template files, CSS, JavaScript, and images that can be plugged into Drupal to provide layout and styling to a site. If we want to change the look and feel of a site, the best place...

Ea

De natura mentis humanae quod ipsa sit notior quam corpus. Submitted by mbutcheron Sun, 08 10 2008 - 15 56 In tantas dubitationes hestern meditatione conjectus sum, ut nequeam ampli s earurn oblivisciJ nec videam tarnen qua ratione sotvendae sint sed, tanquam in profundum gurgitem ex improviso delapsus, ita turbatus sum, ut nec possim in imo pedem figere, nec enatare ad sum mum. De Us quae in dubium revocari possunt. Submitted by mbutcheron Sun, 08 10 2008 - 15 55 ' CT Animadverti jam ante...

The comment watcher

We have just configured the server to give us the information we need in order to find out what the latest comment is, using AJAX and JSON. In this section, we will develop a JavaScript tool that will use this information in order to generate comment notifications. The script will watch the JSON feed for changes. When a new comment appears in the JSON feed, the comment watcher will notify the user. To create our script, we are going to draw on our existing toolkit, using behaviors, theming, and...

The Drupaltheme function

On the server side, the PHP theming system is remarkably sophisticated. There are PHP template files, theming functions, and preprocessing functions. There is a .info file and a complex system of theme inheritance. The JavaScript side of things is considerably simpler. The drupal.js library in Drupal 6 only has two theme-related JavaScript functions Drupal.theme which is a paltry seven lines of code and Drupal.theme.prototype. placeholder with only three lines of code . As you may have guessed,...

[PACKl

This is the area that the ID identifies. But there is the additional not .ui-accordion . The ui-accordion class is added by an accordion widget. As with other behaviors, we add this extra check to ensure if the behavior is run multiple times, we won't try to repeatedly turn the left column into an accordion widget. Let's now take a look at the second part of the query The jQuery UI functions are added onto the main jQuery object we will see how to do this in our final project . So adding the...

Configuring languages

Once we have downloaded and unpacked the desired language s , we need to configure Drupal's language support to determine how to handle multiple languages. There are two steps to this process 2. Configure the global language settings. In the first step, we are going to let Drupal know about the new language. We've already installed the language, but we also need to tell Drupal that we want it to go through the process of scanning the language files and compiling a translation database. This...

The Drupalcheck Plain function and the jQuery alternative

The first function we will look at is the Drupal.checkPlain function. If you have already written some Drupal PHP code, you will probably recognize the name. The Drupal.checkPlain function takes a string and prepares it for display, escaping symbols that have a special meaning in HTML. While the use of the term check implies that this will return a Boolean value true if the text is plain, false if otherwise , it actually performs the escaping, and returns the escaped string. So what does it...

Checking capabilities with Drupaljs Enabled

The first utility we will check out is not a function. It's a property of the Drupal object Drupal.jsEnabled. This variable indicates whether or not the browser will support drupal.js and jquery.js. The name of this property is slightly misleading. It doesn't actually indicate whether JavaScript is enabled. That wouldn't be all that useful, would it If JavaScript was truly disabled, a JavaScript variable would be worthless. Instead, this flag is set to true if the requisite level of JavaScript...

The editor behavior

We will begin with the behavior Drupal.behaviors.editor . This function is called when the document is ready, as well as any time a major DOM change results in behaviors being reattached Drupal.behaviors.editor function 'textarea not .editor-processed ' .addClass 'editor-processed' .mouseup BetterEditor.watchSelection .keyup BetterEditor.watchSelection .each function item for i 0 i lt BetterEditor.buttons.length i button BetterEditor.buttons i buttons.push Drupal.theme ,button', button var bar...

Project a simple text editor

In this project we are going to create a simple text editor. We are going to begin with text areas and add a couple of buttons that insert HTML tags for us. In doing this project, we will make use of the jQuery techniques we learned in the previous chapter, as well as behaviors and some of the utility functions we saw earlier in this chapter. There are already several rich text editors available for Drupal, all of which are more advanced than the simple tool we will create here. The WYSIWYG API...

The main behavior

There is one main behavior registered for our simple editor. It learns about all of the text areas in the document and then adds editor support to those areas. This behavior illustrates the compactness that is achievable with jQuery and drupal.js. It also makes use of constructs that you are likely to see in Drupal code, such as nested anonymous functions. Since it is complex, we will walk through it carefully. Drupal.behaviors.editor function 'textarea not .editor-processed ' .addClass...

Drupals architecture

As mentioned in the previous section, almost all of the server-side Drupal code is written in PHP. Just like a complex physical structure a building or an airplane this code is organized into units, each of which does a particular job. Let's take a look at what might be called a blueprint of Drupal Let's look at the pieces in the diagram. This diagram is divided into two major components the browser and the server. The majority of Drupal's processing is done on the server. On the server side,...

Adding a block with a menu in it

The new menu and block will be added as soon as the document is loaded. This means we can start with the now familiar jQuery ready event handler document .ready function var links name 'Drupal.org', link 'http drupal.org' , name 'jQuery', link 'http jquery.com' , name 'No Link' var text Drupal.theme 'shallow_menu', links title 'JavaScript Menu', content text var block Drupal.theme 'block', blockInfo '.block first' .before block This call creates a new array of links, themes them, adds them to a...

A template system

We now have HTML templates on the server and a theming system on the client. The first step toward linking these two is to fetch the templates from the server. To do this, we are going to create a new namespace object named TplHtml. We don't want to put our custom code inside of the Drupal namespace as this code is not the official Drupal code. This new namespace will house our main template function, in addition to all of the templates that we load from the server. Here's what the code for our...

Adding Java Script to a theme

We now have a shiny new theme to work with. Let's turn our attention to incorporating our JavaScript print tool into that theme. This will require three short steps 1. Add a template that will display a Print link. 2. Make a minor adjustment to the stylesheet to make this link stand out. 3. Add the JavaScript to our page. Bluemarine already has all of the templates required for displaying Drupal. However, we want to add a link on the righthand side of the main content display that will show a...

Drupal Behaviors

In the previous chapter, we spent some time getting to know jQuery. We will now look at another library that comes bundled with Drupal. In fact, the library we will see here is Drupal-specific. The drupal.js library is composed of tools commonly used in Drupal-centred JavaScript. There are four major sets of tools in drupal.js translation functions, theming system, some utility functions, and the core code for Drupal Behaviors. In this chapter, we are going to focus on Drupal Behaviors and then...

Theming with templates

The last part of our template system is a theme function that can make use of the template. Based on the jQuery ready handler we just wrote, we now have a template stored in TplHtml.template.node. Here, we need to provide a function that will take that template and then populate it with data. To do this, we will once again use jQuery since it provides powerful tools for navigating HTML and modifying the document's structure. Here's our new function Drupal.theme.node function node var out '' Do...

Using jQuery in Drupal

So far, we have seen just a few lines of jQuery code. But, our examples have been independent of Drupal. How can we use jQuery inside of Drupal The answer is simple. If we write our JavaScript the Drupal way, then Drupal will make it very easy to use jQuery. Here's what I mean. How do we include JavaScript files in Drupal themes By using the scripts directive in the theme's .info file. And if you're a PHP programmer, you can use the drupal_add_js function in either a theme or a module. If you...

A brief introduction to closures

A closure provides a convenient way of providing a context in which we can store local variables and functions that we don't want other outside scripts to have access to. A closure basically seals-off a context for us. Inside of a closure, we can create variables and functions that would not be accessible to the outside world. However, code inside the closure can access these functions and variables. With a closure, we can hide data from outsiders, while making it available to the code inside....

Move over XML

XML has enjoyed tremendous success in the online world. Every major programming language has at least one XML parser available. PHP 5 comes with several XML tools out of the box, including a DOM. This DOM provides an interface almost identical to the JavaScript DOM API. But the DOM-XML combination isn't a panacea. Some problems even problems involving data formatting are better solved by other tools. In addition, the X in AJAX hasn't always right for the job. Sometimes, instead of getting XML,...

The search autocomplete Java Script

The last thing we need to do is create a JavaScript tool that will turn our plain old search box into an autocomplete-capable search box. We will put this code in search_autocomplete.js, the last JavaScript file that we added in our hook_init implementation. The main task of this code will be to modify the search block in order to turn it into an autocomplete function, and then let the Drupal autocomplete behavior do the requisite processing on that field. Turn the search block into an...

The addTag theme

The three theming functions, which we are about to look at, are all new in BetterEditor. We will begin with the most complex. Drupal.theme.prototype.addTag is responsible for taking some text and wrapping it in the appropriate HTML. It is passed two arguments. First, the button object for the button that was just clicked. This contains the data passed from the server. The second argument is the text that should be surrounded Drupal.theme.prototype.addTag function button, text var tag null if...

Really Simple Syndication RSS

Really Simple Syndication RSS was devised as a way of sharing news with other websites. Initially, it was envisioned as a thin web service, where some remote site could simply access a URL and get back an XML-formatted list of the latest articles. It became an attractive offering for two reasons. First, the XML format is simple, which makes a programmer's life easier. Second, the idea of getting an up-to-the-minute news feed has a wide appeal. RSS readers and aggregation services quickly...

Installing Views and Views Datasource

One of the most frequently used add-on modules for Drupal is the Views module. This module provides Drupal developers and administrators the ability to build up a dynamic view of content by composing a query and determining how the results will be displayed. Want to show all nodes created before July 1, 2008 in a block Want to display all Page nodes created by mbutcher Want to create an RSS feed containing a list of all Story nodes with the taxonomy term important Views is the most popular tool...

The buttonBar theme function

The Drupal.theme.prototype.buttonBar theme is also very straightforward. It's job is to take an array of buttons and combine them into a single button bar. Since more than one button bar may exist on a page, each button bar needs to have its own ID. Drupal.theme.prototype.buttonBar function buttons, id var buttonBar ' lt div .attr 'id', id jQuery.each buttons, function i, item First, the new button bar jQuery object is created and the ID is appended. Next, we loop through each of the items in...

Translating the projects strings

With our application written to take advantage of the translation system, what we want to do now is provide translations for other languages. To do this, we will use the Translation template extractor module discussed earlier in the chapter. To do our translation, we will have the template extractor analyze the code in our theme and generate a translation template file. From there, we will simply add the translated text, and then add the translation file to the correct location in the file...

Project rotating sticky node teasers

Now we're ready to start our first jQuery project. We're going to write some code that rotates sticky node teasers. With a description like that, it's got to be good Seriously, the phrase rotating sticky node teasers is pretty jargon-laden. Here's what I mean. On various Drupal pages, the main content area of the page is composed of node teasers. The following front page is one such example Frobnitz Central Reviews of Stuff You Need

Creating a JSON view

The Views module comes with a very sophisticated builder interface for creating your own views. If this book were on using Drupal modules, we would certainly spend several pages at least describing the details of the Views UI. But for our immediate purposes, we will constrain our discussion to building just one simple view. r' amp rX Views UI is a module that is included with Views. This module contains I Nij the user interface for building custom views. I We want to track new comments as they...

[PACKTl

script 'BetterEditor.buttons ' . buttonJS path drupal_get_path 'module', 'bettereditor' drupal_add_css path . ' bettereditor.css' drupal_add_js path . ' bettereditor.js' drupal_add_js script, 'inline' The help function, bettereditor_help , does the same thing here as it did in the previous project. It provides very basic help that will be shown on the help screen for this module. Again, when building a production-quality module, it is a good idea to write longer, more descriptive help text....

Defining a behavior to handle repeatable events

The ready event that jQuery defines and that we saw at the end of the previous chapter is fired as soon as the DOM is ready for manipulation. But that's the only time it fires. The DOM can undergo many changes between the time the page loads and when the user leaves the page. Some of those DOM changes may have an impact on how the other JavaScript works. In cases like this, we want to be able to re-run our query to add the fancy class whenever a new paragraph is inserted into the DOM. This is...

Creating the web clips tool

In this project, we will create our web clips tool in webclips.js. As we have done in previous chapters, this file will be added to frobnitz.info using a directive like this scripts webclips.js. We will begin by taking a quick look at the code in its entirety. We will then look at it more closely. One thing that should be immediately noticeable is our use of several tools introduced in earlier chapters Create a web clips tool for displaying random RSS items. var WebClips WebClips settings...

The divWrap function

Inside of our closure we define one new function var attrs arguments.length gt 0 arguments 0 var div This function takes all of the items wrapped in the current jQuery object and wraps each in lt div gt lt div gt tags. It takes an optional parameter an object. The attributes of that object will be used as attributes for the new div element. The first thing our divWrap function does is check to see if any arguments were passed in. Recall that JavaScript's built-in arguments variable is an...

A first jQuery script

When you read the first few pages of this chapter, you must have noticed that very little was said about Drupal. jQuery is a standalone library with no dependency on Drupal, which means it can be used on its own. In fact, that's the way we are going to dip our toes into the topic. Don't worry though. We will be coming back to Drupal just a little later in the chapter. We are going to start out with a static HTML document and take a look jQuery in this simplified context. In the next section, we...

The DrupalencodeURIComponent function

Earlier, we looked at encoding HTML with Drupal.checkPlain . Here, we will look at another encoding function one designed for encoding pieces of a URL or URI. Drupal PHP programmers may also recognize this function. It essentially performs the same task as the drupal_urlencode PHP function. Those familiar with JavaScript will recognize this as having the same name as a built-in JavaScript function. The built-in JavaScript function, encodeURicomponent , is used to encode values that will be used...

Project collapsing blocks

In this project, we will write a very simple behavior that will be attached to blocks on a page. We will make blocks collapsible. Clicking on a block's title will cause the body of the block to slide up or slide down. Here are the contents of a file called behaviors.js, which is part of the Frobnitz theme, included in using a scripts directive in frobnitz.info Defines behaviors for Frobnitz theme. Toggle visibility of blocks with slide effect . Drupal.behaviors.slideBlocks function context...

Changing a translation file

There is one thing you should be aware of when developing translations for your themes and modules. Once Drupal has scanned your translation PO file once, it will not automatically scan it again. The translation database never gets automatically updated. Practically speaking, this means that changing the translation file requires an extra step before your changes show up. You will have to manually import the modified translation file. If you add the new Drupal.t call to you script, you can walk...

Telling Drupal to attach behaviors

After modifying a portion of the document, it might be desirable to notify Drupal so that behaviors can be re-attached. This is done with yet another function from drupal.js Drupal.attachBehaviors . When should attachBehaviors be called There are some DOM modifications which probably don't warrant calling Drupal.attachBehaviors . For example, just changing the text of a node without altering any elements can usually be done safely. Also, there are other elements, such as lt br gt , that rarely...