Drupal Snippets

Continuously updated space listing different useful snippets from drupal

Tested: Drupal 7.1x

1. Displaying login

Usually you would add user login to region and then render the region, but if you like to directly print the user login then:

<div id="login">
<?php
$elements = drupal_get_form('user_login_block');
$rendered = drupal_render($elements);
$output  = '<form action="' . $elements['#action'] .'" method="' . $elements['#method'] .'" id="' . $elements['#id'] .'" accept-charset="UTF-8"> <div> ';
$output .= $elements['name']['#children'];
$output .= $elements['pass']['#children'];
$output .= $elements['form_build_id']['#children'];
$output .= $elements['form_id']['#children'];
$output .= $elements['actions']['#children'];
$output .= '</div> </form> ';
print $output;
?> 
</div> 

2. Display Menu (i.e.main_menu)

<?php print theme('links__system_main_menu',
array('links' =>  $main_menu,
'attributes' =>  array('class' =>  array('nav', 'nav-pills'))));
?> 

3. Display Content Title.

<?php print render($title_prefix); ?> 
<?php if ($title): ?> 
<h2 > <?php print $title; ?> </h2> 
<?php endif; ?> 
<?php print render($title_suffix); ?> 

4. Construct Relative URL
For Other pages(content types):
For Js files:

<?php print '<script src="'.base_path() . path_to_theme() .'/js/lib.js" type="text/javascript"> </script> '; ?> 

For images in public folder

$url_image = url('sites/default/files/'.file_uri_target($fieldHeaderBkIma[0]['uri']), array('absolute'=> true));

If you have a multilingual site then the proper url can be retrieved as following:

url('sites/default/files/'.file_uri_target($menu_item_node->;field_menu_icon[LANGUAGE_NONE][0]['uri']),array('absolute'=> true, 'language' =>  (object)array('language' =>  FALSE)));

The ‘language’ option set to false fixes the issue for multilingual sites where url() method returns url that have language prefix(i.e. domain.com/lang_code/path/)

5. Construct Complete URL
this seems seems to be working in Drupal 7:

<?php print '<a href="'.$GLOBALS['base_url'].base_path().'/url-of-node.'"> ...';?> 

The Global variable retrieves domain name. The base_path() retrieves everything else except the url of the node itself

6. Check for Anonymous User
Quick way to find out if anonymous user is currently visiting the site

global $user
if($user->uid == 0){
//do something for anonymous user
}

In Drupal 7, the anonymous user got assigned ‘uid’ of 0 that is why there is the check

To check if user is authorized with admin role:

$roles = array_intersect_key(user_roles(), $user->roles);
if ($user->uid && in_array('administrator',$roles)) {
//authorized and admin
}

7. Setting Template Suggestions
Here is different ways to set Template suggestions both resulting to

function themeName_preprocess_page( &vars, $hook) {
$vars['theme_hook_suggestions'][] = 'page__'. $vars['node']->;type;
...
}

This will result using template page1–type.tpl.php despite the page–type.tpl.php that was declared last. This is because the ‘theme_hook_suggestion’ is stronger than ‘theme_hook_suggestions’ suggestion

8. Choose Different Page for Anonymous Users
For new visitors you may want to prompt to login if updating template.php in you theme as follows:

...
function themeName_preprocess_page( &vars){
if($vars['user']->uid == 0  & & $_GET['q'] != 'user'){
$vars['log_in'] = l('log in', 'user');
$vars['theme_hook_suggestion'] = 'page__anonymous';
}
}

Unless user have logged in, drupal will load template page–anonymous.tpl.php. In the page–anonymous.tpl.php, there may be a link(i.e. $log_in) to login

9. Adding classes at HTML, Node and Page level
Your theme may need different CSS classes to be added at body tag(HTML level), page and node wrapper, then to do so update preprocessor functions in template.php file as following:

function themeName_preprocess_html( &variables){
$variables['classes_array'][] = 'all html class come here';
}

function themeName_preprocess_node( &variables){
$variables['classes_array'][] = 'all node classes come here';
}

function themeName_preprocess_page( &variables){
$variables['classes_array'][] = 'all page classes come here';
}

For the page level, your page theme template file may need to add ‘class=”‘ to the page wrapper to make it look as following:

...
<div id="page-wrapper"> <div id="page" class="<?php print $classes;?> "> 
...

