Monday, April 25, 2011

Drupal 7 Views 2.0 Tutorial

Finally here is a good screencast about Drupal 7 Views 3.0 . Views 3 has lot of new functionalities as compared to its previous version. I will gather more good tutorials on views and will publish them on this blog. There are other related videos regarding this video in youtube. However I post them here if I found them useful. So , see the video , do some experiments and enjoy!




Sunday, April 24, 2011

Drupal Forms API Reference

The Drupal forms API is a powerful leap forward. It also allows for almost unlimited possibilities for custom theming, validation, and execution of forms. Even better, ANY form (even those in core) can be altered in almost any way imaginable--elements can be removed, added, and rearranged. This page is certainly not a comprehensive guide to this functionality, but should provide a good working foundation with which to do the most basic form creation, theming, validation, and execution. For programming details on form elements and their properties, please see the Forms API Reference.

Creating Forms

Form elements are now declared in array fashion, with the hierarchical structure of the form elements themselves as array elements (which can be nested), and each form elements properties/attributes listed as array elements in key/value pairs--the key being the name of the property/attribute, and the value being the value of the property/attribute. For example, here's how to go about constructing a textfield form element:
$form['foo'] = array(
  '#type' => 'textfield',
  '#title'
=> t('bar'),
  
'#default_value' => $object['foo'],
  
'#size' => 60,
  
'#maxlength' => 64,
  '#description'
=> t('baz'),
);
?>
and a submit button:
$form['submit'] = array(
  '#type'
=> 'submit',
  
'#value' => t('Save'),
);
?>
a few things to note:
  1. The element's name property is declared in the $form array, at the very end of the array tree. For example, if an element in the form tree was structured like this:

    $form['account_settings']['username']
    ?>

    ...then that element's name property is 'username'--this is the key it will be available under in $form_state['values'], in your validation and submission functions, as the form code flattens the array in this fashion before it passes the key/value pairs. NOTE: if you wish to have the full tree structure passed to $form_state['values'], this is possible, and will be discussed later.
  2. The type of form element is declared as an attribute with the '#type' property.
  3. Properties/attributes keys are declared with surrounding quotes, beginning with a # sign. Values are strings.
  4. The order of the properties/attributes doesn't matter, and any attributes that you don't need don't need to be declared. Many properties/attributes also have a default fallback value if not explicitly declared.
  5. Don't use the '#value' attribute for any form elements that can be changed by the user. Use the '#default_value' attribute instead. Don't put values from $form_state['values'] (or $_POST) here! FormsAPI will deal with that for you; only put the original value of the field here.
One great advantages of this system is that the explicitly named keys make deciphering the form element much easier.
Let's take a look at a working piece of code using the API:
function test_form($form_state) {
  
// Access log settings:
  
$options = array('1' => t('Enabled'), '0' => t('Disabled'));
  
$form['access'] = array(
    '#type'
=> 'fieldset',
    '#title'
=> t('Access log settings'),
    '#tree'
=> TRUE,
  
);
  
$form['access']['log'] = array(
    '#type'
=> 'radios',
    '#title'
=> t('Log'),
    '#default_value'
=>  variable_get('log', 0),
    '#options'
=> $options,
    '#description'
=> t('The log.'),
  );
  
$period = drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 9676800), 'format_interval');
  
$form['access']['timer'] = array(
    
'#type' => 'select',
    '#title'
=> t('Discard logs older than'),
    '#default_value'
=> variable_get('timer', 259200),
    '#options'
=> $period,
    '#description'
=> t('The timer.'),
  );
  
// Description
  
$form['details'] = array(
    
'#type' => 'fieldset',
    '#title'
=> t('Details'),
    '#collapsible'
=> TRUE,
    '#collapsed'
=> TRUE,
  
);
  
$form['details']['description'] = array(
    
'#type' => 'textarea',
    '#title'
=> t('Describe it'),
    '#default_value'
=>  variable_get('description', ''),
    '#cols'
=> 60,
    '#rows'
=> 5,
    '#description'
=> t('Log description.'),
  );
  
$form['details']['admin'] = array(
    '#type'
=> 'checkbox',
    '#title'
=> t('Only admin can view'),
    '#default_value'
=> variable_get('admin', 0),
  );
  
$form['name'] = array(
    '#type'
=> 'textfield',
    '#title'
=> t('Name'),
    '#size'
=> 30,
    '#maxlength'
=> 64,
    '#description'
=> t('Enter the name for this group of settings'),
  );
  
$form['hidden'] = array('#type' => 'value', '#value' => 'is_it_here');
  
$form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
  return
$form;
}

