# Question
Title: Create a view that shows all events and the users that have signed up for each event
I am using the Signup module, and I am trying to create a view that shows all events and the image associated to the users who signed up for each event.

This is the exported view I have so far.

# Answer
> 1 votes
Doing something like this is pushing views to it's limits. You want to pull in a lot of data and group it by the node id. I'm not sure if all this is possible through the views interface, though I believe it will be possible with the engine that's running views.

Instead of trying to achieve this rather complex view, which may become something, that's hard to modify, you could do this quite easily using more and simpler queries. Such a simple solution could look like this:

1. You could create a simple view, which display all the info except the signups. (Node title etc)
2. Signup already has a view, which will display the people that signed up for an event. With a little bit of modification, you could make it show the avatar of the users that has signed up for an event. Then you could embed this view in either a preprocess function and/or a template for the view you created in step 1.
3. You're done.

The **ideal** thing would be to create all of this in a single view, but sometimes you have to think about what the cost will be compare to the gains. I doubt you will be able measure any performance differences, unless you list hundreds if nodes with signups. But the time you save doing it this way is quite a lot.

This is the same with views itself, it's inefficient, but nothing important (for most sites) and it allows us to save lots of time, not having to code queries, theme functions etc.

**Update:**

Embedding a view with arguments (like node id) is pretty simple:

```
$html = views_embed_view($name, $display_id, $arguments)

```

Or in your case

```
$html = views_embed_view('signup_user_list', 'default', array('nid' => $nid));

```

# Answer
> 0 votes
Create a "Group" named "Event". You don't need to install all of the OG modules, just a few. You dont need to create a group content type: you simply need an "Event".
People create Events and join Events. Go into group default permissions and make the group public by allowing people to join the event without subscribing.

