Saturday, November 30, 2013

Drupal 7 - Moving the messages text from a zone to a region in an Omega subtheme

The messages always mess up my page layout, so I usually simply want them on the top of my page content.

1. remove message from its default postion
1.a  Copy  zone--content.tpl.php to your subtheme's template directory (if you have not done that already)
1.b Remove these lines
  <?php  if ($messages): ?>
      <div id="messages" class="grid-<?php print $columns; ?>"><?php print $messages; ?></div>
    <?php endif; ?>


2. transfer the messages variable to the region template
2.a Open template.php
2.b add a preprocess functio, or modify if you alreay have one

 function THEMENAME_preprocess_region(&$vars) {
      $theme = alpha_get_theme();
     if ($vars['elements']['#region'] == 'content') {
       $vars['messages'] = $theme->page['messages'];
    }

 }


3. add the messages to the region template
Just write anywhere you want in the template
    <?php if ($messages): ?>
      <div id="messages" class="grid-<?php print $columns; ?>"><?php print $messages; ?></div>
    <?php endif; ?>

Drupal 7 - Adding multiple javascript files to an Omega subtheme

Adding a javascript to an Omega subtheme is a bit complex.
I'd rather use  scripts[] = js/chr.js in the info file, which works by the way, but for some reason you first need to add the js file as a library, and then enable it in the settings.
(see https://drupal.org/node/1416128 and https://drupal.org/node/1205984)
I this example I add one library containing two javascript files.

0. Add your javascript files in the js folder of your theme
(in this example I use files chr.js and chr2.js)

1. Add some code like this to your theme's info file

libraries[chromega][name] = CHR KHR main javascript
libraries[chromega][description] = Quirqks and Jeeeequery fun for th CHR website
libraries[chromega][js][0][file] = chr.js
libraries[chromega][js][0][options][weight] = 1
libraries[chromega][js][1][file] = chr2.js
libraries[chromega][js][1][options][weight] = 2

(you can use any name where I use chromega)

2. Go to your theme's settings page

3. Select tab toggle libraries and add your custom library











4. Clear you cache  

5. and then GO javascripting
(I always forget the structure for the D7 javascript files so thats why I add this wonderfull example)


// JavaScript Document
// http://drupal.org/node/756722
(function ($) {
 //////////////////////////////////////////////////////////////////////////////////////// All code here
   $(document).ready(function() {
     // maak op d ehomepage beide blokken even lang
     dotherightthing();   
  });
  function dotherightthing(){
      alert('Do the right thing!');
  }
 ////////////////////////////////////////////////////////////////////////////////////////  end of all code
}(jQuery));



        ---

Nota bene

For some reason this (lazy) way of adding the javascript in the template file does not work

function themename_preprocess_page(&$variables) {
  drupal_add_js(path_to_theme() . '/js/chr.js');
}

Friday, November 29, 2013

Drupal 7 - Adding captcha to a webform

Another thing I always have to lookup while it is so simple....
1. install the captcha and image captcha module
https://drupal.org/project/captcha

2. go to configuration > people > captcha

3. Add form id
Add the form id of the forms to which you want to add a captcha challenge on the bottom of this page and select the captcha type







You can find the id by opening the form an looking in the HTML. There you find an id like: webform-client-form-75

<form accept-charset="UTF-8" id="webform-client-form-75" method="post" action="/en/order" enctype="multipart/form-data" class="webform-client-form">


NB! Replace all hyphens by underscores!

webform-client-form-75    ->    webform_client_form_75

4. Translation
If you have a multilingual site and want to translate the description, you have to do this partly on the capcha configuration page, partly via the normal Drupa interface translation.
(which is rather stupid)

captcha config
For instance, as I am Dutch (although also half Frysian) I always translate
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
To a bit archaic
Deze vraag wordt gebruikt om te testen indien u een menselijke bezoeker bent teneinde spam-inzendingen te vermijden.

Interface translation
What code is in the image? *To
Welke code ziet u in de afbeelding?: *
Enter the characters shown in the image.
Which is more or less a useless repetition of the previous sentence I think, to
Vul bovenstaande code in.

5. State of Bliss
And then, your webform will contain a captcha. Rejoice!















For Drupal 8: see this post



Thursday, November 28, 2013

Drupal 7 - Changing the default file type icons without hacking core

A lot of time the designers want the icons just a little bit different than they are in drupal core. So, being lazy, I always just replaced the icons in core with the designer icons ad made a remark in my upgrade doc for that particular site.

A better way to achieve this is to just change the file icon path in your theme and put the modified icons somewehere outside the drupal core, so as being ably to upgrade your site and modules without any extra configuration steps.


function THEMENAME_file_icon($vars) {
  $file = $vars['file'];
  $icon_directory = drupal_get_path('theme', 'THEMENAME') . '/images/file_icons';
  $mime = check_plain($file->filemime);
  $icon_url = file_icon_url($file, $icon_directory);
  return '<img alt="" class="file-icon" src="' . $icon_url . '" title="' . $mime . '" />';
}


Copy the map modules/file/icons to a the images directory in your theme.
Rename the map file_icons
Change any image in this map to your (or your beloved designers) liking and you're set.


Monday, November 25, 2013

Drupal 7 - Presave a node (or doing custom validation and/or manipulation on field values)

I now have the simple specification that I have a text field in a Node which always needs to be uppercase, whatever the editor enters in the field. As a second specification I also want all spaces removed from the field values.
I could not find an example snippet to start up from, so I thought better publish this, maybe someone else will have  an easier live than me....

Specification
Field x: user may enter any character, but on saving the field all characters will be uppercased.
Field x: Also, alle whitespaces will be removed from the string


1. Create a module, in this example called customchr.
1. a Create info file  customchr.info

name = Custom CHR
description = Custum manipulations for the CHR site
package = Overboord
core = 7.x



2. Create module file customchr.module

function customchr_node_presave($node) {
  if ($node->type == 'publication') {
    // convert to uppercase
    $tempstring=strtoupper($node->field_publication_code[und][0][value]);
    // strip all whitespaces
    $node->field_publication_code[und][0][value]= preg_replace('/\s+/', '', $tempstring);
  }
}










Drupal 7 - Theming file field for documents

What seems to be a really simple task for any Drupalist got me really walking the ceiling this evening.
I just want to display my filefields, for the document, as a download limk with an icon denoting the file type and with the filesize mentioned. It seems to me that that should be the default way to show a download, but it is not.
After playing with the custom field formatters for a while, I used an easier approach.


1. Go to view modes and add a viewmode
2. give it a understandablen namen (vm_file_icon_download_size)
3. Check file
4. save
5. go to structure > file types (or older Drupal version you can find that under configuration)
6. click 'manage display' in the document row
7. click on tab 'custom display settings'
8. check the new view mode you just added
it appears as a tab in the top of your page
7. click on this tab and then click on manage file display
8. Choose table of files
Drupal will then show a rather ugly table with all element I want, the icon, the filename, the size.
I can rewrite the css to make it all a bit less ugly


.file.file-document table thead {
       display:none;
 }

.file.file-document table, .file.file-document table tr  {
      border:none;
      background-color: #FFFFFF;  
}
.file.file-document table td  {
      display:inline;
}


The link in the display will then look like



BUG: Description bug
But when you enable a description this still won't show.
This is caused by a bug in the file entity module.
https://drupal.org/node/1784762
Using the patch resolves this issue

https://drupal.org/files/file-entity-load-description.patch




Wednesday, November 20, 2013

Drupal 7 - how to create a views block of all referenced nodes in the entity reference fields

I did this so many times but every time I seem to have to start all over again. Reason to write it all up and publish it here.
Others may have done this before and much better.

Setup
Drupal 7, Views, entity reference (multilingual)
In have contenttype A which contains an entity referemce field that can make a reference to contenttype B.

Specification
A. View of items referencing
I also want to display the list of all node C and D referring to the current project. Here I also want to show multiple fields from the referring node linking to the referring node itself.

I my case contenttype A is a project, and contenttype B are Institutes cooperating on these projects. Contenttypes C and D are articles and publications which are refer to the project in question.


B. View of referenced items
On displaying a contenttype A node I want to display some of the fields from the referenced node (contenttype B) in a sidebar.


How to A. View of items referencing
A.1 Create a new view
A.1.1 Call it f.i.  'related'
A.1.2 Choose fields for the format


A.2 Open the 'Advanced' tab on the right hand side
A.3 Click the Add button behind relationships
A.4 Select
(you have ond eof these for every entity reference field in your contenttype)
In my case I have A bridge to the Content entity that is referenced via field_project_institutes
A.5 Click Apply
A.6 On the next screen check Require this relationshop
You can also change the name of the identifier but I never see a reason for this.

In this example it is called:Content entity referenced from field_project_institutes
Now we need an argument to provide to the relationship, and the argument will be the nid of the current contenttype A node. To do this you have to provide a contextual filter
A.7 Click the Add button behind contextual filters
A.8 Check Content: Nid
A.9 Click Apply
A.10 A new screen: Choose the relationship you just made
In this example it is called:Content entity referenced from field_project_institutes
A.11 Select Provide a default value under When the filter value is not available
A.12 Under Type select Content id from url
A.13 Then, under When the filter value IS available or a default is provided check the Specify validation criteria box
A.14 Under Validator choose content and then check the contenttype b. The contenttype that is referred to, not the contenttype that contains the reference field.
A.15 Under Filter value format choose Node ID
A.16 Under Action to take if filter does not validate choose Hide view
A.17 Apply
A.18 Save your block view





How to B: View of referenced items
B.1 Create a new view
B.1.1 Call it f.i.  'related'
B.1.2 Choose fields for the format

B.2 Open the 'Advanced' tab on the right hand side
B.3 Click the Add button behind relationships
B.4 Select
B.5 Click Apply
B.6 On the next screen check Require this relationshop
You can also change the name of the identifier but I never see a reason for this.
B.6.1 and click Apply

In this example it is called:Content referencing Content from field_project_institutes
Now we need an argument to provide to the relationship, and the argument will be the nid of the current contenttype A node. To do this you have to provide a contextual filter
B.7 Click the Add button behind contextual filters
B.8 Check Content: Nid
B.9 Click Apply
B.10 A new screen: Choose the relationship you just made
In this example it is called:Content referencing Content from field_project_institutes
B.11 Select Provide a default value under When the filter value is not available
B.12 Under Type select Content id from url
B.13 Save your viws, and place ypur block in the correct region...


Extra
Suppose you want to show an image field from the node that is referred to in the sidebar, linking to this orihinal node. Seems an easy task doesn't it?
No. The problem is that you can easily ad the field to the view, select its viewmode, but wehn you want to link this field to the containing node, all html cleaners protest:
Adding the link aroudn the field does not work in this case, the a tag contains the div tag.  Rewriting the output presents me with the samen problem.
The way i figured it out finally was to
a. Add the content path, as a field (use absoklute and hide from display)
b. Add the image, set its view mode but then strip all html tags except <img>
c. Create a global text field, and there rewrite the output to
something like <a href="[path]">[field_institute_logo]</a>
d. But you still have a problem than because the field_field_institute_logo value containes stripped text from html that is normally hidden to users. So then just create a field template for this global text field removing everything from there except the a and im tags and inner attributes.
$output = preg_replace('#.*?(<(img|a).+?>).*?#is', '$1', $output);



Node reference
On trying the same with nodereference I got really stuck but solved it eventually....

A.
1. add relationships
2. search for the noderefence field you want (NB NOT with ' - reverse')
(this is the node reference field in the node referring to the node type entity B)
(In my case, Inhoud: Verwijzing (field_verwijzing) )
3. Click apply (remember the name of the relationship*)
4. Select 'Require this relationship'
5. click apply
5. Add contextual filter
6. Chose Content: Nid
7. Click apply
8. Choose the relationship you just made (*)
9. Under When the filter value is not available choose 'provide default value'
9.1 Choose 'Content id from Url'
10. Under when the filter value is avaialable or a default is providedselect 'Specify validation citeria'
10. 1 (Depending on the install there should be an extra box , but in some installs the box wont show up, and you have to click apply and then click on the contextual filter again before you can add these criteria)
Under Validator choose Content
10.2  Under contenttypes choose your contenttype B
10.3 Under filter value format choose 'Node ID'
10.4 Under action to take when filter value does not validat Choose 'Hide view'





Friday, November 1, 2013

Dupal 7 - Media and View modes - How to get an image style as a view mode in the list in the media browser



I've been battling with this for quite some time, so maybe someone else be happy with this post.
You define an Image style and want to be able to select this style in the display setting for your content type, or in the display settings for a field in a view.
Here is a simple flowchart to achieve this.


1.define a new image style
1.1 go to administration > Configuration > Media
admin/config/media/image-styles
1.2 add image style
1.3 give it a descriptional name
f.i. call it verylargeimage
1.3 add effects
f.i. set scale and crop
Width 624
height 400

1.4 update style

2. create a corresponding view mode
Do this with display suite or with entity view mode
example here is done with Display suite
2.1 got to administration > Structure > Display Suite > View Modes [tab]
admin/structure/ds/view_modes
2.2 click add a view mode
2.3 Give it a name you can easily relate to the image style
In this example f.i. vm_verylargeimage
2.4 Select the file checkbox
2.5 Click Save

3. Connect the style and the view mode
3. 1 Navigate to Administer -> Configuration ->Media -> File Types
If you are using Media 2.x, then the File types has moved to Administer -> Structure -> File Types.
admin/structure/file-types

3.2 Click on manage display on the image row
3.3 open tab (under left) custom display settings
3.4 check the checkbox in front of youre viewmode name
In this example vm_verylargeimage
3.5 In the upper right corner you see your viewmode added to the viewmodes menu
3.6 Click on manage file display
3.7 Click on your viewmode
In this example vm_verylargeimage
3.8 Select under Enabled displays 'Image'
3.9 Select your image style on the bottom of the page


In the display settings for the field in your contenttype, or your view, you can now choose the corresponding view mode.
  • Drupal 7
  • Media
  • view modes