function test_page() {
  return
drupal_get_form('test_form');
}
?>
This example demonstrates how form elements can be built in a hierarchical fashion by expanding and layering the form array. There are two functions involved - the function that builds the form, and another that renders the form using drupal_get_form(). Note that the form builder function always takes $form_state as its first argument, though for basic usage (as here) it is not used. Also note that the test_page() function that renders the form is returning the rendered HTML output, which is what you would need to do if test_page() is the page callback from a hook_menu() implementation, for example.
Notice that the first layer is made up of two form groups, 'access', and 'details', and that inside each of these groups, one layer down, are some individual form elements. Order of construction is important here, as the form building code will default to the constructed order of the $form array when it builds the form (this can be overridden, and will be discussed later in the custom theming section).
For form groups, the '#type' parameter is set to 'fieldset', and notice how the 'details' form group is made into a collapsed form group with the addition of a few attributes.
All groups/elements are been built into the master $form array by the builder function.
The drupal_get_form function is the "key" function in the Forms API. Note that in its basic usage, it takes just one argument, a string which is both the form ID and also the name of the function that builds the $form array. Because the form ID is generally also the name of a function, it must be a valid PHP variable name. It should start with a letter or underscore, followed by any number of letters, numbers, or underscores; spaces and hyphens are not allowed. drupal_get_form can take optional additional arguments, which will be simply passed on to the $form builder function.
drupal_get_form does the following:
  • Starts the entire form-building process by getting the $form from the builder function
  • Translates the $form['name'] items into actual form elements
  • Performs any validation and "clean-up" that needs to be done, and calls custom validation functions if declared
  • Submits the form if a submit function is declared, and the form has been submitted
  • Calls any custom theming functions that have been declared
  • Returns an HTML string which contains the actual form.
For more detailed information, also see the API page for drupal_get_form()
An important thing to note: notice that $form['access'] has a '#tree' => TRUE attribute. this setting retains the full tree structure for all elements under it when it is passed to $form_state['values']. you must explicitly declare this anywhere you wish to retain an array's full hierarchy when it is passed.

Theming Forms