You may want to use the "String Replace" module to easily customize some of the language to your liking, or over-ride the group theme functions. "String Replace" is simple and fast, but can be a bit too universal (it's up to you). Either can help make the language of joining to be just as you want. The template over-ride will allow you to make additional changes to the user interface.

Use a view, and a custom template.tpl.php! Done! Its fast, light weight and easy. Users will never know they are joining a "Group" and the results you get will exactly match what you want. Easy as PIE!

# Answer
> 0 votes
Add a user reference to your content type if it doesn't already include one and include it on your view with a relationship.

---
Tags: 7, views
---


# Question
Title: Allowing role permissions to a content type based on the date
I'd like to allow a certain role can add new content of a certain content-type ONLY between two dates. Before or after these dates the role shouldn't be able to create a new content of this content-type.

Is it possible through the Drupal core or any module? I haven't found anything about it.

# Answer
You can implement hook\_node\_access() (This is now a real hook in Drupal 7) and implement whatever you want.
> 2 votes

---
Tags: 7, users, nodes
---


# Question
Title: How does form API work for CCK (and other #after_build processes)?
When you want to hook into a CCK form and alter something, you are usually required to call a custom function from `$form['#after_build']` (right?).

When doing so, I have noticed I can't write $`form['field_name']['#disabled'] = TRUE;` but instead I have to use the `#attributes` approach.

Why? Am I doing something wrong?

# Answer
> 2 votes
The form API is usually doing that for you, but it probably does that before calling the after\_build functions.

The #after\_build functions are called in form\_builder(), #disabled handling is in \_form\_builder\_handle\_input\_element(), which is called earlier in form\_builder().

---
Tags: forms
---


title: Several variants in a page

text:
# Question
Title: Several variants in a page
Is it possible to use several variants in a page?
In the page I made only one variant is shown.

# Answer
The first variant that "passes" will be the one that is shown.

So if the first (top) variant does not have any conditions limiting when it is displayed, it will **always** be the one that is shown.
> 2 votes

---
Tags: 7, panels
---


# Question
Title: Get the username of a user who is being added to an organic group
We're using organic groups, and we'd like to notify an administrator every time someone joins a group.

At the moment, we've set up a trigger for this, and set up an action to send an email. We're using the %username token in the email, but this refers to the username of the person who created the group in the first place, not the username of the person joining.

Is there any way to send an email that includes the username of the person who is joining the group?

# Answer
> 2 votes
I nice and simple way of accomplishing this will be to download the token (http://drupal.org/project/token) module. Once you've downloaded the token module be sure to enable token and token\_actions module.

The token module will give you more "tokenize" options besides the default %username.

Now instead of creating a "send email" action create a "send tokenize email" action, this is going to give you a lot more token options to choose from.

The two options we care about are \[author-mail\] and \[mail\], in your case author-mail is the group manager email address and \[mail\] is the email address of the user that's joining the groups.

So add \[author-mail\] to the recipient option in the action and \[mail\] to where ever in the body you want to put it.

Now all you have to do is go to the Organic Group trigger page and add the new action we created to the "New user joins a group" trigger. That should do it. If you can't seem to be able to add that option to the trigger check out the triggerunlock module (http://drupal.org/project/triggerunlock) which will fix that problem for you.

Hope this helps.

---
Tags: 7, organic-groups, tokens
---


# Question
Title: How to alter the Views field Format drop-down menu
I am exporting some XML feeds using Views. One of these fields needs to look like this:

```
<image>http://example.com/path/to/myimage.jpg</image>

```

I am storing my image in a CCK field. When selecting that field in Views, these are the options provided:

I don't need an teaser, full node, editable something, or HTML formatted link, just the path to the image. How do we alter that **Format** selector?

# Answer
> 2 votes
If your content type is blog, for example, and it has a CCK image field, create a relationship from your blog content type to the image content type.

Create a new field in the View and select the field\_image from the image content type, make sure to select the relationship you created:

And select URL to file from the Format dropdown:

---
Tags: 7, views, entities, files, media
---


# Question
Title: How do Iindex content from the Aggregator module?
I use the Aggregator module to create a list of titles and snippets of articles from The Economist.

I would like to be able to search for a term like *Morality and the brain* and see the recent Economist article in the results.

Is it just a matter of change settings to use the right directory for the indexed content?

# Answer
> 1 votes
The Aggregator module in Drupal core doesn't implement `hook_update_index()`, so your options here are to either do a bit of coding in a custom module to expose the contents of the aggregated feeds to the search module, or, to use the Feeds module.

I would recommend using the Feeds module, as this allows you to store imported feeds as nodes, which are then automatically included in the search index.

---
Tags: search, feeds
---


# Question
Title: Easy content management for a Views powered site
I'm building sites using Views and Panels, as you do. When handing over to the client/content editor, I want to make things as user-friendly as possible. Ideally this means they don't need to get their heads around View settings, but sometimes it seems unavoidable even for the simplest things? Or maybe I'm not designing the IA the best way...

Example: a movie review site, where each review is a node. On the homepage, we have a 'featured reviews' display with preview images for 3 movies. So I make a View that selects the 3 most recent reviews, and use some nice imageslider display or whatever. Nice.

Then the client asks if he can manually override this, and manually choose which 3 reviews to feature. He expects to just go into 'homepage settings' or something and select from a list.

So what to do... introduce him to Views filters and selecting node IDs...? Not good :(

So I resort to adding a 'featured' checkbox to the review content type, and filtering the view that way. Now this is easier for him, but still means ticking boxes on and off in various nodes. And it means I'm using content fields for something that isn't really content.

I run into this kind of situation very often, so wondered what other developers do?

# Answer
> 3 votes
For that particular use case, I'd suggest using the Nodequeue module. You could set up the nodequeue to contain 3 items and then users with the correct privileges would have the ability to add new items to the queue by clicking on a link on the node they want to add. In addition, users with permission to the administrative side of the Nodequeue module can also control the sorting of the items in the queue.

# Answer
> 0 votes
There is no universal solution. Views 3 for D7 has a nicer UI, but letting a client go near it will never be very smart. I see nothing wrong with adding a checkbox, like you did.

# Answer
> 0 votes
Clearly, this is a situation where the initial requirements are changed by your client; this means it's quite normal to not expect the implementation to adapt nicely to the (modified) use case.

What I recommend for the case used as example is to create the normal page display and an accompanying page, used as administrative panel as local tasks (tabs); in the "administrative" display, you just use something like nodequeue or draggable views to give the user the possibility to sort the nodes arbitrarily.

A more powerful approach would be to use panels instead of views, allowing the client to administrate it using the nice In Place Editor that ships in. Though I think this could require much more work from you to streamline the content editing workflow for your client.

---
Tags: views, nodes
---


# Question
Title: Which menu should a third-party module choose, between "Structure" and "Configuration"?
I noticed that some module prefers to add their menu items under "Structure," while other modules prefer to add them under "Configuration."

I thought that the reason of choosing "Structure" was because the menu items were related to some kind of "entities," but I then noticed that Rules is adding its menu items under "Configuration." Vice versa, Views and Flags put their menu items in "Structure."

What is then the criteria to use when deciding under which menu a module put its menu items? Does the "Structure" menu contains only menu items that are related to content?

# Answer
> 7 votes
This and many other D7UX related things are best explained in the UI Patterns session from yoroy and Bohjan: Drupal 7: Interface patterns.

In short, Structure is meant for structural things which are used regularly (mostly during site building). If those modules add their stuff their and are not Views, Panels or similar, chances are that they are doing it wrong. :)

Not everyone exactly agrees on the IA (Information Architecture) of Drupal 7 yet or simply doesn't know about it. Not even Drupal 7 core is very consistent IMHO; I don't think the contact.module settings belong to Structure, for example, when not even those from path.module are, which are most likely way more often used.

---
Tags: 7, routes
---


# Question
Title: Is there a way to make the comment module email the administrators when a comment needs approval?
I'd like to be notified whenever comments are made on the site which require administrator approval before publishing; basically, I'd like to know when something new appears in the Approval Queue. I can't see any obvious settings for this.

# Answer
Sounds like something Rules should be able to do.
> 4 votes

# Answer
Check out the Comment Mail module -- if you're going to get an email each time there is a comment you might as well simplify the process by adding approval functionality:

> The Comment Mail module allows an email to be sent to the site administrator(s) when new comments are posted. A link in the email allows quick approval, editing, deletion, and/or banning of the poster's IP address.

Word of caution: I've used this method before but quickly turned it off after the spam comments broke my spirit. Make sure you've got a robust anti-spam strategy setup (ex. antispam, mollom, captcha/recaptcha, etc.)
> 3 votes

# Answer
Yes; "rules" in your Drupal is the way to go: easiest and fastest.
> 1 votes

---
Tags: 7, comments
---


# Question
Title: Is there a way to know the view type from PHP code?
Is there a way to know the view type (page or block) from PHP code?

```
if (views type is block) {
  echo "This is a block view.";
}
elseif (views type is page) {
  echo "This is a page view.";
}

```

# Answer
> 2 votes
In the Views module, the exact term for what you're talking about is *display handler*.

If you have a view object, you can find the current object for the display handler at `$view->display_handler`. The class for that object is returned by `get_class($view->display_handler)`, which would return a string like `'views_plugin_display_page'`, for example.

When checking the class of an object, you can use `instanceof`, as in the following code.

```
if ($view->display_handler instanceof views_plugin_display_page) {
  // Your code
}

```

---
Tags: 7, views
---


# Question
Title: Views 3 doesn't recognize a declared handler. Why not?
In modules/addressfield/addressfield.module I have:

```
/**
 * Implements hook_views_api().
 */
function addressfield_views_api() {
  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'addressfield') . '/views',
  );
}

```

and

```
/**
*  Implements hook_field_views_data_alter
*
* @param mixed $result
* @param mixed $field
*/
function addressfield_field_views_data_alter (&$result, $field) {
  if (array_key_exists('field_data_field_address', $result)) {
    $result['field_data_field_address']['field_address_country'] += array(
      'title' => t('Country'),
      'help' => t('The Country name of the field'),
      'field' => array(
        'handler' => 'addressfield_views_handler_field_country',
        'click sortable' => TRUE,
      ),
    );
  }
}

```

In modules/addressfield/views/addressfield.views.inc:

```
/**
 * Implementation of hook_views_handlers().
 */
function addressfield_views_handlers() {
  return array(
    'info' => array(
      'path' => drupal_get_path('module', 'addressfield') . '/views',
    ),
    'handlers' => array(
      'addressfield_views_handler_field_country' => array(
        'parent' => 'views_handler_field',
      ),
    ),
  );
}

```

This file doesn't get triggered in the debugger when I clear the cache. I don't understand this.

The handler is in modules/addressfield/views/addressfield\_views\_handler\_field\_country.inc which I took from the location module:

```
/**
 * @file
 * Country field handler.
 */

class addressfield_views_handler_field_country extends views_handler_field {

  function option_definition() {
    $options = parent::option_definition();
    $options['style'] = array('default' => 'name');
    return $options;
  }

  function options_form(&$form, &$form_state) {
    parent::options_form($form, $form_state);
    $form['style'] = array(
      '#title' => t('Display style'),
      '#type' => 'select',
      '#options' => array('name' => t('Country name'), 'code' => t('Country code')),
      '#default_value' => $this->options['style'],
    );
  }

  function render($values) {
      return check_plain(strtoupper($values->{$this->field_alias}));
  }
}

```

Any advice on how to get this to work would be helpful. Thank you.

# Answer
Which core version? In Drupal 7, hook\_views\_handlers() is gone, add your files to your .info file instead.

```
files[]=views/addressfield_views_handler_field_country.inc

```
> 22 votes

---
Tags: 7, views
---


# Question
Title: Creating individual fields from a multi-column Field API widget
This references the Addressfield and Views modules.

I would like to have extended Views support for the Addressfield module like the Location module does. Some of the extra fields that the Location module makes available are Country, Longitude, and Latitude by themselves and Proximity or Distance filters and sorts.

I've added longitude and latitude columns to the Addressfield module.

The database for the Location module is fairly straight forward in Drupal 7 but not built using the D7 Field API.

The Addressfield module is built using the Field API and with Views it has a Content: field available and also arguments, sorts and filters based on each of the columns in the Addressfield database table. Views only offers a choice of formatters on a single field.

This is fine because it's just as easy to add a formatter to a Fields API module as it is to theme a view . So I can make a formatter that only shows latitude or longitude. Perhaps, better yet, I can make a formatter that displays the latitude and longitude as a WKT point to be used for an OpenLayers map.

However, what I need is a proximity filter so I'm setting out how to extend the Field API's functionality in Views which isn't very straight forward.

Is there documentation available for the particular case or modules that extend the Fields API which can be used as examples?

I thought the logical thing to do was use `hook_field_views_data_alter()`. Here is the attempted code and I'm not sure why it doesn't work.

```
function addressfield_field_views_data_alter (&$result, $field) {
  if (array_key_exists('field_data_field_address', $result)) {
    if ($result['field_data_field_address']) {

      $columns = array();
      $columns = array(
        'field_address_administrative_area',
        'field_address_country',
        'field_address_lat',
        'field_address_lng',
        'field_address_locality',
        'field_address_postal_code',
        'field_address_premise',
        'field_address_thoroughfare',
      );

      $add_fields = array('entity_type', 'delta', 'language', 'bundle');
      foreach ($result['field_data_field_address'] as $column => $data) {
        if (in_array($column, $columns)){
          $result['field_data_field_address'][$column]['field'] = array(
            'field' => $column,
            'table' => 'field_data_field_address',
            'handler' => 'views_handler_field_field',
            'click sortable' => TRUE,
            'field_name' => $column,
            'additional fields' => $add_fields,

            'entity_tables' => array(
              'node' => 'node',
              'node_revision' => 'node',
            ),
            'element type' => 'div',
            'is revision' => FALSE,
            'entity id' => 'nid',
            'base table' => 'node',
          );

          $result['field_data_field_address'][$column]['group'] = 'Content';
        }
      }
    }
  }
}

```

# Answer
> 0 votes
Here is the solution.

```
/**
*  Implements hook_field_views_data_alter
*
* @param mixed $result
* @param mixed $field
*/
function addressfield_field_views_data_alter (&$result, $field) {
  if (array_key_exists('field_data_field_address', $result)) {
    $result['field_data_field_address']['field_address_country'] += array(
      'title' => t('Country'),
      'help' => t('The Country name of the field'),
      'field' => array(
        'handler' => 'addressfield_views_handler_field_country',
        'click sortable' => TRUE,
      ),
    );
  }
}

```

Or if you want to not use a real field in the table such as field\_address\_country but to instead alias a field you can add a field and table attribute to the field array like this.

```
function addressfield_field_views_data_alter (&$result, $field) {
  if ($field['type'] == 'addressfield')) {
      $result['field_data_field_address']['country'] = array(
        'title' => t('Country'),
        'group' => 'Bad Ass',
        'help' => t('The Country name of the field'),
        'field' => array(
          'field' => 'field_address_country',
          'table' => 'field_data_field_address',
          'handler' => 'views_handler_field',
          'click sortable' => TRUE,
        ),
      );
   }
}

```

---
Tags: 7, views, entities
---


title: Permissions defined by fields

text:
# Question
Title: Permissions defined by fields
I have some content that has state field. I would like to permit users with the **same state** to delete this content.
Can I implement this in Drupal?
Can I implement it with PHP code?

# Answer
*custom.info*

PS. Do not include \<?php ?\> tags.

```
; $Id:
name = Custom
description = Custom validate node delete permission
package = Custom
core = 6.x

```

*custom.module*

```
  <?php
    /*
     * file
     */
    function MYMODULE_form_alter(&$form, &$form_state< $form_id){
      switch($form_id){
        case 'node_delete_confirm':
          $form['#validate'][] = 'my_custom_validate';
          break;
      }
    }

    function my_custom_validate($form, &$form_state){
      $nid = $form_state['values']['nid'];
      $node = node_load($nid);
      if(/* conditions */) {
        // some procedure to check fields
        $message = t('You have not any permission to delete this node!');
        form_set_error('nid', $message);
      }
    }
  ?>

```

Place this files into `/sites/all/modules/custom/*.*` and activate it on module administration page. Enjoy.
> 1 votes

---
Tags: 7, users
---


title: Multiple image styles

text:
# Question
Title: Multiple image styles
Is there a way to take multiple style image for one image field?
I want to use a 150×150, 180×180, and a 300×300 style at the same time.

# Answer
If I understand your question correctly, you'll want to use the ImageCache module. This is in core as of Drupal 7. Try the documentation for Drupal 6 and/or this screencast if you need help understanding how to use this module.
> 4 votes

# Answer
You can manually call the image caches either in your template file or create them in hook\_preprocess\_node(&$vars). You can get the image with theme\_image\_style($vars). There are some useful comments in the docs for theme\_image\_style.
> 2 votes

# Answer
And once you've created the imagecache presets, they will then show up as field formatters for your teaser and node display settings as well as in views.
> 1 votes

---
Tags: 7, media
---


# Question
Title: How to create a menu with background images for list items?
How would you make a menu that have a different background image for each `<li>` element in the menu?

# Answer
> 2 votes
I would suggest:

1. Use the module http://drupal.org/project/menu\_attributes (beta 1 is out for Drupal 7)
2. Give each menu item a CSS ID or class that needs an image
3. Use CSS to assign background images to the menu items

Using this method, no PHP coding is required, and the menu images become content editable by your authors (once the CSS images have been setup).

# Answer
> 0 votes
also: Use the module http://drupal.org/project/imagemenu

A simple module which allows you to create menus from image files. Supports title (displayed when hovering over a menu item), alt text, weights and optional mouseover behaviour.

---
Tags: 7, routes, theming
---


# Question
Title: Best practice for building modules using classes
I'm looking to start building my modules as classes now that lazy/auto-load are in Drupal 7, and I'd love to look at some modules (contrib or core) that are doing a great job of it.

Is there a creative way for integrating a class as hooks? Do I implement each feature as a ctools plugin?

Any passers-by should note that D7 has new `files[]` declarations in module `.info` files for auto/lazy-loading classes/interfaces: Writing .info files (Drupal 7.x).

The following is a good read to get the motivations and the constitution (as it were) from the Drupal community Drupal programming from an object-oriented perspective.

# Answer
A module is not a class by Crell is what you should read first.

The biggest OOP part in Drupal 7 is the new database abstraction layer (designed by the very same Crell and others). That implements many patterns which can and should be re-used.

For example:

Something that is still controversaly discussed is Information hiding. DBTNG implements that by making class properties protected and disallowing direct access. On the other hand, we have hook\_query\_alter() and they can be changed almost freely with various by reference getter methods.
> 16 votes

# Answer
This is an interesting question.

The idea of a Drupal module as a class is very interesting. However even in D7 modules simply implement hook functions which are checked for by name, so even if you create a class for your module you will still need to implement hook functions to invoke them.

However many modules use classes internally, and expose functionality via these classes. The most obvious example is views. So that may be a good place to look. However be aware that many modules use classes in their own way, so what you learn from looking at views may not always be applicable.
> 3 votes

# Answer
Entity API (the contrib module) allows you to declare an "entity class" for each of your entity types, so all code related to your entity (create, load, save, access, etc) can go in a class (see how Organic Groups does it, for example).

That said, don't overdo it. ctools plugins are a good thing when you need them (you're writing the next Views, Panels or Rules), but using classes everywhere just for ideological purity won't do you much good.
> 2 votes

---
Tags: 7
---


title: How to inspect outgoing email content?

text:
# Question
Title: How to inspect outgoing email content?
There are several modules that send email from my site: Rules, Trigger, User, ...

I am looking for a place to set a `drupal_set_message()` and print out the email contents. Where in the code would be the best place for that?

# Answer
> 6 votes
You can use `hook_mail_alter()` to get, or alter, the content of an e-mail message before it's sent out.

```
function mymodule_mail_alter(&$message) {
  dpm($message);
}

```

Not all modules use `drupal_mail()`, which means that for those modules `hook_mail_alter()` won't be invoked when they send an email.
In this case, you need to identify where in the module's code the mail is sent out, and see if they provide their own alter hooks. Look for any call to `drupal_alter()`, `module_implements()`, `module_invoke()`, or `module_invoke_all()`.

Failing that, you may have to temporarily add the `dpm()` call directly to the module in the right place.

---
Tags: debugging, emails
---


title: Send email with attachment

text:
# Question
Title: Send email with attachment
I want to send an attachment with `drupal_mail()` using `hook_mail_alter()`. Do you have any ideas about which parameter should I use?

Does the variable `$param` help, in some way?

# Answer
The default mail implementation in Drupal does not support attachments.

You will need one of the contrib mail modules which support attachments, for example http://drupal.org/project/mailmime. I wasn't able to find any useful docs and it seems that the maintainer is aware of it and hopefully working on something.
> 1 votes

---
Tags: 7, hooks, emails
---


# Question
Title: How do I overwrite the variables in my theme?
```
function rate_preprocess_test(&$variables) {
  extract($variables);
  $buttons = array();
  foreach ($links as $link) {
    $button = theme('rate', $link['text'], $link['href']);
    $button .= $link['votes'];
    $buttons[] = $button;
  }
  $variables['buttons'] = $buttons;
}

```

I want to overwrite the `$link['votes']` variable to add a `<span>` tag around `$link['votes']`.

This is the code I added to template.php, but it doesn't contain the `<span>` tags that I added.

```
function mytheme_preprocess_test(&$variables){
    $link['votes']='<span>'.$link['votes'].'</span>';
}

```

I want to add the `span` tags around `$link['votes']`.

# Answer
If you are wondering why the `<span>` tags don't appear in the button output from `rate_preprocess_test()`, that is probably because `mytheme_preprocess_test()` is called after `rate_preprocess_test()`.
I take `rate_preprocess_test()` is defined inside a module; in that case the preprocess function defined inside the module is invoked before the implementation of the preprocess function contained in the theme, as reported in the documentation for theme(), which lists the preprocess functions in the following order:

* template\_preprocess(&$variables)
* template\_preprocess\_HOOK(&$variables)
* MODULE\_preprocess(&$variables)
* ENGINE\_engine\_preprocess(&$variables)
* ENGINE\_engine\_preprocess\_HOOK(&$variables)
* ENGINE\_preprocess(&$variables)
* ENGINE\_preprocess\_HOOK(&$variables)
* THEME\_preprocess(&$variables)
* THEME\_preprocess\_HOOK(&$variables)
> 0 votes

---
Tags: 7, theming
---


title: How do I truncate strings?

text:
# Question
Title: How do I truncate strings?
For example, I need to truncate the following text.

> Drupal is free, flexible, robust and constantly being improved by hundreds of thousands of passionate people from all over the world. Join us!

I have used `drupal_substr()`, but the result may be "Drupal is free, flexi."
How can I avoid to truncate a word?

# Answer
You need to use **truncate\_utf8()** using `$wordsafe = TRUE;`

> **$wordsafe** Flag to truncate at last space within the upper limit. Defaults to FALSE.
> 8 votes

---
Tags: 7
---


# Question
Title: Accessing imagecache path inside template
I'm using the ImageField module together with Imagecache to display a picture for one of my content types.

To display the content body I'm using Contemplate, I'm accessing the path to the image in the following way:

```
'[...]/imagecache/[preset]/[...]/'.$node->field_picture[0]['filename']

```

This usually works, but it breaks when someone uploads a picture with the same filename as the existing one. The file itself is then automatically named `filename_0.jpg` instead of `filename.jpg`, but the filename variable of the ImageField I'm accessing stays `filename.jpg`.

This of course leads to the old image being displayed. It seems the filename variable does not do what I expected, what would be the correct way to access the Imagecache generated files?

# Answer
> 3 votes
Using the Contemplate module is not recommended since it puts PHP code into the database which is generally considered a security vulnerability and non-performant.

You want to use theme('imagecache', ...) instead, which will return the HTML img tag with the proper path.

---
Tags: files, media
---


# Question
Title: The most searched keyword of the default search?
Is there a way, or a module, to get the most searched keyword of the site's default search?

# Answer
You can check the "Top Search Phrases" report at "/admin/reports/search". This will give you a count of the search phrases used. It doesn't make it out by individual keyword, but at least gives you an idea of what people are searching for.
> 2 votes

---
Tags: 7, search
---


# Question
Title: How to restrict users to view their own custom content type?
I am developing a custom module called 'serviceentry' which also exposes a custom content type called 'serviceentry'.

I also exposes the custom permissions as :

```
function serviceentry_permission() {

        return array(
           'view own serviceentry content' => array(
            'title' => t('view own serviceentry content'),
            'description' => t('view own serviceentry content')
        ),
        'view any serviceentry content' => array(
            'title' => t('view any serviceentry content'),
            'description' => t('view any serviceentry content')
        ),
        'create serviceentry content' => array(
            'title' => t('create serviceentry content'),
            'description' => t('create serviceentry content')
        ),
        'edit own serviceentry content' => array(
            'title' => t('edit own serviceentry content'),
            'description' => t('edit own serviceentry content')
        ),
        'edit any serviceentry content' => array(
            'title' => t('edit any serviceentry content'),
            'description' => t('edit any serviceentry content')
        ),
        'delete own serviceentry content' => array(
            'title' => t('delete own serviceentry content'),
            'description' => t('delete own serviceentry content')
        ),
        'delete any serviceentry content' => array(
            'title' => t('delete any serviceentry content'),
            'description' => t('delete any serviceentry content')
        ),
        'administer serviceentry' => array(
            'title' => t('administer serviceentry'),
            'description' => t('administer serviceentry')
        ),

        );
    }

```

Then, I check for permissions using following function.

```
function serviceentry_node_access($node, $op, $account) {
    $type = is_string($node) ? $node : $node->type;

    if (in_array($type, node_permissions_get_configured_types())) {
        if ($op == 'create' && user_access('create ' . $type . ' content', $account)) {
            return NODE_ACCESS_ALLOW;
        }

        if ($op == 'view') {
            if (user_access('view any ' . $type . ' content', $account) || (user_access('view own ' . $type . ' content', $account) && ($account->uid == $node->uid))) {
                return NODE_ACCESS_ALLOW;
            }
        }
        if ($op == 'update') {
            if (user_access('edit any ' . $type . ' content', $account) || (user_access('edit own ' . $type . ' content', $account) && ($account->uid == $node->uid))) {
                return NODE_ACCESS_ALLOW;
            }
        }

        if ($op == 'delete') {
            if (user_access('delete any ' . $type . ' content', $account) || (user_access('delete own ' . $type . ' content', $account) && ($account->uid == $node->uid))) {
                return NODE_ACCESS_ALLOW;
            }
        }
    }

    // Returning nothing from this function would have the same effect.
    return NODE_ACCESS_IGNORE;
}

```

Now, I want to restrict users to view nodes of serviceentry based whether they have 'view own serviceentry content' or 'view any serviceentry content' permissions. The above code is not working as Drupal is not passing $op='view' in order to restrict the user. If user has 'access content' permission, then all nodes are shown otherwise not. I want to have finer control over my own node type. How to do that?

# Answer
> 1 votes
When the implementation of `hook_node_access()` returns `NODE_ACCESS_IGNORE`, it is not denying the access to a node, but it is letting other modules decide if the user has access to the node. If none of the modules implementing `hook_node_access()` returns `NODE_ACCESS_DENY`, and none of the modules implementing `hook_node_grants()` returns 0 for the node, then the user has access to the node.

# Answer
> 0 votes
You can do the same through administrator menu (People -\> Permissions). You can assign permissions by role. Perhaps I don't understand the doubt.

---
Tags: 7, users
---


title: Safe user template system

text:
# Question
Title: Safe user template system
Is there a template system for users that would be very safe, and very simple? I'm looking for something along the lines of the following:

> Hello \[first\_name\],
>
> We hope you have enjoyed the \[product.name\] purchased on \[transaction.date\] for \[product.price\].

I realize this is kind of a contrived example, but what I'm looking to do is give users the ability to customize some information but not give them PHP as that would be out of control.

I would use a filter editor, but I need to provide the context for the variables and I'm not sure how much it would complicate matters to have to provide that context, (which could not be done from a filters standpoint so far as I know because I'm providing one template for many nodes)

# Answer
There are some modules that implement an input filter which allows you to decide which text is replaced in the body of the node and with which text needs to be replaced.

* Custom filter allows the administrator users to define, through regular expressions, which text is replaced and, through a string or PHP code, the replacement text. Normal users cannot decide neither which strings to replace nor the replacement strings; this means that they cannot do anything bad by creating a replacement rule using unsafe PHP code.
* Regex Filters is a module with similar features.
* Rep\[lacement\]Tags allows you to define tokens like `{AUTHOR}` which will be replaced.
* Token Filter replaces, for example, text like `[token user <token>]` with the content of the user token implemented by a module. This module requires Token.
> 2 votes

# Answer
You want http://drupal.org/project/token

There are also modules which allow to use tokens in nodes and other places, you can use it in custom places and also define your own tokens.

The token API is even part of Drupal 7 core.
> 3 votes

---
Tags: 7
---


title: Show related Taxonomy list if created

text:
# Question
Title: Show related Taxonomy list if created
I have created the following construction. If a student choose option A with the if construction the following step in the wizard is the internships with medicine domain A, but what if the school create another medicine domain B. With this construction the student will only see the internship domain A and not the medicine domain a AND b. I'm looking for a construction that grows with my Taxonomy (shows medicine domain a and b and if the school create 5 months later a medicine domain c that last one must seen by the student also), so if a student choose medicine than he get all medicine domains (medicine domain a and b and so on) and not just $internship domain a as defined in my if structure. Hope you understand my problem because it is explained in terrible English.

enter code here case 2:

```
// Taxonomy list: 'valid type of internship'.

$valueInternship = $_SESSION['gekozenOpleiding'];

//var_dump($valueInternship);

if($valueInternship == 1) { // Stagedomein a
    $internship = 10;
}

if($valueInternship == 2) { // Stagedomein b
    $internship = 11;
}

if($valueInternship == 3) { // Stagedomein c
    $internship = 13;
}

if($valueInternship == 4) { // Stagedomein d
    $internship = 12;
}

if($valueInternship == 5) { // Stagedomein e
    $internship = 14;
}

$dropdown_source_geldig_soort_stage = taxonomy_get_tree($internship);
$dropdown_array_geldig_soort_stage = array();
foreach ($dropdown_source_geldig_soort_stage as $item) {
    $key = $item->tid;
    $value = $item->name;
    $dropdown_array_geldig_soort_stage[$key] = $value;
}
$form['geldig_soort_stage'] = array(
        '#key_type' => 'associative',
        '#multiple_toggle' => '1',
        '#type' => 'checkboxes',
        '#options' => $dropdown_array_geldig_soort_stage,
        '#title' => 'Welk geldig soort stage',
        '#multicolumn' => array('width' => 4,
                '#default_value' => isset($default_value['geldig_soort_stage']) ?
                $default_value['geldig_soort_stage'] : '',
        ),
);
break;

```

# Answer
This is a very frequent problem. Drupal has a simple solution. It is called the Context module.

The context module will allow you to ONLY show information based on term throughout the whole website. Or, only show information based on a user role. So a teacher will have different Views show in a block than a student who will have different Views based on the internship they have.

The context module also allows you to stack. You can have a context for A, B, C, D. In the Right block region of the page.tpl.php that shows four different blocks based on the taxonomy terms selected. If the student selects term A & B. Then they have the Views block for a & b show at the same time. Or, they can have terms A, B & C. If term A shows 1 block and term B shows 1 block then A & B will have two sidebar blocks showing. If intership C is much more complicated and requires 5 blocks of information then a student with terms A, B & C will have 7 blocks on one page.
> 1 votes

---
Tags: 7, taxonomy-terms
---


title: Which pages affect text area CSS?

text:
# Question
Title: Which pages affect text area CSS?
I have a text area with CKEditor. The default font in this text area and my theme is 20 pixels and I cannot change its size with CSS, but if I change theme and use Garland, the font change to the normal size.

If I copy Garland styles and page.tpl.php in my theme, the text area is still using a 20 pixels font. Why?

# Answer
CKEditor set its own CSS classes for text areas, but that would not explain why copying the CSS files from a theme to another doesn't change the visualized styles.

The problem here is that simply changing the files used by a theme doesn't change the used styles; you need to let Drupal know the theme has been changed, and this can be done in two ways:

* you select a different theme as default one, disable the theme you modified, re-enable it, and select it again as default theme
* you force Drupal to refresh the cache it is using, or you empty the cache tables

In the first case, you submit the theme selection form after each operations.
> 0 votes

---
Tags: theming, wysiwyg
---


# Question
Title: Is there an accordion-style menu module?
I have been searching high and low for a module that integrates an accordion-style menu system in D7, similar to http://drupal.org/project/accordion\_menu. Anybody know of one?

# Answer
> 1 votes
If the Accordion Menu module does what you need, consider helping the maintainer port it to Drupal 7. Here is an excerpt about it from the module's project page:

> ... will display a menu using a jQuery UI accordion effect.
>
> Features:
>
> * Multiple menu blocks, each separately configurable
> * Menu source may be a Menu block sub-menu definition or a Drupal menu
> * Setting to render the header menu item as a non-link (to avoid conflict between the accordion effect and the link behavior)
> * Setting to not expand a header menu item even if it is in the active trail
> * Setting for scope (see drupal\_add\_js())
> * Settings for all published jQuery UI accordion options.
> * Theme suggestions and template
> * Multiple CSS classes including zebra, menu link ID, and count

# Answer
> 4 votes
DHTML Menu is great and it should work for what you need. I haven't used the 7.x version yet but they have a stable release. Here is an excerpt about it from the module's project page:

> ... uses Javascript to reduce the number of page loads when using nested menus; this is particularly useful with Drupal's administration system.
>
> Ordinarily in Drupal, in order to see the sub-items in a menu, you need to click the link of this item and wait for a full page load. After enabling DHTML Menu, clicking a menu link once will expand it to reveal its sub-items without reloading the page. A double-click on the item will load the page normally. Additionally, a cookie stores which menus are open and which are closed, so that the state of the menus remain consistent as you navigate around the site.

# Answer
> 1 votes
Is jquery UI available for Drupal7 yet? You could hook a View into it easily to make your own accordion.

---
Tags: 7, routes
---


# Question
Title: Invoking the rate module in views template file doesn't work
I have installed both the Views and Rate modules. In the views-view-fields.tpl.php file, I put the following code.

```
$node = node_load($row->nid);
echo $node->content['rate_poll']['#value'];
echo $node->title;

```

There is no output for `$node->content['rate_poll']['#value']`, while the code outputs the node title. Why?

How can I output `$node->content['rate_poll']['#value']` in views-view-fields.tpl.php, or other Views files?

# Answer
> 0 votes
The code you wrote doesn't work because `$node->content['rate_poll']['#value']` is only present when the node is being viewed. The code that adds `$node->content['rate_poll']['#value']` is in the implementation of `hook_nodeapi()`, and the code is executed when the operation is "view."

```
/**
 * Implements hook_nodeapi().
 */
function rate_nodeapi(&$node, $op, $a3, $a4) {
  // Adding the form to the node view
  if ($op == 'view') {
    $widgets = rate_get_active_widgets('node', $node->type, $a3);

    foreach ($widgets as $widget_id => $widget) {
      $widget_name = 'rate_' . $widget->name;
      _rate_check_widget($widget);

      $display_mode = $a3 ? $widget->teaser_display_mode : $widget->node_display_mode;

      $widget_code = array(
        '#value' => rate_generate_widget($widget_id, 'node', $node->nid, $display_mode),
        '#weight' => $widget->node_display == RATE_DISPLAY_ABOVE_CONTENT ? 0 : 50,
      );

      if ($widget->node_display != RATE_DISPLAY_ABOVE_CONTENT && $widget->node_display != RATE_DISPLAY_BELOW_CONTENT) {
        $node->$widget_name = $widget_code;
      }
      else {
        $node->content[$widget_name] = $widget_code;
      }
    }
  }
}

```

For the code to work, you should change it to the following one.

```
$node = node_load($row->nid);
node_invoke_nodeapi($node, 'view', FALSE, TRUE);
echo $node->content['rate_poll']['#value'];
echo $node->title;

```

node\_invoke\_nodeapi() invokes any implementation of `hook_nodeapi()`, using its first parameter as operation value. Once the function returns, `$node` will contain any `$node->content` value added by the modules, including `$node->content['rate_poll']['#value']`.

---
Tags: 7, views, rating
---


# Question
Title: Output Flexifield content as Excel file?
I'm using Drupal 6 and Flexifield to create an extensible CCK content type for doing various measurements. The content type is composed of three flexifield fields -- "levels", "rooms" and "fixtures", all of which can have new rows added to them via the "Add another..." button (no min/max to the number of rows in each flexifield sub-type).

The "levels" flexifield sub-type has two fields: level name and total area. The "rooms" flexifield sub-type has three fields: length, width, area. The "fixtures" flexifield sub-type is irrelevant for this part of the project.

What I ultimately need to do is output the "rooms" data as a table, then export that as an XLS file (which is then used by some CAD software somewhere down the line). I've been trying to do this via Views UI and Views Excel Export, but I can't see to make the latter module conform to the Excel template I've been given:

Each room's row in Excel should look something like:

Block Name | Roomname | Imperial | Metric

"Block Name" is the same string for all rows; "Roomname" has to be the name of the room as defined in the "room" flexifield sub-type. The values entered in each room are all either Imperial or Metric as per an option on the main content type, but I'll need some way to populate the correct column based on whichever type of data's been entered, plus convert those values to the other system.

**Is Views UI (with Excel Export) the right way to go about this? If so, how do I interact with the "room" flexifield data insomuch that I can make each "Room" object a separate row in the Excel sheet?**

Many thanks. This is the last part of a huge project I've been working on for months and will be grateful for any help.

# Answer
> 0 votes
Have you tried the CSV export provided by Views Bonus Pack? It's not true XLS, but does it need to be, as long as it opens in Excel and the data is correct?

---
Tags: views, 6, entities, importing-exporting
---


# Question
Title: Choosing between stable and development snapshot releases for a new high trafficked site
After some research, I am planning to start the migration of a high trafficked site from Pressflow 6 to Drupal 7, as the current implementation (Pressflow 6 + 200 modules) is making it crawl. I've read that most of Pressflow 6 (if not all) performance changes have made into Drupal 7, and that's awesome. I will be starting the project in a day or 2 and I was wondering if I should be starting with the stable version (Jan 5, 2011) or the latest development snapshot.

There is a gap of over 3 months, and I am wondering if I will lose on fixes that made into the 7.x branch in these 3 months (that's a long time for a open source project so popular) and if a new stable release is around the corner.

I would also like to understand the impact on frequency of code updates on drupal core ( in case I use dev snapshot) and ways to manage it properly.

# Answer
> 2 votes
Start with -dev. D7 got a fair number of bugfixes since january, as well as performance improvements. However, 7.1 is still not around the corner, so using -dev is your best bet.

Plus, when a release is that old, you need to test and report bugs against -dev (which is true for all contrib modules as well). Otherwise you might just be reporting bugs which are already fixed.

# Answer
> 2 votes
It's a difficult question to answer, because the status of a release (dev, beta, RC) is not necessarily a measure of it's stability, but rather an indication how well it has been tested before the maintainer released it. A module's dev version can (but does not need to be) more stable than the latest beta, RC or stable release.

IMHO, 200 is a huge amount of modules. If it's an option, consider reducing the number of modules. Often, 80% of a site's functionality is created with 20% of the modules, so the question is if the last 20% of functionality justifies the other 80% of modules.

# Answer
> 0 votes
I think the answer really depends on how comfortable you are getting your hands dirty if you run into an issue. I personally like working with 'dev' versions, especially in cases where there has been a lot of active development that hasn't made it back to the latest 'stable' build. That being said, I have a pretty solid feeling for how Drupal works, and have built many sites in the environment.

I feel that it helps developers if I can point out bugs (or maybe even suggest a fix every once and a while) and I get to use the newest version of the code! Win win.

---
Tags: 7, migrations
---


# Question
Title: Is there a function or a way to invoke the comment object?
I want to use the `$comment` object in page.tpl.php. Is there a function or a way to use it?

# Answer
The page.tpl.php template file is used for any page output from Drupal; it is not said the page is being output for a node. It would be rather better to use node.tpl.php, which is always used for a node, except when a different template is being suggested and that file exists.

The code I am reporting is valid for page.tpl.php, but with few changes it can be used also for node.tpl.php.
I am taking the assumption you are interested in the comments for the node being shown.

```
if (!empty($node)) {
  $result = db_query('SELECT * FROM {comments} WHERE nid = %d', $node->nid);
  while ($comment_obj = db_fetch_object($result)) {
    // $comment_obj contains the comment object.
    // ...
  }
}

```

In the case the code is used in node.tpl.php, it is not necessary to verify if `$node` is not empty, as the template is surely used to visualize a node.
I called the variable `$comment_obj` because in node.tpl.php there is already a variable named `$comment`, but that variable doesn't contain any comment object; it contains the comment settings for the node.

As pointed out from Jeremy French, such code should never go inside a template file, which should just contain presentation code (i.e. code that prints out the content of variables). That code could be the body of a function (contained in template.php of a theme) that builds up the output shown from the template file; alternatively, similar code should be used in a preprocess function.

In this case, the code is similar to the following one.

```
function mymodule_preprocess_node(&$variables) {
  $variables['comment_output'] = '';

  if (!empty($variables[node])) {
    $result = db_query('SELECT * FROM {comments} WHERE nid = %d', $variables[node]->nid);
    while ($comment_obj = db_fetch_object($result)) {
      // $comment_obj contains the comment object.
      // ...
      $variables['comment_output'] .= // ...
    }
  }
}

```

page.tpl.php should then print the content of `$variables['comment_output']`.

```
print $comment_output;

```

To notice also that Drupal uses comment.tpl.php, to which is passed a comment object. Depending on what you are trying to do, that could be the template file you are really interested in.
> 2 votes

---
Tags: 7, theming, comments
---


title: hook_theme_registry_alter() and theme()

text:
# Question
Title: hook_theme_registry_alter() and theme()
How can `hook_theme_registry_alter()` associate, for example, `theme_mymodule_image_output()` with the 'image' theme ID?

# Answer
> 5 votes
As reported in the documentation, hook\_theme\_registry\_alter() is invoked from Drupal to allow third-party modules to alter the theme registry information returned from hook\_theme().

The value returned from the implementations of `hook_theme()` is an array containing information about the different theme functions implemented by the modules (or themes).

```
function node_theme() {
  return array(
    'node' => array(
      'arguments' => array('node' => NULL, 'teaser' => FALSE, 'page' => FALSE),
      'template' => 'node',
    ),
    'node_list' => array(
      'arguments' => array('items' => NULL, 'title' => NULL),
    ),
    'node_search_admin' => array(
      'arguments' => array('form' => NULL),
    ),
    'node_filter_form' => array(
      'arguments' => array('form' => NULL),
      'file' => 'node.admin.inc',
    ),
    'node_filters' => array(
      'arguments' => array('form' => NULL),
      'file' => 'node.admin.inc',
    ),
    'node_admin_nodes' => array(
      'arguments' => array('form' => NULL),
      'file' => 'node.admin.inc',
    ),
    'node_add_list' => array(
      'arguments' => array('content' => NULL),
      'file' => 'node.pages.inc',
    ),
    'node_form' => array(
      'arguments' => array('form' => NULL),
      'file' => 'node.pages.inc',
    ),
    'node_preview' => array(
      'arguments' => array('node' => NULL),
      'file' => 'node.pages.inc',
    ),
    'node_log_message' => array(
      'arguments' => array('log' => NULL),
    ),
    'node_submitted' => array(
      'arguments' => array('node' => NULL),
    ),
  );
}

```

The returned array used what in my previous comment I called theme ID, and it is the same value that is passed to theme().
node\_theme() doesn't use it, but the documentation for `hook_theme()` reports that the array can use the `function` index to report which function needs to be called as theme function.

A module implementing `hook_theme_registry_alter()` should use the following code to change the function that is invoked when `theme('image')` is called.

```
function mymodule_theme_registry_alter(&$theme_registry) {
  if (isset($theme_registry['image'])) {
    $theme_registry['image']['function'] = 'theme_mymodule_image_output';
  }
}

```

When a module alters the theme registry using that code, any call to `theme('image', ...)` will not invoke theme\_image() anymore, but it will invoke the function defined from that module.
To notice that it is not necessary to name the function `theme_mymodule_image_output()`; the code would work the same if the function is renamed `mymodule_image_output()` and the code of `mymodule_theme_registry_alter()` is accordingly changed. I usually use the prefix `theme_` to make clear the function is a theme function.

---
Tags: 7, theming
---


title: Mailto link causes blank page

text:
# Question
Title: Mailto link causes blank page
I just attempted to add an e-mail address link to a drupal page putting

```
<a href="mailto:email@email.com">Contact us</a>

```

on the page. I then preview it, and no content shows up but the title. I remove the link and all the text is back again. What is causing this and how can I fix it? The strange thing is I have pages made earlier that already have mailto links on them.

Edit: I've tried this with both filtered and full HTML. I also have Invisimail installed, which does some e-mail filtering.

(I also couldn't get filtered html to turn a e-mail address into a hyperlink, but then discovered it was because it was in a `<strong>` block.)

# Answer
If all else fails, you could try using the Bbcode module. The advantage here is that you can turn Email address encoding on, so your address isn't spammed. (If you want this feature without the Bbcode module, you could use the SpamSpan module.)

Sorry, I can't tell you how to fix your issue... but this may possibly be a workaround if all else fails?
> 1 votes

---
Tags: 7
---


# Question
Title: Keep the URL alias for a node when using href
I am using Drupal 6 and I have set aliases for my nodes under Administer \> Site building \> URL aliases. This works properly; for example, I have alias = about/faq, node = node/33, and when I click on my menu the page shows up properly on the browser address bar as about/faq.

The problem I have occurs when I want to reference my node from hyperlinks placed in a page on the website (or any other website). I want to use `<a href="http://mywebsite.com/node/33">` instead of `<a href="http://mywebsite.com/about/faq">` so that I don't have to change the href if I later decide to change the alias. However, when I do this, the page shows up as `http://mywebsite.com/node/33` on the browser address bar.

I was wondering whether it would be possible to have it show up as `http://mywebsite.com/about/faq` on the address bar instead.

# Answer
> 1 votes
You can use global redirect so that it does a 301 redirect to the aliased url.

I would recommend you additionally use path redirect so that you can keep old aliases and redirect them to the new one. That way you don't even have to worry about using the unaliased url.

---
Tags: 6, nodes, path-aliases
---


# Question
Title: Can I expose the signup form through views 2?
I am using Signup and Views in Drupal 6 (I can't install Drupal 7), and I created a view that lists all the nodes for which users can signup.
Now I want to enable users to signup for one of these nodes without forcing them to navigate to the node itself, and I need to expose the signup form though Views (perhaps using a PHP field). I've searched for this, but most of the comments are a few years old. Furthermore, I'm rather unfamiliar with PHP.

Can I expose the signup form through views 2? How can I do it?

# Answer
This is currently a feature request for the Signup module (originally submitted to that module's issue queue 3 days before this StackExchange post). For the latest progress on this feature, see the issue: http://drupal.org/node/1118448 .
> 1 votes

# Answer
Theoretically, it can be done with Views Embed Form.

I couldn't get the form to display, due to permissions errors despite not having any access constraints (like vermo, although they somehow got it to work).
Documentation is at http://drupal.org/node/329511.

My basic module contains the follow function.

```
function MYMODULE_views_embed_form() {
  return array(
    'signup_form' => t('Signup form')
  );
}

```
> 0 votes

---
Tags: 7, forms, views, users
---


title: How to speed up Batch API Operations?

text:
# Question
Title: How to speed up Batch API Operations?
I've run into this both with 3rd party contrib modules as well as some of my own operations. I'm curious at the various ways to speed up my/contrib batch operations?

Assume they work with nodes (import/update etc) and we're dealing with parsing lists of nodes in the 10,000+ range (although I've had to deal with 15 million rows.. which yes - I'm just screwed on..)

Is it quicker to attach to drupals cron.php job and run "headless"? Using Drush? or is this simply a question of how efficient and quick parsing I can develop my code and there are **no** outside influences or batch specific optimization tips ...

Currently I've run into operations that (using some rough calculation) *could* take 24+ hours...

Thanks!

# Answer
> 11 votes
This doesn't work for contrib code, but if it's your code and you know it well, I recommend writing a drush command to do the work. Within drush, limit drupal\_bootstrap() to the appropriate bootstrap level. I can't recall the actual numbers, but a very large percentage of time for every drupal request is spent in bootstrap, and you can save a lot of time there.

Furthermore, check out the guts of the Migrate module. I don't know how it does it's mojo (never taken the time to grok it), but it can blaze through huge batches of nodes very quickly.

# Answer
> 9 votes
Every batch call is an HTTP request. So you need to find the perfect blend of how many iterations you can process before another HTTP request gets fired. Two things to consider are memory and max execution time. You'll want to process as many iterations as possible per batch to reduce the number of HTTP requests as they are most likely the culprit to your slow batch.

If your batch is just too heavy to run efficiently you could try using a queue instead. There is a good batch vs. queue presentation here http://sf2010.drupal.org/conference/sessions/batch-vs-queue-api-smackdown. Queues do not provide user feedback and can be run in parallel.

If you require user feedback you are tied to batch, but you could even use queue in your batch to try to optimize it.

# Answer
> 3 votes
As others have said Drush is a good solution, but a queue is a great tool to use. Batch API in Drupal 7 uses the built-in core Queue API so if you're using MySQL your process could be bottlenecked there. But, Drupal 7's Queue API is pluggable, so you could use another queue system like beanstalkd.

# Answer
> 2 votes
If you can make it parallel thats a good start. Here are some of my thoughts on this as I've used 4 threads to crawl over a million pages before (via boost). Looking to make it generalized now. http://groups.drupal.org/node/126624

---
Tags: 7, batch-operations
---


title: Panels, Diff and nodes

text:
# Question
Title: Panels, Diff and nodes
Does the Diff module work with nodes that are displayed using the Panels template? I go to `/revisions` and I get a "Page not found".

# Answer
A panels display for a node should not affect diff/revisions.

Is there a revision tab for the node? "node/NID/revisions" also were any revisions created for the node for diff to even compare? By default they won't create a revision.
> 1 votes

---
Tags: 7, panels
---


# Question
Title: Create a new revision automatically on edit
When a node is edited I want to always create a new revision. I do not want people to be able to turn this off. How can I do this?

# Answer
> 17 votes
To enabled automatic revision creation go to the content type page (admin/content/node-type) and select edit for whatever content type you wish to have revision created automatically.

Under the workflow fieldset there's going to be an option "Create new revision" make sure you check that box and save your content type settings.

Now under your permissions (admin/user/permissions) be sure to not to give your users the "administer nodes" permission. This will prevent them from overwriting that option.

# Answer
> 2 votes
There's a few different ways to do this. Assuming you want to avoid to disable the *administer nodes* permission for users, the easiest way is probably to turn off access to the *Create new revision* checkbox creating a custom module with the following code.

```
function sandbox_form_alter(&$form, &$form_state, $form_id) {
  // Node forms have an ID of the form CONTENTTYPE_node_form. Modify only those forms.
  if (strstr($form_id, '_node_form') === FALSE) {
    return;
  }

  if (isset($form['revision_information'])) {
    $form['revision_information']['revision']['#access'] = FALSE;
  }
}

```

In this way, users don't have the ability to change the default value of the checkbox, which is set on the settings page for each content type.

---
Tags: nodes
---


# Question
Title: How to add a category in the FAQ_ask module
I am using the FAQ Ask the Expert Module on my drupal 6. I am not very familiar with the drupal interface and have trouble setting up modules. I would like my ask a question for to have categories in which the asker can check off. The question would then be sent to the expert corresponding with that category.
It seems like this is what this module would do except I cannot get the categories to show up. Can someone give me step by step instructions?

EDIT: I would like the categories to show up on this form:

# Answer
> 3 votes
In order to use categories with the FAQ module you need to have the taxonomy module enabled.

Once you have the taxonomy module enabled you will need to create at least one vocabulary and associate it with the "FAQ" content type.

Once you've completed the above step you can visit the FAQ categories configuration page (admin/settings/faq/categories) and set up how you would like the categories to be display and there expected behavior on the faq page.

Hope this helps.

---
Tags: 6
---


# Question
Title: Is there a function that can output an image?
```
[field_img] => Array(
  [0] => Array(
    [fid] => 200
    [list] => 1
    [data] => Array(
      [alt] =>
      [title] =>
    )
    [uid] => 1
    [filename] => cpon.jpg
    [filepath] => sites/default/files/cpon_0.jpg
    [filemime] => image/jpeg
    [filesize] => 4434
  )
)

```

Is there a function that, using the above information, can output an image?
Is there any other method to output an image using the above information?

# Answer
> 5 votes
You can use theme('image').

Supposing that `$img` contains the PHP object you reported, then the following code can be used to output the image.

```
$output = theme('image', $img->filepath); // Drupal 6.
$output = theme('image', array('path' => $img->filepath)); // Drupal 7.

```

# Answer
> 4 votes
file field has theme function in \*filefield\_formatter.inc:117\*

```
/**
 * Theme function for the 'generic' single file formatter.
 */
function theme_filefield_file($file) {
  //
}

foreach($node->field_image AS $image){
  print theme('file_field', $image);
}

```

# Answer
> 3 votes
In addition to `theme('image', $path, $alt = '', $title = '', $attributes = NULL, $getsize = TRUE)`, you can also use `theme('imagecache', $presetname, $path, $alt = '', $title = '', $attributes = NULL, $getsize = TRUE)` if you use the ImageCache module.

# Answer
> 0 votes
I got it, using `theme_image()`.

---
Tags: theming, media
---


# Question
Title: How to keep underlying file when deleting a Filefield value
I have a Content Type with a FileField (Image, in particular). When one of these values is deleted, then Drupal deletes the underlying file as well (as long as no other nodes reference the same file).

I don't want the underlying files to be deleted, I want them to remain in the filesystem. Are there any hooks or other techniques I can use to make sure it remains after its FileField value is deleted?

# Answer
It's an ugly hack, but this is the simplest way I found to prevent a file from being deleted. It works by hooking `file_delete` and then removing the `uri` property from the `$file` variable. Without the uri, Drupal is unable to delete the file.

```
// Think twice before using this ugly hack.
// It probably breaks something and kills kittens.
function mymodule_file_delete($file) {
  $path = drupal_realpath($file->uri);
  if (!is_dir($path) && is_file($path)) {
    if (preg_match('/insert_regex_here/', $path)) {
      $file->uri = NULL;
    }
  }
}

```

The other alternatives I considered were:

* **Hacking core**
Although hacking core is taboo, it would be a cleaner solution than the hook I use above.
* **Using file\_usage\_add() on each file I want to retain**
Doesn't fit my use case very well - tens of thousands of files created and deleted independently of Drupal. Synchronizing all those files with `file_usage_add` would be daunting.
* **Use Media module to reference the file paths**
Media seems like overkill and it isn't stable yet. Plus I'm not sure if it would do what I need.
> 0 votes

# Answer
This has already been answered: https://stackoverflow.com/questions/2101754/drupal-filefield-remove-file-from-node-but-leave-on-server
> 0 votes

---
Tags: 7, files, media
---


# Question
Title: Views filter depending on the number of node references
I have a content type `A` that has a node reference to a content type `B`.

How can I create a view that show `A` nodes, and either filter by or sort by the number of references to the content type `B`? (Let's suppose the node reference to B field in A is named `field_reference_b`)

I'm interested in both filtering and sorting by that criteria.

**Edit:**

I could do this using the module Views PHP Filter, but I'm trying to avoid using it as much as possible.

# Answer
I don't have enough points to leave a simple comment. I haven't tested this yet. However, I think that you need to select in the 'Relationships' section the node reference. This will join the two tables and give the view access to all the fields in both. Then add an argument and when configuring the argument use the relationship you choose. I'm not sure which argument is best to choose but I think that node title is a good one for the summary and then select the Summery, ascending or desc. This actually creates a list of all the possible titles of A with the number of node B attached to each with a number next to is. When the title of node A is clicked in the block or page view it opens the page with node A's title as the big page title and all of fields of B as long as you selected the relationship under each fields setting.

I wish I had time right now to test it. It's only a theory but I'm sure it's the general direction of solving this.
> 2 votes

---
Tags: 7, views
---


title: views with a SOAP back end

text:
# Question
Title: views with a SOAP back end
views3 supports plugable backends rather than a RDBMS, there are backends for solr, sparql, mongodb.

Is there such a plug in to enable views to be a front end for a SOAP api? I have found a number of modules to do with services, soap, etc. But nothing which would clearly fill this role.

# Answer
I can't speak for Drupal 7/Views 3, but with Views 2 I used the Services module several times to expose content via Views, e.g. Services + SOAP Server + Views to make a bespoke Drupal-powered SOAP API. Perhaps that's not what you're after? SOAP Server would need porting anyway, but perhaps you could experiment with Views 3 and Services 3 and if it works ok with XML-RPC then consider helping port SOAP Server. It probably wouldn't take much work.
> 1 votes

# Answer
We have done this internally, but we coded it all ourselves. It is not tricky to do, but will take time.

You need to get a handle on how Views are built. Because you can use plugins to define how datasources, fields, filters, and arguments are handled, you can integrate with views really nicely.

Here are some good resources:

http://views.doc.logrus.com/

http://blue.live4all.co.il/~mooffie/tmp/views\_illustrated/views\_life.html
> 0 votes

---
Tags: 7, views
---


# Question
Title: Change field options after form has been filled with data
When creating my form, I wasn't enough aware of the configuration for the default core description field. I don't want a summary field, but I did not pay much attention at that when setting my form in the past. Now, when I try to change the field options to remove the summary field, I get the message "There is data for this field in the database. The field settings can no longer be changed.". Is it possible to override this restriction and force the change?

# Answer
I'm guessing the type is `Long Text with Summary`. If thats the case, can't you just go to admin/structure/types/manage/`[your content type]`/fields/`[your field name]` and uncheck `Summary input`.

Drupal will then automatically create a summary if it's required to, just as it would if you had chosen `Long Text` (without summary).
> 2 votes

---
Tags: 7, entities
---


# Question
Title: What are the potential security issues when importing an entity type?
I'm working on a module.

If the module is enabled, there would be an overview page showing the field structure of different content types. The visitor could then click a button to get a copy of the bundle's field structure (JSON encoded) and then use the code to create that content type on their site. Basically, like a feature except copy and paste rather than download.

What would potential security issues be? Is there any way to ensure that the hosting site (the site the content type is copied from) won't be able to do anything malicious?

# Answer
Who would you expose this feature to?

If it's users with one of the permissions listed on http://drupal.org/security-advisory-policy then you shouldn't really worry about the security implications because those users can already do a lot of malicious things to the site.

I believe that all field names and field values should be filtered appropriately already and Drupal handles filtering on output, so I don't see a need for something like xss filter during import.

The fact that you want to use JSON instead of a PHP array as the method to represent the code seems great: copy/pasting PHP arrays around is an easy way to create an arbitrary code execution problem.

There is more discussion about safe ways to offer this feature in an issue in the Views queue.

If this doesn't answer your question please leave a comment and I'll do my best to expand.
> 2 votes

# Answer
I think that you can never really be sure what is on the hosting site, and should assume that it is untrustworthy.

Anywhere that text is rendered to the user can be used to display malicious content.

The bundle arrays are a known structure so you should be able to deduce which fields are displayed to the user and apply xxs filters when importing.

There may also be potential to bypass security by re using known field names (for example), so it is probably worth namspacing items in the array to prevent this.

so for example if a field was referred to as `first_name` you may want to convert this to `importXXX_first_name`.
> 0 votes

---
Tags: 7, security, entities
---


# Question
Title: Save and preview differences in hook_form_alter()
I've created a module which uses hook\_form\_alter(). When a form is loaded (node/add) I hide a field, and the hook works fine. The problem appears when I do a preview of the form. When the form appears again I see the hidden field (the hook doesn't work). Why?

I hide the field through the line:

```
$form['field_versio']['und']['0']['value']['#type']="hidden";

```

# Answer
hook\_node\_validate() is the answer.

I have built a personal function X that includes a drupal\_add\_js function that I need to link to my form.

Depending on the form (content-type) I call my function X from hook\_form\_alter() (node/add first load) or from hook\_node\_validate() (node/add after previewing, validating,...).

```
function my_javascripts($form_id) {
  $path = drupal_get_path('module', 'MYMODULE');
  switch ($form_id) {
    case "CONTENTTYPE-node-form":
        drupal_add_js($path.'/CONTENTTYPE.js','file');
    break;
  }
}

function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  my_javascripts($form['#id']);
}

function MYMODULE_node_validate($node, $form, &$form_state) {
  my_javascripts($form['#id']);
}

```
> 0 votes

# Answer
First, you should use #access = FALSE which will disallow access to a element. #type hidden is not safe, it means that it is printed as a hidden input field which can be easily changed by the user, for example with Firebug.

When you do that, you can also directly set #access on the field element, like $form\['field\_versio'\]\['#access'\] and it will disallow access to all subelements (if there are multiple).

Not sure why it doesn't work in Preview, try adding a drupal\_set\_message('test') call to see if your hook is called.
> 1 votes

---
Tags: 7, forms, hooks
---


# Question
Title: What's the best way to include PHP in nodes?
We're converting some sites over to a Drupal 6 multi site and we have a number of existing pages that make heavy use of PHP.

What's the easiest way to include these scripts, assuming that they may want to live in different menus in different languages, and that we want these pages to also work like other pages on our site (e.g. take advantage of Rules, Views, CCK etc).

* Using `hook_menu()` to create a `MENU_CALLBACK` seems to mean we couldn't treat them like other pages (have people edit titles/content, use Views/Rules etc).
* Using `hook_nodeapi()` to add the PHP only works if it is always at the end (or beginning) of any content.
* Using the PHP filter to include a file works, but means editors would need the right to use PHP.

The solution I'm leaning towards is creating a custom filter that replaces a keyword/token with a file/function so editors would add {{FOO\_SCRIPT}} to their page and the relevant code would get included.

Is there a better way?

# Answer
Normally I do heavy php lifting on nodes in `hook_preprocess_node(&$vars)` and parse / include content in the `$vars`.

`hook_nodeapi()` is of course another way to go about it and your additional content will be available in many different `$op`erations, I don't use hook\_nodeapi() unless I'm altering data that gets saved, deleted etc within nodes - for display layer stuff hook\_preprocess\_node() always treats me well.

If you could expand on what sort of preprocessing and content you are including in nodes I'm sure we could go into more details into the best suited solution :)

**Update:** Given the variety of the tasks you aim to use (APIs, Additional DB Calls, or User Input Parsing etc), I'd definately recommend you use hook\_nodeapi so you have the fine grained control over the context. preprocess is view layer only and I feel as though you will likely want to hook the `nodeapi(&$node, $op = 'load')` so as to make your data entries high level enough to have the information widely accessible (like `$node->your_custom_api_field` in a `node.tpl.php`)

I *highly* recommend that you try to stay with Drupal's conventions as much as possible. Using database functions etc. Checkout the http://drupal.org/project/data module and possibly http://drupal.org/project/schema which both help working with your own tables (and the data module even helps expose that table to views so you can stay with Drupal core more!)

**p.s.**

My advice is to create a custom module for each data module you have so it can have it use it's own `hook_nodeapi` and any other hook's that may be required :)
> 5 votes

# Answer
Are you thinking of something like token filter?

Have the PHP functions available as tokens using the token api and then allow people to enter these tokens in your page.
> 0 votes

# Answer
If you are talking of nodes, and you just need to convert the existing nodes that were using PHP as input filter, then I would suggest you to do what was done from Drupal.org.

* Create a custom module that implements hook\_nodeapi().
* In the implementation of that hook, add the code that, when the operation is "view"
    + checks the node ID of the node being viewed;
    + when the node ID matches the ID of one of those nodes that were using the PHP filter, it executes the code that was contained in the node body.

The code should be something similar to the following one.

```
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  if ($op == 'view') {
    switch ($node->nid) {
      case 23:
        // Change the content of $node->content['body']['#value'].
        break;
      // ...
    }
  }
}

```

If the purpose is to allow some code to be used also to change the content of nodes created even after the site has been converted, or to keep the pages existing before the site is converted editable, then you have two possibilities.

* You use the code I reported before, but instead of changing the content of `$node->content['body']['#value']`, you append the result of the executed code to `$node->content['body']['#value']`.
* You use a filter module. Custom filter, for example, allows the users with the right permission (which should not be given to the normal editor users) to define a string that needs to be replaced (using a regular expression) and the replacement string that can be either the string returned from PHP code, or a string containing `$1`, `$2`, etc (in other words, a string similar to the string used by `preg_replace()`).

Another module that is similar to Custom filter is Regex Filters, but I have never used it, and I don't know if it allows to use a PHP code as replacement rule.

In general is preferable to not use drupal\_eval() (or `eval()`); this means that it is preferable to create a custom module that alters the node content through `hook_nodeapi()`, or a custom module that implements an input filter and replaces some defined string with the result returned from PHP code that is not passed to `eval()` in any way.
The problem with the input filter is that users could use the string replaced by the module in contexts where the string used to replace it should not appear. To resolve this problem, you could install Better Formats, which allows to control the allowed formats per content type, and decide which users can use a specific input format.
> 0 votes

---
Tags: 6
---


# Question
Title: Is there a module for creating a web directory like Dmoz?
I need to be able to organize different sets of content using the taxonomy. The user can visually click through the different layers of the directory and find what there looking for. I want to have full control over the way the categories are arranged and styled.

# Answer
> 2 votes
You could use taxonomy\_menu module. It is compatible with D7. You can arrange the taxonomy in whatever style you want and embed it in views/pages/blocks.

---
Tags: 7, taxonomy-terms
---


title: Minimalistic page.tpl.php file

text:
# Question
Title: Minimalistic page.tpl.php file
Do you know what to write to the **page.tpl.php** file so that it shows only 5 regions (header, menu, left\_sidebar, content, right\_sidebar)? Something like the following code, but to work correctly with other Drupal files and components (like \*.info file) and don't collide with Drupal default regions.

```
<body>
  <div id="header"><?php print $page['header']; ?></div>
  <div id="menu"><?php print $page['menu']; ?></div>
  <div id="left"><?php print $page['left']; ?></div>
  <div id="content"><?php print $page['content']; ?></div>
  <div id="right"><?php print $page['right']; ?></div>
</body>

```

# Answer
> 0 votes
You want to use render() like this:

```
 <?php print render($page['content']); ?>

```

I'm not really sure what you mean by "but to work correctly with other Drupal files and components."

You should also print all the standard regions and any other variables you might need. You can find a list of the default variables available to page.tpl.php in the documentation page.

Also here's a list of the regions you probably should include:

* `$page['help']`: Dynamic help text, mostly for admin pages.
* `$page['highlighted']`: Items for the highlighted content region.
* `$page['content']`: The main content of the current page.
* `$page['sidebar_first']`: Items for the first sidebar.
* `$page['sidebar_second']`: Items for the second sidebar.
* `$page['header']`: Items for the header region.
* `$page['footer']`: Items for the footer region.

---
Tags: 7, theming
---


# Question
Title: What are methods for tracking discussions or issues on Drupal.org
On Drupal.org, there are a number of discussions or issues that I subscribe to and wish to track. Do folks use any particular method to receive push updates or alerts when replies are added to threads?

Is typing in "subscribe" still the only method for tracking discussions?

I dislike having to "check" on webpages to be notified of updates. I'm more of an RSS and Google Reader tracker.

# Answer
You can now track issues where you haven't posted comments. To track an issue, you can just click the *Follow* button now available to the sidebar.

>

Followed issues will show up on your Drupal.org account under *Your Posts*.

If you want to track *all* the issues for a project, there are a few additional options:

* You can subscribe by e-mail by going to a project page and clicking on *Subscribe via e-mail* under the *Issues for PROJECT* heading
* You can subscribe to an RSS feed if you go to the issue list for the project and click the link at the bottom of the list (but your reader should also autodiscover the feed)
> 9 votes

# Answer
All issue queries have RSS feeds. I sometimes set up feedburner feeds with email notification when I want to get emails if something pops up in a particular category.

1. Create an issue query at http://drupal.org/project/issues
2. Grab the feed URL using your browser or whatever. For example, the feed url for all views issues in "Needs Review" is http://drupal.org/project/issues/search/rss?projects=Views&status\[0\]=8
3. Go to feedburner.google.com and create a feed there, and choose to send out email with new articles.

I'm sure there are other approaches that turn feeds into emails. This is just one I've used. This one is nice because you can share it with others.
> 5 votes

---
Tags: community-official-site
---


title: Pressflow caching directives

text:
# Question
Title: Pressflow caching directives
I have a setup with Varnish. Varnish decides when to clear the cache for a page according to the PHP headers. I want to force Varnish to regenerate the cache for each node every time it gets updated by an user. I am looking for the best place to do this. Ideally it would be in a Drupal/pressflow hook (if there is any available) implemented in a custom module.

* What HTTP caching directives Pressflow sets?
* In what function, file and line number?

Answers that don't address those two bullet points will be appreciated, but not accepted.

# Answer
> 3 votes
The varnish module handles clearing the cache for you when a node is update via a socket connection to varnish. It can also be configure to clear the cache based on a lifetime period. If you still need to clear the cache based on your own custom requirements the module also provides a helper function such as \_varnish\_terminal\_run that allows you to send commands to varnish from your php code.

Also in regard to the bullet point checkout the drupal\_page\_cache\_header\_external in pressflows bootstrap.inc file

There is also more documentation of varnish with pressflow over at fourkitchens wiki

---
Tags: caching
---


# Question
Title: Tiered HTML lists using Views and Taxonomy?
I would like Views to output an HTML unordered list of a certain vocabulary (Taxonomy Term). This is not a problem... the problem is that the list is rendered flat, instead of showing the parent\>children relationships contained in the vocabulary.

How to I get Views to render this:

> * Parent
>     + Child
>     + Child
> * Parent

Instead of:

> * Parent
> * Child
> * Child
> * Parent

# Answer
> 3 votes
I'm going to assume your view is a taxonomy term view.

First thing you would want to do is add a relationship to your view. The relationship you want to add is the Taxonomy: Parent term relationship and set required this relationship.

Once you're done adding the relationship add another Taxonomy: Term field to your view but this time make sure to select the "Parent" relationship for that field.

Also select "Exclude from display" for this field if not this is going to show up twice.

Once you've done that you will need to group your fields by the Parent Term. This can be accomplish by going to the settings option for the format and selecting the Parent term you just added.

You will now get the display you want.

Hope this helps.

---
Tags: 7, views
---


# Question
Title: How to add a node field to a database table in a custom module
When I am writing my own custom module, and designing a database table, if I want to use the field `nid` to refer to a node, because I want my module to adding something to each node, how should I implement this in the module's mymodule.install file?

# Answer
> 1 votes
Most of the time you will probably want to use the field API (CCK module in D6) rather than adding custom tables or modifying node by yourself.

Adding custom tables was a very D5 way of doing thing.

If you want to do this you will need to define your tables using `hook_schema()` and then in your mymodule\_install() hook you can call `drupal_install_schema()` this should create a new table which represents your module.

It is worth mentioning that your schema should always represent your current schema. If you add a column you should alter the schema so that someone who installs your module will get the correct schema, but also write an update function to alter the table so that existing users get the correct new schema.

It is possible to alter other modules' tables, but I think that should be covered in another question.

---
Tags: 7, database, installation
---


# Question
Title: Is there any implication/consideration for using the boost module on many different websites running on the same VPS?
Is there any implication on using the Boost module on many different websites running on the same VPS?

# Answer
Boost has options for how you structure the files, you can use the ip address or the host name.

In your case you would want to stick to the host name so the files are separate. Other than that I see no reason why it shouldn't work. Though I haven't tried.
> 1 votes

---
Tags: 7, caching
---


# Question
Title: How to make the custom module effect on the node and only one content type?
The following code is used to output five images, according to what's number contained in `$fen`. I want to put the button in nodes of a specific content type (e.g. "company").
Which code should I use in my module to get this?

```
<form action="" method="get">
<input type="submit" name="fen" />
</form>
<?php
  $star = getStar($_GET['fen']);
  echo "<img src=\"xing_$xin.jpg\" />";

  function getStar($fen) {
    if ($fen < 10) {
        return 1;
    }
    elseif ($fen < 100) {
      return 2;
    }
    elseif ($fen < 1000) {
      return 3;
    }
    elseif ($fen < 10000) {
      return 4;
    }
    else {
      return 5;
    }
  }
?>

```

# Answer
If you want to add content to nodes, you can in drupal 6 use the `hook_nodeapi` where `op` is `view`.

As you get the node object, you can detect the node type ect. You would need to add something like this to your module

```
module_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  switch($op) {
    case 'view':
      if ($node->type == 'node_type') {
        // $a3 indicates if teaser
        // $a4 indicates if page
        $node->content['my_additional_field'] = array(
          '#value' => 'HTML', // create html with theme or form function.
          '#weight' => 10,
        );
      }
      break;
  }
}

```
> 2 votes

---
Tags: 7
---


title: Creating a form

text:
# Question
Title: Creating a form
I am new to Drupal 6. I have been playing around with the settings and have been able to create a static website.

What I can't seem to figure out is how I create a form with some input fields and a submit button. When the submit button is clicked, the form data should be saved into a database table.

This is straight forward stuff using raw PHP/MySQL, but I can't seem to figure out how to do this in Drupal.

# Answer
To write a module that displays a form, there is a link called "Form generation" on http://api.drupal.org/api/drupal/6, which then links to the quickstart guide.

As an alternative, have a look at the http://drupal.org/project/webform project, which allows you to create forms through the User Interface.
> 6 votes

# Answer
If you'd just like to collect data from your users, such as a contact form or a feedback form, or even a simple survey, you can check out the webform module which will allow you to collect the data, review it later, download it as a CSV, and, optionally, send you an email every time someone fills it in.
> 2 votes

---
Tags: 6, forms
---


# Question
Title: "init "and "mail" fields in the users table
What is the difference between the "init" and "email" fields?

```
mail varchar(64)  User's e-mail address.
init varchar(64)  E-mail address used for initial account creation.

```

# Answer
> 15 votes
The difference is that *mail* is the actual email address used by the user, while *init* contains, in a plain Drupal installation, the email address used when the user account was created.
In the case the Bakery Single Sign-On System module is installed in a slave site (in Bakery parlance), the *init* field contains the link to the user account on the master site.

So, the *init* field could be described as the field that unequivocally identifies a user account, and that is (by default, when third-party modules don't change its content) set to contain the initial e-mail address. (That seems the reason why the field has been named *init*.)

Drupal.org uses the *init* field in the case users lose the access to their account, and create a new account to report that. They are asked (not publicly) which email they used when registering their previous account; a Drupal.org administrator would then verify that is exactly the email they used while registering the lost account by reading the database content. (There isn't a module that allows to do so automatically, for what I know.)

---
Tags: users, database
---


# Question
Title: Concatenate $base_url and path_to_theme()
I'm used to write this kind of code in **.tpl.php** files in order to display images (for instance) :

```
<?php echo $base_url .'/'. path_to_theme();?>

```

I wonder if it would be possible to concatenate **$base\_url** and **path\_to\_theme()** into one single command/variable ?

# Answer
In `hook_preprocess($vars)` create a new variable called `path_to_theme` in $vars by including the following (where `$hook` is page, node, block etc)

```
function mymodule_preprocess(&$vars, $hook) {
  $vars['path_to_theme'] = base_path().path_to_theme();
}

```

Now in virtually all of your theme's template you can use the variable `$path_to_theme` and it will be the contents of `base_path().path_to_theme()`

Note, that you can put this in a custom module, or replace `mymodule` with the name of your theme and you can place it in your theme's `template.php`

You can use node, page, and other "hook" specific preprocess functions if you only wish to add this variable to specific content of your site.

There are many options for preprocessing nodes, pages etc. which can be read up in: Setting up variables for use in a template (preprocess and process functions)

Also be sure to read up on the Default baseline variables such as:

> **$directory** The theme path relative to the base install. example: "sites/all/themes/myTheme"
> 4 votes

# Answer
You can theme\_preprocess\_node() or theme\_preprocess\_page() in your template.php file in your theme and create your concatenated path there so it is accessible in template files.

```
function yourthemename_preprocess_node(&$vars) {
  $vars['theme_path'] = base_path() . path_to_theme();
}

function yourthemename_preprocess_page(&$vars) {
  $vars['theme_path'] = base_path() . path_to_theme();
}

```

Then $theme\_path is always available in your template files.
> 0 votes

---
Tags: theming
---


# Question
Title: My custom preprocess function works as soon as the cache is cleared, then stops working
I have a custom Drupal 6 module, with a custom theme function. I have implemented hook\_theme in my mymodule.module (main module file) as follows:

```

function mymodule_theme() {
  return array(
    'mymodule_template_regions'   => array(
      'arguments' => array('template' => array()),
      'file'      => 'mymodule.theme.inc',
      'path'      => drupal_get_path('module', 'mymodule') . '/templates',
      'template'  => 'mymodule-template-regions',
    ),
  );
}

```

I have implemented mymodule\_preprocess\_mymodule\_template\_regions() in a file called mymodule.theme.inc, in the main module folder.

I have placed mymodule-template-regions.tpl.php in the templates subfolder inside my main module folder.

This all works fine when the cache is cleared. As soon as the page is refreshed after the initial cache clear, it stops working.

The offending line is line 696 of theme.inc in Drupal Core version 6.19, which states:

```

if (function_exists($preprocess_function)) {
  call_user_func_array($preprocess_function, $args);
}

```

When the cache is cleared, the mymodule\_preprocess\_mymodule\_template\_regions function exists, so it gets called because the 'if' statement yields TRUE. However, on each subsequent page request, the function does not exist. I presume this is because, for whatever reason, mymodule.theme.inc is not being included.

This is where my knowledge of Drupal breaks down, as I'm unaware of what else is going on here and how to track down why the function is not being included. It looks like the theme registry is still aware of mymodule\_preprocess\_mymodule\_template\_regions, but that it's simply not being called because it's not included.

# Answer
Drupal is looking to include the following file:

```
drupal_get_path('module', 'mymodule') . '/templates' . '/mymodule.theme.inc'

```

but, you say that you've put it in the main module folder, here:

```
drupal_get_path('module', 'mymodule') . '/mymodule.theme.inc'

```

So Drupal isn't going to include the file on subsequent calls to the theme function. So, you might want to move your include.

You can see this from how your hook\_theme is processed in: \_theme\_process\_registry
> 2 votes

---
Tags: 6, hooks, theming
---