Mar 08 2013
Mar 08

In this blog we will see some basics of drupal theming .

1.               Importance of theming in drupal?

2.               Which files are required for theming?

3.               What does these files works?

Before we go to actual theming, we will first see theme layer in drupal.

Theme Layer In Drupal:

[Source---Packtpub Drupal 7 Module Development]

From above fig,

•         There are two layers, business logic(Module) and presentation logic(Theme)

•         In business logic (Module), data comes in(plain data, no html and no tags) and these data get check in business logic(functional units, all modules, plugins, etc.), then default themes is applied on data(plain data).

•         In presentation logic (Theme), additional styles are applied if mention according to requirement and in the same logic, if new theme is provided by developer then it get override on default theme.

•         Final output is displays in form of html format i.e. final output is embedded in html format.

This is all about theme layer in Drupal.

Now we will see What Theming is?

1.               In Drupal, presentation layer displays the content to website visitor based on set of template.

2.               “A Theme is a collection of files that define the presentation layer.” ----Drupal.org

3.               You can change theme layout by different types of module(e.g.: panels, Display suits, skinr, etc..), but these modules only changes layout of pages not the frame of website

4.               To change actual frame of your website then you need different types of files.

Files involved in Theming:

Many files are required for theming i.e. CSS files, script files, .tpl.php files, etc,

Files required for theming are:

1.               .info file

2.               template file(.tpl.php file)

3.               CSS file

and many files required for theming but it depends on how much you want to coustomise the look of your website like:

1. node.tpl.php

2. block.tpl.php

3. comment.tpl.php

5. style.php

6. html.tpl.php and many more....

.info file:

These .info contain: name of your theme, version of Drupal, CSS file, regions for your frame, features, script files (if available), etc..

Now let’s see how to define all of these file:

name = Ourtheme [Declares theme name]

description = my theme [Declare theme description]

core = 7.x [Declares what version of Drupal]

stylesheet[all][] = style.css [Declares CSS files]

script[] = script/my.js [Declare javascript file]

regions[content] = Main content [Declare regions]

features[] = logo [Declare features]

Above mentioned anatomy of theme are pretty much clear from their name only, but what region are:

 

                                                                                                   [google image]

We can understand the concept of region in theme development easily from above fig. Different fruits are placed in different region i.e. every type of fruit have one different region, these same happen in Drupal theme. Different region are allocated for content, left side bar, right side bar, header, footer, etc.

i.e. in .info file

region[leftside bar] = Left side bar

region[header] = Header, etc..

page.tpl.php:

1.               Like in html file, we print all content in tags of <body> </body>

2.               Same, you print your region in your page.tpl.php

<?php print render($page['preface']); ?>

3.               Create the page layout, where content is printed, menu, search, sidebar, etc.

e.g.: below is from my page.tpl.php file, but this code is for main section and same we can write for  header section, footer section, etc..

<div id="main" class="clearfix">

      <div id="content">

        <div id="content-inner" class="inner column center">

          <?php if ($breadcrumb || $title || $messages || $tabs || $action_links): ?>

            <div id="content-header">

              <?php print $breadcrumb; ?>

              <?php if ($page['highlight']): ?>

                <div id="highlight"><?php print render($page['highlight']) ?></div>

              <?php endif; ?>

              <?php if ($title): ?>

                <h1 class="title"><?php print $title; ?></h1>

              <?php endif; ?>

              <?php print $messages; ?>

              <?php print render($page['help']); ?>

              <?php print render($tabs); ?>

            </div> <!-- /#content-header -->

          <?php endif; ?>

          <div id="content-area">

            <?php print render($page['content']) ?>

          </div> <!-- /#content-area -->

          <?php print $feed_icons; ?>

          </div>

        </div> <!-- /content-inner /content -->

        <?php if ($main_menu || $secondary_menu): ?>

          <div id="navigation"><div class="section clearfix">

            <?php print theme('links__system_main_menu', array(

              'links' => $main_menu,

              'attributes' => array(

                'id' => 'main-menu',

                'class' => array('links', 'clearfix'),

              ),

              'heading' => array(

                'text' => t('Main menu'),

                'level' => 'h2',

                'class' => array('element-invisible'),

              ),

            )); ?>


            <?php print theme('links__system_secondary_menu', array(

              'links' => $secondary_menu,

              'attributes' => array(

                'id' => 'secondary-menu-links',

                'class' => array('links', 'clearfix'),

              ),

              'heading' => array(

                'text' => t('Secondary menu'),

                'level' => 'h2',

                'class' => array('element-invisible'),

              ),

            )); ?>


          </div></div> <!-- /.section, /#navigation -->

        <?php endif; ?>

        <?php if ($page['sidebar_first']): ?>

          <div id="sidebar-first" class="column sidebar first">

            <div id="sidebar-first-inner" class="inner">

              <?php print render($page['sidebar_first']); ?>

            </div>

          </div>

        <?php endif; ?> <!-- /sidebar-first -->

        <?php if ($page['sidebar_second']): ?>

          <div id="sidebar-second" class="column sidebar second">

            <div id="sidebar-second-inner" class="inner">

              <?php print render($page['sidebar_second']); ?>

            </div>

          </div>

        <?php endif; ?> <!-- /sidebar-second -->

    </div> <!-- /main -->
 

so, in all we can say that,

[Source: Internet]

Folder Structure for theme folder:

Below is the structure of fusebasic theme:

1.go to var/www/your_drupal_folder/sites/all

2. in theme folder put your theme(here fusebasic theme)

3. like this will be your theme folder(here fusebasic theme) i.e css folder, script folder, themplate folder, etc..

4. this your templates folder

For more anatomy refer:

http://batayneh.me/sites/default/files/Drupal7-theming-cheatsheet_2.pdf

Sourses:

1. Internate

2. Book---Packtpub Drupal 7 Module Development

3. www.drupal.org

4. shareslide

Feb 15 2013
Feb 15

I am so glad that my Dear friend Ashwini broke the ice for us. And I would

like to thank him for the same, I followed the steps and Bingo!!! 

I have Drupal on my machine. I  walked little further and quick look over changes.

Most striking changes I found :   

1) The biggest bang, if you haven't heard of is "Symfony meets Drupal 8"

Yes, that is correct! Drupal 8 has adopted many low level components like 

HttpFoundation, HttpKernel, Routing, EventDispatcher, DependencyInjection, and ClassLoader from 

Symfony to achieve more structured code & semantics with the help of OOPs,

which community was waiting a while.

According to me  Drupal will achive the same objects transmission through out

the flow with better encapsulation.

"By adopting HttpKernel, Drupal and Symfony projects will become more interoperable. 

It means that you will be able to easily integrate your custom Symfony applications with Drupal... and vice-versa."

- Courtesy Fabien Potencier, www.symfony.com (http://symfony.com/blog/symfony2-meets-drupal-8

2) New drupal 8 has Twig as template engine. Personally I was waiting for such change in drupal after

working for last 5 years. It was always a wish to have template engine as a part of core to speed up the 

performance. I hope it will be fast, secure & flexible as it is mentioned on http://twig.sensiolabs.org/.

Thanks to Fabien Potencier. But I guess this is also because Symfony2 has it.

3) The next thing made a tick was the folder structure & separations. Now drupal has structure like

core, modules, profiles, sites, themes and index level files with ROBOT.txt. The core has drupal's

traditional file & folder structure but there you can find additional folder called as "vendor".

This is the folder where symfony components resides. You can find 

Symfony classes : 

Symfony framework classes

Twig :

Twig is a modern template engine for PHP 

Composer :

Composer is a tool for dependency management in PHP. It allows you to declare the dependent 

libraries your project needs and it will install them in your project for you.

Doctrine :

The Doctrine Project (or Doctrine) is a set of PHP libraries primarily focused on providing 

persistence services and related functionality.

EasyRDF :

A PHP library designed to make it easy to consume and produce RDF.

Guzzle :

Guzzle takes the pain out of sending HTTP requests and the redundancy out of creating web service clients.

By bunch of all these, drupl 8 was never powerful than this.

4) While administration I did not find many changes than admin menu structure. But there are some modules

included in core than drupal7. 

Majorly, 

Views is part of core now. 

ckEditor is in there, which was surprise to me as I always prefered TinyMCE for Drupal sites. 

Language module is included in core for i18n.

With curasity I tried to have contents in two differant languages and it is user friendly.

Though personally I feel adding plugins in CKEditor is pain and needs improvements.

5) Last but not the least for now, documentation of hooks available for Drupal 8 is ready before 

it is stabalizing core. It is at http://api.drupal.org/api/drupal/core!includes!module.inc/group/hooks/8

And I am happy that it will really help community to conribute back to core modules/themes, core & contributed 

modules/themes.

I will try to explore more and will try to share more in upcoming posts.

Feb 12 2013
Feb 12

Hey all now days Drupal community is very hard at work in developing Drupal 8. If you are passionate about Drupal and want to contribute to Drupal 8 but not finding any source to start then this is blog can help you.

What we will cover in this blog :-

1       How to take Drupal 8 stable core to your local machine and start developing with it.

2       What's new in Drupal 8?

3       Some explanation of changes with code.

Below are the steps to setup Drupal 8 stable core to local machine. I am hoping you have GIT installed in your machine.

1       git clone --branch 7.x  http://git.drupal.org/project/drupal.git

2       cd Drupal

3       git checkout 8.x

If you want to go back to your D7 version just do " git checkout 7.x " . For updating your Drupal 8 core do "git pull " . It will update your Drupal 8 code instance .

Now you can start building your custom modules , Themes for Drupal 8 .

In Drupal 8 till now what community has updated has many changes in core . Below is link of list of changes in Drupal 8 .

http://drupal.org/list-changes/drupal

You can check out each change and start writing your code with Drupal 8 .

Menu change example :-In D8 menu links are converted into entities . So in order to create new menu in Drupal 8 you can do like this .

<?php

$menu_link = entity_create('menu_link', array(

  'link_title' => t('Home'),

  'link_path' => '<front>',

  'menu_name' => 'main',

));

$menu_link->save();

?>



Saving menu links with Drupal 8 :-



<?php

$menu_links = entity_load_multiple_by_properties('menu_link', array('link_path' => $link_path));

foreach ($menu_links as $menu_link) {

  $menu_link->link_title = t('New link title');

  $menu_link->save();

}

?>



Some changes are also happens with hooks like :-

hook_menu_link_alter() has been replaced by hook_menu_link_presave()

hook_translated_menu_link_alter() has been replaced by hook_menu_link_load().

Below are some other links which give you information about Drupal 8 development , roadmap , Documentation , code , contributors , IRC channels , meeting times etc.

http://drupal.org/community-initiatives/drupal-core

http://drupal.org/update/modules/7/8

This is link to video which drive you through some custom code development in Drupal 8 .

http://sydney2013.drupal.org/program/core-conversations

Some other links for understanding architecture and developing in Drupal 8 :-

http://drupal.org/node/1911346

Please feel free to comment and send your queries to me .

Feb 09 2013
Feb 09