The API makes custom theming of all forms (including those found in core) possible. This custom theming becomes possible when all hard coded theming elements have been abstracted, so that they can be overridden at time of form generation. The abstraction is accomplished using one of the following methods:
  1. Adding '#theme' attributes to the form and/or elements. This allows you to specify which theme function will be used to render the form or elements, overriding the default theming function.
  2. Including any markup directly as an element in the $form array:
    • There are '#prefix' and '#suffix' attributes, and these will place the declared markup either before or after the form element in question. for example:
      $form['access'] = array(
        '#type'
      => 'fieldset',
        '#title'
      => t('Access log settings'),
        '#prefix'
      => '
      ',
        '#suffix'
      => '
      ',
      );
      ?>
      ...will place the div tags before and after the entire form group (meaning the form elements of the group will also be enclosed in the div). if you were to put those attributes in one of the form elements inside that form group, then they would only wrap that particular element, etc.
    • There is a '#markup' type which you can place anywhere in the form, and its value will be output directly in its specified location in the forms hierarchy when the form is rendered. example:

      $form['div_tag'] = array('#type' => 'markup', '#value' => '
      ');
      ?>
      This markup form element can then be accessed/altered through its name in the array, 'div_tag'
      NOTE: it's not necessary to explicitly declare the type as markup, since type will default to markup if none is declared.
  3. Break out any markup into a separate theme function. This is the preferred method if the markup has any degree of complication. it is accomplished by creating a theme function with theme_ prepended to the name of the form ID that is to be themed. in cases where you want to use the same theming function for more than one form, you can include the optional callback arg in drupal_get_form--in which case the third arg of drupal_get_form will be a string containing the name of the callback function which the form building code will call, and the theming function will be theme_ prepended to the name of the callback. example:
    For our above form, we could create a custom theming function as follows:
    function theme_test_form($form) {
      
    $output = '';
      
    $output .= drupal_render($form['name']);
      
    $output .= '
    ';
      
    $output .= drupal_render($form['access']);
      
    $output .= '
    ';
      
    $output .= drupal_render($form['details']);
      
    $output .= '
    ';
      
    $output .= drupal_render($form);
      return
    $output;
    }
    ?>
    A few things to note:
    1. The theme function has one argument, which is the form array that it will theme
    2. You build and return an output string just as you would do in a regular theming function
    3. Form elements are rendered using the drupal_render function
    4. If you call drupal_render and pass it an array of elements (as in a fieldset), it will render all the elements in the passed array, in the order in which they were built in the form array.
    5. While the default order of rendering for a form is the order in which it was built, you can override that in the theme function by calling drupal_render for any element in the place where you would like it to be rendered. In the above example, this was done with $form['name'].
    6. The rendering code keeps track of which elements have been rendered, and will only allow them to be rendered once. Notice that drupal_render is called for the entire form array at the very end of the theming function, but it will only render the remaining unrendered element, which in this case is the submit button. calling drupal_render($form) is a common way to end a theming function, as it will then render any submit buttons and/or hidden fields that have been declared in the form in a single call.

Validating Forms

The form API has general form validation which it performs on all submitted forms. If there is additional validation you wish to perform on a submitted form, you can create a validation function. the name of the validation function is the form ID with _validate appended to it. the function has two args: $form and $form_state. $form is the form array of the executed form, and $form_state['values'] contains the form values which you may perform validation on. (Note - in more advanced usage, several forms may share a _validate or _submit function - so if the form's ID is needed, it can be retrieved from $form['form_id']['#value'], or $form_state['values']['form_id'].)
Here's an example validation function for our example code:
function test_form_validate($form, &$form_state) {
  if (
$form_state['values']['name'] == '') {
    
form_set_error('', t('You must select a name for this group of settings.'));
  }
}
?>

Submitting Forms

The normal method of submitting forms with the API is through the use of a form submit function. This has the same naming convention and arguments as the validation function, except _submit is appended instead. Any forms which are submitted from a button of type => 'submit' will be passed to their corresponding submit function if it is available.
example:
function test_form_submit($form, &$form_state) {
  
db_query("INSERT INTO {table} (name, log, hidden) VALUES ('%s', %d, '%s')", $form_state['values']['name'], $form_state['values']['access']['log'],  $form_state['values']['hidden']);
  
drupal_set_message(t('Your form has been saved.'));
}
?>
a few things to note:
  1. A submit function is called only if a submit button was present and exists in the $_POST, and validation did not fail.
  2. The $form_state['values'] array will not usually have the same hierarchical structure as the constructed $form array (due to the flattening discussed previously), so be aware of what arrays have been flattened, and what arrays have retained their hierarchy by use of the tree => TRUE attribute. notice above that 'statistics_enable_access_log' belongs to a tree'd array, and the full array structure must be used to access the value.
  3. If a form has a submit function, then hidden form values are not needed. Instead, any values that you need to pass to $form_state['values'] can be declared in the $form array as such:

    $form['foo'] = array('#type' => 'value', '#value' => 'bar')
    ?>
    This is accessed in $form_state['values']['foo'], with a value of bar. This method is preferred because the values are not sent to the browser.
  4. To determine where the user should be sent after the form is processed, the _submit function can place a path or URL in $form_state['redirect'] which will be the target of a drupal_goto; every form is redirected after a submit. If you store nothing in $form_state['redirect'], the form will simply be redirected to itself after a submit. It is polite to use drupal_set_message() to explain to the user that the submission was successful.

Understanding the Flow

An important concept with Forms API compared to using raw HTML forms (as in Drupal 4.6 and before) is that the drupal_get_form() function handles both presenting and responding to the form. What this means is that the $form array you construct in your function will be built first when the form is presented, and again when the form is submitted.
The practical upshot to this is that many developers immediately find themselves asking the question of "where does my data get stored?". The answer is simply that it doesn't. You put your $form data together, perhaps loading your object from the database and filling in #default_values, the form builder then checks this against what was posted. What you gain from this, however, is that the FormsAPI can deal with your data securely. Faking a POST is much harder since it won't let values that weren't actually on the form come through to the $form_state['values'] in your submit function, and in your 'select' types, it will check to ensure that the value actually existed in the select and reject the form if it was not. In addition, Drupal adds, by default, a security token to each form that will protect against cross-site forgery.

Tuesday, April 19, 2011

How to install ubercart in Drupal


Modules Needed for Ubercart Tutorial Part 1

You'll need to download the following modules to set up your Ubercart store. We're using Drupal 6 and Ubercart 2.

Ubercart Modules Needed

So first we need to install Ubercart. Here's a clean installation of Drupal, and we're going to go online and find the Ubercart module. We're using Drupal 6 and Ubercart 2. So google Ubercart and look for the module and download the version for Drupal version 6.

You'll want to download all of them there's links to them, and then just go into your drupal installation folder. Go to /sites/all/. You're going to want to make a directory called modules in there, and then unzip or untar all of your module files here such as Ubercart, FileField, all of them there.

So be sure to check the description of the YouTube video for links to my blog, and the post that has all the modules you need to download and unzip in that folder.

So you go to Admin > Modules and we'll enable all the modules we need. First we need to enable the Content module, enable the FileField module, ImageField, as well as Path. We also need ImageAPI, ImageAPI GD2, ImageCache, this will give us support for images for products. We need Token, Cart, Conditional Actions, Order, Product, Store, Catalog, and that's it!

So we save our configuration, and after we've enabled all the modules we need, it's time to start configuring the store.

Ubercart Store Configuration

On the menu click on store administration and then configuration and then choose store settings. So this is all the information about your store. If you pick edit, you can pick your store name, Ubercart Demo Store. Store owner, put in your name, and put in your email address below, your store phone number, your store fax number, and then the address of your store here. Pick your country and province, or territory, or state and then your postal code.
You can put in a help page if you want, you'll have to configure that later though.

Enable image support in Ubercart

At the next screen after Save Configuration, scroll to the bottom and click on "click here" to enable image support. Now images are enabled for our products and our catalogs.

Creating products in Ubercart

If you click on Create Content in the menu, and click on product, we'll create our first product here. So I'm going to create a fish hat. I don't know why but I saw a cool fish hat on reddit and I've been a bit obsessed with it ever since. I want one, I want my girlfriend to make me one.

Now we're going to find an appropriate photo for this fish hat. I wouldn't recommend google ganking like this on a production web site, but this is just for fun. So browse and find the image. Make sure it fits the file format standards.
You can add some text here that will show up in the alternate. You need to enter an SKU. It can be anything but Drupal requires that you do. Also add a sell price, that's the cost that customers will be charged. You want to put in a weight, and you also want to put in the dimensions of the product in whatever unit measurement you want or else you won't be able to ship the product and get shipping quotes later on.

Now we'll have to go into Administer > User Management > User Permissions. For the anonymous and authenticated user enable the following permissions:
  • View ImageCache Cart
  • View ImageCache product
  • View ImageCache product_full
  • View ImageCache product_list
  • View ImageCache uc_thumbnail
So save your configuration and if you go to the home page you'll notice that the fish hat is now a product that's showing in the front page. You can go to your cart and play around with the shopping cart that's provided with Drupal, and ya it' looks pretty cool.That's how you create a product.

Creating an Ubercart Catalog

We are going to go to store administration, and you'll notice we have an unlisted product. We have created a catalog for it yet, so we need to add terms for the product to inhabit.

We'll do that by creating a catalog by clicking the link below, add terms for this product to inhabit.

Now I'm trying to find a suitable image for this. We'll add a silly hats catalog for the fish hat to inhabit. Add an image and a description and then click save. You've just created a catalog.

So now if you go back to store administration, and click on the orphaned products link at the bottom. Find the orphaned product which is the fish hat and if you go to catalog, just add it to the fish hats catalog and click save.
You'll see there are no more orphaned products which is great. Now we go to our catalog and our fish hat is in the silly hats catalog which is very nice.

Creating a menu link to the Ubercart catalog

So now click on administer then menus and then primary links. We're going to create a link to the catalog here. You want to put the menu link title silly hats catalog down below, and in the top you put the path to the catalog which is /taxonomy/term/1.

Create a description, click enabled, and then click save.

So now the silly hats catalog will show up in the primary links menu, but now we have to go to Administer > Blocks. Go to the very bottom and find Primary Links Menu and set that to the right sidebar and click save. Now you'll see the Primary links in the right side that now has our catalog on the right.

Creating more Ubercart products for our catalog

Now lets create another product for our catalog. Lets call it beer hat. Everyone loves beer hats, if you've been in college anyways. Add a description, add the catalog silly hats. Lets find a beer hat picture real quick off google. I wouldn't recommend this, this is for demonstration purposes only. Lets rename the file here real quick. There we go we can upload the file now.
Add a title here called beer hat. Change the weight, add a length, width and height, I don't really know what it is I'm just guessing here. Oops we forget to add the SKU, add the pesky SKU, just add beer-0001, it can be anything. Now click save and you've got a beer hat in the catalog here.
So now you can see we have a beer hat and a fish hat in our catalog. You can add each of them to your cart and play around with it. You can checkout and pay for it, but we haven't set up payment yet, and that will be the next step.

Wrapping up and Ubercart Tutorials parts 2 and 3

This is going to be part of a 3 part Ubercart tutorial. The first one shows you how to do basic setup for your store. The second shows you how to setup payment with Paypal. The third one will show you how to get shipping quotes working properly with UPS or FedEx I haven't quite decided yet.




Monday, April 18, 2011

15 Outstanding Drupal Modules You Should Be Using

Drupal is a (CMS) any web developer should get to know. It is in my opinion the best open source CMS available at the moment, and it has a huge community of contributors. If you have not looked into drupal check it out at drupal.org.

Just like WordPress, Drupal is powerful “out of the box” but has thousands of modules that have been contributed to the community to extend upon that functionality. A few of the most popular modules are Views, CCK, Panels, XML Site map and Google Analytics.



1. String Overrides



The String Overrides module allows you to override text on a drupal site such as the default text on a contact form page. Some text that Drupal auto generates is difficult to change, but using String overrides allows you to change those text strings with a fairly easy user interface.

2. Date Module

The Date Module is very powerful because it can tie so many modules together using something simple such as the date. It allows you to assign a date to an event or a custom content type and distribute that value to other modules.

The date module is a flexible date/time field type for the cck content module which requires the CCK content.module and the Date API module.
This module does need CCK in order to work but most if not all drupalheads use CCK so thats not a big issue.

3. Calendar Module

The Calendar Module is intentionally listed after the Date Module because they work so flawlessly together. It pulls in dates of events or custom content types and generates them all in a calendar that is ready to be styled with CSS.

This module will display any Views date field in calendar formats, including CCK date fields, node created or updated dates, etc. Switch between year, month, and day views. Back and next navigation is provided for all views.
I have used this calendar module on multiple sites and it really makes it easy to get a clean looking dynamic calendar up fairly quickly. I highly recommend.

4. Location Module

The Location Module is similar to the Date Module in the sense that is is adding specificity to a piece of content. As you probably guessed by it’s name it allows you to add a location to individual nodes.

The Location module allows real-world geographic locations to be associated with Drupal nodes, including people, places, and other content.
The actual functionality of adding a location to a node or person isn’t all that exciting, It’s what you can do with paired modules that truly brings this module to life.

5. GMAP Module

I was just talking about how other modules bring the Location Module to life. Enter the GMAP Module. This takes the location module and gets all kinds of crazy with it, allowing you to now map all or some of your locations or people. You could build a medium sized social network site just based off of Drupal.

The GMap module provides an interface to the Google Maps API within Drupal. It integrates with the Location module to provide users a clickable map for entering latitude and longitude, as well as to display maps of Drupal nodes and users.
The possibilities are endless and these modules are only in the beginning stages. I can’t wait to see what Drupal 7 holds.

6. UBERCART Module

Ubercart in my opinion is the best e-commerce solution to-date for Drupal. It is a seamless integration that leverages the strengths of Drupals backend to deliver a great shopping experience.

Ubercart is an e-commerce suite developed for Drupal. It has been designed with the end user in mind, focusing on usability in three key areas: store configuration, product and catalog creation, and order administration.
Not only does Ubercart easily integrate with drupal it has built-in modules for shipping calculation, payments, taxes, and much more.

7. Signup Module

The Signup allows a user of the site to “Sign Up” for specific events/nodes and it will email them the day before the event happens just to serve as a reminder. It is a wonderful tool to use if you can get your audience to use it.

Signup allows users to sign up (or register, as in register for a class) for nodes of any type. Includes options for sending a notification email to a selected email address upon a new user signup (good for notifying event coordinators, etc.) and a confirmation email to users who sign up.
I used this on a site I just finished developing, and it hasn’t caught on with in the community yet. I guess we’ll see with time, either way I still like it :p

8. Content Access Module

I use this module to set permissions to different roles per node, so if I have one page I only want important people to see I can go in and set permissions for that specific node. This module is very powerful.

This module allows you to manage permissions for content types by role and author. It allows you to specifiy custom view, edit and delete permissions for each content type. Optionally you can enable per content access settings, so you can customize the access for each content node.
Drupal gives you so much control over the permissions of your site, but the Content Access Module is an awesome add-on to increase Drupals functionality.


9. Webform Module

The Webform Module adds a webform as a nodetype which allows you to offer register forms, surveys, polls and much more. It’s also a good alternative to Drupal’s site-wide contact form.

I mainly use the Webform Module in place of Drupal’s site-wide contact form. It gives you more flexibility and it’s easier to style.

10. Nodewords Module

Nodewords is great for SEO because it allows you to set meta tags for each drupal page or node. This gives you awesome control over what keywords and descriptions are used on each page of your site, and if used correctly can really help your rankings.

This project allows you to set some meta tags for each Drupal page.
I user the Nodewords Modules for the reasons stated above. It helps out with SEO and keeps google’s attention by constantly updating content with new keywords.

11. Nice Menus Module

Nice Menus enables drop down menus for your navigation items in drupal. It uses completely CSS and even has a small bit of Javascript for IE6.

Nice Menus enables drop-down/right/left expandable menus. It uses only CSS for most browsers, with minimal Javascript for IE6. (Version 2 uses the Superfish jQuery plugin for all browsers, with an option to disable JS, and falls back to CSS-only for browsers that can handle it.)
It’s a quick easy way to get a drop down menu going and can easily be changed to drop to the left, right or down.

12. Mollom

Mollom is a great spam catcher for contact forms, web forms, comments, blogs, messages and more and was developed by Dries Buytaert the creator of Drupal.

Mollom is a web service that analyzes the quality of content posted to websites. This includes comments, contact-form messages, blogs, forum posts, etc. Mollom specifically tries to determine whether this content is unwanted – i.e. “spam” – or desirable – i.e. “ham.”
It significantly cuts down on the amount of spam you get on your Drupal site. It will provide CAPTCHA’s for you to further reduce spam.

13. Scheduler Module

The Scheduler Module allows you to create a piece of content and choose a day for it to become public, instead of having to go back in yourself and set it to public on the day it needs to go live.

This module allows nodes to be published and unpublished on specified dates.
I’m am horrible at remembering things people tell me unless I write it down. So the ability to go in and create the content and then schedule it for the day I actually want it to go live is an awesome feature.

14. Menu Block Module

Menu Block simply enables a block for each of the menus you have so you can place them in a block somewhere else on the site.

It provides configurable blocks of menu trees starting with any level of any menu.
I use this module on almost every site I do. Mainly because I can grab my secondary navigation and throw it in the sidebar, it really gives you a lot of flexibility.

15. Admin Module

This Admin module has some serious promise. They have integrated a very nice administrative theme that makes it super easy to update content within a great looking admin theme.

The admin module provides UI improvements to the standard Drupal admin interface.
I am not currently using this on any sites, but I am looking forward to what this module could become.

Sunday, April 17, 2011

Content Translation (field translation) in Drupal 7

Drupal has long been a leader in the ability to present a website in multiple languages. In Drupal 7 we continue that tradition: Field translation or "content translation" made it into Drupal 7, but it's not obvious from a plain Drupal 7 install how you would use it.

This article is fundamentally about content translation, not about interface translation, which is a completely different thing in Drupal (and always has been). Interface translation is about prompts, labels, menu entries and the like, all of which are handled by the core locale module and various contrib modules like i18n. I will explain how to import basic interface translation files, however.

Drupal 6 has a node translation system which basically allows you to make "translation sets" of nodes. You start with a node in a source language (and set the language on that node), and then you can create additional translations of that node to other languages. So for example, we might start with a node in English, then use the "translate" tab to add additional nodes in different languages that are tied to that original node. That node translation system is still supported in Drupal 7, but it doesn't support translation of CCK fields, and is quite awkward in reality because you're dealing with a number of separate nodes, instead of translations of a single node. Edit: See Gabor's comment below for more on this, and considerations regarding it.

Drupal 7 got field translation (yay!), also referred to as "content translation", which is an entirely different thing. In content translation you have a single node, but with different translations for each field on the node that should be translatable. And the body is a field. Unfortunately the title is not a field, and therefore is not translatable, but more on that later. To restate this: In Drupal 7 "content translation" there is just one node, and translatable fields on it are translated to provide the translations, but are still part of that single node. The gotcha in field translation (content translation) though is that in core it didn't get a user interface. As a result the contrib Entity Translation module improves content translation and provides a UI and works alongside the core content translation module, and it's fundamental to the approach described here.

Here is the process I went through to set up a basic multilingual site:

1. The core field translation facilities have no user interface, so you'll need the Entity Translation module. After installing and enabling it (which also enables translation and locale modules), you may need to run update.php.
2. You need to enable languages for your site.
* Add languages at admin/config/regional/language
* Download interface translation files from http://localize.drupal.org
* Import interface translations into the configured languages at admin/config/regional/translate/import (under "Translate Interface"
* Click "Enabled" on the languages you've configured
* At "Detection and Selection" (admin/config/regional/language/configure), choose how you want languages to be chosen. My experience is that URL selection is the best approach, so you'll need to configure subdomains or some related approach. Note that when you use URLs you need to enter the full URL including "http://". There doesn't seem to be any error checking on this. Also remember to click "enabled" on the strategy that you choose.
* On the same "Detection and Selection" page, in the lower section of the page under "Content language detection" select "Interface", so that the same language is chosen for content language detection as for interface language detection.
3. Enable translation of nodes and any other entities that should be translatable at admin/config/regional/translation.
4. Enable "Multilingual support: Enabled, with content translation" on the content type edit form under "Publishing options". For example, for a content type named "example", this would be at admin/structure/types/manage/example/edit in the "publishing options" fieldset.
5. For each field that should be translatable, go to field settings and check "users may translate this field". For the body field of the "example" content type, this would be at admin/structure/types/manage/example/fields/body/field-settings.
6. Now you can create and translate fields.
* Create a node and set its language to a specific language.
* When you've saved it a "Translate" tab will appear allowing you to translate into other configured languages.
* Click "Add translation" to add translations for the fields that have translation enabled.
* Make sure to publish the translation. Publication is unfortunately hidden in the collapsed-by-default "translation options" fieldset

Some gotchas regarding field translation:

* The Title module is required to make titles translatable. This currently only works for nodes, not entities. All the work is actually being done in #924968 so you have to apply the patch from that issue.
* Entities other than nodes are not translatable out of the box. The entity must be specifically enabled to allow its fields to be translated. das-peter will elaborate on this later.

Since I'm a newbie at the D7 translation scene, I'm sure there are errors or omissions here, so please correct this and I'll update the article based on your corrections.

Saturday, April 16, 2011

Building Drupal with Reusable Fields

CCK and Field API

CCK is the most useful module for Drupal. It adds custom fields and content types to Drupal. Drupal 7 incorporates the community efforts of CCK into the core as the Field API.

The CCK module allows a content type to have multiple fields with various field types and different field widgets and formatters. A field must be assigned a widget to define its input style and at least one formatter to define its display style. The UML diagram above describes the relationship between content types, fields, field widgets, and field formatters in creating a CCK type.

Reuse Fields

When a CCK field is added to a content type for the first time, this CCK field’s is created in Drupal as a class and an instance is assigned to the given content type. When the field is assigned to a content type, its configuration parameters are stored in the instance instead of the class. Instead of adding new fields to a content type, adding existing fields is a better option to reduce the system’s complexity and to improve scalability.

Adding an existing field only requires the administrator to choose a field from a list of fields defined in other content types and select a widget to define the input style. The most recently created field instance brings in the default parameters that can be changed later.

Reuse Fields with the API

CCK allows adding customized fields, widgets, and formatters in modules. Many third-party modules (Drupal CCK modules list) are already created to accomplish different tasks, including images, videos, and other internal and external references. CCK for Drupal 6 provides a set of API (CCK Developer Documentation for Drupal 6) for module developers. Drupal 7 provides native Field API for module developers.

Performance Issues

CCK (or Field API in Drupal 7) adds extra complexity to a Drupal system. When creating a new field, the field’s definition is added to the field class table and the field’s configuration is added to the field instance table; meanwhile, a new table is added to the Drupal database to store the field data. Database tables add complexity to the system. In addition, queries of nodes will incur JOIN expressions of tables to field data. Multiple JOINs will impact database performance since MySQL responds poorly to queries with multiple JOINs of tables if not properly configured.
Reuse of fields can reduce the number of tables in the Drupal database. For example, if 10 image fields, field_image_a, field_image_b, …, field_image_j, are added to the system, 10 tables are added to the database. If a single content type only utilizes two image fields, one thumbnail and one image, we can redefine the fields as field_image_thumbnail and field_image. Only two tables are introduced to the database with the latter configuration.
Reuse of fields can also reduce the system’s complexity. Instead of creating and maintaining 10 different fields, Drupal admins maintain only two fields and their documentation. Database administrators only need to improve performance of two extra tables. KISS is always a good principle.

Drupal Ebook Download

Here I have found a rapidshare link having good collection of Ebooks about Drupal 7. This file is about 60MB in size. It have 9 files inside a rar file. This ebook will surely help those people who are new in Drupal 7 and ofcourse the professionals who are trying to grasp all the techie thing hidden inside drupal. So.. Why are you waiting for? Download this file, extract it and get started with Drupal. Enjoy !!

Download E-Books :
http://rapidshare.com/files/262785787/9PACK_Drupal_ebook.rar

Wednesday, April 13, 2011

New features in Drupal 7

Drupal 7 is a hot topic of discussion these days and all active Internet users are talking about recent release of this Content Management System. To be on the wave of all modern approaches and technologies we've decided to sum up all advantages of this CMS system and make a short review. So, why should we use this CMS script and why it's better than Drupal 6 or other CMS systems. In the overview below we present new top features that have been made in Drupal 7.

Let's start from the beginning, from the installation. Drupal's installation script makes launching of the system much easier and it automatically populates database tables and configures the correct settings you need. It runs natively on MySQL but also supports a wide range of other databases. If you are not aware how to install Drupal 7 you can find out it in this detailed guide.

Three are better than one! Three core layouts instead of the default Garland theme! New amazing trio which includes Bartik, Seven and Stark themes can be easily downloaded and installed from Drupal.org or you can create your own custom theme!

If you want to have a full control over the look and feel of the site you’re building - Drupal7 is the best solution for this. The main change in updated Drupal 7 is the generalization of common data structures into entities. You can put fields almost on everything: on nodes, terms and even users. You are able to do CCK (Content Construction Kit) stuff to comments and vocabularies. This CMS system enables to create new content types, such as an article, blog post, or even music album. And this wholesome feature is used by default in Drupal7.

One more build-in to the core Drupal 7 installation feature is - image styles. It enables to set picture styles, such as scaling, cropping and even turning your images grayscale. It is perfect for people who want to build a portfolio website, cause they can specify different image styles for thumbnails and full-view images. Just upload one image, and Drupal creates all the other pictures for you!

The Toolbar gives you a quick access to administrative functions from any part of the site. When you click on one of the toolbar items you are not taken to a back end area as you may expect. Now the administration pages load on the top of your website as a light box. With the improving administration interface, the appearance of the Drupal 7 has been also sophisticated. And its new look is really cool, we are sure, you'll appreciate it!
The shortcut feature is also very useful and functional. Now you can add items which is used more often and get immediate access to them. It's possible to add custom shortcuts to the admin menu navigation and create several different ones for different users. The admin menu tools can be fully customized for different responsibilities such as admins, editors, authors, designer and site builders.
Drupal 7 has plenty of modules by which it's easy to achieve pretty much any functionality! This is an open source Content management system which is absolutely free of cost. Drupal CMS platform is very comfortable in usage and anyone can without efforts install it and have their own website up and running within minutes.

Monday, April 11, 2011

Drupal 7 E-Books Download

See this link: http://pdf-ebooks.org/ebooks/drupal-7-module-development-pdf.pdf

This has links of many pdf files regarding Drupal 7 Development. checkit out.

Comments Expected!




Saturday, April 9, 2011

Converting Drupal themes from Drupal 6 to Drupal 7

Blocks have new, more meaningful CSS IDs

I’d say it’s about time this happened. Core CSS block IDs now have more meaning that relates to their functionality.
Some examples:
Recent blog posts
Old CSS ID (Drupal 6): block-blog-0
New CSS ID (Drupal 7): block-blog-recent
Recent comments
Old CSS ID (Drupal 6): block-comment-0
New CSS ID (Drupal 7): block-comment-recent

** n.b: If you like this article, then please click on any one of the ad links on the top or side panel. Your small help will encourage me to deliver more useful and good tutorial resources for Drupal in this blog. **

HTML classes generated through a variable

This is something I used to patch into my node.tpl file & preprocess_node hook but now it has been included in core.
Each template (.tpl file) now has a $classes variable which now gives themers a standard way to add HTML classes to their template files:

print $node->nid; ?>" class="print $classes; ?> clearfix"print $attributes; ?>>
.....
The $classes variable can be added to in your preprocess hooks using the $classes_array:
/**
* example taken from core bartik theme
*/
function bartik_preprocess_block(&$variables) {
 
// Set "first" and "last" classes.
 
if ($variables['block']->position_first){
   
$variables['classes_array'][] = 'first';
  }
  if (
$variables['block']->position_last){
   
$variables['classes_array'][] = 'last';
  }
 
// Set "odd" & "even" classes.
 
$variables['classes_array'][] = $variables['block']->position % 2 == 0 ? 'odd' : 'even';
}
?>

HTML attributes generated through a variable

Now all template (.tpl) files can output 3 new variables; $attributes, $title_attributes, and $content_attributes which like the $classes variable mentioned above can be altered or added to in your preprocess functions.

Nice additions to drupal_add_css() function

The drupal_add_css() function is used to attach CSS files to pages and the following functionality has been added:
  • ‘weight’ – You can now weight your CSS file loading although I can’t think of too many times when you’d need this.
  • ‘browsers’ – You can now browser-targeted your CSS files, so you can easily add IE CSS fixes without needing to add code to your templates, which is great in my opinion.

Variable process functions can now be used for all theming hooks

Previously you could only use preprocess functions (called before the theme template to add/alter variables that go into the .tpl file) in your theme when a .tpl file was defined for the theme function output:
template (.tpl) file:


  echo $some_custom_var; ?>

Related hook_preprocess:
function THEME_preprocess_HOOK(&$vars) {
  if (.....) {
   
$vars['some_custom_var'] = t('Hi there');
  }
}
?>
BUT now all theme hooks can have a hook_preprocess and a new hook_process (see notes on that below) which can be used to add new variables & alter current variables which are passed to the define theme function:
theme_ function:
function theme_something_nice()
 
$output = $some_custom_var;
  return
$output;
}
?>

Related hook_preprocess:
function THEME_preprocess_HOOK(&$vars) {
  if (.....) {
   
$vars['some_custom_var'] = t('Hi there');
  }
}
?>

Function names must match theme name

This will save a fair bit of confusion! When overriding module theme functions in your theme you can no longer use the phptemplate_ prefix and instead have to use the name of your theme as a prefix instead:
Drupal 6:
/**
* both examples work in Drupal 6
*/
function phptemplate_breadcrumb() {
......
}
?>
Drupal 7:
function THEMENAME_breadcrumb() {
.....
}
?>
Read more on why the phptemplate prefix was removed.

Granular rendering in node and user templates

Ever hacked up your node.tpl.php file and print bits of the $node object all over the place to get the content layout exactly as you want? Well with the new render & hide functions things just got a little easier!!
The $content variable is now a keyed array of the content values including field values, comments, file attachments or other node components which vary depending on the view mode (full, teaser etc). If you’d like to go deeper check out the the node_build_content API doc on api.drupal.org
Here’s an example from the Garland theme node.tpl.php file, as you can see the node links & comments can be pulled out and rendered as where you please:
 
print $content_attributes; ?>>
          // We hide the comments and links now so that we can render them later.
     
hide($content['comments']);
     
hide($content['links']);
      print
render($content);
   
?>

 


 

    if (!empty($content['links'])): ?>
     
    endif; ?>

    print render($content['comments']); ?>
 

Alter hooks available to themes!!

This is by far my favourite addition.
The following alter hooks have now be added or made available to use in your themes:
  • hook_page_alter – This is a new D7 hook which allows all variables displayed on a page to be alter or hidden.
  • hook_form_alter – I’ve lost count of how many times I’ve wanted to make a small tweak to a form without wanting to override the form theme or create a custom module.
  • hook_js_alter
These additions give even more power to Drupal theme developers which is brilliant news!! :) :)

