# Question
Title: What are the major differences between Drush versions 3 & 4?
What are some of the biggest differences between Drush versions 3.x & 4.x?

# Answer
There's a lot of new user management stuff

* user-add-role Add a role to the specified user accounts.
* user-block Block the specified
* user(s). user-cancel Cancel a user account with the specified name.
* user-create Create a user account with the specified name.
* user-information Print information about the specified user(s).
* user-login Display a one time login link for the given user account (defaults to uid 1).
* user-password (Re)Set the password for the user account with the specified name.
* user-remove-role Remove a role from the specified user accounts.
* user-unblock Unblock the specified user(s).

The cache clear functionality has become more fine grained The backup folder for module updates now appears outside of webroot and you have greater control during updates over which modules to update (security updates only)

Check out http://docs.drush.org/ for more information.
> 6 votes

# Answer
Drush 4 features a great feature where it can act upon all the sites defined in your sites/ folder in one command. So if you run multisite you can run Drush commands against them all.
> 2 votes

---
Tags: drush
---


title: Views 2 Conditional Filter

text:
# Question
Title: Views 2 Conditional Filter
How can I apply a conditional fitler to a view (using views 2)?

For example: I have a view which displays the teasers for several different node types using a filter on Node:Type in \[Blog entry, Forum topic, User profile\]

This works well for showing all nodes of those types, but suppose I only want to show a user's profile if it has a picture as well (and all of the other types).

# Answer
> 3 votes
clone a display for the "filtered (must have picture)" view. Add a relationship on the picture field and make it required. This will limit the display of content to that which has a picture field populated.

Now you can use a link in the headers to jump back and forth or provide another means.

# Answer
> 2 votes
The method I use for this is to override the page callback and then provide my own custom code for manipulating the view. Here's an example:

```
  $view = views_get_view('profile_listing');
  // The display name is has been renamed in a a features export. It's more likely to be page_1 or block_1, something along those lines.
  $view->set_display('page_profile_listing');

  if (some condition) {
    $date_filter = array(
          'date_filter' => array(
            'operator' => '>=',
            'value' => array(
              'value' => NULL,
              'min' => NULL,
              'max' => NULL,
              'default_date' => 'now -7 days',
              'default_to_date' => '',
            ),
            'group' => '0',
            'exposed' => FALSE,
            'expose' => array(
              'operator' => FALSE,
              'label' => '',
            ),
            'date_fields' => array(
              'node_data_field_feature_updated_date.field_feature_updated_date_value' => 'node_data_field_feature_updated_date.field_feature_updated_date_value',
            ),
            'date_method' => 'OR',
            'granularity' => 'day',
            'form_type' => 'date_select',
            'default_date' => 'now -7 days',
            'default_to_date' => '',
            'year_range' => '-3:+3',
            'id' => 'date_filter',
            'table' => 'node',
            'field' => 'date_filter',
            'override' => array(
              'button' => 'Use default',
            ),
            'relationship' => 'none',
          ),
        );

        $existing_filters = $view->display_handler->get_option('filters');
        $view->display_handler->override_option('filters', array_merge($existing_filters, $date_filter));
  }

  return $view->execute_display('page_profile_listing');

```

The actual filter I'm adding is nonsensical in this case (it's just copied/pasted from somewhere else I'm doing this). You can get the specific filter you need to add by adding it to the view, using the export function, and finding that specific filter in your export code.

Hope this all makes sense, feel free to ask for more details if you need it.

# Answer
> 1 votes
You can pass the user id as an argument to the view and set a php code validator to check if the user has a picture for exemple.

# Answer
> 1 votes
You would want to add other filters to create the new view.

If you want to make the view change based on different conditions you could add arguments that limit the output.

If you want to get really complicated you could write a module that filters through the view results manually and only displays content based on your arguments.

---
Tags: 7, views
---


title: Redirect on Login?

text:
# Question
Title: Redirect on Login?
I have tried making this a rule as well as used `hook_user` with no luck. It definitely gets inside of the login case (had a watchdog log), but the redirect doesn't happen and they are still sent to `/user` upon logging in.

I am trying this with no luck:

```
/**
 * Implementation of hook_user()
 */

function multistep_registration_user($op, &$edit, &$account, $category = NULL) {
    switch ($op) {
        case 'insert':
            multistep_registration_save_content_profile_name($account);
            break;
        case 'login':
            if (!multistep_registration_is_complete($account->uid)) {
                drupal_goto('user/register/complete-registration');
                exit;
            }
            break;
        default:
            break;
    }
}

function multistep_registration_is_complete($uid) {
    if ($uid == 1) {
        return TRUE;
    }

    $node = content_profile_load('profile', $uid);

    if ($node->field_completed_registration[0]['value'] == 'yes') {
        return TRUE;
    }

    return FALSE;
}

```

Why is it not redirecting? New users all have the value set as 'no'.

# Answer
You could try using LoginToboggan, which allows you to set a redirect on login.
> 8 votes

# Answer
One method that we use is using Rules. It allows you to make a rule for:

* User has just logged in.
* User has not completed Content Profile (you can select the particular content type).
* Do an action for: Redirect user to URL that you want

Hope it helps!

EDIT: You can also make it when a user views a page and has a role you want, redirect them. That way, it forces them to fill it out and doesn't allow them to do anything else (if you want that).
> 6 votes

# Answer
I use Login Destination to redirect after logins on my sites; I know that it has the ability to use php snippets to create conditions for specific situations, but I've never used them.
> 4 votes

# Answer
I'll just put this here in answer form, You can use rules to do this, even if the rule provided by content profile isn't available.

Just use the "User has logged in" trigger, add conditions for the fields of interest being empty and redirect.
> 1 votes

---
Tags: users, redirection
---


# Question
Title: How do you load extra javascript files required for wysiwyg api plugin on node/edit pages?
I'm building a plugin using the WYSIWYG API module for Drupal 7 that will add a button to the toolbar of supported editors.

I'm using the `hook_wysiwyg_plugin()` hook to create a new button on editor toolbar but I need to load a few other javascript files. The `hook_wysiwyg_plugin()` hook seems to allow you to specify one JS and CSS file.

How can I load extra required javascript files required for the plugin javascript?

I've implemented `hook_library()` to define a library i.e. js/css files but am unsure how I hook that up to wysiwyg api so that they load on the node/edit screens?

# Answer
> 1 votes
It's actually quite simple, although my experience with doing the same thing is through Drupal 6, so there may be some minor differences with my code:

```
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  // Only modify node_form's.
  // @TODO - Set a condition for all forms you wish to alter for D7 entities.
  if (isset($form['type']['#value']) && $form_id == "{$form['type']['#value']}_node_form") {
    // We use after build to add JS and CSS to prevent issues caused by form caching.
    $form['#after_build'][] = 'MYMODULE_form_alter_after_build';
  }
}

function MYMODULE_form_alter_after_build($form_element, &$form_state) {
  drupal_add_js(...);
}

```

Again, this code is for D6, but the basic principle should still work.

While it's not tied directly to the Wysiwyg API, it's probably the best option as the Wysiwyg API only supports on JS file per plugin (iirc).

A few wild/untested options for you:

* Make a menu callback for the Javascript file defined in the plugin and pass back a somewhat cached javascript file containing the sources of multiple javascript files. (Wysiwyg Fields does do the menu callback for dynamically generated plugins, but only for one javascript file, see the source for ideas).
* Use a Javascript dynamic Javascript loading technique similar to http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml

Hope this helps.

# Answer
> 2 votes
With drupal\_add\_js:

```
function yourmodule_preprocess_page(&$vars)
{
  $node = $vars['node'];
  if($node->type == 'yournodetype' AND arg(2) == 'edit')
  {
    drupal_add_js([...]);
  }
}

```

# Answer
> 1 votes
In theory, all you would need to do is use the right "**#text\_format**" parameter on the `#type textarea` FAPI element for the wysiwyg editor associated with the Text Format to be automatically included, this way:

```
function mymodule_menu(){
    return array(
        'mypage' => array(
            'title' => 'A page to test wysiwyg',
            'page callback' => 'drupal_get_form',
            'page arguments' => array('mymodule_page'),
            'access arguments' => array('access content'),
        )
    );
}

function mymodule_page($form, &$form_state) {
    $element = array(
        '#type' => 'textarea',
        '#title' => t('Comment'),
        '#default_value' => 'something',
        '#text_format' => 'full_html',
        '#required' => TRUE,
    );
    $form['mytext'] = $element;
    return $form;
}

```

However, it doesn't get included unless it's a "node edit" page, so something related to functions "`filter_process_format`" or "`wysiwyg_pre_render_text_format`" may be able to force it, but I haven't found the magic combination yet, still reading the source of the Wysiwyg module to find the missing piece.

---
Tags: 7, hooks, wysiwyg
---


# Question
Title: Is it possible to replace the original RSS content?
Is it possible to replace the original RSS generated for the front page by custom content?

I know how to create custom RSS channels using views, but not how to replace the original RSS.

# Answer
> 4 votes
When editing the Feed display of your view you have the **Feed settings** box with two settings there - Path and Attach to. If you set Path to 'rss.xml' or if you're using a view for your frontpage and you choose it in "Attach to", that should do the trick.

---
Tags: nodes, feeds
---


title: Authentication for iCal feeds

text:
# Question
Title: Authentication for iCal feeds
I have a calendar feed (using the Drupal Calendar module) on a site and I'd like to add this calendar to Google Calendar. I have this working for a publicly accessible calendar and it works fine.

The problem now is that my calendar is only accessible for authenticated users and should remain so. I see no way to authenticate the application accessing a feed and therefore can't access that calendar from Google Calendar.

Is there any way to provide credentials in the feed url or something similar?

# Answer
Secure remote access to an RSS page via HTTP authentication using the Secure Site module.

> This module allows you to authenticate users with a browser-based password (HTTP Auth). You can restrict access to the site by role and choose to secure restricted pages or the entire site. This means the site will be inaccessible to search engines and other crawlers, but you can still allow access to certain users.
> 4 votes

---
Tags: 6, feeds, authentication-authorization
---


