Here is screencast, how Gmaplocation Drupal module looks and feels on one website:
The video is created with Castanut, tool that allows one to write script that will move mouse, open webpages, enter text and record all this into the screencast. Castanaut scripts are written in Ruby and commands are scripts are relatively easy to write.
Please note, that it is MacOSX Leopard only tool (there is a fork on GitHub that allows it to be used with 10.4 thought).
I had some problems with dissapearing mouse cursor using Snapz Pro X capture tool and it draws up that Snapz Pro X is currently not ready to be used together with scripting yet. Guys in Ambrosia Software are working on the next generation and it would probably allow Snapz Pro X to be used with Castanaut . On the end of the day I bought iShowU which did not had any problems.
In Drupal many things are cached with static variables and this is often main source of headache. I just submitted small patch for bug where static cache does not work as it should. Bug report and this example shows that unset() should not be used with static variables:
<?php
function locale_supported_languages($reset = FALSE, $val = array()) {
static $all = NULL;
if ($reset) {
// If a static variable is unset() inside of a function, unset() destroys the variable only in the context of the rest of a function. Following calls will restore the previous value of a variable.
unset($all); // this would not work
//$all = NULL; // this would work
}
if (is_null($all)) {
$all = array();
foreach ($val as $key => $value) {
$all[$key] = $value;
}
}
return $all;
}
echo "\narray should have 'cached' element (PASS):";
print_r(locale_supported_languages(FALSE, array("first" => "cached")));
echo "\narray should have 'new' element (PASS):";
print_r(locale_supported_languages(TRUE, array("first" => "new")));
echo "\narray should have 'new' element but have 'cached' (FAILS):";
print_r(locale_supported_languages(FALSE));
Drupal Color.module allows the admin to change the color scheme of a theme completely.
Color module basically fill viewport with 5 choosen colors, layout transparent PNG on it and then makes image slices and update CSS with this colors.
I would like to share some code that customize color.module further. After color scheme is choosen specified images would be copied and colors updated to reflect current color scheme. This is especially useful for creating buttons that should be color aware.
/**
* Form alter hook
*/
function mycolormodule_form_alter($form_id, &$form) {
if ($form_id == 'system_theme_settings') {
$form['#submit']['mycolormodule_system_theme_settings'] = array();
}
}
/**
* Copy PNG images and change color in images with color from palette.
*
* Settings in color.inc $info array:
*
* 'change_color' => array(
* 'images/form_buttons.png' => array("#3CC6F5" => "bottom"), // Color #3CC6F5 will be updated with color of "header bottom"
* ),
*/
function mycolormodule_system_theme_settings($form_id, $values) {
$theme = $values['theme'];
$target = variable_get('color_'. $theme .'_stylesheet', NULL);
if (!$target) return;
$files = variable_get('color_'. $theme .'_files', array());
$target = dirname($target) . "/";
$info = $values['info'];
$source = drupal_get_path('theme', $theme) .'/';
foreach ($info['change_color'] as $file => $replace_array) {
$base = basename($file);
$source = $source . $file;
// NOTE: change color
$im = imagecreatefrompng($source);
foreach ($replace_array as $old => $new) {
$old_arr = _color_unpack($old);
$index = imagecolorexact($im, $old_arr[0], $old_arr[1], $old_arr[2]);
$new_arr = _color_unpack($values['palette'][$new]);
imagecolorset($im, $index ,$new_arr[0], $new_arr[1], $new_arr[2]);
$files[] = $target . $base;
}
imagepng($im, $target . $base);
}
variable_set('color_'. $theme .'_files', $files);
}
Buttons from above image are based on Wii buttons demo.
Using color.module is described in details here.
While creating an installation profile for Drupal based websites I lost a day tracking what should look like a small error. This seems to be often error and it seems there are many possiblities why this and similiar errors can occur:
warning: call_user_func_array() [<a href='function.call-user-func-array'>function.call-user-func-array</a>]: First argument is expected to be a valid callback, 'page_node_form' was given in /Users/bmihelac/Sites/drupal/tsitedemo/includes/form.inc on line 221.
This error occure in drupal_retrieve_form function of form.inc and means that Drupal did not found callback_function for creating $form_id form.
How Drupal retrieves form:
drupal_retrieve_form function invokes hook_forms on all modules and statically cache returned forms
it execute callback for given $form_id is it exists, if callback does not exists drupal_retrieve_form calls function named $form_id
node.module defines hook_forms so every content type has form_id in format CONTENT-TYPE_node_form (page_node_type for example). Callback for all node forms is same and it is node_form. It is important to know that node_forms calls node_get_types to obtain available node types and this function statically cashes node types.
Possible solutions
In my case the error occured because I created custom node type and wanted to create nodes via drupal_execute_macro in same script. node_get_types returned caches node types and custom node was not in it. That also explains while same code worked if it was split in two scripts. Once the problem is found, solution is easy as reloading node types:
check if you can retrieve form with drupal_retrieve_form($form_id)
check if $form_id is created in module_invoke_all(‘forms’)
check if module that should create form is loaded with module_list(FALSE, TRUE, FALSE)
Thanks for reading and hope this will save you some time.
UPDATE: I noticed that some other functions statically cache variables so similiar problems occured when creating multilanguage nodes. The best solution for now seems to create content types, blocks, etc in installation profile and create content in other script.
About
I am Bojan Mihelac and this blog is dedicated to share code, thoughts, tools and advices I came up with while working in Informatika Mihelac.