In this blog I will drive you through setting up Drupal project instance on Ec2 micro instance of AWS and setting up ftp on your Drupal instance. Before this, of course you have to register with AWS which is straightforward.

So, what we will understand from this blog:-

1       Choosing OS and assigning some security rules on our instance.

2       How to access our instance and play around it?

3       Setting up LAMP on our AWS micro instance

4       Setting up ftp on AWS micro instance

5       Managing your Drupal project using ftp connection using filezilla

Once you are registered with AWS you have to login into your account. Among the AWS services just click on EC2 link which is nothing but a virtual server in the cloud. It will redirect you to EC2 dashboard where you can manage your entire instance. Now for creating new instance follow below steps:-

1       Just click on Launch instance select Classical wizard and click continue.

2       Now you have to select Amazon Machine Image (AMI) from one of the tabbed lists below by clicking its Select button.

3       Let’s say we select Ubuntu 12.04 LTS.

4       Next leave default settings except just select micro instance from the instance type because it’s free to use and click continue.

5       Next again leave default setting and click continue.

6       Next again leave default setting and click continue.

7       Now you have to give name of your key and value. I recommend give key value name more sensible with your project and click continue.

8       Now select creating a new key pair as we are new we don't have existed key pair. Give name to your key pair file it should make sense with regards to your project. Download your keypair.pem file and save at a safe place because we need this file later.

9       Next select create a new security group. Here we will assign some security rule and enable http, SSH and ftp connection to our instance. Http port range is 80 SSH port range is 22, for ftp select custom TCP rule and give port range 21-22. About source you can give any IP range as you need or just leave default for now.

10    Just click continue and launch instance. Your instance will be running in some time as AWS will take some time to run your instance.

Now our EC2 micro instance is running. You can check out from your dashboard.

Now we setup LAMP in our Ubuntu 12.04 LTS instance. For this we access our Ubuntu instance from terminal and setup LAMP in that. Below are the steps to access and setup your LAMP in Ubuntu 12.04 LTS instance.

1       Open your terminal and go to the directory where you stored your key pair file .pem file then run this command into your terminal sudo SSH -i file_name.pem [email protected] .

2       It will give you Ubuntu prompt in your terminal. You can understand like this that now you are logged in into your Ubuntu machine and you can do anything over there. The main thing here is you have to run all commands with "sudo" or as a root user which works on file system directory.

3       In order to setup LAMP we will install three packages in it . Run these command from terminal :-

?       sudo apt-get install apache2

?       sudo apt-get install mysql-server

?       sudo apt-get php5 php-pear php5-mysql php5-suhosin

That's it your LAMP environment is ready. You can check it by navigating your instance url that is for example look like this ec2-43-23-32.compunte.AWS.com in browser. It will give you message Localhost is working something like that.

Till here we got our LAMP environment running into our EC2 instance. Now we install our Drupal 7 instance in it. Here in Ubuntu instance we don't have any ftp connection with ftp client or server. So we can use SCP for taking Drupal tarball from our local instance or we can use wget utility of linux to download Drupal from its url. Below are steps to install Drupal 7

1       cd /var/www/

2       wget  http://ftp.Drupal.org/files/projects/Drupal-7.12.tar.gz

3       tar xvf Drupal-7.12.tar.gz

4       mv Drupal-7.12 Drupal

Below is a link which can tell you how to install Drupal in linux . Just follow all those steps.

http://Drupal.org/documentation/install/developers

When you setup with your mysql database and Drupal configuration then just browser link like for example:

http://ec2-43-23-32.compute-1.amazonAWS.com/Drupal/

It will take you to your Drupal site.

Now we will see how to setup ftp on Drupal instance .Why we need ftp for Drupal instance. In order to work on Drupal we have to use many modules, themes and libraries. So we have to upload those things on site. We can achieve this with SCP but that will be more difficult because you have to do via command line.  Here we will see how to setup Filezilla ftp on Drupal site which is on AWS EC2. Below are the steps to setup filezilla as a ftp client.

1       Install filezilla  into your local system :- sudo apt-get install filezilla

2       Now open filezilla click on file > site manager

3       Enter the details of your site here like :-

?       HOST - ec2-43-23-32.compute-1.amazonAWS.com

?       Port- 22

?       Protocol - SFTP(SSH file transfer protocol )

?       Logon Type - Normal

?       User - Ubuntu

?       Password - Ubuntu . Then click on ok don't click on connect this time.

1       Now click on Edit> Settings > SFTP and addkeyfile. Navigate your .pem file here. It will ask you to convert .pem file just select ok. Now filezilla have your instance credentials to connect and everything is good to connect to your Drupal instance.

2       Now click on file > site manager > connect

Now you can transfer all files from your local to Drupal instance.

I hope you enjoyed this blog. Please feel free to comment and send queries to me.

Reference:-

https://AWS.amazon.com/documentation/

http://library.linode.com/lamp-guides/Ubuntu-12.04-precise-pangolin

Thanks for reading draft of this. Appreciate your help and contribution.

Aug 06 2012
Aug 06

How to send Message or Invitation to LinkedIn friends using Linkedin account with Drupal?

1)     CreateLinkedIn Application

URL - https://www.linkedin.com/secure/developer

·       Create LinkedIn Application 

·       Get Api Key and Secret Key

 

2)      Use following Module for integration

·        Linkedin - http://drupal.org/project/linkedin/

·        OAuth- http://drupal.org/project/oauth

Set consumer key and secret Key then authenticate using OAuth. After authentication it will open a connection to LinkedIn. Once connected, you will be able to access the friends and their information.

function connection()

{

$consumer_key = ‘abcde’                      // app key

$consumer_secret = ‘xyz’  // secret key

Send token to oauth for authentication

$consumer = new OAuthConsumer($consumer_key, $consumer_secret, NULL);

$base_url = "https://api.linkedin.com/uas/oauth";

$url = $base_url . "/requestToken";

$signature = new OAuthSignatureMethod_HMAC_SHA1();

 $request = OAuthRequest::from_consumer_and_token($consumer, NULL, 'POST', $url);

   $request->sign_request($signature, $consumer, NULL);

    $header = $request->to_header("http://api.linkedin.com");

$provider = 'linkedin';

 $tokens = db_fetch_array(db_query("SELECT * FROM {linkedin_token} WHERE uid = 120 AND type = 'access'")); // get token key and token secret from query

        $token = array(

            'token_key' => $tokens['token_key'],

            'token_secret' => $tokens['token_secret'],

        ); // get login user token

$result = linkedin_get_fields('http://api.linkedin.com/v1/people/~/connections', $token);

 // $result is array of connection of friends

}

This function sends Message to Friends

Send message()

{

$base_url = "http://api.linkedin.com/v1/people/~/mailbox";

$signature = new OAuthSignatureMethod_HMAC_SHA1();

$consumer_key = ‘c2tqvnglgfyq’                      // app key

$consumer_secret = ‘hGEkm6Gdpc3ibjP9’  // secret key

 $consumer = new OAuthConsumer($consumer_key, $consumer_secret, NULL); 

$token = new OAuthConsumer($tokens['token_key'], $tokens['token_secret'], 1); // user key

$request = OAuthRequest::from_consumer_and_token($consumer, $token, "POST", $base_url);

// send URL

 $request->sign_request($signature, $consumer, $token);

 $header = $request->to_header("http://api.linkedin.com");

 $friends_id=’abcdf43’;

// send you message using xml format

$xml_message_body .= '<?xml version="1.0" encoding="UTF-8"?>';

$xml_message_body .= '<mailbox-item>';

 $xml_message_body .= '<recipients>';

 $xml_message_body .= '<recipient>';

 $xml_message_body .= '<person path="/people/' . $friends_id. '" />';

 $xml_message_body .= '</recipient>';

 $xml_message_body .= '</recipients>';

$xml_message_body .= '<subject>Flexibage Invitation</subject>';

 $xml_message_body .= '<body>http://flexibadge.10jumps.org</body>';

 $xml_message_body .= '</mailbox-item>';

$response = _linkedin_connections_http_request($base_url, $header, $xml_message_body);

}

The LinkedIn connection -  http request function  to post your request  to server.

function _linkedin_connections_http_request($url, $header, $body = NULL) {

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

    curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));

    curl_setopt($ch, CURLOPT_URL, $url);

    if ($body) {

        curl_setopt($ch, CURLOPT_POST, 1);

        if ($body == 'token_request') {

            curl_setopt($ch, CURLOPT_POSTFIELDS, '');

        } else {

            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

            curl_setopt($ch, CURLOPT_HTTPHEADER, array($header, 'Content-Type: text/xml;charset=utf-8'));

            curl_setopt($ch, CURLOPT_POST, 1);

            // It is important to set request to POST for sending messages.

            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');

        }

    }

    // execute the curl call

    $output = curl_exec($ch);

    // get the http response code

    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    // close the curl connection

    curl_close($ch);

    // check for success. An httpd status of 201 inicates success:

    // see https://developer.linkedin.com/documents/messaging-between-connections-api

    if ($http_code == '201') {

        return $http_code;

    } else {

        // otherwise, return the xml $output

        return $output;

    }

}
Aug 04 2012
Aug 04

0) Try and flush the menu cache, theme cache
Explanation:     I mentioned this in previous post also that, many times we go on making the changes and forget to clear the cache.    Drupal caches everything in database and until and unless you clear cache, it can not pick new changes done in code. This is must when you do something related to menu in the custom module and theme.

     
1) Check for the url aliases setting
Explanation:    Have a look at site building > url alias and get sure of settings. Also you can check if there is any wrong or old alias for your link at site building > url alias > list.
       
2) Verify all the menus
Explanation:        While working as a part of large team, you can use Git/SVN like softwares to manage your code but you can not sync DB. So many times we try to track a url which (assigned to menu) is either deleted or disabled in administration.        

3) Check for the panels or pages, views & their permissions
Explanation:    There are modules like 'Panels' or 'Views' to create view pages to display screens. And we assign urls to such view pages, but because of some mis-configurations the page gets broken. If you find any 'view' or 'panel' related to broken page (broken url) you should check for the following points :
            -    Selected field to be shown but the dependent module is missing
            -    Custom PHP field is added with wrong code
            -    Custom MarkUp field is added with wrong code
            -     Rewritten the output for some field which is having wrong code
  
If every thing is okay in views please check the permissions of the view. You can find it in the views > edit [view name] > Permissions option. It is same for panels.

4) The White Screen of Death (Completely Blank Page)
Explanation:    If you still do not see the desired page on url please go through http://drupal.org/node/158043/ . This is awesome post which will give you the vision to see and check for the errors.  

5) Check for all custom modules
Explanation:    Drupal is a really flexible framework and you can achieve the same thing via many ways. But just because it gives us flexibility we should not code in raw manner. We should always have scope to track it and a specific location control. What I meant is, we should have our own conventions also. There should be some specific location where you will put your own custom codes. Usually inside /sites/all/modules.
       