# Question
Title: What security issues are involved with cross-domain logons using OpenID?
I want to implement cross-domain logons for 3 sites. Is OpenID the best tool for protecting my site and users?

# Answer
> 5 votes
As far as I'm aware OpenID is reasonably secure. The downside to OpenID is that it's fairly complicated for non-technical users to understand. Something like this might make that a little easier on your users. There are options to make your site the OpenID provider, but they don't seem ready for production sites yet from a brief skim through the issues.

Another option might be OAuth. This would let your users log in with their accounts from sites like Facebook, Twitter and LinkedIn.

If all 3 sites are Drupal sites, one final solution might be to share the users between the sites, by sharing certain database tables. This would allow you to share other information about your users between the site profiles as well.

This page on Drupal.org describes the details, as well the downsides. Main one being that upgrades to major Drupal updates aren't supported. I honestly wouldn't recommend this unless you know a great deal about how the database side of Drupal works.

---
Tags: security, authentication-authorization
---


# Question
Title: How should I configure cron tasks to make them automatically run on GoDaddy?
I own a lightweight blog hosted on GoDaddy. I could not get cron to automatically run, so I manually run it when necessary.

How should I configure cron tasks to make them automatically run on GoDaddy?

# Answer
I don't have much experience with GoDaddy (I prefer BlueHost), but you could use the PoormansCron module instead of running it manually. Also, if you update to Drupal 7 this is included in core.
> 6 votes

# Answer
I used to use GoDaddy shared hosting and I had cron working with Drupal for a long time. I have since changed hosts so I can't lookup what my exact settings were. However it was something like this:

> curl --silent --compressed http://www.example.com/cron.php
> 2 votes

---
Tags: cron
---


# Question
Title: How to create relationships between Taxonomy vocabularies?
I'm trying to build a site with similar content conventions to Craigslist. The problem is, I don't really know a good way to create multiple vocabulary relationships in drupal. Here's the end result I need:

**Vocabs:**
*Locations*
*Categories* (contains 'Goods' and 'Services')
*Status*

**Content Type:** Item

> **Relationships:**
>
> * User has many Items
> * User has one Location
> * Location has many Users
> * Location has all Categories
> * Item has many Categories
> * Item has one Location

The end result is having all ***Locations*** be easy to navigate, with ***Items*** being appropriately displayed, in multiple ***Categories***, but restricted to ***Locations***. ***Users*** should also be redirected to their respective locations based on their assigned ***Location*** and should be able to create ***Items*** without having to manually stipulate the ***Location*** they are already in.

**Does that make sense? Can this be done easily in Drupal?**

# Answer
This can all be done with Drupal's built in taxonomy module and the User Terms module.

* Create a node type for Items.
* Any Item a user creates is automatically tied to them by them being the author.
* Create a taxonomy for Locations and assign it to Items and Users.
* Create a taxonomy for Categories, assign it to Items, make it multi selectable.

You can then use Views to create all the different listings pages and blocks.
> 4 votes

---
Tags: views, taxonomy-terms, entities
---


# Question
Title: How do I merge changes from a development copy of the site to the live site without losing new content?
What is the best procedure for merging work done on a development copy of a site to the live production copy? Often times there has been a lot of new content added to the site since development started on the newest features. And most additions to a site will involve database changes. So copying any new files is easy, but what about the database? How do you merge your changes with the existing production database without losing new content that was added since the last time you updated the production site? Are there any modules that help with this?

# Answer
> 16 votes
For content types, views, and structure changes on the dev site look at using Features to export the database to code.

For content migration there are many options, but not a single solid solution. One example is the Deployment suite.

# Answer
> 2 votes
I've adopted basically two schools of thought here (a 3rd school of thought, doing database diffs, I won't discuss because the complexity is quite high).

1) Deploy by dropping the production database, and importing a mysqldump of the development database. Optionally, run a regex find/replace beforehand on any hard-coded absolute links which reference the dev URL in the SQL dump. After importing the dev db into prod, automatically run SQL statements (usually via script) afterwards to change any settings that are different for prod than dev (e.g., maybe you have in variables table some connection settings for connecting to external systems that you need to change to point at prod external systems instead of at the dev version).

2) Use the Features module, as mentioned by budda, for admin settings, and use the Node Export module for content export/import in combination with the Delete All module. So workflow is:

1. use node\_export and features to export nodes/features to files
2. Optionally (and hopefully) version control
3. Load files on prod system
4. Use drush or admin interface to load features
5. Use drush delete-all or admin interface to delete all nodes of the types you want to import
6. Use drush ne-import or the admin interface to import the nodes from the nodes file you exported.

One note, I would highly suggest adopting a standard workflow, where content goes one direction only. Either Dev -\> Prod or Prod -\> Dev (I prefer this one).

I've done this, and am doing this on some big systems, with fairly good results, but there will always be many ways to slice this apple, choose whichever way works best for you.

# Answer
> 1 votes
Dump databases of live site copy & development copy of site in SQL file (use same parameters & settings for both dumps).
Then, compare both SQL files using a small comparison tool ExamDiff. It'll display file differences side-by-side with different colors. You can directly jump to the differences also (without scrolling). Examine the differences & add/edit lines to SQL file of live site. Make sure there's no absolute path/URL of development environment in that file. That's done! Time to restore the database for live site.
**Make your life easier:** In first step, dump only those tables which are changed. For example, if you've edited a module in development copy which targets a separate table, dump only this table. If you're not sure about particular table, whole database dump is fine.

---
Tags: database, updating
---


# Question
Title: Making responses to public nodes only viewable by the creator and the originator
I've got a prototype site built in D6, pertinent modules:

* CCK
* Comment block
* Node Comment
* Views
* Views Or

The site is built around a list of open requests; to solicit a private response. These nodes are of content type Request.

All open requests are public in that all users (logged in or not) can view these nodes.

When a response (comment) is received to an open request it should only be viewed by the author of the original request, or the author of the response.

These responses should be shown to these users on the original node as comments and on a seperate list.

How do I do this?

# Answer
A quick search on D.o. came up with this forum post asking to do the exact same thing: http://drupal.org/node/919914

They suggest using Node Comment and Content Access together to achieve it, but I'm not certain Content Access will give you the specific option you're looking for.

It would be a start though, and you might be able to hook into Content Access and create a new "Parent Node author" or similar option if you are up for a coding session.
> 1 votes

---
Tags: views, nodes, 6, entities, comments
---


# Question
Title: How to migrate Drupal nodes from one installation to another, preserving revision history?
Is there a good way to export a set of nodes from one Drupal installation, including node revision history, and then to merge these into another Drupal installation, including revision history?

I'm familiar with modules such as Node Export and Backup and Migrate... But `Node Export` doesn't preserve revision history, and `Backup and Migrate` doesn't allow merging (only full table replacement).

# Answer
You can also try UUID and UUID Features, can export both Nodes and Nodes revisions.
> 5 votes

---
Tags: migrations, version-control, nodes
---


# Question
Title: How do I show a "read more" link in my RSS feed?
I need to trim down my RSS feed so that people come back to the site to read the full article, how might I do this and is there a preferred / best method?

# Answer
That's what **Teasers** are for — the Teaser is the shortened version of the content, presented in RSS feeds (among other places, such as the site's front page).

When editing a node in Drupal 6, use the "**Split summary at cursor**" button to split the node's body into a Summary/"Teaser" and "Full view".

Then go to your site's `/admin/content/rss-publishing` page, and set "**Feed content**" to "**Title plus teaser**".

Additionally, on your site's `/admin/content/node-settings` page, you can configure the default length to use to split nodes.

For some additional customization, try the Read More Link module (but be aware of this issue), or Display Suite, as @Decipher mentioned.
> 5 votes

# Answer
Try Display Suite / Node Displays, gives you a nice interface for themeing the output of different displays (Full node, Teaser, etc) including the RSS output, so you can move the fields around, use Custom Formatters to theme them, and add extra fields as required.

Nice easy way to customize your RSS feed as you need.

Plus the settings can be exported as a Feature.
> 4 votes

---
Tags: feeds
---


# Question
Title: How to perform an operation every time a node is viewed?
When writing a module, how can I perform an operation every time a node is viewed by a user?

# Answer
You can use `hook_nodeapi()` in Drupal 6 and check that the `$op` argument is 'view'. In Drupal 7, this has been changed to `hook_node_$op()` where `$op` is replaced by the value you would have checked for in the Drupal 6 version. So you would use `hook_node_view()`. For more details about the changes from Drupal 6 to Drupal 7 see http://drupal.org/update/modules/6/7#remove\_op.
> 13 votes

# Answer
Alternatively you could use Drupals Trigger module which has a 'When content is viewed by an authenticated user' trigger by default.

You can create an Action through /admin/settings/actions, or write your own based on the information at http://drupal.org/documentation/modules/trigger. You will also find modules that have predefined triggers and actions.
> 3 votes

---
Tags: 7, hooks
---


title: Bulk saving nodes with a file field

text:
# Question
Title: Bulk saving nodes with a file field
I'm in the progress of creating a bulk upload function for a Drupal site. Using flash I'm able to upload the files to a specific url that should be able to handle the files.

What I want to do, is not just to upload the files, but create a node of a specific type with the file saved to a file-field that has been setup with CCK. Since these are audio files, it's important that file-field handles the files, so additional meta data can be provided with the getid3 module.

I've taken a look at the code/doc, but wasn't able on the first round to figure out how to handle this. Ideally, there is some function that I've missed, that can handle most of this for me.

If any one has experience with this I would apreciate some pointers on how to approach this matter.

# Answer
It's pretty straight forward, setup your content type with the required fields, then you want to use code similar to this:

```
$file = new stdClass();
$file->filename = basename($filepath);
$file->filepath = $filepath;
$file->filemime = $mime;
$file->filesize = filesize($filepath);

$file->uid = $uid;
$file->status = FILE_STATUS_PERMANENT;
$file->timestamp = time();
drupal_write_record('files', $file);

$node = new StdClass();
$node->type = 'type';
$node->body = 'body';
$node->title = 'title';
$node->field_file = array(
  array(
    'fid' => $file->fid,
    'title' => basename($file->filename),
    'filename' => $file->filename,
    'filepath' => $file->filepath,
    'filesize' => $file->filesize,
    'mimetype' => $mime,
    'data' => array(
      'description' => basename($file->filename),
    ),
    'list' => 1,
  ),
);
$node->uid = 1;
$node->status = 1;
$node->active = 1;
$node->promote = 1;
node_save($node);

```
> 5 votes