This ensures the class variable set in the preprocessor function are printed in the output

Check Authenticated User
There may be time you need display things depending on weather user is authenticated or not. From template.php in your theme:

function themeName_preprocess_html( &variables){
if(in_array('authenticated user'), $variables['user']->;roles)){
//do something like adding Css class
$variables['classes_array'][] = 'authenticated';
}
}

Make Hook Available
In your custom module, if you like others be able to hook into some function (i.e. function_to_hook_into()), then within that function

function function_to_hook_into(){
//do some work on list $list_of_things
...
// Allow other modules to add arbitrary things to the list 'list_of_things'
drupal_alter('function_to_hook_into', $list_of_things, $form, $form_state);
...
}

Now, any other module could hook into this function and update the list ‘list_of_things’

function MODULE-NAME_function_to_hook_into_alter( &list, $form, $form_state){
//updated the list as you wish
}

Here, by adding ‘MODULE-NAME_’ in front and ‘_alter’ at the end of the function makes this function to be called within execution of function ‘function_to_hook_into’. Since we are passing the list by reference, we directly can manipulate this list. And thats the Powers of HOOKs in Drupal!:)

Passing Variables from Page to Node

In the following example we specifically passing regions to the node template so it can render blocks within:

function THEME_preprocess_node( &vars , $hook){
// Get a list of all the regions for this theme
foreach (system_region_list($GLOBALS['theme']) as $region_key =>  $region_name) {

// Get the content for each region and add it to the $region variable
if ($blocks = block_get_blocks_by_region($region_key)) {
$vars['region'][$region_key] = $blocks;
}
else {
$vars['region'][$region_key] = array();
}
}
...
}

Afterwards, the regions can be rendered in the node templates as follows:

<?php print render($region['select_product_form']); ?> 
Retrieving Main Menu Alias Links

Put the following in the template.php file into hook ‘theme_preprocess_page’ that is where the $vars[‘node’] is used to determine what is the current node loaded.

$mainMenuArray = menu_load_links('main-menu');
$finalMainMenu = array();
foreach($mainMenuArray as $key=> $menuItem){
$finalMainMenu[$key]['active'] = false;
$linkPath = $menuItem['link_path'];
$linkPathAlias = drupal_get_path_alias($linkPath);
$currentId = $vars['node']->;nid;
if(drupal_get_path_alias("node/$currentId") == $linkPathAlias)$finalMainMenu[$key]['active'] = true;
$finalMainMenu[$key]['url'] = $linkPathAlias;
$finalMainMenu[$key]['title'] = $menuItem['link_title'];
}
$vars['mainMenu'] = $finalMainMenu;

Afterwards, i have the main menu values available in variable ‘$mainMenu’ to insert in html structure as needed.

Load Languages / Get Default Language

To load current languages installed and configured:

$languages = language_list();

This will load array of languages with attributes that can be good to construct the language switch menu
To get currently selected language:

global $language;
return $language->;name;
Retrieve Node Translation Alias

In case you working on language switch menu and you need retrieve all translation node alias of the current loaded page node:

$tanslation_paths = array();
$tanslation_paths = translation_path_get_translations($_GET['q']);

//construct the path
...
$lang_menu[$index]['url'] = '/'.drupal_get_path_alias($tanslation_paths[$lang_code], $lang_code);

In first two lines all of the translations are retrieved into array. Afterwards, the alias path for each translation is constructed

Adding Product to Shopping Cart on Form Submission

There may be time you need to add product once the form is submitted

function moduleName_formName_submit($form,  &form_state) {
...
$default_quantity = 1;
$product_id = array($form['your_form_element']['#value']);
$product = entity_load('commerce_product', $product_id);
// Build the line item we'll pass to cart.
$line_item = commerce_product_line_item_new($product[$product_id[0]], $default_quantity);
$form_state['line_item'] = commerce_cart_product_add(
0,
$line_item,
TRUE
);
...
}

Here the ‘commerce_cart_product_add’ function adds the new line item created from the product

Load Other Modules

To utilize other module within your module, all you need is to load it as following:

module_load_include('inc', 'location', 'earth');
module_load_include('module', 'commerce', 'modules/cart/commerce_cart');

This loads the ‘location’ and commerce/cart modules. Afterwards, you are able to use any of their modules API

Different Ways Query Database

One way