Theme suggestions available for theme_menu_link() and theme_menu_tree()

I’ve previously used the awesome menu_block module to theme out menus better as it uses a similar theme suggestion engine that is now available in Drupal 7.
The new suggestion work for both theme_menu_tree which provides some wrapper HTML for the menu and theme_menu_link which does the actual rendering of the menu link, so you can override these functions per menu.
Here’s a simple example for a theme_menu_link override for a fictional user called “account” where we simply add an extra around the link to give us another HTML element to theme with:
function THEMENAME_menu_link__account($variables) {
 
$element = $variables['element'];
 
$sub_menu = '';

  if (
$element['#below']) {
   
$sub_menu = drupal_render($element['#below']);
  }
 
$output = ''. l($element['#title'], $element['#href'], $element['#localized_options']) .''; //add extra span tag here for theming
 
return '. drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "\n";
}
?>

hook_preprocess is now followed by hook_process

I’m still a little hazy on the exact usage of the new hook_process so I wouldn’t consider it a favourite of mind….yet but I thought it should be mentioned.
The idea is that hook_preprocess is run first to define values of variables then hook_process is fired after to render variables.
An example being the $classes_array is defined/constructed in hook_preprocess and is then rendered into the $classes string in hook_process.
That concludes my favourite additions to Drupal 7 theming but please note that with Drupal 7 still being developed some of this functionality could (although unlikely) change so comment below if you find something has changed or add your favourite additions.