Showing posts with label drupal 7. Show all posts
Showing posts with label drupal 7. Show all posts

Wednesday, June 11, 2014

Translating the Site Name in Drupal 7

Allmost all parts of Drupal are easily translatable but a select few are hidden. The Site name and Slogan are a couple of those.
To translate a Drupal 7 Site name you have to activate 'Variable translation' module (which is in the same package as i18n) and the required ones (like 'Variable store').
After you install these modules, go to Configuration -> Multilingual settings -> Variables tab and choose 'Site name' (?q=admin/config/regional/i18n/variable). Then go to Configuration -> System -> Site information (?q=admin/config/system/site-information) and select the language you. Change the 'Site name' field and save.
You'll find the translated site name in 'variable_store' table.

Friday, June 6, 2014

Bulding a custom token for url aliases (or anything else)

Tokens are a great resource in Drupal when it comes to creating url aliases, replacing text in emails, creating Rules actions or pretty much anything when it comes to automation.

Here's how to create a custom token for nodes that will perform an action on a field from the node and return it as a replacement.

We start out by informing Drupal that we provide a token applicable to nodes. You can replace node with any entity bundle name to provide tokens for them.

/**
 * Implements hook_token_info().
 * Provides Drupal with a list of our tokens to present in the UI 
 */

function example_token_info() {
  $info = array();
  // Define a new token for nodes.
  // "node" can be replaced with other entity names
  $info['tokens']['node']['reverse'] = array(
    'name' => t('Reverse category term name'),
    'description' => t('Outputs a reversed term name.'),
  );
  // Any other tokens follow here
  return $info;
}

We continue by implementing the hook_tokens method to provide methods for performing the token replacements.

/**
 * Implements hook_tokens() .
 * Takes care of the actual replacement of the token
 */
function example_tokens($type, $tokens, array $data = array(), array $options = array()) {
  $replacements = array();

  if ($type == 'node') {
    // Loop through the available tokens.
    foreach ($tokens as $name => $original) {
      // Find our custom tokens by name.
      switch ($name) {
        case 'reverse':
          // Load field from node.
          $fielditems = field_get_items('node',$data['node'],'field_category');
          if ($fielditems[0]['value']) {
            // Load the term.
            $term = taxonomy_term_load($fielditems[0]['value']);            
            // Replace placeholder with reversed term name.
            $replacements[$original] = strrev($term->name);
          }
          else {
            // No category assigned, replace with ''.
            $replacements[$original] = '';
          }
          break;
      }
    }
  }
  // All done.
  return $replacements;

}

That's it. You are now replacing tokens like nobody's business.

Thursday, June 5, 2014

Why Display Suite is a bad idea

And why Code Fields are an even worse idea

You start out with three content types and a couple of view modes and everything is hunky-dory. Then the customer has some specific requirements and you say to your self – "Hey, that's kind of a weird thing to do but what the heck, I'll just do a code field and get it done!"
Of course, this continues throughout the project and you keep adding view modes and code fields to fulfil the reqs because once you've started down the DS + code fields road there's just no stopping it.

A year later, the Customer comes back with some new requirements. The site is going to be relaunched with multiple languages. And you're like – "Fuck yeah! i18n FTW!". Until you realize that all those sweet code fields are all like UND UND UND UND and you really should have written those umpteen gazillion tpls instead.

So, Display Suite? No.
Code Fields? No.

Wednesday, June 4, 2014

Apache Solr Search and FacetAPI translation

To be able to translate the strings "Displaying: 1-10 of 20" and the other parts of the current search blocks you need to install facetapi_i18n. After installing it you need to visit your config for the current search block and hit Save. Then go to your facet configuration and hit Save. Last but not least you need to refresh the strings for translation.

Oh, and btw, the text "Displaying..." will be triple encoded and output escaped html if you don't patch facetapi_i18n with this patch referenced in this issue https://drupal.org/node/1741444

Tuesday, June 3, 2014

Drupal and Ajax, now with language negotiation...

Sometimes I just want to kick myself! I was struggling to set the language for a module that gets called via Ajax and that prints out the contents of a view (with supposedly the correct field language set) but the field language always went for default language...

Well, turns out, sometimes it's Just Not That Hard.

Set up the language negotiation to use prefixes and then just prefix the url with the desired language like /lang/arg

Menu hook from the module:

function example_menu(){
$items = array();
$items['example/ajaxview'] = array(
        'title' => 'Ajax View Loader',
        'page callback' => 'example_loadview',
        'access arguments' => array('access content'),
        'type' => MENU_CALLBACK
);
$items['sv/example/ajaxview'] = array(
        'title' => 'Ajax View Loader',
        'page callback' => 'example_loadview',
        'access arguments' => array('access content'),
        'type' => MENU_CALLBACK
);
$items['en/example/ajaxview'] = array(
        'title' => 'Ajax View Loader',
        'page callback' => 'example_loadview',
        'access arguments' => array('access content'),
        'type' => MENU_CALLBACK
);
$items['de/example/ajaxview'] = array(
        'title' => 'Ajax View Loader',
        'page callback' => 'example_loadview',
        'access arguments' => array('access content'),
        'type' => MENU_CALLBACK
);
return $items;
}

The callback:

function example_loadview($arg){
  // Print the output from a view that takes a contextual argument
  print views_embed_view('myajaxview', 'my_display_id, $arg);
  exit;
}


Calling the function from javascript (Drupal keeps a note of the path prefix used in Drupal.settings.pathPrefix)

var url = "/" + Drupal.settings.pathPrefix + "example/ajaxview/" + arg;
$.get(url, function (data) {
  alert(data); // Or do something with it
});

The language negotiation will do the rest of the heavy lifting.

String just won't translate?

... make sure you're not overwriting it with your fancy-pants javascript functions... :)

Getting the path of a translated node

for those pesky hardcoded links in tpls

global $language;
$translations = translation_path_get_translations("node/42");
/*
Returns the paths of all translations of a node, based on its Drupal path:
array(2) {
        ["de"]=>string(7) "node/42"
        ["en"]=>string(7) "node/43"
}
*/
print l(t('Link Title'), $translations[$language->language]); //l() will return the alias to node/42

Wednesday, May 28, 2014

Adding new node operations for the content overview screen

Extending the list of operations available for batch processing on /admin/content is quite easy. This goes in a module called example.module

function example_node_operations() {
  $operations = array(
    'example_magic_operation_1' => array(
      'label' => t('Works magic on your nodes'),
      'callback' => 'example_operation',
      'callback arguments' => array('bulkupdate', array('message' => TRUE)),
    ),
    'example_magic_operation_2' => array(
      'label' => t('Works even more magic on your nodes'),
      'callback' => 'example_operation_2',
      'callback arguments' => array('bulkupdate', array('message' => TRUE)),
    ),
  );
  return $operations;
}

// This function gets an array of nids from what was selected
// on the /admin/content screen
function example_operation(array $nids, $op, array $options = array()) {
  foreach ($nids as $nid) {
    // Work your magic here
  }
}