//Build query
$query = new EntityFieldQuery();

//Only show of specific content type
$query->;entityCondition('bundle','contetTypeName');

//only show latitude between the range
$query->;fieldCondition('field_name', 'value', $range_lat, 'BETWEEN');

//only show longitude between the range
$query->;fieldCondition('field_name', 'value', $some_value, 'EQUAL');

//Excecute query
$result = $query->;execute();
// will return array of associate arrays keyed by entity type outside and relative entity inside

//Check if No results
if(!isset($result['node'])){
return '';
}

//load all of the nodes
$nodes = node_load_multiple(array_keys($result['node']));

//accessing property values
foreach($nodes as $node){
$propertyOne = $node->;propertyOne[LANGUAGE_NONE][0]['value'];
...
}

Second Way

//Get All Node IDs with specific content type
$sql_query = 'SELECT nid ';
$sql_query .= 'FROM {node} '; //brackets to add table prefixes
$sql_query .= 'WHERE {node}.type = :type ';
$result = db_query($sql_query, array(':type' =>  'contentTypeName'));

//array to hold nids
$nids = array();
foreach($result as $row){
$nids[] = $row->;nid;
}

//delete all content instances
node_delete_multiple($nids);

Third Way

$nid_member = db_select('node', 'n')
->;fields('n', array('nid','type'))
->;condition('n.type', 'member')
->;condition('n.uid', $user->;uid)
->;execute()
->;fetchCol();// or
//load the member
$listOfMemberNodes = node_load_myltiple($nid_member);

Or for only single node instance:

$nid_shop = db_select('node', 'n')
->;fields('n', array('nid','type'))
->;condition('n.type', 'shop')
->;range(0,1)
->;orderBy('nid', 'DESC') // Additional sorting
->;execute()
->;fetchCol();

//load first shop node
$shopNode = node_load($nid_shop);
API For Constructing URls

a)To generate URL from Alias path(particular good using in custom module development):

$newUrl = url('alias-path');
$newUrl2 = t('See all <a href="@url"> memberships</a>  page', array('@url' =>  url('members')));
1
Here, we generate the Url path using URL() API

b)To generate complete anchor link(specially well for multilingual support):
1
l('See all members', url('members'), array('language'=> 'lv'));

Here, we generate complete link anchor for latvian language user

Make Regions/Blocks Available in HTML or Node scope(html.tpl.php/node.tpl.php Template)

If you like to have regions with blocks available from html(i.e. html.tpl.php) or node(i.e. node.tpl.php) scope , then add the following the preprocessors - hook_preprocess_html or hook_preprocess_node functions:

function THEMENAME_preprocess_html( &vars, $hook) {
include_blocks($vars, 'html');
//include_blocks($vars);//for hook_preporcess_node()
}

//includes blocks in current scope(i.e html, node,etc) and places them in $region['block_id'] variable
function include_blocks( &vars, $scope = 'page')
{
$all_blocks = array();
$ctx_blocks = array();
$blocks = array();
//retrieve context plugin as alternative for managing blocks
$ctx_plugin = (module_exists('context')) ? context_get_plugin('reaction', 'block') : '';

foreach (system_region_list($GLOBALS['theme']) as $region_key =>; $region_name) {

if (block_get_blocks_by_region($region_key)) {
$blocks = block_get_blocks_by_region($region_key);
}

if (!empty($ctx_plugin) &amp;&amp; ($region_key !== 'content')) {
if ($scope == 'html') {
//blocks not build in html scope, so we build it manually
$region_blocks = $ctx_plugin->;block_list($region_key);
$ctx_blocks = _block_get_renderable_array(_block_render_blocks($region_blocks));
} else {
$ctx_blocks = $ctx_plugin->;block_get_blocks_by_region($region_key);
}
}

$all_blocks = array_merge($blocks, $ctx_blocks);

//sort the blocks merged
$all_blocks['#sorted'] = FALSE;

//maintain weights
foreach ($all_blocks as  &block) {
if (isset($block['#block']->;weight)) {
$block['#weight'] = $block['#block']->;weight;
}
}

// add it to the $region variable
$vars['region'][$region_key] = (isset($all_blocks) &amp;&amp; !empty($all_blocks)) ? $all_blocks : array();

//reset arrays
$all_blocks = array();
$blocks = array();
$ctx_blocks = array();
}
}