---
Tags: 7, files
---


# Question
Title: How to use Drupal in the cloud with on demand instances
Services such as Rightscale do lots of things to help mange unpredictable traffic and bring more servers online when traffic spikes.

**Is it possible to use Drupal with services such as this?**

While Drupal can be set up for a number of configurations, is it possible to set it up so the configuration is flexible.

**What do you need to do to make sure it works?**

Assuming that you can bring on demand instances online, what do you need to do to make sure that Drupal will work in this situation. What do you *have* to do?

**What is the optimal setup?**

Once you have done what you *have to* do, what *should* you do to ensure that you can scale to more servers seamlessly. What is the best configuration in terms of number of servers. How many caching servers should you bring on line for each web server. Should you scale each tier independently?

*edit*

Edit to clarify that this is to do with the implications of *on demand* scaling for a Drupal site.

# Answer
Rackspace put together a pretty decent start to this subject here which uses a couple of specific technologies which you might not want to use, but the principles are the same.

You might also need to look at Mysql clustering, but only really if you're hitting serious traffic levels
> 7 votes

# Answer
if the webservice supports php5 and mysql then there should be no problems with running drupal in the cloud. that said you may want to consider looking at the pressflow fork of drupal if you are looking for serious scaling
> -1 votes

---
Tags: performance
---


title: Site stuck in maintenance mode

text:
# Question
Title: Site stuck in maintenance mode
I have put a site in maintenance mode. Before I could visit the administration pages as user #1 (which was the user account I was already using before to put the site in maintenance mode), I had to reset the computer; when I tried to visit the administration pages, Drupal didn't give me access to those pages.
I cannot change the content of the settings.php file because the installer tool that I used from the control panel for the domain probably created the files using credentials different from the ones I use to connect through FTP, which is the only way I have to upload files to the server, or change them.

Apart re-installing the Drupal files manually (and in a different directory), what can I do to access the administrative pages?

# Answer
You should be able to log in by going to http://example.com/user directly (or http://example.com/index.php?q=user if clean URLS are turned off).
> 30 votes

---
Tags: maintenance-mode
---


title: Integration with the RDF module

text:
# Question
Title: Integration with the RDF module
I have a module that creates HTML output.

What are the functions made available from the RDF module that allows a module to integrate with it?

# Answer
Themes will work with the RDF module if they use the proper attributes variables. If you are generating HTML outside of the core theming system (which seems unusual), you will need to get this information yourself.

The RDF mapping API is quite well documented. Essentially there is a mapping between fields and RDF, so a title field could have a mapping to *dc:title*.

You can then add RDFa markup to the fields as you output them.

If you are using standard theme functions, then as long as you stick to the Drupal 7 guidelines, all the RDF magic should be done for you. Specifically, make sure that you use `$attributes` `$title_attributes` and `$content_attributes`.
> 4 votes

---
Tags: rdf
---


# Question
Title: What argument to use in Views that excludes the node currently being displayed?
For instance: if you have a view that produces a list of titles of nodes of content type X, how can you make that list exclude the node that is currently displayed to a site visitor?

# Answer
This can be done with a regular argument.

Create an argument for `Node -> ID`, choose `Node` as the validator and `Node ID` as the argument type. Then just tick the `Exclude the argument` check box. You can also choose specific node types here if you want.

Used with a block, this will list all nodes that aren't the one currently being viewed. You can then filter it further to suit your needs.
> 4 votes

---
Tags: views
---


title: Field API versus custom code

text:
# Question
Title: Field API versus custom code
If I need to add custom fields only to user profiles, is it better to create a module that uses the field API, or a module that uses its own code to show the custom fields at a custom URL and to save the data in its own database table?

The field API doesn't implement the permissions necessary to decide which fields are visible to which users, if that is a reason enough to implement custom code.

# Answer
Implementing a custom Field API field is quite simply, there are already many tutorials and example modules available. One of the advantages is that it provides all the storage handling for you and it can provide handling for multiple values and so on.

Note that Field API provides the framework for field level access permissions but it doesn't implement it. Just like node\_access. So that's not a reason against using it.

See http://drupal.org/project/field\_permissions for a project that provides an implementation for that.
> 7 votes

# Answer
In the long run, it will be better to use the fields API. It will give you more flexibility and allow other modules to integrate. Besides there are some various hooks that gets called when different actions occur which also might come in handy. All in all, this is what the API is for.

Learning how to use it might take a little while longer than a custom solution, but the gains makes that time well spent.
> 4 votes

---
Tags: 7, entities
---


# Question
Title: Which criteria should I adopt when deciding to implement hook_xmlrpc() or supporting the Services module?
If I should decide between implementing `hook_xmlrpc()` and supporting the Services module, what should I consider on taking this decision?

# Answer
> 4 votes
Consider carefully your

* audience
* goals
* time
* alternatives

Is your audience going to know how to make calls to your implementation in hook\_xmlrpc? Many developers today are familiar with using RESTful services, but I would argue the number working with xml-rpc services is dwindling. Is your audience willing to install the services module to use your functionality, or would they more likely want a solution that is already available in core?

Is your goal to do something simple, such as interface with Drupal's blog system? If so, then hook\_xmlrpc may be a better approach. Is your goal to create a fully featured web service for integration with external apps? Then, you may be better off using the services module.

Do you have the time to learn setup and learn the Services module? This could take more time than using a simple hook\_xmlrpc, but it could also save you much time in the long run.

Have you considered the alternatives such as Rest Server?

---
Tags: services
---


# Question
Title: How to retroactively apply Mollom spam filtering?
I've been asked to clean up a site that's been running for a few years, and has accumulated some spam in addition to a lot of valid content.

I've just installed Mollom on the site to help reduce future spam postings; but is there some way I can have Mollom process what's already been posted to the site, and flag potentially-spammy content for my review (rather than having to review **all** of the mostly-valid content individually)?

# Answer
> 3 votes
Not currently. See http://drupal.org/node/734476 for the feature request in the Mollom issue queue.

---
Tags: 7, advertising
---


title: Invoke Mollom CAPTCHA directly

text:
# Question
Title: Invoke Mollom CAPTCHA directly
I have a custom form within CTools form wizard that I would like to use Mollom on. Is there an API function I can use to place it in the Form API on that page?

# Answer
I'd suggest you simply integrate with mollom to expose your form.

You just need to implement two simple hooks and you can also configure if it should be CAPTCHA only or analyse some fields.

Hook documentation:

As an example implementation, you can have a look at my patch against Privatemsg: http://drupal.org/node/720038#comment-3501758 or have a look at these: http://drupalcontrib.org/api/search/7/\_mollom\_form\_.
> 6 votes

---
Tags: 7, advertising
---


# Question
Title: What is the difference between user_is_anonymous() and user_is_logged_in()?
What is the difference between `user_is_anonymous()` and `user_is_logged_in()`?

It not clear to me when a module should use one instead of the other one.

# Answer
The functions are essentially opposites.

The only real difference is the user\_is\_anonymous() function has an additional check for $GLOBALS\['menu\_admin'\] to allow menu admins to be able to administer menu links that are visible to anonymous users only.

It's used by drupal\_valid\_path() as well as the menu\_overview\_form() function:

```
function drupal_valid_path($path, $dynamic_allowed = FALSE) {
  global $menu_admin;
  // We indicate that a menu administrator is running the menu access check.
  $menu_admin = TRUE;
  if ($path == '<front>' || url_is_external($path)) {
    $item = array('access' => TRUE);
  }
  elseif ($dynamic_allowed && preg_match('/\/\%/', $path)) {
    // Path is dynamic (ie 'user/%'), so check directly against menu_router table.
    if ($item = db_query("SELECT * FROM {menu_router} where path = :path", array(':path' => $path))->fetchAssoc()) {
      $item['link_path']  = $form_item['link_path'];
      $item['link_title'] = $form_item['link_title'];
      $item['external']   = FALSE;
      $item['options'] = '';
      _menu_link_translate($item);
    }
  }
  else {
    $item = menu_get_item($path);
  }
  $menu_admin = FALSE;
  return $item && $item['access'];
}

```
> 6 votes

---
Tags: 7
---


title: Multiple (and differents) crons?

text:
# Question
Title: Multiple (and differents) crons?
In a normal production webiste, there are many tasks that need to be done via crontab, but lets say you *dont want all of these tasks* to run on every cron.

For example, i would love to have:

1. A cron that run once a day, for the 'normal' maintenance (updates checks, for example)
2. B cron that runs every 15 minutes, to send newsletters (from simplenews)
3. C cron that run twice a day, that pull data from a view (json view) and write down a json file on the server (for a geomapping service with lots of data that doenst need a real-time sincronyzation).

Actually, i have a unique cron that do the A, B and C tasks on every run, every 15 minutes; so i created 2 php scripts that bootstrap drupal, one send the emails, and the other one cache the geomapping file.. it works, but is pretty a *manual* way that i dont like too much.

What is the best practice to set different crons, get all the modules hook\_cron, and assign them **only** to a specific cron?

# Answer
There is a module for that (tm):

http://drupal.org/project/elysia\_cron

Have a look at http://2bits.com/drupal-performance/improving-performance-drupals-cron-using-elysia-cron-module.html for more information about it.
> 13 votes

---
Tags: cron, maintenance-mode
---


title: How can I add an object to a form?

text:
# Question
Title: How can I add an object to a form?
How can I add an object to a form array to make it available to `hook_form_alter()` implementations?

I have an object I pass to a form, which may have the `new` property. I would like to implement `hook_form_alter()` in another module to add/change form items based on that property.

There is no need for the item to be available after submission. I would like to avoid the overhead of using a *value* form element.

# Answer
> 2 votes
You don't have to add the entire object to the `$form` array: You can just add the property you need to share with the `hook_form_alter()` implementations, for example with the following code.