Check all such modules to see custom code and look for 'hook_menu' implementation. And if you find the url which you are looking for you should debug the callback function and your error will be resolved.
       
6) If error is module specific, update module & run update.php               
Explanation:    Check if the error is module specific meaning that the error show up after visiting a specific page/url from a module. If the culprit module is contributed or core module check for the Update of module on 'drupal.org'. Make sure you update the module to the latest version. Running update.php is necessary after this process because update may need some necessary manipulations in database.        

7) Check .htaccess for any specific rule
Explanation:    If none of the above works for you, please have a look at .htaccess. It may be a condition that someone might have placed a hard code redirect rule because of which you are not able to  see the desired page.

Jul 31 2012
Jul 31

0) Try and flush the menu cache, theme cache
Exp:     Many times we go on making the changes and forget to clear the cache. Drupal caches everything in database and until and unless you clear cache, it can not pick new changes done in code. This is must when you do something related to menu in the custom module and theme.
 
1) Check the content-types and it's fields on the admin side
Exp:    Overall, it is the best practice to check the administration side and get confirmed about 'all good' condition.

2) Check the module dependencies
Exp:     If you have created a field and it has some dependency to be fulfilled; the field may not work as desired. e.g. If you have used/imported the field which works based on condition but the actual 'Conditional field module' is missing, then the field will not work.

3) Check the settings involved in CCK fields
Exp:    Check the field created using CCK has all the configurations. This is necessary especially in case where you export and import the content-types. As if you export a feature and import it in other environment, some modules may get installed little later, and here the configurations can be missed out.

4) Check the permissions of CCK fields
Exp:     This is extremely important step in drupal troubleshooting, most of the problems get solved in this step. Check if the content permission module is enabled and if yes go visit /admin/user/user/list. 

        Note which user you are looking at and what roles it has. Now go and visit /admin/users/permissions.
        Get confirmation that the user you are looking at has proper access permissions. While doing this, make sure you are not logged in as user->uid = 1 (i.e. admin), because this user has no restrictions it can see everything.

5) Check the hook_form_alter function
Exp:  If your problem still exists, means there is something wrong in the code. This happens generally while moving the site from dev -> test -> live. Whether you have this function in the module or have you missed the complete file? Make sure you are using '&form' in the arguments to hook_form_alter(). Have you written the most important " case 'content-type-machine-name': "?  

6) Check the machine name of content-type and CCK fields used in hook_form_alter
Exp:     If it is all there please check for the spell difference in content-type machine name set in administration and the machine name used in code. And if your problem fit in this case, please don't bang your head. This is perfectly normal if you are working on big poject or working with big team.

7) Check the weight of your custom module
Exp:    Many times you do all above correct but still your module hooks like hook_form_alter() or hook_user() does not reflect the changes or work as desired. This is because your module is included and hooks are invoked before some of core/necessary modules. So it is always best to set the heavy weight (greater integer number) to your developed custom module, in order to get it invoked at the last of the stack of modules. Most of your worries will go away, benefited your site will be always consistent. If you are not in situation where you can actually uninstall / install module then go to system table, find the module record, set the weight column, reload drupal and clear the cache.

8) Check for the template.php for any hacks, hard codes or preprocessor hooks
Exp:    This does not happen usually, but may happen if some novice is in your team or somebody had to do because of toughest situation. Now you are in driver seat where you do not know much, then please go ahead and check the template.php of the active theme for hooks or hacks.

9) Check for specific CSS rule for the form item / form
Exp:    This is very common, the people beginner in drupal feel this as short and easy way to fullfill the requirement and make some of the fields go away on the form. So if your  CCK field is not showing up at all then this could be a problem and give it a thought.

10) Check for the Javascript/Jquery if the particular element is removed from the page
Exp:    Like I mentioned above this goes same with JavaScript, people used remove the fields on "onload" event from the document to get rid of the field.
       
I hope you agree with my views and findings. If you have some other case which is not covered in this post, please take out a minute and contribute a comment. If you disagree with any of my views please comment and share your knowledge.  

Apr 07 2012
Apr 07

Very often we work on projects that are hosted on a remote server. There are multiple ways to work on the remote files:

1. ssh into the remote machine and use an editor like vi or emacs to edit the files

2. Develop on your local machine and FTP every change

The second choice is preferable if you want to use an IDE or if the conenction to the server is slow.

However, there is a 3rd approach, that combines the above two. If you are using Eclipse or NetBeans as your editor, then you can connect your editor to the remote server over FTP. I will only cover Eclipse since that is what I use.

1. Download and Install Eclipse PDT from http://www.eclipse.org/projects/project.php?id=tools.pdt

2. Go to Help->Install New Software...

3. Chose 'All Available Sites' and serach for 'Remote System' and then select the Remote server Explorer plugins as shown in the attached screenshot.

Install RSE plugin

4. This will install the remote server explorer or RSE plugin.

5. There are other ways to insall the plugin, but this is the only method that really worked for me.

6. Next opn the 'Remote Server Perspective' ineclipse (I am assuming basic Eclipse knowldge) and add the remote server location, including your username and password. Use the FTP option.

Now, under the Remote Systems tab in the Eclipse, you can browse to the directory of your Drupal installation and start editing your files. Everytime you save, you are saving on the remote server. Just make sure you are not overwriting changes from other developers and that you use SVN or CVS as a code repository.

There is a Drupal plugin for Eclipse and you can get the instructions from here:

Apr 03 2012
Apr 03

You can face performance issues in two sides - client side and server side. Client side performance issues can be caused by a bad javascript library or plugin, too much files to download, etc. Tools such as Chrome's web inspector or Yahoo’s YSlow for firefox can tell you what assets (CSS files, JS files, images) are being loaded, how big they are and how long it is taking, among other useful metrics. In the backend, there are lot of possible causes though. Like a particular page or View. Sometimes a particular view block (not well configured) can cause extreme slowness in the site where ever we are using that block. Pagination in views can drastically improve the execution of that view.


It's a good idea to determine what the bottleneck is, if possible. Take a look at the load on your CPU when you notice poor performance as serving complex PHP applications can be quite taxing. You might also want to turn on the Devel module's query log (or the MySQL slow query log) to determine if any queries are taking an exceptional amount of time. It will highlight all the queries whose execution time is more than a threshold.
On every production Drupal site I'll take the following steps for a quick performance improvement:

  • Enable CSS/JS compression - this mainly reduced the number of trips the client makes to the server.
  • Disable unnecessary modules - also uninstall them if not required at all.
  • Clean up as many PHP errors as possible, especially if we're logging with the dblog or syslog modules (for development, enable all the error display settings in PHP as well as Drupal)
  • Make sure the MySQL query cache is enabled and properly configured
  • Sprite images where possible for frontend performance benefits