This takes all the blocks and assigns to the regions variable available in the html or node scope. Afterwards, In the template file html.tpl.php or node.tpl.php, you would render as following:

<?php print render($region['some_region_name']);  ?> 
Adding CSS Programmatically

To add CSS:

//Add before all other theme CSS files
drupal_add_css(drupal_get_path('theme',$GLOBALS['theme']) .'/css/fullcalendar.css', array('type' =>; 'file', 'weight' =>; CSS_THEME - 1));

//Add after all other theme CSS files
drupal_add_css(drupal_get_path('theme',$GLOBALS['theme']) .'/css/fullcalendar.css', array('group' =>; CSS_THEME, 'type' =>; 'file'));

// Add a CSS file that will appear before any other system-level CSS files.
drupal_add_css('mystylesheet.css', array('group' =>; CSS_SYSTEM - 1, 'preprocess' =>; FALSE));

In the last, we set 'preprocess' to false to make sure the attached style sheet is of LINK tag instead of the STYLE. This is important for IE support specifically to make the respond.js work in Twitter Bootstrap.

In case, the stylesheet is external, then set the type to be 'external' and ensure include full path to the external stylesheet as following:

drupal_add_css('http://fonts.googleapis.com/css?family=Play|Oswald|Arbutus+Slab|Abel|Open+Sans|Shadows+Into+Light&amp;ver=3.7.1', array('type' =>; 'external', 'weight' =>;CSS_THEME, 'preprocess' =>; FALSE));
Removing CSS Programmatically

There are several ways to accomplish this
1)Via Hook_Css_alter()

function THEME_css_alter( &css){

//for removing single file
$path = path_to_theme() . '/node.css';
unset($css[$path]);

//for removing multiple css files
$exclude = array(
path_to_theme() . '/node.css' =>  FALSE,
path_to_theme() . '/node2.css' =>  FALSE,
);
$css = array_diff_key($css, $exclude);
}
Adding JS Programmatically

Currently, you can only add JS in header or footer regions but not your custom regions. To add js in footer:

drupal_add_js(drupal_get_path('theme',$GLOBALS['theme']) .'/js/switcher/some.js', array('scope' =>;'footer', 'type' =>; 'file'));

To add external Js:

drupal_add_js('https://maps.googleapis.com/maps/api/js?sensor=false', array('type' => 'external', 'scope' => 'footer'));

Or if you like to add inline js, than:

$js_to_add = 'var thickboxL10n = {"next":"Next >;","prev":"...};';
drupal_add_js($js_to_add, array('scope' =>;'footer', 'type' =>; 'inline'));

Note, there is no need to add 'javascript tag or wrap into 'CDATA' because Drupal does it for you

For IE specific:

$html5shiv = array(
'#tag' =>; 'script',
'#attributes' =>; array( // Set up an array of attributes inside the tag
'src' =>; drupal_get_path('theme', $GLOBALS['theme']) . '/assets/js/libs/html5shiv.js',
),
'#prefix' =>; '<!--[if lt IE 9]>;',
'#value' =>; '',
'#suffix' =>; '<![endif]-->;',
);
drupal_add_html_head($html5shiv, 'html5shiv');

2. Via Theme_System_Info_Alter hook

function Theme_system_info_alter( &info, $file, $type) {
if($type == 'module'  & & $file->;name == 'node') {
unset($info['stylesheets'][all]['node.css']);
}
}
Retrieve Current User Img

To retrieve current user profile image url as following:

global $user;
$user_profile = user_load($user->;uid);
$user_img_url = image_style_url("medium", $user_profile->;picture->;uri);

The last line, creates the url of current user profile specific to the image style(i.e 'medium') specified. For all available image styles see admin->;configuration->;'Image Styles'
If you 'fid' of the picture, then:

$user_img_url = image_style_url("medium", file_load(FID)->;uri);

the 'FID' is the id of picture file

Extend Breadcrumbs With Title

To extend breadcrumbs with '/ Title Of Page' or any other info from Node instance, then use THEME_breadcrumb() hook to manipulate breadcrumbs and node_load(art(1)) to load current Node instance as following:

function THEME_breadcrumb($variables) {
....
if ((arg(0) == 'node')  & & is_numeric(arg(1))  & & ($node = node_load(arg(1)))) {
$breadcrumbs .= '<li> <span> '.$node->;title.'</span> </li> ';
}
...
return $breadcrumbs;
}
}