```
$form['#mymodule_new'] = $object->new;

```

You don't have to worry about adding overhead because the values submitted in a form are transient by design, if they are not stored in the database.

As additional note, `$form['#mymodule_new']` is available to form validation and submission handlers. The array key should not be already used by other Drupal modules, including Drupal core modules, to avoid conflicts.

---
Tags: forms
---


title: Login shared between subdomains

text:
# Question
Title: Login shared between subdomains
If I should allow users to log in using the same username/password, what should I consider when choosing between the following solutions?

* Install, and use Bakery Single Sign-On System on the main site, and all the subdomains.
* Share the database table containing the user data.

# Answer
> 5 votes
**`Bakery` decouples the multisites** — if you're sharing a table, you must use exactly the same Drupal version on all sites in the multisite configuration, and update them in lockstep. With `Bakery`, the Master and Slaves can be running different Drupal versions. Additionally, any modules that modify the `users` table on the Master site would need to be applied to the Slave sites with corresponding settings.

**`Bakery` improves scalability** — user accounts are not created on slave sites until they are needed, conserving server computational and data storage resources.

**`Bakery` synchronizes sessions** — for example, if the user logs out of one Bakery site, the user will be logged out of all Bakery sites in that group. (To achieve equivalent behavior with shared tables, you'd also need to share the `sessions` table, which would further complicate maintenance.)

# Answer
> 2 votes
If your only concern is sharing username and password you might want to consider OpenID, especially since support is in Drupal core.

If that doesn't seem like something your users could manage then I'd consider the Janrain module it would allow your users to sign in with a whole host of accounts they probably already have, like Facebook, Twitter and Google.

It's worth pointing out that this is the method used by StackExchange.

---
Tags: 7, authentication-authorization
---


# Question
Title: Alternatives of using user_load_multiple()
Considering that the parameter `$conditions` of the function user\_load\_multiple() has been declared deprecated, if I would keep the code compatible with Drupal 8 code, which Drupal function should I alternatively use?

# Answer
> 2 votes
Use the `EntityFieldQuery` class. It allows to set the query conditions using its methods. The example code in How to use EntityFieldQuery for Drupal 7 show how a module can build a query for an entity.

```
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'article')
  ->propertyCondition('status', NODE_PUBLISHED)
  ->fieldCondition('field_news_types', 'value', 'spotlight', '=')
  // See the comment about != NULL above.
  ->fieldCondition('field_photo', 'fid', 'NULL', '!=')
  ->fieldCondition('field_faculty_tag', 'tid', $value)
  ->fieldCondition('field_news_publishdate', 'value', db_like($year) . '%', 'like') // Equal to "starts with"
  ->fieldCondition('field_news_subtitle', 'value', '%' . db_like($year) . '%', 'like') // Equal to "contains"
  ->fieldOrderBy('field_photo', 'fid', 'DESC')
  ->range(0, 10)
  // Run the query as user 1.
  ->addMetaData('account', user_load(1));

$result = $query->execute();
if (isset($result['node'])) {
  $news_items_nids = array_keys($result['node']);
  $news_items = entity_load('node', $news_items_nids);
}

```

---
Tags: 7
---


# Question
Title: Programmatically impersonating another user without causing the currently logged-in user to log out
How should a module change the value of the global `$user`, execute its own code, and restore the original value of `$user` without causing the current user to be logged out if an error happens?

# Answer
> 19 votes
The drupal\_cron\_run() function gives a perfect example for exactly this, since it changes the current user to anonymous whenever cron is run, then switches back after it is done.

```
// Prevent session information from being saved while doing funky stuff.
$original_session_state = drupal_save_session();
drupal_save_session(FALSE);

// Force the current user to anonymous to ensure consistent permissions on
// funky stuff runs.
$original_user = $GLOBALS['user'];
$GLOBALS['user'] = drupal_anonymous_user(); // Or use user_load() for a non-anonymous user.

// Do funky stuff here...

// Restore the user.
$GLOBALS['user'] = $original_user;
drupal_save_session($original_session_state);

```

---
Tags: 7, users
---


# Question
Title: Is hook_translated_menu_link_alter() thought to be used only on translated menu links?
Could `hook_translated_menu_link_alter()` be implemented to simply alter a menu link before it is rendered?

Clearly, `hook_translated_menu_link()` is only invoked for menu items that have been flagged from `hook_menu_link_alter()` as altered; if a module uses `hook_translated_menu_link()` to alter a menu item before it is rendered, it needs to implement `hook_menu_link_alter()` too.

# Answer
> 3 votes
Take a look at Devel, it uses `hook_translated_menu_link()` along with `hook_menu_link_alter()` to add a destination query to the end of a few of the links.

http://drupalcode.org/project/devel.git/blob/0ca6cc9bd5e2cf650717b73e8938b88726d0ebbd:/devel.module

* Line #331 - devel\_menu\_link\_alter()
* Line #342 - devel\_translated\_menu\_link\_alter()

---
Tags: routes, hooks
---


# Question
Title: What is the best way to keep your site code in git and pull in core and contrib in the same repository?
Back when drupal was in CVS I had my sites in a git repository and then pulled in core and contrib via CVS. The two systems happily co-existed and I could track changes to everything and make patches to contrib modules. Now with git I am unsure whether to just download contrib and core and check it into my site's git repository, or maybe use submodules?

I am wondering if there are any best practices on this yet? I am particularly puzzled about how to have core as a submodule if my repo uses drupals root directory as its own root?

# Answer
> 6 votes
Not exactly the same question as https://drupal.stackexchange.com/questions/260/deploying-drupal-with-git but I have the same answer for you.

http://freso.dk/en/2011/02/26/managing\_fresodk\_from\_cvs\_in\_svn\_to\_git

I think it can be useful to have Drupal Core as a real check out, makes it for example easier to track hacks. Because sometimes, there simply is no other way, be it changes to .htaccess or maybe you applied some patches for bugs which affect you directly.

# Answer
> 3 votes
As you shouldn't be hacking core, reverse your thinking: instead of making core a submodule of your site, make your custom code a submodule of core. Once you clone the core repository, you can do whatever you want to it, including adding your own submodules to it.

Alternatively, consider not using the core git repository for your site and update to the latest release using other functions, like drush. This way, you'd only have to submodule contrib modules. Unless you're contributing to core or doing bleeding edge things that depend on bug fixes that haven't made it into a release yet, the utility of getting all commits via VCS is minimal.

---
Tags: version-control
---


# Question
Title: Is it possible to assign permissions that apply to specif users from independently from their roles?
Using a custom module, is it possible to assign permissions to specific users independently from the assigned roles (which means, without to create temporary roles to which users are assigned), or is it preferable not doing so?

# Answer
Once again, there is a module that allows to do that:

http://drupal.org/project/user\_permissions

I however agree that this doesn't sound like a good idea. Not because of Performance but because of the Maintainability of your site.

Maybe in a situation where you want to give users some permissions dynamically based on an action they just did but unless you have 30 different possible combinations, I'd suggest to create some roles and then assign these dynamically. One example of a module that does this is userpoints\_roles from the Userpoints Contrib project, that assigns roles to users once they reach a certain amount of points.
> 3 votes

# Answer
I believe user-based permissions (as opposed to roles-based permissions) to be bad (security) practice. They tend to don't scale very well when the users base grow. With the multiplication of users, permissions management becomes harder and error prone. Roles based permissions doesn't add too much management overhead and scale much better.

That said, the Drupal permissions control is roles-based. I'm not aware of any module allowing it to becomes users-based. A *naive* solution would be to (automatically) create a role for each user. If you have only a few users, this shouldn't be a performance issue.
> 3 votes

# Answer
The right way of doing this is by the using Node Access. Node Access isn't easy to grasp, however start with the 2010 node access conference session

However it is probably better to design the roles properly and coherently.
> 1 votes

---
Tags: 7, authentication-authorization
---


# Question
Title: How to automatically highlight syntax of code displayed on page?
I'm developing a website to publish my codes from different programing languages. I want to highlight syntax of codes with different colors. But, doing it manually is time consuming. Is there any module or method which could do this automatically? Strictly, it should be done in CSS way.

# Answer
> 9 votes
There are several options to highlight code.

From the modules available on d.o. -- GeSHi Filter and Syntax highlighter

A very recent module (yet to make it to Drupal.org) is Wiredcraft's highlight\_js on GitHub. They provide a Drupal 7 only version, but (\*shameless plug\*) I've ported it to Drupal 6 -- https://github.com/ThinkFabrik/highlight\_js/tree/6.x-1.0

Edit: depending on the module you may either have to create a new input filter or use Full HTML to get best results

# Answer
> 1 votes
With the code filter module filter you can enclose php code in `<?php` and `?>` to highlight it. But this only works for php code. Other code can be enclosed in `<code>`tags, but the result is not syntax highlighted.
*(edited to reflect Berdir's comment)*

---
Tags: 7, nodes, input-formats
---


title: Gmap Views Module - Popups are too big

text:
# Question
Title: Gmap Views Module - Popups are too big
I'm using GMAP module and its views counterpart. The issue I'm having is that I'm using a custom text field to display fields wrapped in HTML that I have pulled in from the query. However, the popup won't size correctly; it ends up being too big. This is my code for Custom Text Field:

```
<div id="col1">
  [field_thtr_img_fid]
</div>
<div id="col2">
  <h5>[title]</h5>
  [address_1]
</div>

```

Any help would be greatly appreciated.

# Answer
> 3 votes
looking at the details from https://stackoverflow.com/questions/5186047/drupal-gmap-views-popups-are-too-big I would suggest to wrap everything in the custom text field in a div with a specific class then do .myclass { width: DESIRED\_WIDTH; } in your stylesheet.

or try to `div.gmnoprint .views-field-nothing { width: DESIRED_WIDTH; }` where `div.gmnoprint` is the wrapper div for the gmap popup and `.views-field-nothing` is the default wrapper for a custom text field in views.

Without a live example, it is harder to give an exact answer. I suspect you may have to add `overflow:hidden;` to your wrapper div if you have any floating going on there.

---
Tags: 7, views, google-maps
---


# Question
Title: What can cause a site to hang when deleting a user?
When I try to delete users the whole site hangs, i.e. Drupal does not respond anymore. What can cause that?

The site does not have any special user profile modules installed.

**Edit:**
There is only one custom (self made) module with a hook\_user which switches on `$op`. The 'delete' case looks unsuspicious:

```
case 'delete':
    $sql = "DELETE FROM {mynewsletter_users} WHERE uid = %d";
    db_query($sql, $account->uid);
    break;

```

Doesn't look bad to me. Should not invoke a hook\_user-circle.

**Edit:**
The problem is gone all by itself. No idea what happened.

# Answer
For me, this has happened when there is a misconfiguration on `hook_user` in a custom module. Specifically, check all of your implementations of `hook_user` to make sure there are no functions that lead to additional calls for `hook_user`.

That is, if you have a module that calls `foo_do_magic_to_user()` under `hook_user` (or, some other function that hits `hook_user`), and `foo_do_magic_to_user()` calls `user_save()`, then you have an infinite loop on your hands.

**Update**

If you're absolutely certain that it's not a `hook_user` loop, then there could be any number of module-associated hangups. These often involve external services that are non-responsive (e.g. sending a "Goodbye" email but sendmail (or equivalent) isn' set up properly).

In your shoes, I would try:

1) Disable all non-core modules and see if the problem persists. If this still happens with only core modules, then you might have a deeper and more fundamental issue (correct version of PHP?)

2) If not #1, then re-enable contrib modules one-by-one and see which one is causing the issue. Inspecting that module's hook\_user should give you a good clue as to what the root issue is. Most likely, one of the modules is calling some other service that is non-responsive.
> 4 votes

# Answer
The very first thing I'd do is to set up a local VM with a replica of the live server for local testing. Ideally this would be a copy made with `dd` or similar.

See if anything is implementing `hook_user`. For D5-D6 sites I use a recursive grep (using ack) from the site root to locate these. Remove this code and see if the site still hangs.

Use the MySQL Slow Query Log to see if it has any hints. Use ps and top to see what's actually happening on the web server.

I don't think that D5 has locking (D6 has lock\_acquire in lock.inc)

It would also help if you could explain how you manage to recover the server once it's /locked/.
> 2 votes

---
Tags: users, 7
---


title: Core forum form dropdown empty

text:
# Question
Title: Core forum form dropdown empty
In a D6 site, when a user goes to node/add/forum, they find that the dropdown "Forums" just shows "Please choose" but there is nothing in that menu.

There is nothing in the PHP error log or in the watchdog.

I am sure the user has correct privileges - after all, the form does show. It's just that the dropdown that otherwise (for admin) shows all the different forums on the site, is empty, and the form cannot be submitted without it.

I've seen pretty much all the web searching for a solution, without success. Hope there's somebody in this new slick interface who will show me the right answer or direction.

# Answer
> 2 votes
Right, so I tried all sorts of illogical things, one of which was deactivating and uninstalling Forum Access module (http://drupal.org/project/forum\_access).

I did not have to - because the form was accessible - but I did anyway, out of desperation.

Then I enabled it again. Set all permissions again.

And things work!

BUT this is not a proper solution. Something in Forum Access was screwed up badly and ideally this issue should've been solved at its root, not by a workaround like mine.

# Answer
> 1 votes
Since you report that Forum Access is also installed, did you check that the logged in user was allowed to add a post in at least one of the forum defined for the website?
As the module purpose is to control which users are allowed to view, edit, and update each forum, that could be the cause of the drop down list not being populated.

In fact, the following hook is the responsible of changing the values contained on the select form field that allows to select to which forum a forum post is associated with:

```
/**
 * Implementation of hook_form_alter().
 *
 * Alter the node/comment create/edit forms and various admin forms.
 */
function forum_access_form_alter(&$form, &$form_state, $form_id) {
  //dpm($form, "form_id($form_id)");
  if (isset($form['type']['#value']) && $form['type']['#value'] .'_node_form' == $form_id) {
    module_load_include('node.inc', 'forum_access');
    _forum_access_node_form($form, $form_state);
  }
  // …
}

/**
 * Rewrite the taxonomy item on the node form.
 */
function _forum_access_node_form(&$form, &$form_state) {
  global $user;
  $vid = _forum_access_get_vid();

  if (!isset($form['taxonomy'][$vid]['#options'])) {
    return;
  }

  // True node administrators are all powerful and do NOT get their forms rewritten here.
  if (user_access('administer nodes') && empty($user->_forum_access_moderator)) {
    return;
  }

  $roles = array_keys($user->roles);
  $result = db_query("SELECT tid FROM {forum_access} WHERE rid IN (". db_placeholders($roles) .") AND grant_create = 1", $roles);
  while ($obj = db_fetch_object($result)) {
    $tids[$obj->tid] = $obj->tid;
  }

  // Also get all forums they happen to be able to moderate.
  $result = db_query("SELECT a.number AS tid FROM {acl} a INNER JOIN {acl_user} u ON a.acl_id = u.acl_id WHERE a.module = 'forum_access' AND u.uid = %d", $user->uid);
  while ($obj = db_fetch_object($result)) {
    $tids[$obj->tid] = $obj->tid;
  }

  // Ensure the forum they're trying to post to directly is allowed, otherwise
  // there will be much confusion.
  $forum_tid = arg(3);
  if (isset($forum_tid) && is_numeric($forum_tid) && !isset($tids[$forum_tid])) {
    drupal_access_denied();
    module_invoke_all('exit');
    exit;
  }

```

---
Tags: 6, routes, users, nodes
---


# Question
Title: Custom SQL: nodereference joins and latest VID
I'm having a heck of a time constructing a custom SQL query. **The query has multiple nodereferences and needs to return the latest node revision.** I understand joins pretty well, but for some reason the added complexity of returning the latest revision is tripping me up.

I would prefer to go this route over creating views and executing them programmatically, just because of the complexity of the `WHERE` clauses.

I've tried translating the output of an equivalent View, but the prefixing that Views tacks on is making it a huge chore to comprehend. My instinct is that it shouldn't need that many joins either.

**Would love to see a generic structure that people might start with**, or for conversation's sake here's a massively simplified version of what I'm working with. This version is in a bit of flux, I think I have the latest revision covered but now person1Name, person2Name aren't returning anything.

```
SELECT event.nid AS eventnid,
       event.field_event_date_value AS date,

       event.field_event_person1_nid AS person1Nid,
       person1.field_person_name_value AS person1Name,

       event.field_event_person2_nid AS person2Nid,
       person2.field_person_name_value AS person2Name,
FROM {node} n

LEFT JOIN {content_type_event} event
    ON n.vid = event.vid

LEFT JOIN {node} refevent
    ON event.vid = refevent.nid

LEFT JOIN {content_type_person} person1
    ON refevent.vid = person1.nid

LEFT JOIN {content_type_person} person2
    ON refevent.vid = person2.nid

```

# Answer
> 0 votes
```
LEFT JOIN {node} refevent
    ON event.vid = refevent.nid

LEFT JOIN {content_type_person} person1
    ON refevent.vid = person1.nid

LEFT JOIN {content_type_person} person2
    ON refevent.vid = person2.nid

```

This looks wrong. Instead, you probably want to use event.field\_event\_person1\_nid and 2 instead of refevent.vid. The additional join of node shouldn't be necessary, you already have node as the main table.

The query still returns something because you are using LEFT JOIN. Since I assume that these fields are required and/or you only want those which are filled, you should just use JOIN. LEFT JOIN means that the main table is returned even if there is no matching row in the joined table.

The same is true for the content\_type\_event table. No need for a LEFT JOIN. That is just what views does by default unless you specify that the relationship is required.

---
Tags: 7, views, database
---


title: Programmatically insert webform result

text:
# Question
Title: Programmatically insert webform result
I'm using drupal 6 with the webform module installed.

I need to be able to remotely POST, from PHP results to a webform. Pseudocode:

```
<?php
//File: remote_script_not_hosted_on_the_same_server_as_drupal.php

$results = array(
'name' => 'testname',
'age' => '6',
);

$node = 5;

$url_to_drupal = 'http://remote_server.com/drupal-6.2';

insert_into_webform($results, $node, $url_to_drupal);

```

Of course, this example isn't perfect, but you (hopefully) get the idea.

How would you go about doing this?

I've opened an issue on the drupal queue: http://drupal.org/node/1082016

I'm concerned about these two fields invalidating my remote submission:

```
------WebKitFormBoundaryKIiNRZCPZIFlYWKc
Content-Disposition: form-data; name="form_build_id"

form-58f36748bfffd6752f204eadf1ba87c9
------WebKitFormBoundaryKIiNRZCPZIFlYWKc
Content-Disposition: form-data; name="form_token"

e4becb726ea858b6914980b9142b7f30

```

# Answer
Have you tried using PHP to manually send the POST data? Here is a snippet from http://www.webmasterworld.com/php/3164561.htm

```
$server= 'www.someserver.com';
$url = '/path/to/webform/posturl';
$content = 'name1=value1&name2=value2';
$content_length = strlen($content);
$headers= "POST $url HTTP/1.0\r\nContent-type: text/html\r\nHost: $server\r\nContent-length: $content_length\r\n\r\n";
$fp = fsockopen($server, $port, $errno, $errstr);
if (!$fp) {
    return false;
}
fputs($fp, $headers);
fputs($fp, $content);
$ret = "";
while (!feof($fp)) {
    $ret .= fgets($fp, 1024);
}
fclose($fp);
print $ret;

```

Of course this would fail if you are using any form of captcha on the form, and will also currently fail if you are required to be authenticated to post a reponse
> 1 votes

---
Tags: 6
---


# Question
Title: When should the "container" form element be used?
The System module defines the *container* form element, but that form element is not documented in the Form API Reference.

When should that form element be used?

# Answer
It looks like it can be used when you want to wrap a part of the form in a div, for example to be able to add some classes to it.

Some examples from core are the following:

* field\_default\_form()

```
// Also aid in theming of field widgets by rendering a classified container.
$addition[$field_name] = array(
  '#type' => 'container',
  '#attributes' => array(
    'class' => array(
     'field-type-' . drupal_html_class($field['type']),
     'field-name-' . drupal_html_class($field_name),
     'field-widget-' . drupal_html_class($instance['widget']['type']),
    ),
  ),
  '#weight' => $instance['widget']['weight'],
);

```
* node\_filter\_form()

```
$form['filters']['status'] = array(
  '#type' => 'container',
  '#attributes' => array('class' => array('clearfix')),
  '#prefix' => ($i ? '<div class="additional-filters">' . t('and where') . '</div>' : ''),
);
$form['filters']['status']['filters'] = array(
  '#type' => 'container',
  '#attributes' => array('class' => array('filters')),
);

```
* search\_form()

```
$form['basic'] = array(
  '#type' => 'container',
  '#attributes' => array('class' => array('container-inline')),
);

```

Forms in Drupal 6 often used `#prefix` and `#suffix` on the first/last element to do this; this is a lot better because it is easier to add additional items or move them around.

I could use this in a few places in my own contributed modules, actually. ;)
> 8 votes

# Answer
In D6, there were often times when you would need to add a `<div>` around a FAPI element (for example with `#ahah` / `#ajax`), so `container` is a more consistent solution in regards to the Forms API to this common pattern than adding a wrapper div using `#prefix`/`#suffix`.
> 0 votes

---
Tags: forms
---


title: Would cache in files be an alternative?

text:
# Question
Title: Would cache in files be an alternative?
Once I worked in a company that had its own CMS and we used to cache data in files so basically the system would check if the cache file existed, if not it would go to the database, get the data, save it in a file and then show it to the users (basic cache thing). This resulted in less connections to the database.

I would like to know if this is a good option to Drupal or if there is any problems with this way of caching things.

# Answer
> 14 votes
As anschauung mentioned you can use Boost to create a static page cache. Boost will copy the entire HTML of a page and store that HTML as a static file on the disk in a specific directory. A set of rewrite rules will cause the webserver to first look for a static HTML file for each request and serve that file if it's found. If it isn't, a normal Drupal request occurs via PHP. Requests served through the static file will be really fast, but PHP and the database are **completely** bypassed.

Boost is not a replacement for the cache backend and that Drupal will still use the cache tables in the database when a miss occurs on the static HTML files created by Boost. If you want to completely replace the cache backend, you could look into memcache, which stores serialized objects in memory. Memcached runs as a daemon on the server and can be connected to via TCP. This can be both a good and bad thing, depending on number of servers in the environment and

Note that it is possible to have the database keep the cache tables in memory as well (at least with MySQL), although I'm not sure about the specifics of doing so.

You could all use the APC module if you're running Drupal 7. The APC modules integrates with the APC opcode cache and uses it as Drupal's cache backend. APC can be faster than memcached in certain scenarios because there is no TCP connection overhead. Each APC cache is tied to a specific server, while memcached and the database can be shared by multiple front end servers (again, this can be good or bad).

# Answer
> 7 votes
In fact, the `Boost` module does exactly what you're describing -- it creates file caches of pages and re-checks the database if a particular file doesn't exist.

Give it a look :)

