Thursday 29 December 2011

What is AHAH in Drupal? How it works

AHAH in Drupal is a feature provided by the Forms API.
  • You write the form using the Drupal Forms API.
  • You specify what button activates the AHAH behavior.
  • You specify what part of the form's HTML is to be replaced by the callback
  • You write a callback that generates the replacement HTML
  • Drupal manages everything so that when the button or control is used, the callback gets called and the replacement of HTML is done 
The AHAH framework is fully integrated into Drupal 6 so all you need to do is hook into it using Drupals form API. Here's an example of how to make the form API to use AHAH.
<?php
  $form
['my_form_submit'] = array(
   
'#type' => 'submit',
   
'#value' => t('Submit'),
   
'#weight' => 1,
   
'#submit' => array('my_form_submit'),//none JS version
   
'#ahah' => array(
     
'event' => 'click',
     
'path' => 'mymodule/js',
     
'wrapper' => 'myform-wrapper',
     
'method' => 'replace',
     
'effect' => 'fade',
     
'progress' => array(
       
'type' => 'bar',
       
'message' => t('Loading...')
      )     
    ),
?>
We're focusing on the #ahah array at the end of the form array, let me explain the various parameters one by one:

#ahah['event']
This is the type of event that must be perform on the $form item (in this example the Submit button) in order for the AHAH behaviour to be triggered. 
Possible values: 'click', 'blur', 'change' (Optional will default to click) 
Examples: user clicking a button (click) or user selecting a value in a drop down menu (change)

#ahah['path']
This is the menu item or URL that is called when the "event" has been triggered. Without this AHAH will not be triggered.In the above example you would need to have a coresponding menu item defined in your hook_menu like so:
<?phpfunction mymodule_menu() {
 
$items['mymodule/js'] = array(
   
'page callback' => 'mymodule_js',
   
'access arguments' => array('access mymodule js'),
   
'type' => MENU_CALLBACK,
  );
  ...
  return
$items;
}
/**
* callback function for mymodule/js
* The return HTML will be outputted by AHAH
*/
function mymodule_js() {
  return
drupal_json(array('status' => TRUE, 'data' => "Hello Drupal World"));;
}
?>

It's important the you use the drupal_json function so that Javascript can understand the returned values/HTML.
Alternatively you could use the AHAH helper module which can handle all the menu definitions for you.

#ahah['wrapper']
This is the ID of the HTML element on the current page that should be updated with the returned HTML from our #ahah['path'] defined menu path.
In our example 'wrapper' => 'mymodule-wrapper' corresponds to <div id="mymodule-wrapper">.....</div> and this div would display the "Hello Drupal World" text returned by our mymodule_js() menu function when AHAH has been triggered.

#ahah['method']
This is how you want the HTML returned from our #ahah['path'] menu function to be attached to our #ahah['wrapper'] defined wrapper.
By default it with replace the HTML currently in the wrapper with the new HTML, but you can also have the follow:
'after' = Insert returned HTML after the wrapper element'append' = Append returned HTML to the inside of our wrapper element.
'before' = Insert returned HTML before our wrapper element.
'prepend' = Prepend returned HTML to the inside of our wrapper element.

#ahah['effect']
This is the jQuery effect you want to apply to the wrapper element when it receives the new HTML from our menu function. 
Possible values: 'none' (default), 'fade', 'slide'.

#ahah['progress']
This is the type of animation you want to display while the user is waiting for the AHAH menu function to response. It can either be a progress bar or a throbber icon and you can also add an optional message too.The #ahah['progress'] value should be an array of settings (see example above). Here are the full parameters:#ahah['progress']['type'] = Type of animation to display, bar or throbber
  #ahah['progress']['message'] = An optional message that should be displayed with the progress bar or throbber. You should wrap the text in the t().
#ahah['progress']['url'] = An optional URL to a menu item that determines how full the progress bar is.

How to integrate Apache Solr with Drupal 6 in windows or linux

I want to share my experience of integrating Apache Solr (Full text search and powerful than drupal core search) with Drupal 6.

Step 1: Download Apache Solr module from here http://drupal.org/project/apachesolr, and
place it in your drupal contributed modules folder.

Step 2: Before enabling the module, we need to do some additional configurations.
Download the apachesolr php client library from here http://code.google.com/p/solr-php-client/downloads/list .
After extracting the files, place solrphpclient folder into apachesolr module folder.

Step 3: Now enable Apache Solr Framework and Apache Solr Search modules from admin/build/moules section.

Step4:  Now download Apache Solr from here. http://apache.osuosl.org//lucene/solr/1.4.1/apache-solr-1.4.1.zip and extract the contents.

Step 5: Unpack the tar ball or zip file downloaded in step 3 outsite your drupal installation and outside web root.

Step 6:  Goto /apachesolr1.4.0/example/solr/conf and copy schema and solrconfig files to the same directory and rename them as schema.bak and solrconfig.bak

Step 7: Copy schema and solrconfig files from your drupal installation apachesolr module to above location and replace wih existing files.

Step 8: Now open your command prompt and browse to apachesolr1.4.0/example directory.

Step 9: Type belo command to start apachesolr service
               >> java -jar start.jar
Step 10: Test your solr server admin innterface by visiting http://localhost:8983/solr/admin/ . If you can able to see admin page then your solr is running and ready to use with drupal.

Step 11:  Its time to configure drupal search with apache solr. Please goto admin/settings/apachesolr/index and run cron to index the content using apache solr search engine.

Step 12: Now goto admin/settings/apachesolr click on advanced configuration and make apache solr as default search. Now go to admin/settings/apachesolr/enabled-filters and enable the sorting filtrers.

Step 13: Now goto blocks and enable the necessary apache solr related blocks.

Step 14: To enable facets please go to admin/settings/apachesolr/enabled-filters and enable filters. Now go to blocks and enable the facets filtering blocks where ever you want !!

Sunday 25 December 2011

Using Hook Views Query Alter

Building a website I recently ran into an issue where I had HTML search facets interacting with Drupal views. The user would click on the facet and it would filter the view depending on the argument. I ended up implementing hook_views_query_alter. To make sure the values I wanted to filter on were in the view, I added the search facets into the view as fields. This automatically joins the necessary tables so that you don’t have to.
Implementing hook_views_query_alter requires two parameters, view and query, both are passed by reference. Since this hook is called for every view the first thing I did was check that I was altering the right query by adding an if statement that checks the view name. After that you're free to modify the query as you wish. In my example, I looped through the search facets and added them as where statements and arguments to the query.

function search_views_query_alter(&$view, &$query) {
  if($view->name == 'example_view_name'){
    foreach($parsed_url AS $key => $value){
      $query->where[0]['clauses'][] = 'profile_values_profile_' . $key . '.value IN ("%s")';
      $query->where[0]['args'][] = $value;
    }
  }
}

One of the search facets was a taxonomy filter which the user was allowed to multi select. In order to get the view to grab the correct values, I had to add join clauses to dynamically create term_node table aliases. This is done by adding a join clause to the table_queue and tables array elements within the query object. I was able to just copy the existing term_node table_queue and tables array elements because I only wanted to create different aliases. Then I incremented the existing term_node table count within the tables array. If you wanted to create a new table join dynamically, the same approach is used but the table_queue and tables definitions need to be created by hand.

foreach($parsed_url AS $key => $value){
  $vid = _search_get_vocabulary_id(str_replace('_', ' ', $key));
  $tid = _search_get_term_by_vocabulary($vid, $value);
  $table_term_node_join = $query->table_queue['term_node'];
  $query->table_queue['term_node_' . $count] = $table_term_node_join;
  $query->table_queue['term_node_' . $count]['alias'] = 'term_node_' . $count;
  $query->tables['term_node']['count']++;
  $query->where[0]['args'][] = $tid->tid;
  $query->where[0]['clauses'][] .= 'term_node_' . $count . '.tid = %d';
  $count++;
}

The query table_queue and tables array elements looks like so:
Table Queue:

'table_queue' => array (
  'term_node' => array (
    'table' => 'term_node',
    'num' => 1,
    'alias' => 'term_node',
    'join' => views_join::__set_state(array(
      'definition' => array (
      'left_field' => 'vid',
      'field' => 'vid',
      'table' => 'term_node',
      'left_table' => 'node',
    ),
    'extra_type' => 'AND',
    'table' => 'term_node',
    'left_table' => 'node',
    'left_field' => 'vid',
    'field' => 'vid',
    'type' => 'LEFT',
    'adjusted' => true,
    )
  )

Tables:

'tables' => array (
    'node' => array (
      'node' => array (
      'count' => 1,
      'alias' => 'node',
      ),
    'term_node' => array (
      'count' => 1,
      'alias' => 'term_node',
    )
  ),
);

In my book this makes views more comfortable to use because it gives me more control over them. This along with a view preprocessor allows me to style and output pretty much anything I want within a view.

Wednesday 7 December 2011

Embed Drupal Views Using PHP

When theming Drupal and wanting to output a view there are occasions where using a view display (e.g. a page, or a block - perhaps placed within a custom region ;-) ), or using Views Attach will not suffice.
Instead, you can embed a view using the following PHP snippet:
(NOTE: you'll need to have the core PHP input filter enabled if embedding in a node body)

<?php
$view
= views_get_view('VIEWNAME');
print
$view->preview('default'); 

?>
or, if you need to use an argument with the view:
<?php
$args
= array(ARGUMENTS);$view = views_get_view('VIEWNAME');
print
$view->preview('default', $args); 

?>

NOTE:
  • replace VIEWNAME with your actual view name - e.g. 'my_drupal_posts'
  • replace ARGUMENTS with the argument(s) your view is expecting - e.g. this may be a node id
The PHP snippets above will output your view's 'default' display. However, you can output other displays from your view (if your view has multiple displays) - e.g. to output a view's first block display you'd modify the snippet by replacing the Views display id 'default' with 'block_1' and use:

<?php
$args
= array(ARGUMENTS);$view = views_get_view('VIEWNAME');
print
$view->preview('block_1', $args); 

?>

Drupal: How To Programmatically Add, Embed Or Insert Views In Your Theme tpl

The Views module is one of the best things to have happened to Drupal. Views provides an easy way for any Drupal site designers to present how lists and tables of content. Views has a smart query builder that can build the proper query, execute it, and display the results. In this article we will tell you how to programmatically add, embed or insert Views in your theme's tpl. 
You can easily embed your pre-configured views in your theme's TPL using this command:

The Views module is one of the best things to have happened to Drupal. Views provides an easy way for any Drupal site designers to present how lists and tables of content. Views has a smart query builder that can build the proper query, execute it, and display the results. In this article we will tell you how to programmatically add, embed or insert Views in your theme's tpl. 
You can easily embed your pre-configured views in your theme's TPL using this command:

The snippet above shows a variable $display_id which is set to block_2. The illustration below shows how to find out the value for $display_id corresponding to the Display of the view that you want to embed in your website, progammatically.


The function views_embed_view won't display the title of the view. In order to get the title of the view, you can use the following code snippet:
$view = views_get_view($view_name);
print $view->get_title();

Thursday 10 November 2011

Drupal Camp Delhi-November 7, 2011 at JNU

I attend Drupal Camp today, it was awesome and meet face to face DRIES-founder of Drupal at first time. I surprised to see the crowed and see the success of Drupal and found that Drupal is the best CMS in today era.
The news is that Drupal 8 is targeted to Mobile environment (Android,Iphone,Blackburry).
Titanium-The platform by using, you can run your drupal site in Android or Iphone etc. Any language one solutions Titanium.
Some New things which I learn in Camp are following-
CDN Module- manage your site traffic by distribute requests like your site is example.com and you use image.example.com sub-domain for image requests and use static.example.com sub domain for js,css etc static contents. This all make your site faster as traffic is distribute to many sub domain. Explore CDN module for more details.

Tuesday 25 October 2011

Creating views for custom tables in Drupal 6

At a minimum, if your module wants to use Views, it needs to implement one hook:


function hook_views_data();


This function returns data that will describe how your module's tables relate to the Drupal node table, as well as what fields can be displayed and sorted, and how your tables may be filtered. This hook can return just one or many tables. This function should be placed in a file named MODULENAME.views.inc in your module's directory. Views will automatically find it and include it when necessary.

If you want to provide default views that your users can immediately use, implement hook_views_default_views(). You can use the views exporter tool to create this hook. This hook should be placed in MODULENAME.views_default.inc.

Implementation steps

1.Implement the hook_views_api() in your module.


function MODULENAME_views_api() {
return array(
'api' => 2,
'path' => drupal_get_path('module', 'MODULENAME') . '/modules',
);
}


2. Create a file named MODULENAME.views.inc and put it in your modules diretory.
/sites/all/modules/MODULENAME/modules/MODULENAME.views.inc

3. This .inc file must implement the hook_views_data() and the sample impelemntation is given below.

function custom_views_views_data() {

$data['custom_views']['table']['group'] = t('Custom View');

// Here 'custom_views' will be your table name and this will be treated as base table
$data['custom_views']['table']['base'] = array(
'field' => 'id',
'title' => t('Custom table'),
'help' => t('Stores information about custom table.'),
'weight' => 10,
);
// Following are the fields of the table 'custom_views'
// Field:custom_id
$data['custom_views']['custom_id'] = array(
'title' => t('ID'),
'help' => t('ID of the custom table.'),

'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
),
'filter' => array(
'handler' => 'views_handler_filter_string',
),
'argument' => array(
'handler' => 'views_handler_argument_string',
),
'sort' => array(
'handler' => 'views_handler_sort',
),
);

// Field:custom_title
$data['custom_views']['custom_title'] = array(
'title' => t('Name'),
'help' => t('Name of the field.'),

'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
),
'filter' => array(
'handler' => 'views_handler_filter_string',
),
'sort' => array(
'handler' => 'views_handler_sort',
),
'argument' => array(
'handler' => 'views_handler_argument_string',
),
);

return $data;

}

Now when you create a new view, the custom fields will be included in the view.

For more information on views2 visit on http://drupal.org/node/235062

Drupal 6 Hooks

hook_menu_alter(&$callbacks)
Alter the data being saved to the {menu_router} table after hook_menu is invoked.This hook is invoked by menu_router_build(). The menu definitions are passed in by reference. Each element of the $callbacks array is one item returned by a module from hook_menu. Additional items may be added, or existing items
altered.

hook_mail($key, &$message, $params)
Prepare a message based on parameters. @see drupal_mail for more.

hook_watchdog($log_entry)
Log an event message. This hook allows modules to route log events to custom destinations, such as SMS, Email, pager, syslog, ...etc.

hook_theme($existing, $type, $theme, $path)

Register a module (or theme's) theme implementations.

Modules and themes implementing this return an array of arrays. The key to each sub-array is the internal name of the hook, and the array contains info about the hook.

hook_theme_registry_alter(&$theme_registry)

Alter the theme registry information returned from hook_theme().

The theme registry stores information about all available theme hooks, including which callback functions those hooks will call when triggered, what template files are exposed by these hooks, and so on.

Note that this hook is only executed as the theme cache is re-built. Changes here will not be visible until the next cache clear.

hook_boot()

Perform setup tasks. See also, hook_init.

This hook is run at the beginning of the page request. It is typically used to set up global parameters which are needed later in the request.

Only use this hook if your code must run even for cached page views.This hook is called before modules or most include files are loaded into memory. It happens while Drupal is still in bootstrap mode.

hook_form_FORM_ID_alter(&$form, &$form_state)

Provide a form-specific alteration instead of the global hook_form_alter().

Modules can implement hook_form_FORM_ID_alter() to modify a specific form, rather than implementing hook_form_alter() and checking the form ID, or using long switch statements to alter multiple forms.

Note that this hook fires before hook_form_alter(). Therefore all implementations of hook_form_FORM_ID_alter() will run before all implementations of hook_form_alter(), regardless of the module order.

hook_term_path($term)

Allows modules to provide an alternative path for the terms it manages.

For vocabularies not maintained by taxonomy.module, give the maintaining module a chance to provide a path for terms in that vocabulary.

"Not maintained by taxonomy.module" is misleading. It means that the vocabulary table contains a module name in the 'module' column. Any module may update this column and will then be called to provide an alternative path for the terms it recognizes (manages).

This hook should be used rather than hard-coding a "taxonomy/term/xxx" path. 

hook_locale($op = 'groups')

Allows modules to define their own text groups that can be translated.

hook_schema()

Define the current version of the database schema.

A Drupal schema definition is an array structure representing one or more tables and their related keys and indexes. A schema is defined by hook_schema() which must live in your module's .install file.

By implementing hook_schema() and specifying the tables your module declares, you can easily create and drop these tables on all supported database engines. You don't have to deal with the different SQL dialects for table creation and alteration of the supported database engines.

hook_system_info_alter(&$info, $file)

Alter the information parsed from module and theme .info files

This hook is invoked in module_rebuild_cache() and in system_theme_data(). A module may implement this hook in order to add to or alter the data generated by reading the .info file with drupal_parse_info_file().