In the highlighted line, the node instance is loaded from which the 'title' is extracted afterwards

Load View Programmatically

To load a particular view in code:

$view_big_posts = views_get_view('blog_content_view');
//        $view->;set_arguments(array($tid));
// change the amount of items to show
$view->;set_items_per_page(4);
$view_big_posts->;set_display('machine_view_id');
$view_big_posts->;pre_execute();
$view_big_posts->;execute();

Here he 'blog_content_view' is the view name that you can obtain by hover in over edit of the view. The 'machine_view_id' is the block id set 'other' setting of the view. At last you can render the view 'print $view->;render();'
Alternative, if you like to have the view rendered already, then:

$view_big_posts2 = views_embed_view('blog_content_view', 'machine_view_id');

This will produce already rendered view good for printing on the page

Retrieve Field Value

To retrieve field value using Field API:

$field_instance = field_get_items('node', $node, 'field_name');
$field_value = render(field_view_value('node', $node, 'field_name', $field_instance[0]));

Here we do for entity type 'node' but there are other types such us 'taxonomy_term', 'commerce_product',etc. If you don't know the type, run 'var_dump(entity_get_info()' to see which type is for your particular entity instance

You can also pass view mode (i.e. 'full', 'teaser',etc) as following:

$field_value = render(field_view_value('node', $node, 'field_name', $field_instance[0]),'teaser');

This will format the field in teaser view

Extend Location to Custom Module For Looking Up Templates

This will extend the location where theme registry is looking for template files

/**altering Theme registry to look up template files in our module folder***/
/**
* Implements hook_theme_registry_alter().
*/
function NAME_OF_MODULE_theme_registry_alter( &theme_registry) {
//make local templates available
$path  = drupal_get_path('module', 'NAME_OF_MODULE');
$registry_entries = drupal_find_theme_templates($theme_registry, '.tpl.php', $path);
//to avoid error message adding 'type'
foreach($registry_entries as $key =>; $entry){
$registry_entries[$key]['type'] = 'module';
$registry_entries[$key]['theme path'] = $path;
}
$theme_registry += $registry_entries;
}

Now, you can store template files in custom module

Options For Logging and Other Things

To Log into watchdog log:

watchdog(WATCHDOG_NOTICE, 'Log entry added to test the dblog from menu import.');

To flatten array before printing on the screen:

include_once DRUPAL_ROOT . '/includes/utility.inc';
...
drupal_set_message('item installed: '.drupal_var_export($item)."\n");

here the variable $item is array that we would like to see. So, include utility.inc code base in order to use function drupal_var_export that nicely flattens the array into a variable to print out

Including Files In Theme Space

To include files, so it doesn't break when theme is changed

include_once dirname(__FILE__).'/includes/widgets_js.inc';

or perhaps have function so modules can include some theme artifact

function _theme_include($theme, $path) {
static $themes = array();
if (!isset($themes[$theme])) {
$themes[$theme] = drupal_get_path('theme', $theme);
}
if ($themes[$theme] &amp;&amp; ($file = DRUPAL_ROOT . '/' . $themes[$theme] . '/' . $path) &amp;&amp; file_exists($file)) {
include_once $file;
}
}
Check If Currently in Admin UI

To see if currently in the admin UI:

if (path_is_admin(current_path())) {
//do something
}
Get Current Module Name

To get current module name:

basename(__FILE__, '.module');

This assumes that the module is following Drupal convention of having the .module file the same as the module name. Alternative would be to grab and parse module .info file for retrieving current module name

$module_config_file = drupal_parse_info_file('path/to/.info file');
$module_name = module_config_file['name'];
Product Api Snippets

To get price already formatted as well as currency only:

$price = commerce_product_calculate_sell_price($product);
$prod_default['price'] = commerce_currency_format($price['amount'], $price['currency_code'], $product);
$prod_default['currency'] = $price['currency_code'];
To Get Display For Product

to get a display referencing a particular product:

function _get_referencing_product_display_id($product) {
global $language;
// Iterate through fields which refer to products.
foreach (commerce_info_fields('commerce_product_reference') as $field) {
// Build query.
$query = new EntityFieldQuery;
$query->;entityCondition('entity_type', 'node', '=')
->;fieldCondition($field['field_name'], 'product_id', $product->;product_id, '=')
//            ->;propertyCondition('language', $language->;language, '=')
->;range(0, 1);

if ($result = $query->;execute()) {
// Return node id.
$node = $result['node'];
return array_shift(array_keys($node));
}
}

return false;
}
Finding Drupal Config Variables

To find Drupal variables:

global $conf;
var_dump($conf);

The $conf contains all the Drupal config variables

Retrieve Messages Programmatically
$messages = theme_status_messages(array('display' =>; null));

Here, all messages are retrieved and it also clears the message queue. The "display" can be set to 'error', 'status', 'warning' to retrieve only certain type of messages. The theme_status_messages API is better then calling directly drupal_get_messages because it includes the html of the current theme

Formating Dates

If you have Date module enable and field of Date type, then to format date:

$field_instance = field_get_items('node', $node, 'field_event_date');
$event_date = $field_instance[0]['db']['value'];
$vars['event_date'] = $event_date->;format('j M, Y');
$vars['event_time'] = $event_date->;format('g:i a');

In line one, the field instance is retrieved. In line two, the Date object is retrieved. At last two lines, there are some samples of formatting the date.

if the field is not of type Date, but contains timestamp(i.e. 'created', 'changed',etc)

date("F j, Y, g:i a", $comment->;created)

Here the $comment->created contains a timestamp and we use PHP Date API to format the time

if the field is of ISO Date format, then you will have value in string form for the date(i.e.) In that case, first convert it to timestamp before formating:

$field_instance = field_get_items('node', $node, 'field_event_date');
$date_stamp = strtotime($field_instance[0]['value']);
date("F j, Y, g:i a", $date_stamp);

Here, the time stamp is generated via 'strtotime()' function from the string before its formatted
Consult documentation for different date formats available http://php.net/manual/en/function.date.php

Snippets of Context API

Here little snippet of Context API:

$context = context_load('CONTEXT-NAME');//load certain context
if(empty(!$context->;disabled){
context_set('context', $context->;name, $context);//enable certain context
}

Here we load specific context and activate it if its enabled

//retrieve active contexts
        $all_active_contexts  = context_active_contexts();
        foreach($all_active_contexts as $key => $context){
            context_set('context', $context->name, $context);//activate to render
        }
//        context_flush_caches();

Her, we retrieve all active contexts for the current request. Afterwards, we loop through each and activate.
Here is an example, how to activate context of node type - $type

        $map = context_condition_map();
        foreach ($map['node'][$type] as $key => $context_name) {
            $context = context_load($context_name); //load certain context
            if (empty($context->disabled)) {
                context_condition_met($context, 'node');//activate
            }
        }
Get Path To Public Dir

To get path to the public directory:

$uri = 'public://';
if ($wrapper = file_stream_wrapper_get_instance_by_uri($uri)) {
  $path = $wrapper->realpath();
}
1

Or another way is:
1
$path = file_create_url('public://');
Retrieving Tags

Here is one way to retrieve tags

$field_instance = field_get_items('node', $node, 'FIELD_NAME_REFERENCING_TAXONOMY');
    foreach ($field_instance as $key => $tid) {
        $tag = taxonomy_term_load($tid['tid']);
        $name = $tag->name;
        $url = base_path().drupal_get_path_alias('taxonomy/term/'.$tag->tid);
    }
}

Here, first the instance of field referencing Taxonomy term is retrieved. Afterwards, it loops through each term and extracts the name and url of each term

Grails Snippets

This is ongoing post to record different useful codes snippets related to Grails framework

1. Default and Shared Constraints.
It turns out you can specify default constraints that can be applied and shared in any Domain Class. For example, by default the ‘nullable’ constraint is set to ‘false’. If you wish change that,then updated conf/Config.groovy as follows:

grails.gorm.default.constraints = {
    '*'(nullable: false)
    noBlankSized(blank: fralse, size: 4..25)
}

The ‘*’ attaches the constraint to all property’ validations. The constraint ‘myShared’ can be references in any validation you choose as follows:

class User{
...
 static constraints = {
        favoriteDish shared: "noBlankSized"
    }
}

This way you able to share your own default validations while ability to reuse as you like

2. Suppor Handling Request params

A request parameter value can be converted to a specific type with method invocation:

params.long('book.id')

This takes book.id and converts it to long type. Grails supports other methods like byte(), long(), boolean(). Since Grails 2.0 also support for dates.

3. Access Domain class from Plugin
Say you developing plugin that needs to access domain class in the application.

String className = "com.foo.bar.MyDomainClass"
Class clazz = grailsApplication.getDomainClass(className).clazz
def findAnything = clazz.findByStuff(params.stuff)

If Domain class without package and name unique across all packages:

String className = "MyDomainClass"
Class clazz = grailsApplication.domainClasses.find { it.clazz.simpleName == className }.clazz
def findAThing = clazz.findByStuff(params.stuff)

This may not be best practices as we are coupling the plugin with particular applications, however,perhaps in some circumstance it necessary

4. Mocking Upload File feature with multipart/form-data

void testFileUpload(){
        def imgContentType = 'image/jpeg'
        def imgContentBytes = '123' as byte[]
...
        controller.metaClass.request = new MockMultipartHttpServletRequest()
        controller.request.addFile(
            new MockMultipartFile('image', 'myImage.jpg', imgContentType, imgContentBytes)
        )
...
        controller.save()
...
        assertEquals HttpServletResponse.SC_OK, controller.response.status
..
    }

Current Path from Request
To get current path from the current controller and action:

request.forwardURI

Groovy Snippets

This is ongoing blog where i plan to record groovy code snippets that convenient, useful and powerful

Generating Long Strings

Generating certain size string( used in testing to test sized string constraints)

def genString(size){
    def nameTooLong = 'x'
    size.times { nameTooLong <<= "x" }
    nameTooLong
}

-or-

'x'*100

Avoid Exception – MissingPropertyException

There is null safe operator (?.) to avoid exceptions when calling methods on null object, however. If you call a property or method that is not defined, you will receive an exception – ‘missingPropertyException’. To make it similar as null safe but this time exception safe, add the following to your class:

def propertyMissing( name ) {
  null
}

This will make call to a method, that hasn’t been defined, return null, instead throwing exception. Likewise, this will make access to a variable, that hasn’t been defined, return null instead of throwing exceptions

If you don’t have access to changing the class, then the alternative would something like:

def result = obj.hasProperty( 'b' ) ? obj.b : null

It requires much more to accomplish the same as adding the method – propertyMissing to the class only once, but it may work some situation better

 Remove last characters from string

assert 'some' == 'someString'[0..-7]

Checking if String

To determine whether its valid string, make sure check case for empty string like – ‘ ‘:

asset someString?.trim()

Java Gotchas

This is ongoing post where i hope to continue list different Java gotches

1. java.util.ConcurrentModificationException – Removing children from the parents’s collection while we’re iterating over it.

As example we use groovy. In our example, we have RentalUnit object that contains colection of Reviews and Reviews contain collection of RentalUnit all in many-to-many relationship

Error:

review1.rentalUnits*.removeFromReviews(review1)

Solution:

def r = []
r += review1.rentalUnits
r.each {RentalUnit renUnit ->
     renUnit.removeFromReviews(review1)
}

Grails Custom Validator Snippets

This post is going to be updated on-going and is a space where i hope to collect different examples of custom validators that ensure  some constraint for a Domain class in Grails Framework

1. Ensure specific Date format constraint (i.e. ‘Jan 22, 2011’)

String submitDate 
...
final static DateFormat DATEFORMAT  = DateFormat.getDateInstance(DateFormat.MEDIUM)
static constraints = {
      submitDate validator: {
         try{
             Date date = DATEFORMAT.parse(it)
             return DATEFORMAT.format(date) == it
         }catch(ParseException exception){
             return false
         }
      }

2. Zip Code validator

static constraint = {
   zipCode blank: false, size: 5..10, validator:{zip ->
            (zip ==~ /^(\d{5}-\d{4})|(\d{5})$/) ? true : false
        }
}

3. Numeric validator for Phone number,Social Security number,etc
a) If you know exactly how many numbers should contain. Here is example for 10:

static constraints = {
     ...
        phone matches: '\\d{10}'
     ...
    }

b) If its necessary to validate for some specific pattern such as 651-555-5555

static constraints = {
     ...
        phone matches: '\\d{3}\\-\\d{3}\\-\\d{4}'
     ...
    }

c)If its necessary to validate that it contains only numbers

static constraints = {
     ...
        phone matches: '\\d+'
     ...
    }