# Answer
> 2 votes
While the Boost module accomplishes the same method, there are many alternatives that may perform even better, such as the Drupal page cache (which caches the whole page into a single database record), memcache, or even Varnish.

---
Tags: caching
---


# Question
Title: How can I have non-exact locations on a map?
I'm using GMap to help users find other people in their area. But I'd like to let users have some privacy only making their city and zip code available in the map, but still have the full address in the database for mailing purposes. How can I do this? The position of the pin on the map should also be only based on city and zip, as obviously it could be pretty precise as to location.

For example, let's say the president registers on our site. He enters his full address, 1600 Pennsylvania Ave NW, Washington D.C., DC 20500. An administrator can now look that up and mail him our newsletter.

Another user in the D.C. area is looking for people to meet up with. They look and see a pin on the map for a user POTUS. The click on the pin and it only displays a partial address, Washington D.C., DC 20500. And the pin's location isn't exact, so the user can't tell from its placement the exact address of POTUS. But it is enough that the user knows they are nearby, so they send a user to user message to get in touch.

Any solutions for non-exact pin locations would be fine. If it was slightly randomized. Or perhaps all pins in a zip-code are grouped into one with a link for "# users in the 20500 area" which takes the user to a full list.

If this can be done with something other than GMap, that is fine.

# Answer
I had a similar problem, and this is how I solved it:

1. Add another 'location' field to you content type; call it, e.g., 'public user location'.
2. Build up your custom module, and in the `hook_form_alter()` implementation, hide the new location field, so the user cant edit it.
3. Now you need to get the 'non-exact' location for the first location; I do this with a Google geocode.

It's up to you to do it via JavaScript when the first location is set (the way im doing it), or to do the geolocation when the form is submitted to 'manually' add the 'non-exact' location.

If you use a geocode on the partial address, Google Geocode will give you the coordinates in the middle of the area you searched.

Please note that, for more specific geocoding, you could even use the Geonames API.

If you choose the second way (create the 'non-exact' location when the form is submitted), maybe this can help you about the location creation: Creating nodes programmatically in Drupal (including cck and location fields).

As side note, I am not using the Gmap module anymore because my needs were a bit complex and were not fit by this module; if you'll find some trouble, I recommend you building your own small module using Google API v3.

This will let you, for example, show the 'public location' in the map with a circle around, as Google Latitude does.
> 6 votes

# Answer
That pin on the map is going to be the center (usually geometric center) of the zip code (with a few exceptions, such as a zip code that only refers to a single building).

> *Or perhaps all pins in a zip-code are grouped into one with a link for "# users in the 20500 area" which takes the user to a full list.*

This is a better solution than putting 20 pins all on top of each other at the center of 20500 zip code.
> 1 votes

---
Tags: 7, google-maps
---


# Question
Title: How can I provide a filter with context/nid of node invoking?
I'm currently working on a custom module that has a filter that requires the node object for the output.

Originally the filter was simply pulling in the NID from arg(1) and using that to load in the node object, but unfortunately if the filter cache is flushed and the nodes rebuild their output from anywhere other than the node page itself arg(1) will not contain the NID and therefore the filter will break.

I'm considering putting the NID into the token that the filter converts, but obviously the NID would not be known during the creation of a node. It wouldn't be overly difficult to alter the token via `hook_nodeapi()` to insert the NID, but it seems like a lot of hastle.

Is there a simpler way to provide a filter with some sort of context so it can be aware of which node invoked it?

# Answer
> 3 votes
Filters are not context-aware and AFAIK, there is no way at the moment to do what you want. This has been a feature request since 2008, but the proposed patch didn't make it into Drupal 7.

If this is very important to the site you're building, you can consider patching Drupal core. However, once Drupal core is patched, you will need to take extra care (and time) when updating your site.

# Answer
> 0 votes
Filter modules are invoked also for comments, but none of the arguments passed to the filter allows it to understand when it is invoked to alter a node content, or a comment.

You can implement `hook_nodeapi()` to change the content of a node when it is being assembled before rendering; check the value of `$op` is `"view"`.
This is actually what a third-party module that alters the content of a node basing on the content of some node fields does.

If the string the module is replacing can be entered by the users who edit the node (and the users needs to know this possibility), you also need to alter, for example, the description given for the node body field in the edit form to include a description of the "tokens" the module is replacing.

---
Tags: 7, hooks, input-formats
---


# Question
Title: How do I go about putting standalone PHP files?
I want to add an extra cool PHP Class, where would I put it in Drupal, how do I make absolutely sure the code doesn't present a security risk, should I just make it into a module?

# Answer
Your best bet would be to include it via a custom module, and to include it would be as easy as using module\_load\_include().

As for security, I would advise taking a look at the Drupal coding standards documentation, which is unfortunately tagged as D7 and I wasn't able to find the old D6 version, but generally following standards will help prevent some security issues.

Code not written exclusively for Drupal may not specifically work out of the box either, you may have to write a bridge for the code to integrate it better, otherwise you may need to re-write it completely.
> 4 votes

# Answer
There are two questions being asked, here:

* Should I make the PHP class a module?
* How can I be sure it doesn't contain security issues?

If you are distributing your own PHP class, or you are providing the class to your own customers, making the class part of a module is what I would do it. If the class is part of a module, then it's easier for third-party modules (or even for another module that you developed as part of the custom code you provide to a client) to verify if the class is available; it also make possible to avoid other modules use that PHP class without the need to delete the file, if the other modules check if the module is available instead of checking if the class is available (which means to use `module_exists()`).
With Drupal 7 is even easier create an object of a class defined from third-party modules; the module doesn't even need to first load the file containing the class, if the module containing such file lists it in the *.info* file, using the directive `files[]`: that operation is automatically done from Drupal, through the registry it implements.

Putting code into a module doesn't automatically make it secure; to create secure code you need to follow what reported in Writing secure code. Following the Drupal coding standards allows you to code that can be easier understood from other users (which means they can easier find security issues or other problems present in your code), or code that doesn't create conflicts with the existing modules; the coding standards don't report how to write secure code, except in some particular spots, like when they suggest how to avoid SQL injections.

To notice that the coding standards have not been updated for Drupal 7; in fact, the part about using SQL placeholders is still referring to Drupal 6 code.
> 1 votes

# Answer
Yes, you can do that easily by creating a custom module and then place the class inside that. You likely need some glue code anyway to connect the functionality of that class with Drupal, for example with hooks.

You do have to be aware of a few things:

* Drupal is GPL. All code that is called directly by Drupal (in contrast to an XML-RPC or REST Service) must be GPL or GPL compatible. If you keep that class for yourself, it's not that big of a problem (Still a license vioalation but nobody can verify it ;)) but if you want to distribute it, then it gets important.
* If you plan to release that module on d.o, you must not include that class yourself and instead instruct users to download it themself, *even* if the class is GPL compatible. See http://drupal.org/project/libraries
> 0 votes

---
Tags: 6, security
---


# Question
Title: Allowing third-party modules to alter the query executed by a module
I am developing a module that exposes a public API, which includes functions to save data in his own database table, which is supposed to be used from any module that uses my module.