The aforementioned steps will go a long way to ensuring that your site is performant while having very few, if any, detrimental effects. With that said, sometimes this isn't enough. Fear not, we can go further to attempt to address outstanding issues:

  • Cache expensive or time consuming operations, for example, requesting data from a web service. Drupal makes this simple with cache_set() / cache_get().
  • Turn on additional caching, such as Views or Block, if possible
  • Use the MySQL slow query log and run EXPLAIN on the logged queries. Look for queries which have joins using filesort or temporary tables and determine whether these could be rewritten or sped up with an index.
  • Analyze the traffic pattern. A site with a largely anonymous user base can see a significant benefits from implementing the Boost module or Varnish in to the server stack.
  • Change cache backends. Drupal reads and writes a lot of data from its caches (as it should) so you can see some great speed improvements storing this data in memory (fast!) rather than the database (on the disk, slow!).
  • Authcache ( http://drupal.org/project/authcache ) helps in caching both anonymous users and logged-in authenticated users.

We're still just scratching the surface of optimizations that can be made to a website or the server stack, or even the servers themselves. Scaling vertically (using bigger servers) or horizontally (using more servers) are solutions that are often utilized when a site has outgrown its existing server (and sometimes before that point).

Mar 09 2012
Mar 09

The Gateway to 21st Century Skills (www.thegateway.org) is a semantic web enabled digital library that contains thousands of educational resources and as one of the oldest digital libraries on the web, it serves educators in 178 countries. Since 1996, educational activities, lesson plans, online projects, and assessment items have been contributed and vetted by over 700 quality organizations.

Given their rich pedigree, the site serves over 100,000 resources each month to educators worldwide. Since 2005, the Gateway has been managed by JES & Co., a 501(c)(3) non-profit educational organization. The original site was built on Plone several years ago. In recent years the constraints of the old site proved too great for the quality and quantity of content, and the needs of its increasingly engaged readership. It was becoming difficult and expensive to manage and update in its current configuration.


JES & Co., as an organization with a history of embracing innovation, decided to move the Gateway onto Drupal and looked to 10jumps to make the transition happen. The site had to be reliable with very high up time. Moreover the site would have to be able to handle the millions of hits without batting an eyelid. And most importantly, the faceted search would have to work well with the semantically described records. Based on the requirements, Acquia’s managed cloud seemed like the best approach. It can help a site scale across multiple servers and Acquia provides high-availability with full fail-over support.
“If something does go down, we know that Acquia 24x7 support has our back” - 10jumps


How they did it


There were several hosting options, but very few that met the requirements for the Gateway. And definitely none that made the development-testing-production migration seamless and easy. Usually there are too many manual steps raising the chances of error.

After a few rounds of technology and support evaluation calls, Acquia was retained to provide hosting and site support. A good support package, combined the expertise of Acquia’s support team was a compelling reason to make the move. The technical team at 10jumps was also fairly confident that the move would be a good choice for their customer – the Gateway, freeing them to focus on the site development. With Acquia’s Managed Cloud and the self-service model, code, local files and database can be migrated between development, testing and production systems literally with mouse clicks. With the seamless migration, the development cycle became shorter and with Git in place, collaboration between developers became easier. Moreover caching for anonymous content was provided out of the box and the 10jumps developers did not have to navigate tricky cache settings. Moving the developers to the new platform was the first step and soon the team was on an agile development track, being able to develop and roll out features quickly.

The result

After the new site went live, we were certain that

TheGateway.org would not be effected by traffic spikes, nor would the site be down because of a data center outage. More importantly, the semantically described data could be searched more efficiently because of the integration with Apache’s Solr search that comes from being in the Acquia cloud.
The development life cycle had gone from being clunky and broken to being smooth and agile. The redesigned site makes it simpler for the end users to navigate through large amounts of data and the powerful search is returning better results - improving overall user experience.

Jan 17 2012
Jan 17

Create the custom autocomplete field using the custom module.
How to create a custom autocomplete form and to get the user names or or anything else?
Here is the example.
/**
*Implementation of hook_menu().
*/

$items['custom_automplete_form'] = array(
'title' => 'Custom autocomplete form',
'page callback' => 'drupal_get_form',
'page arguments' => array('custom_autocomplete_form'),
'access arguments' => array('access autocomplete'),
'type' => MENU_NORMAL_ITEM
);
/**
*Implementation of function custom_autocomplete_form()
*/

function custom_autocomplete_form(){
$form = array();
$form['customauto'] = array(
'#type' => 'textfield',
'#autocomplete_path' => 'custom/autocomplete',
'#description' => t('Please type any letter.'),
);
return $form;
}
#autocomplete_path – Custom path to get the autocomplete result.
/**
*Implementation of hook_menu()
**/

$items['custom/autocomplete'] = array(
'title' => 'Custom autocomplete',
'page callback' => 'custom_autocomplete',
'access arguments' => array('access autocomplete'),
'type' => MENU_CALLBACK
);

/**
*Implemtation of function custom_autocomplete($string = '')
**/

function custom_autocomplete($string = '') {
$matches = array();
if ($string) {
$result = db_query_range("SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER('%s%%')", $string, 0, 10); // only 10 results will show
while ($user = db_fetch_object($result)) {
$matches[$user->name] = check_plain($user->name);
}
}
drupal_json($matches); //Returns the data in JSON format
}

Dec 23 2011
Dec 23

We have been faced with the situation where we have to explain to our clients why we might recomment using Drupal as a platform. In many cases however, client knows the Drupal is proving its way high up in the list of CMS platforms.

But in cases where Drupal still needs to elaborate on its advantages then google is the best way to do a research. We have come up with a small list of the most important factors as to WHY DRUPAL?

recently was asked by a client to provide some ammunition for selling Drupal to his management team.  I found plenty info using my friend Google, but ultimately had to spend an hour or so organizing it into a concise list of bullet points that I thought addressed the broad spectrum of benefits that Drupal can provide.  I thought I'd share with others who may need something similar at some point.Without further ado...

First, it's Open Source:

  •     Low or nil cost of ownership:No proprietary licensing fees
  •     Backed up by large developer community
  •     Portable and easy to install and configure
  •     Extremely secure
  •     Super functional custom modules to accomplish practically any task
  •     Performance and scalability achieved via built-in caching and integrates easily with 3rd party caching mechanisms
  •     SEO and Google Analytics right out of the box
  •     standards-compliant HTML/CSS
  •     Flexible and powerful theming possible to enable a rich presentation and look&feel
  •     Easy to install and support, runs on Windows or practically any AMP (Apache, mySQL, PHP) stack

    
Web sites running on Drupal include:

 For a more elaborate list on government websites on Drupal please check out http://groups.drupal.org/government-sites.


Lifestyle driven vertical sites like

  •     Running.Zappos.com
  •     Outdoor.Zappos.com
  •    Clarks.Zappos.com
  •     StuartWeitzman.Zappos.com

Gaming Websites:

Drupal isn't only for work: it's also for play, as "FarmVille" creator Zynga proves. While their games usually appear as apps on social networks such as Facebook, its main site is on Drupal.
 

After all the successful examples would you need to be convinced more ....

For all those who have the new year's resoltion as planning to redesign and migrate your current CMS rethink Drupal!

Dec 23 2011
Dec 23

About thegateway.org:

The Gateway has been serving teachers continuously since 1996 which makes it one of the oldest publically accessible U.S. repositories of education resources on the Web. The Gateway contains a variety of educational resource types from activities and lesson plans to online projects to assessment items.

The older version of the website was on plone. The team hired us to migrate it to Drupal. It was an absolutely right choice to make. Given that, with Drupal comes a lot more benefits.

We redesigned the existing website giving it a new look and on Drupal. Then we hosted it on Acquia managed could to boost its performance and scalability. The new look is more compact, organized and easier to use.

It was a very interesting project for us and our team is proud to be a part of such a great educational organization serving the nation.

Looking forward to a grand success of the new launch!

thegateway.org BEFORE:

 

thegateway.org NOW:

Dec 19 2011
Dec 19

If you are familiar with Drupal Views, you might have come across a very nifty feature called exposed filters. If you expose one of the fields as a filter then views provides a widget and a search option, where the exposed field can be searched. There is good video to learn about filter here.

However, we needed to extend the functionality so all the fields of the content type are exposed as  ‘searchable’ fields, not just the exposed fields. If we expose every fields explicitly, then the views filter will create a textbox for each field, which is not pretty. So in our example, we wanted to search ‘Person’ content type. And if the user entered either the first name, last name, address, of any of the values for the fields in the Person content type, a result would be returned.

In order to do this, we extended the hook_views_query_alter (&$view, &$query)

if ($view->name == 'people_list') {

if (startsWith($query->where[0]['clauses'][0], 'search_index.word')) {

$query->where[0]['clauses'][0] = "search_index.word LIKE '%s'";

$query->where[0]['args'][0] = '%' . $query->where[0]['args'][0] . '%';

}

}

Essentially we are modifying the where clause of the query to search with LIKE %<search term>% which will search across all the fields in the content type.

This simple extension of the hook will enable us to search across all the fields of the content type, in addition to the one that is exposed.

In addition to the code above, in the view we also have to add the ‘ Search: Search Terms ‘ as the exposed field in the filter. This step makes sure that the view uses the Drupal search as the search and filter the content type.

Nov 10 2011
Nov 10

Drush is a powerful shell for Drupal. It can many developer tasks really easy to manage from the command line. If you are installing it on Mac OSX, there might be a step or two which you have to perform for Drush to work correctly.

If you have pear or wget on your machine, then the process would be straightforward as described on the Drush site. However, if you are manually downloading the Drush then:

1. Download and untar the Drush in a directory outside your Drupal.

2. In addition, you might have to get the Console_Table. Download and untar it. Find the Table.php in the newly untarred directory. Copy it to drush/includes as Table.inc (i.e. rename the file).

Step 2 is required when you get the following message while running Drush:

Drush needs a copy of the PEAR Console_Table library in order to function, and the attempt to download this file automatically failed. To continue you will need to download the 1.1.3 package from http://pear.php.net/package/Console_Table, extract it, and copy the Table.php file into Drush's directory as /Applications/MAMP/drush/includes/table.inc.

Hopefully this solves your problem if you see the above error.

Oct 25 2011
Oct 25

Drupal 6 offered two ways to display a node - teaser and full mode. However, There might be custom display types required - e.g. RSS display, search result or even home page display. Drupal 7 offers Custom View Modes to achieve custom rendering of the nodes.

You can create new view modes very easily using code or a module like Entity view modes

I will provide an overview of the code required to create a new view mode and defining a new node.tpl to display the node in the newly defined mode

To create a new custom view mode, implement the hook hook_entity_info_alter()

/**
* Implements hook_entity_info_alter().
*/
function my_modele_entity_info_alter(&$entity_info) {
$entity_info['node']['view modes']['rss'] = array(
'label' => t('RSS View'),
'custom settings' => TRUE,
);
}

We can define a node.tpl.php to leverage the above defined view mode

/**
* Implements hook_preprocess_node().
*/
function my_modele_preprocess_node(&$vars) {
if($vars['view_mode'] == 'rss') {
$vars['theme_hook_suggestions'][] = 'node__' . $vars['type'] . '__rss';
}
}

Name of the file will be node-article-rss.tpl.php

If you do not want to write code, you can also use the Display Suite module to achieve something similar. BTW, view modes is not the same as views module.

Jul 02 2011
Jul 02

AHAH is a way to allow developers to add new form elements to an existing form (on a page) asynchronously, without reloading the page again. Please refer the detailed fapi on AHAH.

The main steps for creating an AHAH form are:

1. Attach the AHAH property to a form element. (Not all form elements support AHAH)

2. Declare a callback function which should be called 

3. Implement the callback function

Despite what you might feel, or might have read, once you try a simple AHAH form, you will get used to it fairly quickly.

You will the other functions like hook_menu and menu callback just like normal callbacks. Let's assume that the menu callback function invokes the get_AHAH() function by calling drupal_get_form('get_AHAH');

In this example, a select form element will load additional values on the page if something is selected from the drop down.

 

1. Define and attach AHAH to a form element. 

function get_AHAH(){

$form['class_registration']['select_category'] = array(

'#title' => t('I want to ...'),
'#type' => 'select',  
  '#options' =>  array(
'1' => 'Travel to Mars',
'2' => 'Write the best code',
'3' => 'Take a good vacation'
),
'#ahah' => array(
      'path' => 'mywishes',   // The URL path that the hook_menu will trigger the callback on.
      'wrapper' => 'render-mywishes',   // The div id where the returned HTML will be applied.
      'method' => 'replace',
      'effect' => 'fade',
    ),
);
return $form;
}

2. Declare the callback:

When an item is selected from the select control defined in step 1, the menu with URL 'mywishes' will be triggered. The control goes to the hook_menu. In the hook_menu, you need to define the code as follows:

$items['mywishes'] = array(
'title' => 'Show AHAH response to my wishes',
'page callback' => 'react_to_my_wishes',
'access arguments' => 'access content',
    'access callback' => 'user_access',
    'type' => MENU_CALLBACK, 
);

the function 'react_to_my_wishes' will be called for the URL mywishes. And this method will serve as the callback method. The function will look something as follows:

3. Implement the callback function: 

The callback function will be invoked by the hook_menu when the menu request is made. 

function react_to_my_wishes(){

// Make a DB query and fetch some nodes into the $nodes

        foreach($nodes as $node){
    $value_to_display = $node['node']->title;
    $form['myform'][$node['nid']] = array(
     '#type' => 'markup',
     '#value' => '<li><a class="reaction" href=' . $base_url . 'mywishes/' . $node['nid'] . '>' . $value_to_display .  '</a>',
    );
 }
  $output = theme('status_messages') . drupal_render($form);
  drupal_json(array('status' => TRUE, 'data' => $output));
}

This function will fetch some nodes based on the selection in the previous step. We are creating URL links to the fetched nodes. You can create any other control from the fetched values or react in any other way.

Well that is all there is to the AHAH forms.

So you create a AHAH control, define the callback for it and the then implement the callback function. Quite an ahah!! 

I also found this note to be quite useful. 

 

Apr 02 2011
Apr 02

SAP ES Workplace: An awesome site for understanding and testing all SAP delivered services:

SAP has a site called "ES Workplace" - Enterprise Services Workplace where all the ES delivered by SAP are consolidate in one place. The aim is to improve adoption of these services and for learning and testing purposes.

The site is at: http://esworkplace.sap.com/socoview(bD1lbiZjPTAwMSZkPW1pbg==)/render.asp?packageid=DE0426DD9B0249F19515001A64D3F462&id=F6CFC0EA3EF14BC9841C528272EE8583

The first step is to get access to the system using http://sdn.sap.com/irj/sdn/soareg. The system that hosts all these services is HU2. You can also use sap_esw/eswork123 if you do no want to register.

The Enterprise service bundle for HCM Master data (Human Capital Management) can be accessed with http://esworkplace.sap.com/socoview(bD1lbiZjPTAwMSZkPW1pbg==)/render.asp?packageid=DE0426DD9B0249F19515001A64D3F462&id=A42BC625EB3346748253B1180B293C65

Also available are numerous simple samples that covers all the steps involved in a business process. For example: Create Leave Request business process uses nearly 7 services to perform the business operation.

All the Drupal scenarios use services from the HCM Master data ES bundle.

Since the SAP webservice and the Drupal commons are in different network we do not use Single sign on, rather we use a username/password authentication mechanism to connect to the SAP webservice. For this testing purpose we use the same user name/password for all our connections. Ideally we would be using the SSO, and each user would be connection to SAP using their own credentials.

All the SAP webservices are defined using a standard WSDL with one or more SOAP Action defined in it. All the SAP specific variables are defined using their own namespaces like "http://sap.com/xi/SAPGlobal20/Global". Each SOAP Action takes optionally one or more arguments. To invoke a SAP webservice, you need to invoke a SOAP Action passing relevant parameters, and get back a return XML. Each of these services can be tested right in the ES Workplace (ofcourse only using IE) using the "Test with WS Navigator" button, which is a really useful tool to understand the workings of the webservice.

Mar 29 2011
mg
Mar 29

Amazon AWS + Drupal

(Some familiarity with Amazon AWS is assumed.)

I have always wanted to setup a high performance Drupal on an AWS EC2. There are several advantages of running your website (or web application) on the AWS. Amazon EC2 creates and provisions virtual Linux (or Windows) servers for you and charge you an hourly rate for usage.

With AWS, it becomes easy to distribute and share the Drupal image with others. And of course it is much easier to scale and is definitely cheaper. You can have different virtual servers running the search engine, database and application servers, therefore all scaling independently of each other.

With the introduction of Micro instances and better yet, free micro instances, the barrier to entry for a new user has really dropped. 

I assume you have or can create an Amazon AWS account and use their management console. These aspects are very well covered in Amazon's site and I will not get into the details of creating an account, etc. Amazon has done a great job of creating the documentation and tutorials for getting started.

I will show how to:

1. Setup a LAMP stack on Ubuntu

2. Setup Drupal on the LAMP stack

3. How to install phpmyadmin

4. Configure the database to reside in the EBS instead of the ephemeral instance storage.

1. Setup a LAMP stack on Ubuntu:

I used a 64 bit image Ubuntu image for my purpose. Amazon provides both 32 bit and 64 bit micro instances, but I wanted to start with 64 bit, because their larger servers are only 64 bit and I can use the same image to scale up to larger Amazon servers. I used the Ubuntu image as my base image. This image is available in the US west region only. (Images are unique to regions and you can get similar images for the region you want to use).

Once your AWS account is setup, sign into the Amazon AWS console. Click on the EC2 tab. Check the region you are running in. If you want to run in US West, select it and click on launch instance. The popup following that will allow you to select an image. Search the image id: ami-01772744. Click on start and continue with default options. You will have to select a key-pair and security group. Make sure the port 80 and port 22 are open in the security group you want to use. Port 80 will allow the HTTP access and port 22 will allow the ssh connectivity to the server. 

You also have to know the location of the Amazon's private key file (.pem) for the key-value pair. The Ubuntu server takes a few minutes to start and be available. 

From the command line on your local machine type:

The part following [email protected] has to be replaced by your server's public dns name that Amazon provides on the console. Note there is no root user and all commands will work through sudo. Ubuntu does this to avoid any root user logins. You can access all the administrative functionality using sudo.

BTW, if the command above does not read and execute due to permission problem, you might want to first run:

        chmod 600 [path to key file]/[key file name].pem

Once connected to the remote server console (your first big milestone BTW), you can create a password for the ubuntu user by typing in (optional):

sudo passwd ubuntu

If you want to enable SSH access via passwords so you don't require the .pem file every time you can do the following:

 edit /etc/ssh/sshd_config to have

PasswordAuthentication yes

Restart the ssh deamon

sudo service ssh restart
OR 
sudo /etc/init.d/apache2 restart

Now with the basic logistics in place, let's set up the LAMP stack on this Ubuntu instance. I found this to be simpler than what I had expected. Write down any usernames and passwords you create from this point on

sudo tasksel install lamp-server

Drupal will need the re-write functionality to be able to perform clean URLs, so run the command

sudo a2enmod rewrite

That's it. You lamp stack is setup.

Go to http://[your public dns] and you should see some output form Apache.

BTW, what I also find really useful is to create some short cuts in the .profile file. For example instead of typing ls -al I can then type la and since I make spelling mistakes while typing sudo, I can point sodu to sudo as well. To do this, edit the /home/ubuntu/.profile file

sudo vim /home/ubuntu/.profile

Add the line:

alias la='ls -al'
alias sodu='sudo'

2. Setup Drupal on the LAMP stack

Setting up Drupal on the LAMP stack is usually just 1 line command and we will need to perform some basic operations:

        sudo apt-get install drupal6

edit the file /etc/apache2/sites-enabled/000-default and change the make the change so that DocumentRoot is now as follows:

        DocumentRoot /usr/share/drupal6

You can install Drupal anywhere and just point the DocumentRoot to that location. Also comment our the block that starts with 

        <Directory />

Also edit the file /etc/apache2/conf.d/drupal6.conf and comment out the line 

        Alias /drupal6 /usr/share/drupal6

restart the Apache so the above configuration changes are reflected correctly

        sudo service apache2 restart

Now go to http://[your public dns/install.php] and voila you are in business.

3. Setup phpmyadmin:

To access the database through phpmyadmin, you will need to install the phpmyadmin and access the URL of the application. Again, this is only optional and you can access all the SQL functionality form command line also. Installing phpmyadmin is trivial:

        sudo apt-get install phpmyadmin

And you are done. Follow the install options if any.

Go the the phpmyadmin application via:

http://[your public dns/phpmyadmin]

The user name is usually root.

4. Configure the database to reside in the EBS instead of the ephemeral instance storage:

Amazon's instances are ephemeral and the storage on the instance is ephemeral as well. That is if the instance is shutdown, the data on it will go away. Now that is not a very desirable configuration. However, Amazon allows you to mount persistant storage on top of the instance. You can mount any number of 1 TB drives on the instance. You can chose the size of the mounted drive at instance startup time.

Essentially, there will already be a mounted drive which you can find by typing:

        mount

The on the mounted drive you can create corresponding directories for logs, DB files and lib

You link the directories on the the mounted drive to the directories on your instance.  The set of commands are as follows:

Shut down the SQL first:
        sudo /etc/init.d/mysql stop

And then create the folders and link them:

        sudo mkdir /vol/etc /vol/lib /vol/log
sudo mv /etc/mysql     /vol/etc/
sudo mv /var/lib/mysql /vol/lib/
sudo mv /var/log/mysql /vol/log/

sudo mkdir /etc/mysql
sudo mkdir /var/lib/mysql
sudo mkdir /var/log/mysql

echo "/vol/etc/mysql /etc/mysql     none bind" | sudo tee -a /etc/fstab
sudo mount /etc/mysql

echo "/vol/lib/mysql /var/lib/mysql none bind" | sudo tee -a /etc/fstab
sudo mount /var/lib/mysql

echo "/vol/log/mysql /var/log/mysql none bind" | sudo tee -a /etc/fstab
sudo mount /var/log/mysql

        sudo /etc/init.d/mysql start

So, in summary, we saw how to setup the LAMP server, install Drupal and make sure the DB runs on the persistant storage. There is still work to harden the image and to create the image from the instance, and that will be covered in a subsequent blog.

Mar 22 2011
Mar 22

At 10jumps we use Drupal heavily. Drupal offers  very flexible, robust and rich UI experience. It is the platform we feel confident of proposing to our clients for their websites.

One of our recent research work at 10jumps alongwith Acquia was to tinker around with Drupal and SAP integration.

Why SAP? The core team at 10jumps have extensive SAP knowledge coming from SAP world.Well just not that! SAP offers the most used ERP solutions in the world.

Why Drupal and SAP? It is still missing in the Drupal community. SAP does sound intimidating at first to integrate with Drupal. But we have dug deep into the intricacies and have found out that it is possible.

Such an integration not only gives the flexibilty of using Drupal as the main platform to build the front-end but also gives us all the benefits that SAP ERP has to offer.

Many businesses small or big use SAP ERP ( HR, CRM, SRM, SCM, Business Intelligence and more).

Now, with Drupal ( Drupal Commons specifically) it can make it possible for them to integrate various scenarios into SAP ERP and provide flexibility of using different front-end solutions.

What is Drupal Commons?

It is Acquia offering. As per the acquia website: Drupal Commons is a single ready-to-use solution that provides familiar tools from the social web to help you create positive buzz, loyalty, and satisfaction in your community. Drupal Commons pre-assembles for you all the features refined across tens of thousands of Drupal community sites. Plus, you can go way beyond that; since Commons is based on the wildly popular Drupal open source web CMS platform, so you get unlimited freedom to add or change how it looks or works to meet the unique needs of your community.

SAP & Drupal Commons can make an unique duo and provide the user all the rich and flexible Drupal Commons features (also free !!) alongwith SAP backend support.

The following video shows the integration scenario between Drupal and SAP HR system.  This video was also featured in a SAP hosted Acquia demonstration.

So if you are interested to find out more of such integrations don't hesitate to contact us at [email protected].

Feb 19 2011
Feb 19

Why should you know about Drupal?

Website is mandatory. Every kind of business small, medium, big or humongous will have to have a website. It’s like the first thing you do after you register your company. Gone are the days when the business owners needed to be convinced of why a website will help in building the brand, improving sales, boosting marketing and the bottom line.

Every business owner knows that the website is a must not only to reach out to potential customers but also to establish an online presence and a strong identity. It is the face of the company’s values, services/products, expertise and trends. That is what people see first nowadays before actually calling in.

Move on to CMS. Now, that a website is the most important thing for a business the next step comes to make it search-engine-friendly and scalable. You can achieve that in many ways by developing it in various platforms or frameworks etc but what you would be missing is the convenience and robustness of a Content Management System (CMS). CMS can help you build a stable, stunning, SEO- friendly and configurable website in a very short period of time as compared to building it in HTML or any other form from scratch. You can now have more control over your website without having to depend on any other vendor to manage it and implement the changes as and when you need in minutes. You will not only have a great website but also save on your website’s TCO (Total Cost of Ownership). Drupal is open source and free. So if you have time and interest to build it yourself it’s a very easy to learn framework. Otherwise we are there to help you.

Get on the Drupal bandwagon. Drupal is the most happening open source today. There are numerous business, governments, schools and corporations adapting to Drupal. Drupal is very powerful and can be used for building large, complex sites. Some example Drupal sites are:

Learn more on Drupal on Dries Buytaert's blog.

Stay tuned for the next blog in which you can learn the top 10 reasons to love Drupal for.

Feb 08 2011
Feb 08

It is fairly trivial and useful to add one or more custom submit handlers in Drupal. in other words, when the user hits the submit button, you can write own handlers to interrupt the normal flow and perform custom actions on the form data. Like what you ask?

You might want to send out mails, preprocess data before submitting it, or store the data in different databases or format (files). There can be seneral usecases where you might want to interfere in the normal code execution flow.

What ever your usecase, here is the way to do it:

1. In the mymodule_form_alter() function (replace mymodule with your module's name), override the #submit property of the form your want to handle.

function mymodule_form_alter(&$form, &$form_state, $form_id){
switch($form_id){
    case 'some_form_id':
      // some code to handle the form. 
       $form['#submit'][] = 'mymodule_mysubmit_handler';
     break;
  }
}

switch($form_id){

    case 'some_form_id':
      // some code to handle the form. 
       $form['#submit'][] = 'mymodule_mysubmit_handler', 'mymodule_second_handler';
     break;
 }


Hopefully you get to use this powerful functionality.

Have fun

Jan 21 2011
mg
Jan 21

Drupal is widely recognized as a great content management system, but we strongly believe that Drupal offers a lot more than that – a framework, a platform, and a set of technology – to build and run enterprise applications, specifically on the cloud. This post is an attempt to explore the benefits and potential of Drupal on the cloud.

Elasticity

One of the last things the customers should worry about their websites is the performance degradation due to sudden spike in the traffic. For years, the customers had to size their servers to meet the peak demand. They overpaid, and still failed to deliver on promise, at peak load. Cloud solves this elasticity problem really well, and if you are using Drupal, you automatically get the elasticity benefits, since Drupal’s modularized architecture - user management, web services, caching etc. - is designed for scale-up and scale-down on the cloud for elastic load.

PaaS

If Heroku’s $212 million acquisition by Salesforce.com is any indication, the future of PaaS is bright. Drupal, at its core, is a platform. The companies such as Acquia through Drupal Gardens are doing a great job delivering the power of Drupal by making it incredible easy for the people to create, run, and maintain their websites. This is not a full-blown PaaS, but I don’t see why they cannot make it one. We also expect to see a lot more players jumping into this category. The PaaS players such as phpfog and djangy have started gaining popularity amongst web developers.

Time-to-market and time-to-value:

Drupal has helped customers move from concept to design to a fully functional content-rich interactive website in relatively short period of time using built-in features and thousands of modules. Cloud further accelerates this process. Amazon and Rackspace have pre-defined high-performance Drupal images that the customers can use to get started. Another option is to leverage PaaS as we described above. The cloud not only accelerates time-to-market and time-to-value but it also provides economic benefits during scale-up and scale-down situations.

Management

The cloud management tools experienced significant growth in the last two years and this category is expected to grown even more as the customers opt for simplifying and unifying their hybrid landscapes. With Drupal, the customers not only could leverage the cloud management tools but also augment their application-specific management capabilities with Drupal’s modules such as Quant for tracking usage, Admin for managing administrative tasks, and Google Analytics for integration with Google Analytics. There is still a disconnect between the cloud native management tools and Drupal-specific management tools, but we expect them to converge and provide a unified set of tools to manage the entire Drupal landscape on the cloud.

Open source all the way

Not only Drupal is completely open source but it also has direct integration with major open source components such as memcached, Apache SOLR, and native support for jQuery. This not only provides additional scale and performance benefits to Drupal on the cloud but the entire stack on the cloud is backed by vibrant open source communities.

Security

It took a couple of years for the customers to overcome the initial adoption concerns around the cloud security. They are at least asking the right questions. Anything that runs on the cloud is expected to be scrutinized for its security as well. We believe that the developers should not explicitly code for security. Their applications should be secured by the framework that they use. Drupal not only leverages the underlying cloud security but it also offers additional security features to prevent the security attacks such as cross-site scripting, session hijacking, SQL injection etc. Here is the complete list by OWASP on top 10 security risks.

Search and Semantic Web

One of the core functionally that any content website needs is search. Developers shouldn’t have to reinvent the wheel. Integration with SOLR is a great way to implement search functionality without putting in monumental efforts. Drupal also has built-in support for RDF and SPARQL for the developers that are interested in Semantic Web.

NoSQL

The cloud is a natural platform for NoSQL and there has been immense ongoing innovation in the NoSQL category. For the modern applications and websites, using NoSQL on the cloud is a must-have requirement in many cases. Cloud makes it a great platform for NoSQL is so is Drupal. Drupal has modules for MongoDB and Cassandra and the modules for other NoSQL stores are currently being developed.

Drupal started out as an inexpensive content management system, but it has crossed the chasm. Not only the developers are trying to extend Drupal by adding more modules and designing different distributions, but importantly enterprise ISVs have also actively started exploring Drupal to make their offerings more attractive by creating extensions and leveraging the multi-site feature to set up multi-tenant infrastructure for their SaaS solutions. We expect that, the cloud as a runtime platform, will help Drupal, ISVs, and the customers to deliver compelling content management systems and applications on the cloud.

Jan 12 2011
mg
Jan 12

I had written about setting up php debugging environment with Eclipse on windows.

Well, turns out, setting up the debug environment on Mac OS X is also a little tricky since the library files do not always work.

I used the Helios Eclipse PDT distribution. I tried using the Zend debugging environment. But after struggling with the settings in the php.ini file, I decided to try XDebug. XDebug is straightforward, once you have crossed the windy roads. 

Here is the main gottcha - the default xdebug.so which ships with MAMP server might not always work. xdebug.org does not have the mac os x distribution for the .so file either. The one that ships with komodo editor however works and you can get it from here. Once you download the right file, save it and note the location.

Next edit the php.ini located at /Applications/MAMP/conf/php5.3 - Add the following to it

zend_extension="/Applications/MAMP/bin/php5.3/lib/php/extensions/no-debug-non-zts-20090626/xdebug.so"
xdebug.profiler_output_dir = "/tmp/xdebug/"
xdebug.profiler_enable = On
xdebug.remote_enable=On
xdebug.remote_host="localhost"
xdebug.remote_port=9000
xdebug.remote_handler="dbgp"
xdebug.idekey=ECLIPSE_DBGP

Now if you run phpinfo(), you should get some output about xdebug. The basic debugging is setup.

Make sure your eclipse is configured to work with php5.3 and that it uses the xdebug.

Don't modify ini files or other setting for php5.2 or in the incorrect directory. This usually makes up for most errors.

You should be on your way to happily debug Drupal now.

Dec 25 2010
mg
Dec 25

Sure there are modules for getting an auto complete textfield in Drupal. But where would the fun be then :)

Here I will show you how to write your own auto complete AJAX textfield. It is surprisingly easy and we will walk through all the steps from defining a text box to writing a SQL query to fetch the results to display.

Basically there are following steps to the whole process:

1. Define a textfield which will act as an auto complete

2. Define a menu item which will be invoked by our textfield(form element)

3. Call a function (handler function) which will hit a SQL query and fetch the results.

1. Define the form element - textfield:

$form['item'] = array(
'#type' => 'textfield',
'#title' => t('Select the entry'),
'#autocomplete_path' => 'nodes/autocomplete',
);

Drupal offers an #autocomplete_path attribute for textfields. This tells Drupal to look at the menu which handles the url and react accordingly. So next we define the menu which will handle this URL

2. Menu item to handle the URL

$items['nodes/autocomplete'] = array(
'page callback' => 'nodes_autocomplete',
'access arguments' => user_access('access example autocomplete'),
'type' => MENU_CALLBACK,
);

This entry in the hook_menu() will forward the request to the function 

nodes_autocomplete()

3. Guts of the autocomplete

In the function, nodes_autocomplete() you will implement the code the return the list of items to be shown in the textfield. In this case, we can fetch a node of type my_type

function nodes_autocomplete($string){
$items = array();
$result = db_query("SELECT nid, title FROM {node} WHERE status = 1 AND
type='my_type' AND title LIKE LOWER ('%s%%')", $string) ;
while($obj = db_fetch_object($result)) {
$items[$obj->nid] = check_plain($obj->title);
}
drupal_json($items);
}

This function makes the SQL query to retrive all nodes of type my_type and searches the title for autocomplete. drupal_json() formats the data in JSON format. So the $items will be returned as JSON which our javascript will be able to handle and show the results.

This is all you need and you should be on your way to having your own autocomplete textfield in Drupal. Drupal has all the built in support for these kinds of calls.

Dec 04 2010
mg
Dec 04

This is the part III of the Drupal Database Abstraction Layer

In part I of the database series we saw how to

1. Creating and deleting the tables when a module is installed or uninstalled.

2. Updating the table structure once the module is in use. So the users can apply a patch easily

In Part II we visited 

1. Ways to write secure database calls that can eliminate SQL injection

2. Reading from the database and iterating over results

Here we will look at the following mechaisms in Drupal Database Abstraction

1. Reading only a certain number of records where the query can specify start and end result number.

2. Making table names unique in a shared hosting environment

1. Reading only a certain number of records where the query can specify start and end result number.

If you substitute db_query with db_query_range($query), you can specify start and end of the result. This function will run a limited-range query.

db_query_range($query, $from, $count, array $args = array(), array $options = array())

$from = starting result number

$count = number of results

This can be a great way to implement stateless pagination.

2. Making table names unique in a shared hosting environment

While writing your queries did you notice that you wrap your tabel names in curly braces {}? There is no evil intention behind this. This actually is a very interesting feature from Drupal's database abstraction layer. The {} tells the query processor to add a unique prefix to your table names. The prefix name resolution is done via the function db_prefix_tables(). This function searches for this syntax and adds Drupal's table prefix to all tables, allowing Drupal to coexist with other systems in the same database if necessary. The prefix is defined in the settings.php with key $db_prefix.

This is useful in a shared hosting environment to resolve any naming clashes.

Hope you find it useful. Please refer api.drupal.org for more details

Nov 30 2010
mg
Nov 30

In the previous blog we saw how to

1. Create and delete tables when the modules are installed or uninstalled

2. Updating a table once the module is in use. This allows for applying patches easily

In this blog we will see two other aspects of the Drupal database layer

1. Writing secure SQL to avoid SQL injection

2. Reading from a database and iterating over results

1. Writing secure SQL:

What is SQL injection attack? 

It is a way to modify the request URL in a way to force the server to execute unintended SQL query. If the application is not performing any sanitization and constructs SQL statements on the fly, SQL injections can be easy to manufacture. For example if you type a query:

"SELECT * from node where type = '$type'";

And $type is a parameter that coming from the URL:

http:yourSite.com/q=story (for Story)

Now all a user has to do is modify the URL and type 

http:yourSite.com/q=story' OR type = 'page'

This will return back all the nodes of type story and page. Think of all the conditions a user can enter in the where clause and retrieve different information from your site.

A simple fix for this is to use placeholders in the query and escaping the inputing. So instead of typing the query as:

$result = db_query( "SELECT * from node where type = '$type'");

you would type it as 

$sql = "SELECT * from node where type = '%s';

$result = db_query($sql, $type);

%s converts the $type to a string so if the user modified the URL as shown above to story' OR type = 'page' the SQL will be converted to 

"SELECT * from node where type = 'story/' OR type = 'page/'; There are no content types that contain / at the end which is basically escaping the single quote. Thus the query would fail and the attack would be useless.

2. Reading data from database

First look at a database statement returning a single value:

So if you had a query:

$sql = "SELECT molecule_name from {molecule} where id = '%s'";

$result = db_query($sql, id);

then a convenience function db_result will will return the result. So to return a single value the code would be:

return db_result($result);

And that's it.

If however the query returns multiple rows then the following while loop is required:

while ($res = db_fetch_object($result)){

  do something with $res2

}

db_fetch_object will parse and iterate over the $result.

These handy trips can be quite useful. Don't forget to refer to http://api.drupal.org for more details. In the next blog, we will cover reading specific number of records from the database and unique table names in a shared hosting environment.

Nov 29 2010
mg
Nov 29

If you develop modules in Drupal you know what I am talking about here. However for the uninitiated, this might be useful.

Drupal provides an abstraction on the database and whether you are using mysql or postgres, you write only one code and call drupal's in built functions. 

The DB layer takes care of 

1. Creating and deleting the tables when a module is installed or uninstalled.

2. Updating the table structure once the module is in use. So the users can apply a patch easily

3. Provides ways to write secure database calls that can eliminate SQL injection

4. Reading from the database and iterating over results

5. It even allows for reading only a certain number of records where the query can specify start and end result number.

6. Making table names unique in a shared hosting environment

In this blog we will only cover 1 and 2. Part II covers 3, 4

Of course there is a lot more, but these are the most commonly encountered actions and we will only cover these. Feel free to comment about your favorite database features that Drupal supports.

Let's assume that your module name is Molecule.

1. Creating and deleting table when a module is installed or uninstalled:

In the molecule.install file, you will use the schema hook (molecule_schema()) to create the required tables. 

This is how you would create a molecule table with a column molecule_name

$schema['molecule'] = array(

  'description' => t('Contain Molecule information'),

  'fields' => array(

    'molecule_id' => array(

      'description' => t('id of the stalker - viewing'),

      'type' => 'int',

      'unsigned' => TRUE,

      'not null' => TRUE,

      'default' => 0,

    ),

  ),

);

To have the table and column created, you would implement the install hook (molecule_install). This will be called when the module is enabled.

function molecule_install(){

  if(!db_table_exists('molecule')){

   drupal_install_schema('molecule');

 }

}

To uninstall the module when the module is deleted, implement the hook molecule_uninstall()

function molecule_uninstall(){

  drupal_uninstall_schema('molecule');

}

2. Updating the table structure once the module is in use. So the users can apply a patch easily:

Let's say after shipping the module, you implemented additional functionality and did 2 things - added a new column and modified the name of and existing column. Drupal provides a very convenient hook to write updates to your existing module. This is exposed when the the user runs update.php.

The code to add and update columns is below. We are adding a column scientific_name and changing the molecule_id to just id.

function molecule_update_6001(){

  $ret = array();

  

  $spec = array(

      'description' => t('Scientific name of the molecule'),

      'type' => 'int',

      'unsigned' => TRUE,

      'not null' => TRUE,

      'default' => 0,

    );

    

    $spec2 = array(

      'description' => t('Id'),

      'type' => 'int',

      'unsigned' => TRUE,

      'not null' => TRUE,

      'default' => 0,

    );

  

  db_add_field($ret, 'molecule', 'scientific_name', $spec);

  

  db_change_field($ret, 'molecule', 'molecule_id', 'id', $spec2);

  

  return $ret;

}

When the user now runs the update.php, he will see 6001 as the update for the molecule module. He can apply the updates and the changes to the database table are made.

In part II we will cover some more details.
Nov 12 2010
mg
Nov 12

Hooks is the central mechanism which allows Drupal its extensibility. New functionality can interact with or extend existing functionality using hooks. Use hook, don't hack is a standard way to write code in Drupal.

user_hook() is a hook which is called when an activity is performed on the user. e.g. A user logs in, logs out, clicks on user profile, etc.. 

In Drupal 6, user_hook is a single hook and there are operations accessible through $op for accessing the operation that was performed. The documentation is available here.

But in Drupal 7, this will change. The $op is gone and there are different hooks, depending on what operation is performed. List of available hooks are here.

There might be different repercussions of this:

First the big switch will not be required, making the code simpler from it is in Drupal 6

However, with one hook a dsm could always print which operations are called for a given operation. That will be harder to track now. A developer would need to implement different hook to figure out which ones get called on certain user related activities. It will be interesting to see what coding pattern emerges.

However, the documentation is very good and its intuitive to know which hook should be called, but still sometimes it can be hard to tell without a generic method.

Jun 25 2010
mg
Jun 25

RDFa (or Resource Description Framework – in – attributes) is a W3C recommendation that adds a set of attribute level extensions to XHTML for embedding rich metadata within Web documents. This metadata protocol (RDFa) is used by the open graph protocol to enable any web page to become a rich object in a social graph. Facebook uses the open graph protocol to to make any web page look like facebook's pages. Example of properties defined in the open graph protocol are (Refer http://opengraphprotocol.org/ for more details):

  • og:title - The title of your object as it should appear within the graph, e.g., "The Rock".
  • og:type - The type of your object, e.g., "movie". Depending on the type you specify, other properties may also be required.
  • og:image - An image URL which should represent your object within the graph.
  • og:url - The canonical URL of your object that will be used as its permanent ID in the graph, e.g., "http://www.imdb.com/title/tt0117500/".

Great - so what about it? Recently Dries Buytaert gave his keynote at DrupalCon (which I highly recommend watching) and laid out the support for open graph protocol in Drupal 7. Meaning that Drupal 7 will inherently support RDF. Here is an update on the progress of this feature in Drupal 7. Facebook CEO Mark Zuckerberg also announced his support for open graph protocol in Facebook. 10s of thousands of website have converted their sites to also publish data in open graph protocol using RDF. Essentially all this makes sense if you also read the post which talks about Facebook search strategy. Facebook will compete with Google in the search market. The sites that implement the open graph protocol to publish data have inherent advantage of being indexed, searched and presented along with Facebook search results. This is huge for websites, since users can 'like' a site or 'comment' on a site like they do to native Facebook objects. The websites would get a lot direct feedback. This would also make the search results more relevant over time since there is a significant user input. This will give facebook a Semantic search engine enriched by inputs from its 100s of millions of users. And to Drupal websites an easy hook to leverage this move seamlessly to their advantage.

May 24 2010
mg
May 24

As some you might have experienced, some of the content types in your Drupal site might get too unwieldy because of their sheer size. Displaying a form for the content type of displaying the node is not elegant anymore and the user has to scroll till figures hurt. I had a similar situation recently (attached image with the fields lists all the fields in this 'Event' content type:

All fields in the Event object The simple and elegant solution is to divide the object into logical tabs both for the form and view. and the final output looked like below for me: After doing all the tab work The way to achieve this is to: 1. Divide the fields in the object into fieldgroups, which will eventually be the different tabs (these are standard groups). 2. Have a custom module where you will override the form and do at least these changes: 2.1 edit form_alter hook to have something like

 

$group_eventcontacts = $form['group_eventcontacts']; unset($form['group_eventcontacts']); $form['group_tabs']['group_eventcontacts'] = $group_eventcontacts;

where eventcontacts is the name of the fieldgroup. So we are creating a new group and removing the fieldgroup from the original form. 2.2. Override the theme hook to have the following: return array( 'myfunc' => array( 'arguments' => array('form' => NULL), ),2.3 In the myfunc function: have the following (refer 2.1 above): $event_keyContacts = drupal_render($form['group_tabs']['group_eventcontacts']); and append the $event_keyContacts variable to the $output. $output .= <div id="event_keycontacts-'.$nid.'">'.$event_keyContacts.'</div> Thats pretty much all for the form. Do this for all the groups(tabs) you want to create . 3. Now for the node viewing part. I created a separate node-event.tpl.php for handling my event content type. This file is created in the theme directory. $content = preg_replace('~<fieldset.+ class="content-multigroup-group-eventcontacts"?</fieldset>~s','',$content); this removes the fieldgroup content from the $content. Do this for all the groups. Now get the contents from $node->content if (isset($node->content['group_eventcontacts'])){ $group_eventcontacts = $node->content['group_eventcontacts']['#children'];Add the $group_eventcontact variable to the tab $tabs_div .= '<div id="event_contacts-'.$nid.'">'.$group_eventcontacts.'</div>';It is important to understand the difference between $content and $node->content. Former is the formatted representation of the content and later is a data structure containing the contents. $node->content has to be themed to become $content. There be sure to manipulate both variables correctly. That is all for getting the tabs. Happy coding

Apr 26 2010
mg
Apr 26

Dries Buytaert gives a state of Drupal talk at every DrupalCon. Here are some of the excerpts from DrupalCon2010, The entire talk is online and I highly recommend you to listen to it. Some of the key highlights of Drupal

  • CVS – RIP. Starting Drupal 8 development, source code will move to Git from CVS
  • 19 different distributions of Drupal are available currently. This phenomenon is mostly unique to Drupal where multiple distributions are available.
  • Jacob Redding has been appointed at the Interim GM of Drupal Association
  • Semantic Web and linked data: Move from WWW to GGG (Global Giant Graph). This is the based on the vision of Tim Berners-Lee. RDF is part of core in Drupal 7. This will enable to mark up different objects with RDF (e.g. products in a web shop application). Essentially RDF lets you turn the internet into a database and reuse data.
  • More big companies are getting involved in Drupal. There are now multi-million dollar Drupal projects and Drupal is hitting on the radar of companies like Cap Gemini. Accenture, IBM, etc. These consulting companies will jump on a bandwagon only if the market is big enough. Microsoft is a platinum sponsor of DrupalCon 2010. Drupal is now being supported on MS SQL server as well.
  • No SQL movement: Drupal 7 now works with CouchDB, mongoDB, Cassandra, etc. This is one of the most interesting developments for me, since this is truly forward looking vision.
  • Pro Drupal Development book, will be available in July
  • Drupal amounts for more than 1% of the web. But there is ground to cover. Wordpress owns 8.5% of the web and Joomla 1.5%. I will leave the translation for you. Drupal 6 is the most used version.
Feb 12 2010
Feb 12

Caching is one of the common ways of improving the performance of a website. Caching aims to reduce the number of trips made to the database by storing the snapshot of the results in a location (like database or file structure or memory) from where it can be retrieved faster the next time. Caching works best for information that do not change often and/or frequently consumed and/or expensive to process. Periodic maintenance need be done on the cached information so that the website users only get the latest information and not 'stale' information. During development one of the most common frustrations is not seeing the latest changes that have been made, because the webpage information is retrieved from the cache that has old information.

Drupal's File-based Cache: Drupal provides a way to consolidate all the css and javascript files into fewer files. This is very useful for pages where many javascript and css files are used to render. Instead of having many roundtrips downloading each of those files, a consolidated file would reduce the roundtrips and can decrease the page loading time significantly. The setting for optimizing the css and javascript files can be found at Administer->Site Configuration->Performance. If “Optimize CSS files” is enabled the css files are compressed by removing the whitespace and line breaks and stored in the “css” directory within the “files” directory as set on the file system settings page. If “Optimize JavaScript files” is enabled the javascript files (without compression) are stored in the “js” directory within the “files” directory. The “Download method” in the file system settings page has to be set as “Public” for these options to be available. Your browser may not support display of this image. It is better to turn on these options only in the production environment as it can interfere with the theme and module development. Also if you are running a load-balancer along with two or more servers please make sure that the cached javascript and css files are available and identical on all the servers.Drupal's Database-based Cache: Drupal comes with a nice cache mechanism that is used by the Drupal core. Drupal exposes this as an api called Cache api that can be used by developers to add caching to their own modules. The Cache api by default stores the information to be cached in a table called 'cache'. If every module uses the same table for caching, the table can grow exponentially leading to increase in overhead rather than reducing it. Hence it is better to have several cache tables to store your information. If needed module developers can add their own cache table, although it should be identical in structure to the default cache table. It is also a good practice to prepend cache_ to your own cache table. Drupal core comes with seven cache tables.

  1. cache: An “all purpose” table that can be used to store a few rows of cached data. Drupal uses this table to store the following:
    Variable data: The table “variable” stores most of the administrative settings. These settings are added to a PHP array(), serialized and stored as a single row in the cache table. This way the settings can be retrieved quickly and avoids making multiple database queries. All variables that uses variable_get() and variable_set() are cached in the cache table.
    Theme registry data: Each of the themes registries are cached in the cache table.

Schema data: Information about the structure of all the tables in the database is cached in the cache table.

    2. cache_block:
    Content generated by the blocks are cached in this table. This reduces Drupal from querying the database repeatedly to get the block contents. The block developer can choose based on the content displayed in the block, whether the block can be cached or not. If the developer decides to cache the block content, he/she has four ways of caching the block content.
      1. Cache block content separately for each available role combination
      2. Cache block content separately for each user
      3. Cache block content separately for each page
      4. Cache block content once for all the users
    Drupal, in addition to above caches block content separately for each theme and for each language supported.
    Block caching can be changed at Administer->Site Configuration->Performance. Also if any of the content access modules that restrict access to different kinds of content are enabled, then block caching is automatically disabled.

3. cache_filter:

    Filters are used to filter node content to make it more secure and consumable. This is a very expensive operation to perform every time a node is viewed. Filters are applied to the node content when they are saved or created, and the results are cached in the cache_filter table.

4. cache_form:

    The form API uses this table to cache the generated form. This saves Drupal from regenerating the unchanged forms.
    5. cache_menu:
    The menu system caches all created menus along with its hierarchies and path information in this table. This saves Drupal from having to regenerate the menu information for each page load. Menus are cached separately for each user and for each language.
    6. cache_update:
    Information about all the installed modules and themes are cached in this table.
    7. cache_page:
    The page caching is one of the important optimization that can truly improve the performance of a heavily used website. Entire page views are cached in the cache_page table. Drupal's full page caching only caches anonymous user pages. It does not cache authenticated user pages because they are often customized for the user and so they are less effective. This saves Drupal from making expensive calls to generate the page repeatedly, instead the cached page content can be retrieved in a single query. Administer->Site Configuration->Performance has several settings that affect the page caching.
    Caching mode:
    Disabled: This disables the page caching although other types of caching would still continue.
    Normal: This mode offers a substantial improvement over the “Disabled” mode. Drupal’s bootstrapping is designed such a way that, only the minimum required amount of code and queries are executed to render a page from the cache. Even with this minimum code, the database system is initialized, access and sessions are initialized, module system is initialized and hooks - hook_boot and hook_exit are called on the modules that implemented them. Only then the cached page is rendered.
    Aggressive: This mode skips the initialization of the module system and so hook functions are never called. This shaves valuable time each time an anonymous user requests a page. But this means that the modules that have implemented the hooks may not work properly. Drupal warns (see image) by listing all the modules that may not function properly if the Aggressive mode is enabled.
    Minimum cache lifetime:
    This sets the minimum lifetime of a cached content. If a user changes content, other users would have wait until this expires, to see the changed content. If it is set to “none”, then there is no wait, and all users can see the latest content immediately.
    Page compression:
    If enabled the page contents would be compressed before caching it. This saves bandwidth and improves the download times. However if the webserver already performs the compression, then this should be disabled. In Apache server you can use module mod_deflate to turn on the compression. IMHO it is better to use this functionality (may be enhance it with modules like css_gzip or javascript_aggregator) rather than mod_deflate because the latter do not have any caching.

Note: Even if the Page cache and/or Block cache are disabled, other types of caching like menus, filters, etc. would still continue to happen and they cannot be disabled. Clear cached data: In the performance page at Administer->Site Configuration->Performance, you can use the “Clear cached data” to clear ALL of the caches in the system including the css and javascript optimizations. If you have your own cache table, you can use the hook_flush_caches() to clear the cache when the “Clear cached data” is executed. Pluggable Cache: Drupal provides a way to plug in a customized caching solution such as memory or file-based or hybrid (memory and database for fail-safe) caching. There are 2 levels of plugging: 1. Solutions that uses the Drupal cache API, but stores information in a customized manner (like memory) instead of the Drupal 'cache*' tables.

    Example: memcache module
    2. Solutions that provide their own cache API implementation, together with customized storage of information. Essentially complete Drupal cache system is bypassed. This is called the 'fastpath' mode (or is it page_fast_cache?). When a cached page is rendered using this technique most of the Drupal bootstrap technique are skipped, and hence the Drupal statistics would not be updated. So for statistics like page views, Drupal statistics may not be accurate.
    Example: cacherouter module

Drupal's modules: There are many contributed drupal modules that extend the Drupal cache, or provides integration with an external caching solution. Some of them even work for some parts of the authenticated user pages. It is certainly possible to combine many contributed modules to get better performance. Here are some of them with a very brief summary (in no particular order): Memcache: This module lets you use a memcache server to do the caching. The nice thing is it provides 2 types of caching, one memory only, and another memory or database. The latter approach certainly has lesser performance improvement than the first, but it gives a failsafe mechanism where if the memcache is not available, it would use the database for caching. Authcache: This module can cache authenticated user pages if the pages are same for a particular user role. This module can be combined with Memcache or Cacherouter to have a customized caching. Advcache: This module extends the caching to areas that the Drupal core does not cover. The main advantage is for authenticated non admin users that have a single role. This module can be combined with Memcache or Cacherouter to have a customized caching. Cacheexclude: You can use this to exclude certain anonymous user pages from being cached. Cacherouter: This module allows users to have different caching technology for different cache tables. It has native support to many caching technologies like APC, Memcache, XCache, even database and file system. Boost: Another external caching mechanism for mostly anonymous users. Cache: Similar to Cacherouter, provide mechanism to use different caching technologies.

References: Pro Drupal Development, Second Edition by John K. VanDyk

Jan 25 2010
mg
Jan 25

I was trying to create different tabs (using YUI) to edit a form. I wanted to create a separate tab for each of the field groups. However, in the form_alter method of the form for my module, I could not see the fields in the fieldgroup. On debugging I found my fields in the fieldgroup to be present in the form_alter of other modules. Problem: The CCK fieldgroup module has a weight of 9. If your module has a weight less than 9, then it is called before CCK fieldgroup, hence the problem. Solution: Set your module's weight more than 9. The setting is in the system table, under the column weight. This fixed the problem for me. It took a long time to solve the problem and thanks to some of the other posts mentioned below for writing about this.

Dec 19 2009
mg
Dec 19

There are several modules I have used during building sites. I am not going to get into details of the modules because you should visit the modules. But by far, the most important / useful modules for me have been:

1. Views ; You can think of views as output to your custom query (except you don't write the query). There are several ways to present the views and Calendar is one example. So this is a query builder which can execute queries at run time and present the data however you want.

2. : You can add custom fields to a node or define a new content type based on CCK, This is powerful functionality with no coding. You can order the fields according to your preference. And CCK will become very powerful once is introduced. As of now, Multigroup is in alpha, but I have been using it with no problems. It lets you create a composite or a compound field, consisting of different base CCK fields.

3. : The module renders all administrative menu items below 'administer' in a clean, attractive and purely CSS-based menu at the top of your website. This is a life saver if you are administering a site. Essentially it is a overlay of the entire admin functionality as a ribbon on the top of your web site.

4. : I have to give it to katrib for this module. This is great if you want spreadsheet functionality in your website. We did some pretty advanced things with the module like embedding it within a node as a tab and YUI integration. We also configured a java bridge to be able to upload excel sheets from desktop to the website. Google spread sheet integration is pretty straightforward. This is based on SocialText platform

5. Enables users to create and manage their own groups (like forums). This can bring great social aspects to your website. For some of the sites, we changed the module to represent a company and it was great.

6. : This adds a lot of umph to the site. It is Mainly used to showcase featured content at a prominent place on the frontpage of the site. Demos and tutorials are excellent.

7. : Essential for developers and themers It can generate SQL query summaries, create data for your test site, show the theme information on your site. Don't develop without this module.

8. Pathauto : It automatically generates path aliases for various kinds of content (nodes, categories, users) without requiring the user to manually specify the path alias. Helps get rid of default / ugly paths (node/3 ... )

9. jQuery : jQuery depends on jQuery UI and jQuery update in drupal 6. And here is a good overview of jQuery.This architectural diagram might also be a useful reference. jQuery modules provides all the nice functionality jQuery library.

10. : This module provides several useful extensions to the login system of drupal. What I found really useful was to allow email based logins, email confirmation during registration and auto logout. Happy drupaling :)

Nov 26 2009
mg
Nov 26

This was one of the most frustrating setups for me, not because it is difficult, but because it is very important to get the xdebug library absolutely correct. For a long time it seemed that everyone could debug but me. There were no posting pointing to the problems I was having, so here it is: I have a wamp install with Eclipse. I am running php5.2.9-2. This is important to know because the library has to match the php version.

1. For this version of php, I downloaded the debug library : http://xdebug.org/files/php_xdebug-2.0.4-5.2.8.dll . There are several libraries listed on the site, and the hard part was to get to the right one.

2. This file was copied to <something>\wamp\bin\php\php5.2.9-2\ext

3. Next: edit the php.ini: Mine looks like following:

zend_extension_ts="C:\wamp\bin\php\php5.2.9-2\ext\php_xdebug-2.0.4-5.2.8.dll"

xdebug.remote_autostart=off

xdebug.remote_enable=1

xdebug.remote_handler=dbgp

xdebug.remote_mode=req

xdebug.remote_host=127.0.0.1

xdebug.remote_port=9000

4. Restart server (WAMP)

5. Run command (type in the URL on the browser) http://localhost/?phpinfo=1 - you are running phpinfo(). This should display all the properties for you. You should see something for Xdebug on the displayed page.

6. If it does, your server is configured. Client configuration is straightforward: On Eclipse, under debug configuration, I selected "Server Debugger" to be XDebug from the drop down And the debug type is php web page. So you have to create e new php web page, give it a name and start debugging. Let me know if you have questions. I can feel the pain of debug setup.

Happy Drupaling :)

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