jide's blog

A friend of mine just pointed out that my name is written in big characters in a slide of the latest Keynote of Dries Buytaert showing Drupal contributors :) It is in slide #10, and also in the video, around 1:00. Yay ! I'm famous !

Random magic hehe, I'm not such a big contributor ;) Try to find my name in this picture where contributors size is proportionate, that's a little harder :) :

/**
* Implements hook_cron_queue_info().
*/
function MYMODULE_cron_queue_info() {
$queues = array();
$queues['MYMODULE_queue_notify'] = array(
'worker callback' => 'MYMODULE_queue_notify_worker',
'time' => 15,
);
return $queues;
}
 
/**
* Queue worker for sending notification mails.
*/
function MYMODULE_queue_notify_worker($params) {
drupal_mail('MYMODULE', 'notify', $params['to'], language_default(), $params, $params['from']);
}
 
/**
* Implements hook_mail().
*/
function MYMODULE_mail($key, &$message, $params) {
$language = $message['language'];
$message['subject'] = $params['subject'];
$message['body'][] = $params['message'];
}
 
/**
* Implements hook_rules_action_info().
*/
function MYMODULE_rules_action_info() {
return array(
'MYMODULE_rules_action_mail' => array(
'label' => t('Send mail'),
'group' => 'MYMODULE',
'parameter' => array(
'to' => array(
'type' => 'text',
'label' => t('To'),
'description' => t('The e-mail address or addresses where the message will be sent to. The formatting of this string must comply with RFC 2822.'),
),
'subject' => array(
'type' => 'text',
'label' => t('Subject'),
'description' => t("The mail's subject."),
),
'message' => array(
'type' => 'text',
'label' => t('Message'),
'description' => t("The mail's message body."),
),
'from' => array(
'type' => 'text',
'label' => t('From'),
'description' => t("The mail's from address. Leave it empty to use the site-wide configured address."),
'optional' => TRUE,
),
),
),
);
}
 
/**
* Action: Add notification mails to the queue.
*/
function MYMODULE_rules_action_mail($to, $subject, $message, $from = NULL, $settings, RulesState $state, RulesPlugin $element) {
// Gather params.
$params = array(
'to' => str_replace(array("\r", "\n"), '', $to),
'from' => !empty($from) ? str_replace(array("\r", "\n"), '', $from) : NULL,
'subject' => $subject,
'message' => $message,
);
// Add to the queue.
$queue = DrupalQueue::get('MYMODULE_queue_notify');
$queue->createItem($params);
}

When using a view with exposed filters, if the exposed filter is empty, by default views renders the view with all results displayed. To make an empty view instead :

  • Add an argument "Global: Null"
  • Action to take if argument is not present: Provide default argument
  • Default argument type: Fixed entry
  • Default argument: let it blank
  • Validator: PHP code
  • PHP validate code:
    if (!empty($view->exposed_input) && count($view->exposed_input) == 1 && isset($view->exposed_input['destination'])) {
    return FALSE;
    }
    return (!empty($view->exposed_input));
  • Action to take if argument does not validate: Display empty text (if you want the view to be rendered)

And voilà !

To create GIT patches using branches (which is required for drush make):
git clone --branch 7.x-1.x http://git.drupal.org/project/session_api
cd session_api
git checkout -b cron
[edit code...]
git commit -a -m "Use an expiration logic when clearing sessions on cron"
git checkout 7.x-1.x
git diff --no-prefix 7.x-1.x cron > session_api_cron.patch

You may use the "master" branch instead of "7.x-1.x".

Recently, I had to use Facebook API for a web site using social networks. When testing these APIs, having test accounts is necessary. Facebook provides an API to create, delete and modify these friends. Here is a handy code snippet which makes it easy to batch create, delete, list test accounts and connect them as friends.

A zipped version is attached below.

Here is a simple database API example :

$results = db_select('authmap', 'am') // 'authmap' is the table name, 'am' the alias
->fields('am', array('uid')) // The alias and the field we want to fetch
->distinct() // Add distinct
->condition('module', 'MYMODULE') // A condition on the 'module' field, 'MYMODULE' value
->condition('authname', $ids, 'IN') // A condition on the 'authname' field, value is in $ids array
->execute() // Execute the query
->fetchCol(); // Fetch column

There are many examples on how to use AJAX using form API, but I could not find a good example on how to use AJAX with markup. Here is a simple method.

To create an AJAX link in Drupal, outside of form API, we first need to add a menu item :

function MYMODULE_menu() {
$items = array();
$items['MYMODULE/ajax'] = array(
'page callback' => 'MYMODULE_ajax_callback',
'access arguments' => TRUE,
'type' => MENU_CALLBACK,
);
$items['MYMODULE/ajax/%/%'] = array(
'page callback' => 'MYMODULE_ajax_callback',
'page arguments' => array(2, 3),
'access arguments' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}

Then, wherever you want to create a link, include the library :

// Add libraries
drupal_add_library('system', 'drupal.ajax');
drupal_add_library('system', 'jquery.form');

Create a link with the "use-ajax" class and a wrapper for the AJAX response. This is a dummy example, you must do this in an appropriate way of course :

// Output a link
l(t('AJAX'), 'MYMODULE/ajax/nojs/' . $some_argument, array('attributes' => array('class' => array('use-ajax'))));
// Output a wrapper
'<div id="MYMODULE-wrapper"></div>'

Finally, create your callback function :

function MYMODULE_ajax_callback($type = 'ajax', $some_argument) {
if ($type == 'ajax') {
$commands[] = ajax_command_replace('#MYMODULE-wrapper', 'Hey ! Some AJAX content !');
$page = array('#type' => 'ajax', '#commands' => $commands);
ajax_deliver($page);
}
else {
$output = t("This is some content delivered via a page load.");
return $output;
}
}

That's it !

Sometimes we need to add template suggestions to a module. To do this, we need to alter the registry and add the template suggestion to the preprocess function.

To add a template suggestion for blocks named "mytemplate.tpl.php" in the "theme" subfolder of your module, do the following :

/**
* Implementation of hook_theme_registry_alter().
*/
function MYMODULE_theme_registry_alter(&$theme_registry) {
  $theme_registry['block']['theme paths'][] = drupal_get_path('module', 'MYMODULE') . '/theme';
}
 
/**
* Implementation of hook_preprocess_block().
*/
function MYMODULE_preprocess_block(&$variables) {
  $variables['template_files'][] = 'mytemplate';
}

To extend a jQuery UI widget with your own widget, 3 important things :

  • jQuery UI uses the data() function to store information related to the widget. The data identifier of the element will be your widget name, so you must copy its value to the original data value.
  • For each function you want to extend, call the original function of the widget with apply().
  • Set the default options.

$.widget("ui.customsortable", $.extend({}, $.ui.sortable.prototype, {
 
  _init: function(){
    this.element.data('sortable', this.element.data('customsortable'));
    return $.ui.sortable.prototype._init.apply(this, arguments);
  }
 
  // Override other methods here.
 
}));
 
$.ui.customsortable.defaults = $.extend({}, $.ui.sortable.defaults);

Freshy 2 theme and Customize plugin have been updated for Wordpress 2.9. I just followed instructions at http://ocean90.wphelper.de/en/3127/fix-freshy-theme-wordpress and did not test this out. Please tell me if everything is fine.

Since I do not have time for Freshy 2 and Customize development, I will put source code on GitHub to allow other developers to help maintain code for future releases.

Syndicate content