The module checks the content of the database to verify if a user is not allowed to access the site, or if users should be notified with an error message when they change something in their user profiles.
Considering that in most of the cases, the database table is the only table to check, should I change the code to allow third-party modules to alter the query being executed from my module through `hook_query_TAG_alter()` (or the more generic `hook_query_alter()`), or use a custom hook that other modules need to implement?

# Answer
> 1 votes
I'm not sure why `hook_query_alter()` even exists; it did not in the beginning. I don't think that hook makes much sense and I can't think of a use case where you want to alter *every* query.

If you expect that other modules want to extend your query, then use `addTag('yourmodule_tag')` so that it is possible to alter it. As you already said, this only covers cases where the same existing query should be changed. It might be possible to do other checks and then add a condition that can never be true (like `1 = 0`) on the query, but that sounds hacky to me.

You can also define your own hook if you think that there could be more complex checks that other modules want to do. You probably want to re-use the `hook_node_access()` pattern with three possible return values (*ignore*, *allow*, *deny*) (See `node_access()`.)

You can do either, or both of, these two things. Hook calls are rather fast in Drupal 7 because the hook implementations are cached and don't need to re-checked every time the hook is invoked.

---
Tags: 7, hooks
---


# Question
Title: How to denote a user as a "system account"?
In the Unix world, there are "user accounts" for humans to use, and there are "system accounts" for software to use.

On a Drupal site, I have a couple of *system accounts* intended for use by `services.module` API calls.

I'd like these accounts to be able to log in via the services API (obviously), but I would like to block these accounts from being used to log in via the standard `user_login` form. I'd also like to prevent these accounts from showing up in standard "active user" lists, such as the "Who's online" block.

How should I approach this?

# Answer
> 4 votes
Have you had a look at using the API key authentication? This will enable you to login effectively without using a username + password combo.

See http://drupal.org/node/762092 for more information

# Answer
> 1 votes
I will reply referring to what the Project issue tracking module does.

The *Project issue tracking* module changes the status of the issue reports that have been marked as fixed for two weeks to "closed (fixed)"; while doing that, it adds a comment that result posted by the "System Message" user (the module has a setting that allows to change that user to any other existing user), as it is visible in this comment.

To create such comments, the module uses the function `user_load()` (see the function \_project\_issue\_followup\_get\_user()), changes the content of the global variable `$user`, does its task, and then changes back the value of the global variable. The full operation is started during the CRON tasks (see the \_project\_issue\_cron() function, which invokes `project_issue_auto_close()`, which invokes project\_issue\_add\_auto\_followup(), which invokes `project_issue_add_followup()`).

In any of these operations, the "System Message" user appears in the list of the users who recently logged in, or in the list of the online users.
It doesn't appear in the "Who's online" block because the hook that outputs that block (user\_block()) uses `SELECT uid, name FROM {users} WHERE status != 0 AND access != 0 ORDER BY created DESC` as SQL query to get the list of online user; as the "System Message" user is never used from a real user to log in, the `access` field always contain `0`. If there would be a module that changes that database field to something different, it is enough to set it to 0 to avoid such system users are listed as online users.

If those user accounts you created to be used by a module have a password that is difficult to discover, the fact somebody could use those user accounts to log in should not be a problem if the password is only known by you. If somebody else knows the password (or somebody is able to change the password associated with the user account), and you want to avoid they use one of the system accounts to log in (considering the user accounts could have permissions that are not assigned to other users as it happens on Drupal.org, which uses some "system users" for some purposes), then you can implement `hook_form_user_login()` to add a form validation handler to the form created by user\_login(), adding the code that verifies if the username passed through the form is one associated with one of the user accounts you don't want to be used to log in.

To notice that it is not necessary to pass any password to `user_load()`; the password is only passed to the function when a user is logging in, and Drupal needs to verify that the user entered the correct password. The suggestion of thsutton to modify the content of the password field with something that is not a MD5 checksum (i.e. a string that doesn't have 32 characters, or that contains characters not present in a MD5 checksum) is valid, if you never use the "system user" to log in.
If you use the user to log in, then the user will appear in the list of the recently logged in users; if you want to avoid this, you need to reset the access field to 0.

---
Tags: 7, users, services
---


# Question
Title: How might I create a "step-by-step process" content type?
I'm thinking about creating a process manual for an intranet. Most (all?) of the processes have a very clear order, although the actual order may change from time to time. The plan is to have the subject matter experts, probably a half-dozen or so, enter and update the process pages. The users of the site need to be able to quickly review the processes while interacting with customers, often face-to-face.

Here's the options I've thought of:

* **Train the authors to use ordered lists.** Pro: easiest for me. Con: relies on training non-technical people, could be hard to style for readability.
* **Organize each process into a book.** Pro: uses something that's already there. Con: harder to enter, complicated to read.
* **Create a content type with a "step" field** that could be entered unlimited times, and theme so as to show the order number. Pro: easy to see that each step is independent, can be reordered easily (?) Con: more work for me (I feel like there something else in this option that I'm missing, but I can't put my finger on it!)
* **Custom module**, something like the Recipe module but w/out ingredients. At least I'm assuming the Recipe module has step-by-step directions. Pro: most customization for entry, learning experience. Con: a LOT more work for me, kinda out of my expertise.

From your experience, is there a clear winner among these options?

Is there an option I'm missing? (is there a module out there that already does this, for example? Googling this concept was a *nightmare*.)

Am I over-thinking this?

*I don't know yet whether this project will be Drupal 6 or 7.*

# Answer
I agree with Craig Hyatt but I thought I'd expand a bit more.

**Train the authors to use ordered lists** \- Like you said it's more effort for you to train users. Your times better spent developing the final product in my opinion.

**Organize each process into a book** \- Why re-invent the wheel? It provides you with the basics of your requirements out of the box. Using this will give you the extra time spent developing something to work on the cons of using this, or better put you get to spend more time adding helpful stuff than building it from the ground up.

**Create a content type with a "step" field** \- You mention that this could be more work for you but it's not a huge amount, using CCK and nodereference this could give you a bit more flexibility compared to the book route.

**Custom module** \- There's no need to do this, the above two points will give you enough freedom to code around drupals inbuilt options.

The clear winner for me would be to create a content type and build around that. You can actually set up a content type to use book functionality as well which is what I'm currently doing for a large project. So in this case you get the best of both worlds.
> 2 votes

# Answer
I think your instinct to use the Book module was right on. Editing book pages would be no more difficult than multiple nodes via a custom content type.
> 1 votes

# Answer
Why not use a CCK field group? The node could have a title, and no body. Then the node has a bunch of CCK field groups. The group might have two fields, such as "step title" then "step instructions". Then you could add as many title/instructions combinations as you like to the same node.

This has the advantage that it's really simple to input, and everything is contained on one node. The actual display of this content would be down to you, too, so you could have all the steps on one page, or have a javascript tab-based system for showing each step, or some other combination.
> 1 votes

# Answer
I would create a content-type called Step and make each step in your processes a node. Then, you can use Views to build lists of steps however you choose.

You'll need to find a way to link the steps to the proper parent "process", perhaps with Taxonomy.

Each step gets a title, body, a weight/order field and then whatever else you need to add.

The version of Drupal you choose won't matter. You'll use CCK for 6 and Core Fields for 7.
> 0 votes

# Answer
Another option maybe to use the pagination module - this module allows you as content creators to insert breaks in the content to make it more manageable. Current methods you can use to paginate content:

1. Content is paginated by a selectable "words per page" count.
2. Content is paginated by manual breaks, inserted by the content creator.
3. Content is paginated by manual breaks, based on tags.
> 0 votes

---
Tags: 7, entities, nodes
---


# Question
Title: How to install a taxonomy system that represents records in another high-volume, non-content-node table?
Here's the scenario:

1. A writer about celebrity gossip posts a **node** (article) on a Drupal website.
2. I have a module that scans the article and automatically creates taxonomy fields based on **celebrity names** posted in the article.
3. These taxonomy "terms" are based on a firstname/lastname list of celebrities that will be high-volume and perpetually growing.
4. This list of celebrities will have various fields to render in-depth profiles of the celebrities
5. Content nodes can have multiple celebrities attached to it.
6. Celebrity nodes can be attached to multiple content nodes.

Here are my assumptions:

1. The ever-increasing volume of celebrities and their atypical field requirements make it necessary to create a table specifically for **celebrities**.
2. The taxonomy-to-node relationships are really nothing more than node\_id and celebrity\_id in a relationship table.
3. While writers can tag an article automatically with my module, they will likely need to sometimes add additional celebrities due to misspellings or scanning errors, thus the celebrity firstname and lastname will need to be a part of the tagging process.
4. Due to name changes, misspellings, etc, we don't want to use celebrity firstnames and lastnames as unique IDs

So, here are my questions:

1. Is there a module already built that renders this functionality?
2. Is there a module already built that helps create a taxonomy that can represent a relationship between a node and entities in a custom table, not just a taxonomy table?
3. Is this functionality already present in a Drupal distribution somewhere?
4. Should I create a custom module to solve this problem (i.e. I won't be re-inventing the wheel)?

# Answer
You don't specify Drupal 6 or 7. If you can, use 7. Then you can do the following

* Have your content (gossip posts), as nodes.
* Put your celebrity names as taxonomy terms
* Apply whatever fields you like directly to the taxonomy term. No need for attached nodes or custom content.

There are several auto tagging modules out there, Open Calais is free and would suit your needs. You could even just use the 'Person' results from it to only tag celebrities.

Drupal 6, did have some issues with very large taxonomies (over 100,000 terms and 2,000,000 individual tags). D7 has sorted most of these, so it is unlikely that you will have to go down the custom code route.

If you do you will not only need to sidestep the node system, but also the taxonomy system and mysql, so it is not as easy as creating a custom table.
> 2 votes

# Answer
Why not make each celebrity into a node, with their bio as a field, and then use a node reference field for the article?
> 1 votes

---
Tags: taxonomy-terms, nodes
---


# Question
Title: Easiest method for conditional fields in a form
What is the easiest way to get some javascript magic for enabling/disabling form fields based on another field's value? This sounds like something there should be an helper for somewhere, but I can't find it. I am looking for a solution that is not restricted to nodes.

# Answer
The magic is using the #ahah/#ajax property with form elements, that way you can define what should trigger the modification and what should be modified as a result, plus it integrates seamlessly with jQuery.

This is the important part from the example below:

```
'#ajax' => array(
    'event' => 'change',
    'callback' => 'myajax_ajax_callback',
    'wrapper' => 'dropdown_second_replace',
),

```

---

Here is an example that shows a form-based page with two dropdowns: the list of options in the second dropdown depend on the selection in the first dropdown.

```
<?php

/**
 * Implementation of hook_menu().
 * Registers a form-based page that you can access at "http://localhost/myajax"
 */
function myajax_menu(){
    return array(
        'myajax' => array(
            'title' => 'A page to test ajax',
            'page callback' => 'drupal_get_form',
            'page arguments' => array('myajax_page'),
            'access arguments' => array('access content'),
        )
    );
}

/**
 * A form with a dropdown whose options are dependent on a
 * choice made in a previous dropdown.
 *
 * On changing the first dropdown, the options in the second are updated.
 */
function myajax_page($form, &$form_state) {
    // Get the list of options to populate the first dropdown.
    $options_first = myajax_first_dropdown_options();

    // If we have a value for the first dropdown from $form_state['values'] we use
    // this both as the default value for the first dropdown and also as a
    // parameter to pass to the function that retrieves the options for the
    // second dropdown.
    $value_dropdown_first = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);

    $form['dropdown_first'] = array(
        '#type' => 'select',
        '#title' => 'First Dropdown',
        '#options' => $options_first,
        '#default_value' => $value_dropdown_first,

        // Bind an ajax callback to the change event (which is the default for the
        // select form type) of the first dropdown. It will replace the second
        // dropdown when rebuilt
        '#ajax' => array(
            // When 'event' occurs, Drupal will perform an ajax request in the
            // background. Usually the default value is sufficient (eg. change for
            // select elements), but valid values include any jQuery event,
            // most notably 'mousedown', 'blur', and 'submit'.
            'event' => 'change',
            'callback' => 'myajax_ajax_callback',
            'wrapper' => 'dropdown_second_replace',
        ),
    );
    $form['dropdown_second'] = array(
        '#type' => 'select',
        '#title' => 'Second Dropdown',
        // The entire enclosing div created here gets replaced when dropdown_first
        // is changed.
        '#prefix' => '<div id="dropdown_second_replace">',
        '#suffix' => '</div>',
        // when the form is rebuilt during ajax processing, the $value_dropdown_first variable
        // will now have the new value and so the options will change
        '#options' => myajax_second_dropdown_options($value_dropdown_first),
        '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
    );
    return $form;
}

/**
 * Selects just the second dropdown to be returned for re-rendering
 *
 * Since the controlling logic for populating the form is in the form builder
 * function, all we do here is select the element and return it to be updated.
 *
 * @return renderable array (the second dropdown)
 */
function myajax_ajax_callback($form, $form_state) {
    return $form['dropdown_second'];
}

/**
 * Helper function to populate the first dropdown. This would normally be
 * pulling data from the database.
 *
 * @return array of options
 */
function myajax_first_dropdown_options() {
    return array(
        'colors' => 'Names of colors',
        'cities' => 'Names of cities',
        'animals' => 'Names of animals',
    );
}

/**
 * Helper function to populate the second dropdown. This would normally be
 * pulling data from the database.
 *
 * @param key. This will determine which set of options is returned.
 *
 * @return array of options
 */
function myajax_second_dropdown_options($key = '') {
    $options = array(
        'colors' => array(
            'red' => 'Red',
            'green' => 'Green',
            'blue' => 'Blue'
        ),
        'cities' => array(
            'paris' => 'Paris, France',
            'tokyo' => 'Tokyo, Japan',
            'newyork' => 'New York, US'
        ),
        'animals' => array(
            'dog' => 'Dog',
            'cat' => 'Cat',
            'bird' => 'Bird'
        ),
    );
    if (isset($options[$key])) {
        return $options[$key];
    }
    else {
        return array();
    }
}

```
> 18 votes

# Answer
Doesn't the Conditional Fields module do just that?

*When editing a node, the controlled fields are dynamically shown and hidden with JavaScript.*
> 7 votes

# Answer
There are two different systems which you can use:

* #ahah/#ajax allows you to submit the form with AJAX and rebuild it on the server side. Useful when you actually want to add *new* form elements, typical example in D6 is upload.module. Already explained above.
* New in Drupal 7 is the #states system which allows you to do stuff like showing/hide/enable/disable form elements based on other elements. See http://www.randyfay.com/node/58 for more information about that.
> 3 votes

# Answer
The easiest method would be to write your own JavaScript and use jQuery to attach event handlers to the blur and focus events. Then when your callbacks are fired, disable / enable the fields based on your logic.
> 1 votes

---
Tags: forms, javascript
---


# Question
Title: How do you use the Drupal 7 overlay on the node/edit screens for your popups when it's already being used?
I'm writing a module that adds a button to node/edit forms. This button needs to popup a DIV/IFRAME in a light box. I notice that Drupal 7 uses the new Overlay module for administrative and node/edit pages.

So my question is as my button is on a node/edit page I need to overlay the overlay. Is there a way to access the overlay and change or z-index or do I just write my own overlay code to create a light box effect (overlaying the node/edit overlay)?

# Answer
It is possible to change the z-index used by the overlay, but I don't think it's necessary. You just use for your overlay a z-index that is higher than the one used by the Overlay module.

In the case you need to know when the overlay is output, or how it is output, you should check the code executed by overlay\_page\_alter(), which is the implementation of `hook_page_alter()` made by overlay.module.

```
function overlay_page_alter(&$page) {
  // If we are limiting rendering to a subset of page regions, deny access to
  // all other regions so that they will not be processed.
  if ($regions_to_render = overlay_get_regions_to_render()) {
    $skipped_regions = array_diff(element_children($page), $regions_to_render);
    foreach ($skipped_regions as $skipped_region) {
      $page[$skipped_region]['#access'] = FALSE;
    }
  }

  $mode = overlay_get_mode();
  if ($mode == 'child') {
    // Add the overlay wrapper before the html wrapper.
    array_unshift($page['#theme_wrappers'], 'overlay');
  }
  elseif ($mode == 'parent' && ($message = overlay_disable_message())) {
    $page['page_top']['disable_overlay'] = $message;
  }
}

```
> 2 votes

---
Tags: 7, modal-dialogs
---


# Question
Title: How do I load a library defined with hook_library() on node/edit pages?
I've defined a library of JavaScript files and CSS files required for my module to function using `hook_library()`.

How do I go about loading this library on node/edit pages?

# Answer
I would call `drupal_add_library()` in a `hook_form_alter()` implementation, like this:

```
function MODULE_form_alter(&$form, &$form_state, $form_id) {
  if (isset($form['#node_edit_form']) && $form['#node_edit_form') {
    drupal_add_library('MODULE', 'LIBRARY');
  }
}

```

This should ensure the library is loaded whenever a node form is displayed.

And using hints from Berdir to use `hook_form_BASE_FORM_ID_alter` and from kiamlaluno to use `#attached`:

```
function MYMODULE_form_node_form_alter(&$form, &$form_state) {
  $form['#attached']['library'][] = array('MODULE', 'LIBRARY');
}

```
> 6 votes

# Answer
If you are modifying, or outputting a form, you can use the #attached attribute, which is described as "allows loading of CSS, Javascript, libraries, or custom types when the form is built".
> 0 votes

---
Tags: 7, hooks, theming
---


# Question
Title: Node form redirect based on submit button value
I've read and experimented with several ways to redirect a form once submitted. However, I only want to redirect a node form if the operation is t('Save').

If I set $form\['#redirect'\] = 'blah' in form\_alter, it will redirect on all types of form submits. If I add a submit handler and then set $form\_state\['redirect'\], this just gets overridden by drupal's node\_form\_submit.

What is the correct way to redirect a node submit only if the submit operation was say t('Save')?

NOTE: I found out that the generic form\_alter attempt of $form\['#redirect'\] interferes with the node delete submit handler, as it has to redirect to node/%node/delete. So hence I am looking for a more accurate method.

# Answer
The answer was to attach my submit handler to the submit button rather than the form, and then the $form\_state\['redirect'\] would work as needed.
> 4 votes

---
Tags: 7, forms
---


# Question
Title: How do I choose which module to use when there are several options for the same functionality?
It's not at all uncommon to find multiple modules that provide basically the same functionality. For instance, there are many SPAM control modules that offer extremely similar functionality (e.g., Spamicide and Hidden CAPTCHA). And there are lots of Taxonomy modules that do similar things. So when multiple modules meet my requirements, how should I choose which one to use?

# Answer
Personally I do a few basic checks before digging deeper.

* How many reported installs? (about the same in your example modules).
* How long since last update to module? (Spamicide is 5 days ago (from today))
* How many open issues?
* Who is the developer? (Have they worked on other modules that I use, etc).

Then you can start digging into integration, if I where looking for an inline image management tool I personally would choose something that takes advantage of other modules instead of rolling it's own solutions, something that is features exportable, etc.
> 25 votes

# Answer
There are comparison pages for some modules.

Information can sometimes be found googling site:groups.drupal.org and the module names.
Generic module comparison search on g.d.o
> 5 votes

# Answer
I check the number of installs, the number of developers.

Then I'll look through the open issues/bugs and use my judgement to decide if I'd ship a problem with those issues. The responses to issues by the developers are very important to me in this process.

The number of open issues is misleading because all too often the issues aren't actually issues at all.

Finally I'll probably look at the source;

I also won't touch anything that doesn't or isn't going to have a D7 version. This may be a crude unfair metric, but it works for me, sofar... Open to persuasion that I'm wrong about this one.
> 3 votes

# Answer
Generally, in addition to the number of installs, how quickly after a new release of Drupal does this module get updated. This tells me how quick the devs are, and that also tells me how quick they will be to address any serious issue.
> 3 votes

---
Tags: 7
---