# Question
Title: Organic Groups module  messes up node editing
**Updated header to reflect real cause of problem**

I've created some content types using node references for "belongs to" or "owned by" relationships.

When I add a new node, selecting the node references seems to work fine, and the default "list view" showing the newly created nodes also shows that the relationsship is correct. However, when I try to view or edit a single node, the form displayed includes only the "Title" field, and nothing else. I've also verified through "Manage fields" and "Manage display" that my node reference field is supposed to be displayed, but it still does not seem to work.

Do you have any ideas?

# Answer
> 2 votes
Just figured out that the problem was not caused by the references module, but by the "Organic Groups" (og) module. It seems to be a known bug in the organic groups module that basically hides/disables all fields for custom content types that are not marked as group or something like that. There's a report about this in http://drupal.org/node/1029230.

Disabling the organic module make the fields come back again, and even relationships seems to be editable again. I can live without organic groups for now, and considering the severity of the bug I will definitively not try to use that module again until it has been fixed.

# Answer
> 1 votes
FYI - this question is in reference to the new D7 "References" module (http://drupal.org/project/references) which is currently in development and has not had a formal release. Have you taken a look in the issues cue for the module related to your problem: http://drupal.org/project/issues/references?categories=All

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


title: Variables used in template.php

text:
# Question
Title: Variables used in template.php
How should I know which variables and objects can be used directly in the template.php file?This is what a template.php file created by somebody else contains:

```
function garland_separate_terms($node_taxonomy) {
  if ($node_taxonomy) {
    foreach ($node_taxonomy as $term) {
      $links[$term->vid]['taxonomy_term_'. $term->tid] // …
      // …
    }
    // …
  }
}

```

Why can he use the $term object directly?

# Answer
> 0 votes
Well first look at what this function is. Is it a theme function? It has a theme prefix, but i cant find it on http://drupalcontrib.org/api/search/6/separate\_terms, so probably it isnt.

You get `$node_taxonomy` in argument, which seems to be a list of taxonomy terms, so you have access to those.

Everything else is not available to you, since you don't receive those variables, only the one in the argument. (well ok, you can access global variables, but I don't want to confuse you)

He can use `$term` because he knows that `$node_taxonomy` is an array of terms, and loops through them with foreach.

If in doubt next time use the devel module and add a `dsm($node_taxonomy)` line to see how that variable is built up.

# Answer
> 2 votes
Simple answer - the line `foreach ($node_taxonomy AS $term)` is where the $term variable is coming from. That's a basic PHPism that treats $node\_taxonomy as an array, and puts the current item from that array into the $term variable as it iterates over the array.

As snufkin noted, $node\_taxonomy is the only variable you're getting access to automatically.

# Answer
> 1 votes
As already reported by Eaton, the template.php file contains functions that are called from the template files used by themes.
`garland_separate_terms()` is then not a function present in the file used by Garland Drupal comes with.

page.tpl.php has access to the variable `$node`, which contains the node object when the page being visualized is a node page; also node.tpl.php has access to the variable `$node`. Those are some of the template files that can invoke that function, and which have access to a node object, from which is possible to access the list of taxonomy terms associated with the node.

---
Tags: 7, theming
---


title: Path associated to Views

text:
# Question
Title: Path associated to Views
I used Pathauto to create URLs for my nodes like `gallery/[node:title]`.

I created a view with an argument, and the path is `gallery/%` (`%` is the node title), but when I point my browser to that URL, I get the standard node, not the view.

How can I override the paths to get my view on that path?
How can I increase the weight of views.module?

# Answer
> 1 votes
To increase the weight of views.module, you can execute the following code:

```
db_update('system')
  ->fields(array('weight' => 10))
  ->condition('name', 'views')
  ->execute();

```

# Answer
> 3 votes
I think the best option here is to actually let Panels take care of this. Install panels, create a variant of the node view panel for the specific node type(s) you want, and then place the view on the panel page. There are a few other options (hook\_menu\_alter(), using hook\_url\_alter() to rewrite the node links rather than using pathauto), but I would definitely go the panels route.

---
Tags: 7, views, path-aliases
---


# Question
Title: Are there still the settings for the arguments passed to a view?
Views 2 for Drupal 6 had settings for the arguments passed to a view.
Does Views 3 for Drupal 7 still have those settings?

This is the partial screenshot that I see when I edit the taxonomy term view (the screenshot appears blur because I resized it to 70% of its original dimensions).

If this makes any difference, the screenshot is for the development snapshot of Views (7.x-3.x-dev), used together the development snapshot of Chaos Tools (7.x-1.x-dev).

# Answer
The argument settings have not been removed; they have been renamed, and in the actual development snapshot they are called *Contextual Filters*.
> 5 votes

---
Tags: 7, views
---


title: How do I output an image in a block?

text:
# Question
Title: How do I output an image in a block?
I tried to put this code in a custom block that uses PHP as input format, but it doesn't work in Drupal 7.

```
$settings = theme_get_settings('my theme');
if (!$settings[toogle_logo] = 0) {
  print '<img src="' . base_path() . $settings['logo_path'] . '" alt="my logo" />';
}

```

How should I output an image in a block?

# Answer
> 9 votes
There are four issues in the code shown in the question; two of them explain why the code doesn't work as expected.

* `theme_get_settings()` has been removed in Drupal 7; instead of that function, the code should use `theme_get_setting()`
* `$settings[toogle_logo]` is using a literal string without using the string delimiters; PHP will take `toogle_logo` is a constant and, not founding its declaration, it will think its value is the literal string `'toogle_logo'`
* As already said from tim.plunkett, `!$settings[toogle_logo] = 0` should really be `!$settings[toogle_logo] == 0`; differently, the code is setting `$settings[toogle_logo]` to `0`, and then checking its value isn't zero, which means the `if()` statement will never be executed
* Instead of rendering an image by writing directly the HTML markup, the code should use the theming functions available in Drupal

The correct code should be similar to the following one.

```
if (theme_get_setting('toggle_logo')) {
  $image = array(
    'path' => theme_get_setting('logo'),
    'alt' => 'my logo',
  );
  print theme('image', $image);
}

```

If you can avoid using the PHP filter, you really should. Consider creating a custom module that implements a block, or include the block implementation in an existing custom module you are already using for the site you developed.

# Answer
> 4 votes
One problem with your code is that you use =, not == in your if statement.

Sounds like a job for Blockify. And if you don't want to use "a whole module" just for that, you can see how it's done and use the correct snippet.

---
Tags: 7, theming, blocks
---


# Question
Title: Creating a view block inside a fieldset using templates
I am trying to create a new `.tpl.php` for some of my views. I know how to create the file and display the elements the way I want, but only by changing the default `views-view.tpl.php` which would change the way **all** my views are displayed.

Supposedly I should be creating a new file by looking at Theme: Information and giving it one of the names available that would be something like: `views-view--VIEW-NAME.tpl.php`, but when I do this and leave the file in the theme folder in the views module and press "Rescan template files" it doesn't detect it.

Should I put the file in a different location?

FYI: What I am trying to do is place my views content inside a fieldset, something like this:

```
<fieldset class="fieldset collapsible form-wrapper"
 <legend>
   <span class="fieldset-legend">
     <a class="fieldset-title">
       <?php print $header;?>
     </a>
   </span>
 </legend>
 <div class="fieldset-wrapper">
    <?php if ($rows): ?>
        <div class="view-content">
          <?php print $rows; ?>
        </div>
    <?php elseif ($empty): ?>
        <div class="view-empty">
            <?php print $empty; ?>
        </div>
    <?php endif; ?>

    <?php if ($pager): ?>
        <?php print $pager; ?>
    <?php endif; ?>

 </div>

```

As I said this is working, I am just trying to put it in a different `.tpl.php` file and apply it only to certain views. Also if there is an easy way of making the fieldset collapsible that would be useful, although not essential.

# Answer
> 3 votes
Put the template file in your themes directory not views theme directory. It will detect it there. I like to have a views directory inside the themes template directory to organize view template files. I mimic views naming convention for a directory structure so views-view-fields--brands--default.tpl.php and views-view-grid--brands--default.tpl.php would go in:

views/brands/default

It's a nice way to keep the files organized.

# Answer
> 3 votes
Drupal 6 has Viewfield (http://drupal.org/project/viewfield). I think this would help you with what you want to do. There is a issue with discussion of porting to D7 and somebody has even released an initial D7 port that you could try out. See that queue here: http://drupal.org/node/704014

It allows you to setup views with a content type and define what params you want to allow the user to control or if you want them to do anything at all with the view.

---
Tags: 7, views, theming
---


title: How do I get the logo path?

text:
# Question
Title: How do I get the logo path?
I have a custom logo and I have tried to get his path in this way `theme_get_setting('logo_path')`, but no expected result.

I am using the code in a custom block, in input PHP.

# Answer
`logo_path` seems to only be set if you override the theme's default logo via its theme settings. To get the default logo, use `theme_get_setting('logo')`.
> 9 votes

# Answer
```
global $base_url;
drupal_theme_initialize();

if (!$logo = theme_get_setting('logo_path')) {
    $logo = theme_get_setting('logo');
}

if (!empty($logo)) {
  // [1]
  // Remove the base URL from the result returned by theme_get_setting('logo').
  // If you don't need the relative path, you can remove this code.
  if (strpos($logo, $base_url) === 0) {
    $logo = drupal_substr($logo, drupal_strlen($base_url));
  }
  // [1]
  // …
}

```

The call to drupal\_theme\_initialize() is not strictly necessary, and it doesn't do anything if the global variable `$theme` is already initialized.
The code is removing the base URL because the value reported from `theme_get_setting('logo')` is an absolute path; if you don't need a relative path to access the file, then the part between `// [1]` can be removed.

When the logo has been disabled in the theme settings, `theme_get_setting('logo')` doesn't return anything.
> 4 votes

---
Tags: 7, media
---


# Question
Title: CCK field value count is never less than 1
I have got a CCK field set up so that unlimited values can be entered upon node creation (number of values: unlimited).

When I try to print values in a node with the following code

```
if ($node->field_tip != NULL) {
  foreach ((array)$node->field_tip as $tip) {
   print "<div class='tip'>" . $tip['view'] ."</div>";
  }
}

```

or I print `count($node->field_tip)`, the value is never less than 1, and `<div class='tip'></div>` is always displayed, even if there aren't values entered in that field.

# Answer
> 3 votes
As far as CCK is concerned, there is still a value, it just happens to be blank (most likely an empty string, depending on what type of field you're using). If you modify your code to check the raw value, you should only see output when there is an actual value:

```
if ($node->field_tip != NULL) {
  foreach ((array)$node->field_tip as $tip) {
    if (!empty($tip['value'])) {
      print "<div class='tip'>" . $tip['view'] ."</div>";
    }
  }
}

```

---
Tags: 7, entities
---


# Question
Title: Best practice to have a 'category' fields where admin can choose wich voices the user can choose
I have a content type that needs a 'category' field; this can both be a taxonomy vocabulary or a text field (with the select widget), it doesn't really matter. (I won't have more then 5-6 voices at once.)

However, those voices may change over time, and normal users should be able to choose only few values when creating a new node.

What is the best practice to achieve this?

My idea is to use a taxonomy vocabulary, where only administrators can insert new voices, but I will need some kind of attribute (e.g., a boolean) that I can use in a module in order to filter them in `hook_form_alter()`. Could this be a Drupal-ish way to achieve that?

# Answer
> 1 votes
You could use a Node Reference field where your 'Voices' are nodes that only administrators can make, that way you can restrict the maximum number of 'Voices' allowed in the Node Reference field settings, and you could turn 'Voices' off by un-publishing them, or if you need the boolean value for the Node output you could just add a Checkbox text field on the 'Voices' node and use the Custom Formatters module to render the Node Reference field out as you wish.

# Answer
> 1 votes
I would use taxonomy terms for *voices*. From there I see two options to store their enabled/disabled states. You can either add a custom table (using the Schema API) with `tid` and `state` columns. Or, if you only have a few enabled voices, use a configuration variable (`variable_get` & cie.). In the later case, adding a configuration page/form to let administrator select the enabled voice is easy with `system_settings_form`. You can also alter the `taxonomy_form_term` form to add a state form field and custom submit handler to terms from your voice vocabulary.

Once you have the enabled/disabled state of voices stored, you can use `hook_form_alter` to alter the taxonomy form field and restricts its allowed value. You will have to make a decision on what to do when editing an existing node using a currently disabled voice. Either allow it to keep that voices or force it to use an enabled one.

# Answer
> 0 votes
Each term in a vocabulary has a 'weight field' to allow for custom sorting. That could allow you to set a specific order of terms. Are you sure you need the boolean? I assume it is to activate & deactivate a voice from showing in the list? You can just delete the term, but that would orphan the term on the nodes that used it.

You may be better off with a 'computed field' that is fixed once the node is published. http://drupal.org/project/computed\_field

Allowing admins to edit taxonomies is probably safer than allowing them to edit a CCK select list.

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


title: Get the title of the active tab

text:
# Question
Title: Get the title of the active tab
Is it possible to get the title of the currently active secondary tab?

I'd like to re-use the the title of this tab later on in the content. I found `menu_local_tasks(1)` which comes close, but this returns full themed output. I just want the title as I've defined it in `hook_menu()`.

**Edit:**
My `hook_menu` structure (trimmed to just the elements in ,not including sibling elements):

```
$items['events/%node'] = array(
    'title' => 'Events',
    'page callback' => 'page_events',
    'page arguments' => array(1),
    'type' => MENU_NORMAL_ITEM,
);

$items['events/%node/stats'] = array(
  'title' => 'Stats',
  'access callback' => TRUE,
  'page callback' => 'page_stats',
  'page arguments' => array(1),
  'type' => MENU_LOCAL_TASK,
  'weight' => 3,
);

$items['events/%node/stats/year'] = array(
  'title' => 'This Year',
  'access callback' => TRUE,
  'type' => MENU_DEFAULT_LOCAL_TASK,
  'weight' => 0,
);

$items['events/%node/stats/lastyear'] = array(
  'title' => 'Last Year',
  'access callback' => TRUE,
  'page callback' => 'page_stats',
  'page arguments' => array(1),
  'type' => MENU_LOCAL_TASK,
  'weight' => 1,
);

```

For example, when at the page `events/%node/stats/year`, I'd like to get `'This Year'`.

# Answer
> 4 votes
menu\_get\_active\_title() should be the function you are looking for.

```
function menu_get_active_title() {
  $active_trail = menu_get_active_trail();

  foreach (array_reverse($active_trail) as $item) {
    if (!(bool) ($item['type'] & MENU_IS_LOCAL_TASK)) {
      return $item['title'];
    }
  }
}

```

It should work for menus for which the menu type contains the flag `MENU_LOCAL_TASK` (which includes also the `MENU_DEFAULT_LOCAL_TASK` menu type).

The function is also defined in Drupal 7.

**Update:** I noticed that for menus like /node/%node/view, `menu_get_active_title()` returns the title for /node/%node. The following code should return the correct title also in those cases, including in the case the title is given by a title callback. I just tested on Drupal 7; I don't actually have Drupal 6 on the test site I use.

```
$item = end(menu_get_active_trail());

if (!empty($item['title_callback'])) {
  $args = array();
  if (!empty($item['title_arguments'])) {
    foreach ($item['title_arguments'] as $value) {
      if (is_int($value)) {
        // Get the value from the menu item map.
        if (!empty($item['map'])) {
          $args[] = $item['map'][$value];
        }
      }
      else {
        $args[] = $value;
      }
    }
  }

  $title = call_user_func_array($item['title_callback'], $args);
}
 else {
   $title = $item['title'];
 }

```

# Answer
> 1 votes
You should be able to do this with drupal\_get\_headers(), and then parsing through the results.

# Answer
> 1 votes
Try **menu\_get\_item($path = NULL, $router\_item = NULL)** http://api.drupal.org/api/drupal/includes--menu.inc/function/menu\_get\_item/6. You should be able to pass the path value which will result in a returned array containing details of the menu tab entry including the 'title' value.

Use $\_GET\['q'\] to get the current path.

---
Tags: 7
---


# Question
Title: How to get the content owned by the currently logged-in user?
A user is the owner of only one node, and I want to redirect the user, at login time, to his only owned node.

How can I get the node content if I know only the logged-in user?

# Answer
This is how I have do it:

```
function MYHOOK_user_login(&$edit, $account) {
    global $user;
    $nid = db_query('SELECT nid FROM {node} WHERE uid = :uid', array(':uid' => $user->uid))->fetchField();
    drupal_goto('node/' . $nid);
}

```
> 3 votes

# Answer
Take a look at **hook\_user\_login** -\> http://api.drupal.org/api/drupal/modules--user--user.api.php/function/hook\_user\_login/7. This is where you can add your own custom code to do things like look up the node ID (nid) by user ID (uid) and then issue a **drupal\_goto** (http://api.drupal.org/api/drupal/includes--common.inc/function/drupal\_goto/7)

There's also the option of doing the customization with **hook\_form\_alter** to the login form which might be considered more of a D6 solution. You'll have to provide more details if these suggestions are not addressing your question.
> 2 votes

# Answer
```
$nid = db_query('SELECT nid FROM {node} WHERE uid = :uid AND type = :type', array(':uid' => $user->uid, ':type' => $node_type))->fetchField():

```

This will get you the nid.
> 2 votes

# Answer
Note: please disregard this answer (see the comments for why).

```

$nid = db_select('node', 'n')
  ->fields('n', array('nid'))
  ->condition('n.uid', $user->uid)
  ->range(0, 1)
  ->fetchField()

```

I'd be tempted to do it this way since it's more the 'Drupal' way, although the other suggestions are certainly valid. Note that I've put a limit on the SQL statement for safety.
> 0 votes

---
Tags: 7, redirection, users
---


# Question
Title: Never show the term name if the user has no permission to view the term
I use a vocabulary to freetag bookmarks I post to my site, and I want to hide all the terms (also most nodes; most or all, I don't care).

With TAC module I use following setting for a start:

```
global default: Show/Create/Delete: ignore   Show-term-checkbox: yes
myvoc default:  Show(node) : disallow;       Show-term-checkbox: no

```

I have also tried with:

```
global default: Show/Create/Delete: ignore   Show-term-checkbox: no

```

I just want to make Drupal show the "access denied" or similar page on /taxonomy/term/xxx. I know my site doesn't show a link with that URL, but I just want to be sure.

Is it possible? Or should I use a simpler module?

# Answer
You could implement hook\_menu\_link\_alter in a custom module and modify access to /taxonomy/term/xxx, if need be, by overriding the existing access callback with your own.

You will need to look at the menu router table to see exactly what menu item you want to alter.
> 1 votes

# Answer
Path Access offers a simple way to display a 403 on any taxonomy/term/\* page.
> 0 votes

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


# Question
Title: Is there any security consideration with webform and Salesforce API?
We are implementing the Salesforce webform module for our client and they are asking us if there are any security issues to consider by having SOAP installed on their server.

(The Salesforce API requires SOAP to be installed for drupal to communicate with it.)

# Answer
> 1 votes
PHP SOAP will not introduce any security issues in itself; it's more about how it is used. If it's used via unencrypted HTTP, for example, the data could be intercepted, like any other data. If you need the data to remain secure, then obviously this would be a consideration.

---
Tags: 7, security
---


title: Image upload & gallery

text:
# Question
Title: Image upload & gallery
Is there a way to limit the number of imagefield fields present in a node?
I am using iTweak Upload, which allows to upload an unlimited number of images, but I need something that can limit the number of uploads.

I want to make a gallery per node with the uploaded files; what module do you recommend?

# Answer
> 1 votes
If you use standard CCK imagefield, you can set the number of images that can be uploaded within one field. For example, you could allow just one image, or up to 10 images, or an unlimited number of images.

Providing you don't have hundreds of images per node, CCK imagefield is fine for having a gallery of images on each node, and we've implemented galleries quite successfully in this way.

# Answer
> 0 votes
You could take a look at my CCK Gallery module - http://drupal.org/project/cck\_gallery \- for some ideas. It's out of date now, and should probably be a Feature - there is no intention to resurrect it, but it might be a good starting point.

I don't really understand "limit the number of imagefield fields" - I mean, you can limit the number of permitted uploads on a field already, so I guess that's *not* what you mean, but I can't work out what you do mean.

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


# Question
Title: File/image upload via CCK and Nginx + FastCGI
I am using the ImageField module with Pressflow, Nginx, and FastCGI. When I go to add a file via the standard ImageField CCK upload widget on a node, the Upload "throbber" does its thing, Drupal does not report any problem. The upload completes fine, but no thumbnail is generated in `imagefield_thumbnails`, and no ImageCache presets are generated.

I can see the file in the right place on the server. It feels for all the world like a file permissions problem, but I'm getting no such warnings from Drupal or PHP and the file is `chmod 664` and belongs to `www-data` (which is the user Nginx is running as). So I can see no reason why PHP would not be able to read the image.

Furthermore, all the ImageField and ImageCache target directories are `chmod 777` and owned by `www-data`, so again, no reason why the application would not be able to write there. *And* anyway, no errors suggest that is the problem, in either `/var/log/messages` or in `/var/log/nginx/error.log`. It makes no sense!

Can anyone shed some light? Is there any simple step I need to follow (or a missing package I need) to make Drupal work, or am I doing something stupid?

# Answer
Ok, turns out unbeknownst to me someone had added rules in the `.htaccess` file pointing image loading to another server, which, of course, did not have the created presets and thumbnails. Gah!

Another gotcha in this was the `$base_url` variable was set in `settings.php` to force Drupal to load a from a specific site, regardless of the one requested.

Hopefully this will help someone in the future.
> 1 votes

---
Tags: entities, files
---


# Question
Title: Is there an easy way to display Atlassian Gadgets within a Drupal node?
We are looking into a way to display information from Jira in Drupal.

Using Drupal 6, is there an easy way to display Jira/Atlassian Gadgets within a Drupal node?

I have looked into a few things, and while it seems that the Dashboard module allows to include Gadgets, I don't want to have to use a Dashboard for this. I just wanted to embed a Gadget into a normal Drupal node.

Any hints or ideas?

# Answer
Well, taking a look at the Jira/Atlassian web site, they are based in Java technology. Without going into too many details, because I'd have to learn how their proprietary environment works to advise you further, it is possible to embed Java applets in a Drupal page, in pretty much the same manner that one embeds a YouTube video on a Drupal page: just embed the markup in the same manner as you would any other web page, just make sure that the Drupal page's Input Filters are set to not strip out your embedding tags (such as using the 'Full HTML' Input Filter.)

However, this just gets one of their Java Applets on the page. It's not interacting with any information in your Drupal installation. In order to get your Java communicating with your Drupal installation's data, you need to install something like the Services Module into your Drupal installation hosting these Jira/Atlassian Java Applets, plus the Services REST server, and then create an API within the REST Services Framework that either mimics what the Java Applet expects for it's communications, or custom modify the Java Applets to communicate thru the API you created within Services.

So, no, there is no easy method if you want these Java Applets communicating with your Drupal installation's data. If you just want to display them, AND they support simple embedded like most Java Applets, just use the appropriate Input Filters when placing the Java Applet's embed script in the Drupal page.
> 2 votes

---
Tags: 6, nodes
---


title: Form Api File upload

text:
# Question
Title: Form Api File upload
I have the following code in my form.

```
$form['new']['upload'] = array(
  '#type' => 'file',
  '#title' => t(''),
  '#size' => 40,
);

```

On the submission handler, it returns the file name but it does not save the file and return a file object. What else do I need to do?

What I am trying to do is create a block where you can upload a file that it is saved in a node's file field.

# Answer
Take a look at file\_save\_upload() and the functions which call it.

The function will handle the validation of the file, and save it to a new location. In Drupal 7 this also adds the file to file\_managed table.
Note that the file will be stored as a temporary file, so make sure to set the status of the file to permanent afterwards.

You will probably want to implement the file\_save\_upload function inside your form's validation hook (before the submit handler), so you can alert the user if the file upload failed, or did not meet your validation requirements.

If the name of the image field you are trying to validate is `image`, then the first parameter of file\_save\_upload should be image, as such:

$path = file\_save\_upload('image', ...);

This function will then return the path on the server to which the image was uploaded (so you can for example store that path in a custom database field).
> 8 votes

# Answer
You are missing this in your form definition:

```
   $form['#attributes']['enctype'] = 'multipart/form-data'; // If this is not here, upload will fail on submit

```

Here's the logic I use to create a file upload widget on a form:

```
   // these give us the file upload widget:
   $form['#attributes']['enctype'] = 'multipart/form-data'; // If this is not here, upload will fail on submit
   $form['fid'] = array( '#title'        => t('Upload image'),
                         '#type'         => 'file',
                         '#description'  => t('Images must be one of jpg, bmp, gif or png formats.'),
                       );

```

And here's the counterpart to that logic, which I have in my form's validate callback, because I have image filename restrictions in my logic, but you can place this in the submit callback if you want:

```
   // @see: http://api.drupal.org/api/function/file_save_upload/6
   // $file will become 0 if the upload doesn't exist, or an object describing the uploaded file
   $file = file_save_upload( 'fid' );
   error_log( 'file is "'.print_r( $file, true ).'"' );
   if (!$file) {
      form_set_error('fid', t('Unable to access file or file is missing.'));
   }

```

that's it.
> 4 votes

# Answer
I have a generic validation function I use primarily in themes that need to support upload of images. You might be able to use it as it, or with minor changes, but this should get you far.

```
/**
 * Validate/submit handler used for handling image uploads
 */
function module_upload_image_validate($form, &$form_state) {
  // This is not needed, I use this to use the same validate function
  // for several fields.
  $key = $form['#key'];
  $file = file_save_upload($key, array(
    'file_validate_is_image' => array(),
    'file_validate_extensions' => array('png gif jpg jpeg'),
  ));
  if ($file) {
    // Get the image info to get the correct extension for the uploaded file.
    $info = image_get_info($file->filepath);
    if (file_move($file, 'destination/filename'. $info['extension'], FILE_EXISTS_REPLACE)) {
      // Mark the file for permanent storage.
      file_set_status($file, FILE_STATUS_PERMANENT);
      // Update the files table.
      drupal_write_record('files', $file, 'fid');
      $form_state['values'][$key] = $file->filepath;
    }
    else {
      form_set_error($key, t('Failed to write the uploaded file to the site’s files folder.'));
    }
  }
}

```

Using this function, you will get the filepath as the the value in form submit handler. You might want the file id instead, depending on your usage.
> 3 votes

---
Tags: 7, forms, files
---


title: How can I add extra info to my menus?

text:
# Question
Title: How can I add extra info to my menus?
I have some menus that are managed in the standard Menus module (Drupal 6, BTW). I want to add a checkbox when I'm editing a menu item to control the display of a "New" banner via CSS (by adding a class for items that have the checkbox turned on).

I can get my checkbox into the form like so:

```
function mymodule_form_menu_edit_item_alter(&$form, &$form_state) {
  $form['menu']['newbanner'] = array(
    '#title' => 'New banner',
    '#type' => 'checkboxes',
    '#description' => "Add a 'New' banner to this item?",
    '#options' => array( 'new_banner' => t("This item is new") )
    );
}

```

But I'm not quite sure how to actually save and use the state of my checkbox. I'm guessing I want to start by creating a `mymodule_form_menu_edit_item_submit()` function? But how do I get my info in/out of the database and use it to add a class to the generated menu on the front-end?

# Answer
> 3 votes
The code you wrote so far is correct; you just need to add the code for getting the saved setting, and the code to save it.

```
function mymodule_form_menu_edit_item_alter(&$form, &$form_state) {
  // Get the mlid ID of the menu item.
  $mlid = $form['menu']['mlid']['#value'];

  $form['menu']['newbanner'] = array(
    '#title' => 'New banner',
    '#type' => 'checkboxes',
    '#description' => "Add a 'New' banner to this item?",
    '#default_value' => variable_get("mymodule_newbanner_$mlid", 0),
    '#options' => array('new_banner' => t("This item is new")),
  );

  $form['#submit'][] = 'mymodule_menu_item_submit';
}

function mymodule_menu_item_submit($form, &$form_state) {
  $item = &$form_state['values']['menu'];
  // Get the last ID inserted in the table.
  if (empty($item['mlid'])) {
    $item['mlid'] = db_last_insert_id('menu_links', 'mlid');
  }

  variable_set('mymodule_newbanner_' . $item['mlid'], $item['newbanner']);
}

```

The `mlid` could be zero, when the menu item is first created; in that case, the form submission handler gets it from the table, as it is executed after the form submission handler added by menu.module, which saves the menu item in the table using menu\_link\_save().

# Answer
> 0 votes
Please, please, please do not add your row-level data to the variables table. The entire variables table is cached and loaded on every page, adding to the memory footprint of each page request.

In this case, a variable would be created for every menu item that is saved, which could quickly add up. Though this individual case may not add up to that much extra data, imagine if many modules used the variables table as a data dumping ground.

As a general rule of thumb, if your data has multiple rows, you should probably use a separate table.

# Answer
> 0 votes
You may want to have a look at the Menu attributes module.

This will allow you to set various additional attributes on your menu items including classes and ids which you can then target with css or jquery.

Some more details about this module (from its project page):

> This simple module allows you to specify some additional attributes for menu items such as id, name, class, style, and rel.
>
> You should use this module when
>
> * You want to "nofollow" certain menu items to sculpt the flow of PageRank through your site
> * You want to give a menu item an ID so you can easily select it using jQuery
> * You want to add additional classes or styles to a menu item
>
> The module currently allows you to set the following attributes for each menu item:
>
> * Id
> * Name
> * Target
> * Rel
> * Class
> * Style
> * Accesskey

---
Tags: 6, forms, routes
---


# Question
Title: What is the access record "content_access: all"? This is overriding my taxonomy access module
I have had problems with my permissions ever since I last rebuilt my permissions. (I did this after working on user reference permissions. This field has no user reference on it)

The taxonomy permissions have the same priority of 0. In fact all access modules have the priority of zero. When I go to the page that can be seen even though it should not be seen, it shows the following as granting access to view the page:

I think that I have to give people access to see pages by default and then take it away if taxonomy is assigned. I had this working before and I don't understand why it stopped working.

What can I do to figure this out? I'm a few hours into the issue and am a bit stumped.

I have the following modules installed regarding permissions:

* Content Access
* Node access user reference
* Taxonomy Access Control

I'm not sure if it is relevant or not but I also get a message when I hover over delete that says:

> DNA and Core seem to disagree on this item. This is a bug in either one of them and should be fixed! Try to look at this node as this user and check whether there is still disagreement.

# Answer
The access record you are seeing could be the default access that Drupal uses and that, as far as I can say looking at the code, is only used when no module implements node access rights.
node\_access\_rebuild() and node\_access\_acquire\_grants() both add that access record if no module implements any node access hook, or no module returns any access record.

```
function node_access_rebuild($batch_mode = FALSE) {
  db_query("DELETE FROM {node_access}");
  // Only recalculate if the site is using a node_access module.
  if (count(module_implements('node_grants'))) {
    // …
  else {
    // Not using any node_access modules. Add the default grant.
    db_query("INSERT INTO {node_access} VALUES (0, 0, 'all', 1, 0, 0)");
  }

  if (!isset($batch)) {
    drupal_set_message(t('Content permissions have been rebuilt.'));
    node_access_needs_rebuild(FALSE);
    cache_clear_all();
  }
}

```

I would not suggest to remove that access record from the node access table, otherwise users without specific permissions would not be able to view any node for which a module doesn't have a node access record. In Drupal, it is default to deny the access to a node; in fact, the node module writes in the node access table only the records that allow to access a node.

**Update:** As you reported that you are using also *Content Access*, you could be interested in this issue report: Do not hijack the 'all' realm.
The access record you are noticing is probably the record added by *Content Access*; the short name of the module is content\_access, and it is probable the module is using that as grant realm.

> I think that I have to give people access to see pages by default and then take it away if taxonomy is assigned.

As Drupal node access works, the access is denied by default, and it is granted for nodes for which a module grants it; it is exactly the opposite of what you are doing.
Access is still allowed for users who have specific permissions, which in Drupal 6 means users with the *administer nodes* permission, and is not allowed for users without a specific permission, which in Drupal 6 means users without the *access content* permission.
> 1 votes

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


# Question
Title: Cached "Page not found" for anonymous users
My site's drupal version is 6.19. There are always logs like the following.

**the recent log entries shows**

```
type: page not found
location:http://www.example.com/display.html
referrer:
  message: 500.shtml
  severity: warning
  hostname: 95.64.11.29 or others (maybe search engine robot IP)

```

The URL and the content is right, but when the anonymous user accesses it, it returns the "Page not found" page. Anonymous users have the permissions to access content.

The cache\_page table contains the following header for http://www.example.com/display.html:

```
Content-Type: text/html; charset=utf-8 HTTP/1.1 404 Not Found

```

Why is the page being cached as "404 Not Found", when it actually exists?

When I access http://www.example.com/display.html as an anonymous user, the site shows "page not found"; when I clear the cache, anonymous users can access the page.
How can I correct the cached content generated by search engine bots?

# Answer
> 2 votes
Is the page actually handled by Drupal or is it a static .html file? It looks like a file that shouldn't be handled by Drupal, the 500 error http://www.checkupdown.com/status/E500.html indicates a fatal server error.

If it is handled by Drupal can you change the url to one without the .html & see if that works with caching. You could use the global\_redirect module to forward the .html addresses, once you figure out why it's failing.

If it is a flat file you may need to change the .htaccess or settings.php file to allow the .html to be processed by the webserver without bootstrapping Drupal.

There is a massive thread about this issue on Drupal.org http://drupal.org/node/76824#comment-3299738 You may find an answer in there.

PS If this is served on a shared host you may want to contact your provider, they can have some strange setups & can fix quickly if you explain clearly what is happening.

---
Tags: 6, caching
---


# Question
Title: What is the difference between the classes ArchiverTar and Archive_Tar?
What is the difference between the classes `ArchiverTar` and `Archive_Tar`?

I am mostly interested to understand which one a Drupal module is supposed to use.

# Answer
> 5 votes
The Archive\_Tar class is a very-slightly modified version of the PEAR library Archive\_Tar. ArchiverTar can be thought of as a wrapper to that library. However, depending on what your module is trying to achieve, you will probably want to call archiver\_get\_archiver(), since this is agnostic of the specific archive format (the system module supplies tar and zip, and your module could provide additional formats using hook\_archiver\_info()).

---
Tags: 7
---


# Question
Title: What is the purpose of the FileTransfer class?
What is the purpose of the `FileTransfer`?

I read its documentation page, but it's not clear when a module should deal with that class or one of its child classes.

# Answer
> 5 votes
FileTransfer is an abstract class for transfering files that specific implementations should extend. The available implementations are FTPFileTransfer, SSHFileTransder and LocalFileTransfer, which are used to transfer files using different methods.

What separates it from the "traditional" file transfer is that it is designed to operate on directories that are not writable by the web-server.

An obvious example is the update manager, which, by using these classes, is able to dowload and install module and theme updates automatically.

A module might interact with one of these classes in order to transfer files via FTP or SSH.

---
Tags: 7
---


title: Panels call custom function

text:
# Question
Title: Panels call custom function
Is it possible to call custom code from a panel? My custom module has a function which returns some content. I wish to call this from my panel.

# Answer
Here's a hackier/quicker solution.

Create a custom content pane using the PHP input format for the content area. Call your function.

You will not have simple access to panels contexts (which you may not need anyway), and must have the PHP input format enabled (which can potentially cause security problems).

You have access to the args, etc so you can pull nid from arg(1) if it's a node panel for example.
> 0 votes

# Answer
It is, but requires a bit of coding. You need to create a ctools content type plugin. I had the same issue a few months back, and found this to be a reasonably good guide for writing you r own content type:

http://shellmultimedia.com/articles/creating-content-type-ctools-panels-3

There are also a couple other options:

1. Expose the data your function is providing in a block. Blocks are automatically supported by panels.
2. You could (likely) use custom PHP in a panels pane. (highly discouraged)
> 2 votes

---
Tags: 7, panels
---


title: Grant access to CCK referenced nodes

text:
# Question
Title: Grant access to CCK referenced nodes
I have one content type 'object' that references one or more nodes of content type 'image'.
I'm granting access to nodes with TAC Lite: a user can view only content with a particular term.
Since the term is present only in the 'object' content type, the images referenced are not displayed in the node page.
How can I grant view access to all referenced nodes?

I've tried with Node access node reference, but it grant access to the parent node if the user has access to referenced nodes.

# Answer
> 1 votes
You could dynamically add the the same tag to the referenced image nodes when the 'object' node is created (or updated). To do this, you'd implement `hook_nodeapi()` and check the `$op` parameter for either "insert" or "edit" (depending on when you want this operation to happen). Then you can pull out the node id's of the 'image' nodes being referenced and apply the terms. This way they have the same taxonomy based permissions at the 'object' node.

There may be other ways, but this seems like it should work for you. I actually do the same thing to set a CCK node reference value during creation. I don't have access to a coding environment right now, or I'd add code snippets.

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


# Question
Title: Where to modify the logic that calculates the height of a collapsible fieldset?
I'm not sure if this is a theme issue, but I continually get my collapsible fieldsets being 1-2 scanlines too short, causing scroll bars to appear.

This project has heavy use of FAPI, sometimes with collapsible fieldsets inside other collapsible fieldsets, and the vertical scroll bars are eating too much page real estate.

I'm using an unmodified version of Fusion Starter theme, if that helps. And, I'm not a themer, but can usually get by.

I would be perfectly happy modifying the PHP or JavaScript code doing this calculation, if I just knew where it is.

# Answer
Are you sure it can't be solved by CSS? Try adding some padding.
> 2 votes

# Answer
Not sure if this is exactly what you mean but try setting the #rows attribute. I use something close to this

```
<?php
$form['description'] = array(
  '#type' => 'textarea',
  '#title' => t('Description'),
  '#default_value' => $text,
  '#rows' => count(explode("\n", $text)),
);
?>

```
> 1 votes

---
Tags: forms
---


title: "focusout" jQuery event

text:
# Question
Title: "focusout" jQuery event
I am using Drupal 6 and, therefore, jQuery 1.2.6.

When a user clicks inside my text, there is a pop-up that comes up with a few more options in it. I would like this pop up to disappear when the focus is moved to anywhere outside. This answer on SO comes very close but the `focusout` event isn't available to me in jQuery 1.2.6.

Has anyone else encountered this issue? How did you work around it?
I would rather not use the jquery update module, as I don't own the site and don't want to be responsible if the update breaks something else.

# Answer
> 1 votes
Add a `.mouseleave()` event to the popup div

Taking the example code from the SO question you mentioned, see the working version at http://jsfiddle.net/Laxman13/Mw8VD/6/

# Answer
> 0 votes
you could try the blur() function.

from the jquery docs

> The blur event is sent to an element when it loses focus. Originally, this event was only applicable to form elements, such as . In recent browsers, the domain of the event has been extended to include all element types. An element can lose focus via keyboard commands, such as the Tab key, or by mouse clicks elsewhere on the page. Blockquote

http://api.jquery.com/blur/

# Answer
> -2 votes
Will it work as expected with jQuery 1.3.2, because you can install the jQuery\_update module. I normally upgrade jQuery on all drupal 6 sites that I work with due to most jquery plugins etc have compatibility with 1.3.x

---
Tags: 6, javascript
---


# Question
Title: drupal_add_js best practice to include inline code or script file
While reading the API page for drupal\_add\_js, I kept wondering what is the best practice to include inline JavaScript or a JS file.

It seems like it works exactly the same even if you omit 'file', 'external' or 'inline' like in this example :

Without 'file'

```
drupal_add_js('misc/collapse.js');

```

With 'file'

```
drupal_add_js('misc/collapse.js', 'file');

```

So the question is rather simple. Why would I choose one over another and what is the standard way of coding this ?

Thanks !

# Answer
They are both and the same. The `file`parameter you have specified in your second example is the same as the first example as it's the default `type`.

> type: The type of JavaScript that is to be added to the page. Allowed values are 'file', 'inline', 'external' or 'setting'. Defaults to 'file'.

Source: drupal\_add\_js

If your question is about whether it's best practice to use inline or file then it depends on your requirements. If you need to load a JavaScript library or a large amount of JavaScript then I would use `file` type. If you are just loading say some tracking code, or a few lines of JavaScript then I would probably use `inline` as it's one less HTTP request.
> 9 votes

---
Tags: 7
---


title: drupal cache_page

text:
# Question
Title: drupal cache_page
My site is on drupal 6.19, but it always shows some "page not found" to anonymous users. Now I want to write code to examine the cache\_page table to know which pages are cached as "page not found", and remove such records from the table.

Which code should I write, and where should I put such code to make it work?

# Answer
As already reported from marcvangend, if Drupal is returning a "page not found" error when it should not be, then it is probable Drupal (or the server running it) is not correctly set. It should not be a permission problem, as in such cases Drupal would return an "access denied" error.

The code to delete records in the cache\_page table for pages that returned the "page not found" error is the following:

```
db_query("DELETE FROM {cache_table} WHERE headers LIKE '%404 Not Found'");

```

You can create a custom module (e.g. mymodule.module) that contains the following code:

```
/**
 * Implements hook_footer().
 */
function mymodule_footer($main = 0) {
  db_query("DELETE FROM {cache_table} WHERE headers LIKE '%404 Not Found'");
}

```

I used `hook_footer()` because it is always invoked all times Drupal displays a page; the hook could also not return any HTML, as shown in the example reported in the documentation page for hook\_footer().

```
function hook_footer($main = 0) {
  if (variable_get('dev_query', 0)) {
    return '<div style="clear:both;">' . devel_query_table() . '</div>';
  }
}

```

`hook_footer()` is not used by Drupal 7, and it is probably not executed for cached pages. For compatibility reasons (which means that few of the module code would be changed when passing to Drupal 7), I would implement `hook_exit()`, which is used also in Drupal 7.

```
/**
 * Implements hook_exit().
 */
function mymodule_exit() {
  db_query("DELETE FROM {cache_table} WHERE headers LIKE '%404 Not Found'");
}

```

The only "problem" would be with modules that call `exit()` without to first call `module_invoke_all('exit')`; in that case the implementations of `hook_exit()` are not invoked, but it should be a minor problem, in this specific case.

As alternative, you could implement hook\_cron(). Keep in mind that `hook_cron()` is invoked periodically, every day or every hour, depending from the settings of the cron task for the server where your website runs on.
If you have Poormanscron installed, then you can set every `hook_cron()` implementations to run every hour. As the module uses JavaScript code to run the implementations of `hook_cron()`, they are really executed when somebody visits your site.

```
/**
 * Implements hook_cron().
 */
function mymodule_cron() {
  db_query("DELETE FROM {cache_table} WHERE headers LIKE '%404 Not Found'");
}

```
> 2 votes

# Answer
Sounds like you're fixing the wrong problem. If url's that should return valid pages, return 404's instead, I would start with looking at the way my menu is cached and if something strange is happening with permissions and access callbacks.
> 1 votes

---
Tags: 6, caching
---


# Question
Title: Lots of 500.shtml page not found errors in logs
I've been getting lots of page not found errors for 500.shtml in my logs. A lot of them seem to be originating from search spider and ho I might be able to fix these, I'm curious to why 500.shtml is even being sought out in the first place and how these are being generated at such a furious pace:

```
   type: page not found
   location:http://www.example.com/test.html
  referrer:
 message: 500.shtml
 severity: warning
  hostname:

```

500.shtml entries in the Drupal logs. In many cases, these are generated by search engines (determined by doing reverse lookups on the IP's), sometimes from users (but in very few cases). How can I fix it?

# Answer
The 500 error page is show when the server has an internal error.

Your server is looking for a file named 500.shtml because a directive set that as the page that must be shown when the server has an internal error. The .htaccess file used by Drupal set the page for the "page not found" error to /index.php with the directive `ErrorDocument`, but it doesn't set any error page for any 500 codes, which is the set by the server using a different file; for Apache, this means the access.conf file, or any files included by that file.

For what can cause an internal error, it could be a server directive, or a wrong argument passed to such directives. Other causes could be:

* directory permissions
* file permissions
* a wrong transfer mode used when transferring the Drupal PHP files to the remote server when using FTP
* the line endings of the files that don't match the one used from the Operating System that is hosting the server
> 2 votes

---
Tags: 7
---


# Question
Title: Displaying SQL-table as a paginated list
I'm trying the following and it works:

**my.module:**

```
   function my_menu() {
      $items['page_example'] = array(
        'title' => 'Page Example',
        'description' => 'Page Example',
        'page callback' => 'page_example',
        'access callback' => TRUE,
        'file' => 'my.page.inc',
        'file path' => drupal_get_path('module', 'my'),
        'type' => MENU_CALLBACK,
      );
     return $items;
   }

```

**my.page.inc:**

```
function page_example() {
  return array(
    'page_example' => array(
      '#type' => 'markup',
      '#markup' => generate_list(),
    ),
  );
}

function generate_list() {
  $query = db_select('users', 'name')
    ->extend('PagerDefault')
    ->fields('name', array('Name'))
    ->orderBy('created', 'DESC')
    ->limit(20);

  $result = $query->execute();
  $output = '';
  foreach ($result as $row) {
    $output .= $row->name.'<br/>';
  }

  $output .= theme('pager');
  return $output;
}

```

But then I try prepending a **uid**-field to each row and it fails:

```
  $query = db_select('users', 'name', 'uid')
    ->extend('PagerDefault')
    ->fields('name', array('Name'), 'uid', array('Id'))
    //->addField('uid', 'User Id')
    //->addField('name', 'User Name')
    ->orderBy('created', 'DESC')
    ->limit(20);

  $result = $query->execute();
  $output = '';
  foreach ($result as $row) {
    $output .= $row->uid.': '.$row->name.'<br/>';
  }

```

With the error:

```
Recoverable fatal error: Argument 3 passed to db_select()
must be an array, string given, called in my.page.inc
on line 13 and defined in function db_select()
(line 2387 in includes/database/database.inc).

```

**UPDATE:**

On Camsoft's comment (thank you) I've modified the code to:

```
  $query = db_select('users')
    ->extend('PagerDefault')
    ->fields('name', array('Name'), 'uid', array('Id'))
    //->addField('uid', 'User Id')
    //->addField('name', 'User Name')
    ->orderBy('created', 'DESC')
    ->limit(20);

```

And now it fails with

```
DOException: SQLSTATE[42P01]: Undefined table: 7 ERROR:
missing FROM-clause entry for table "name" at character 8:
SELECT name.Name AS Name, created AS created FROM {users}
users ORDER BY created DESC LIMIT 20 OFFSET 0; Array ( )
in function PagerDefault->execute() (line 80 includes/pager.inc).

```

I'm just trying to figure out **how to add a 2nd SQL-table field to a paginated db\_select**... Please do not suggest a "View" to me, because I'm trying to understand DBTNG at the moment.

# Answer
> 5 votes
The call to `db_select()` and the following calls to methods are wrong.

* The second parameter of `db_select()` is a table alias, which should then used when referring to the fields used by the query.
* the parameters passed to the `fields()` is wrong; see the following snippet for an example of how the call to `db_select()` should be.

```
$result = db_select('file_usage', 'f')
   ->fields('f', array('module', 'type', 'id', 'count'))
   ->condition('fid', $file->fid)
   ->condition('count', 0, '>')
   ->execute();

```

Your call to `db_select()` should be re-written as:

```
$query = db_select('users', 'u')
  ->fields('u', array('name', 'uid'))
  ->orderBy('created', 'DESC')
  ->limit(20)
  ->extend('PagerDefault');

```

# Answer
> 2 votes
Could you not just use the Views module to do this?

When creating a view just select `User` from the View Type list. It's a lot easier than doing this programmatically.

**Update**

---

According to the documentation for db\_select the third paramter is supposed to be an $options array.

> db\_select($table, $alias = NULL, array $options = array())

The clue is in the error message:

> Recoverable fatal error: Argument 3 passed to db\_select() must be an array, string given, called in my.page.inc

You code passes the string `uid` as the third parameter.

---
Tags: 7, database
---


# Question
Title: When should the "translatable" tag be added to a query?
I noticed that a Drupal core function is using the following code.

```
$categories = db_select('contact', 'c')
  ->addTag('translatable')
  ->fields('c', array('cid', 'category', 'recipients', 'selected'))
  ->orderBy('weight')
  ->orderBy('category')
  ->execute()
  ->fetchAll();

```

When should a module add that tag to the query it is executing?

I take that adding that query tag has some effect.

# Answer
> 1 votes
On its own, that tag doesn't much (yet). This is the so called *Dynamic data translation* feature, an idea that was born from Prepare Drupal core for dynamic data translation.

Basically, you define in your `hook_schema()` (See `contact_schema()` for an example) which fields can be translated, and then add the "translatable" tag to all queries which fetch the data. Use `'translated' => TRUE'` for all those columns.

Then, what is *supposed* to happen is that a contributed module can maintain separate tables per language for your translatable columns, automatically join these tables, and replace the selected columns with those from translated table.

However, as far as I know, nobody has yet attempted to write such a module.

---
Tags: 7, database
---


# Question
Title: display all products in a single page (without using pager) ubercart
I'm trying to display all products on a single page without a pager. Some sites have this functionality where you can click from page to page, or you can choose 'show all'. Or there is a drop down box where you can select how many products you want to view like this: http://www.newegg.com/Store/SubCategory.aspx?SubCategory=32&name=Laptops-Notebooks&Pagesize=100

Does ubercart have anything like this out of the box? I'm using the taxonomy\_term views to display my categorized products right now. So for example, for a category:show, you can get there by going to: taxonomy/term/12 which I override to be category/shoe (with pathauto aliases).

# Answer
You could use the Views module to create a Page display that lists all your products.

Also, I haven't tried it myself, but here's a blog post on Exposing Items Per Page in Drupal Views. A patch has been committed to the 6.x-3.x version of Views that apparently offers a similar "items per page" select box.
> 1 votes

# Answer
I second the suggestion to use Views.

I use it at Ubercart sites to do exactly what you ask.

I also have 'Taxonomy: Term Id' as one of the View Arguments, enabling term filtering in the URL. For example: expressions like '1,2,3' mean 'display all products with term ids 1 AND 2 AND 3' as well as expressions like '1+2+3' mean 'display all products with term ids 1 OR 2 OR 3'. Super useful. Plus I've marked 'all' to be the wildcard term, so displaying every product is the View URL with 'all' at the end.

You can see the semi-fancy result of this at a yet-under-construction site here:

http://www.cg-general-store.com/hdr\_coverflow\_panel/85

This is two Views with a form-block between them. Built using Panels and the Imageflow Views plugin. Both views, top and bottom, display the same info, controlled by taxonomy terms in the URL, with those terms controlled by the form-block simply doing to drupal\_goto() back to the same page with the radio selections providing the term ids for the URL. All done with Views, Panels, and a little bit of custom FAPI.
> 0 votes

---
Tags: views, ubercart
---


# Question
Title: Print module's default setting is annoying
We often use the print module to create PDF of nodes; most of the times, it works out-of-box.
For our requirements, however, one thing that makes me very annoyed is its default settings.

When the print module is installed, the "Print friendly page" option is enabled for all the available content types, even though it is required only for a few content types. Every time I have to disable it manually by editing the individual content type edit tab form.

Is there a global option I can use to disable the option for all the content types, and enable it for the content types I really need it?
Does this way works for everyone, or did I miss anything?

# Answer
Looking at http://drupalcontrib.org/api/drupal/contributions--print--print.module/function/print\_form\_alter/6, it seems to use a constant called PRINT\_TYPE\_SHOW\_LINK\_DEFAULT for the default value. That in turn is hardcoded to 1, see http://drupalcontrib.org/api/drupal/contributions--print--print.module/constant/PRINT\_TYPE\_SHOW\_LINK\_DEFAULT/6.

So you don't have a way to change that without hacking the module.

You could try to submit a feature request in the issue queue: http://drupal.org/project/issues/print
> 1 votes

---
Tags: 7, files
---


# Question
Title: Send a CSV file to the user on FAPI form submit
I have a FAPI form that collects some information from the user, then generates a CSV file. The intent is when the user clicks 'export' on the form, the CSV is downloaded straight away.

However, when the submit handler calls the CSV-generating function, the form just redirects, rather than serving the CSV.

Is there any way to make this form serve the CSV to the user directly, without generating a temporary file?

# Answer
> 6 votes
I guess the code in this blog post http://sirkitree.net/node/23 will help. Essentially you need to use exit() or die() at the end of your submit handler to prevent redirect.

```
  $file = $header ."\n";
  foreach ($accounts as $row) {
    $file .= $row ."\n";
  }
  header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  header('Content-Type: text/csv');
  header('Content-Disposition: attachment; filename="users.csv"');
  die(print $file);

```

# Answer
> 2 votes
The following routine will "push" a file to the user, causing the browser to pop a "save file" dialog:

```
function _cex_download( $output, $filename )
{
  header("Pragma: public");
  header("Expires: 0");
  header("Cache-Control: private");
  header("Content-type: application/octet-stream");
  header("Content-Disposition: attachment; filename=$filename");
  header("Accept-Ranges: bytes");
  echo $output;
  exit;
}

```

(Where 'cex' is the name of my custom module, and '\_cex' designates a private function.)

To use this, generate your CSV file inside a string, and then simply call this, passing in the CSV contents in $output and the filename the browser will be save it as in $filename.

I originally got this logic from how Ubercart handles secure downloads.

---
Tags: 7, forms
---


# Question
Title: How to invalidate a views cache based on custom criteria?
I have a custom content type (`story`) with a datetime field which determines if a story shows up in a the views that list the nodes of that content type; if the datetime defined for a node is newer than the current datetime, it will not show up.

My problem is that I have to go and empty `admin/config/development/performance` and click `Clear all caches` or uncheck `Cache pages for anonymous users`.

I would like to keep caching pages for anonymous users, so I am looking for other options.

Any help is much appreciated.

# Answer
It sounds like the problem is not views being cached, but that the entire page is being cached. If Drupal have a complete page cached, it doesn't matter if the view is cached or not. What you need to do, it to conditionally disable the page cache, or prevent Drupal caching that page in the first place.

There have been some talk about how to do the first, but this is not something I have tested or can advise.

Be warned, that messing with the Drupal caching system can give some unforeseen problems.

An alternative solution would be to empty the page cache or invalidate the cache for that particular page once a day/hour to make sure that it's relatively up to date. This is probably the route I would take in this situation.
> 3 votes

# Answer
I have a patch for boost that does exactly what you want, because that is a requirement of our setup. Problem is it needs an external crawler; we check for new content every 30 seconds across our 1,100 domains and re-crawl them. What you want can be done; But I'm still working on the details of making it work for the average setup. This is also for D6, so not much help for you.

Long story short you need something external to see if the time is up OR some logic in settings.php that handles this. That something external would be cron most likely.
> 1 votes

---
Tags: 7, views, caching
---


title: Custom module with its own menu?

text:
# Question
Title: Custom module with its own menu?
I am in the process of writing my 3rd custom module and this one is my biggest challenge yet. I know how to use hook\_menu to generate menu items, and depending on the path you choose determines where they show up on the site (administration menu or main menu, etc).

My question is - how do I specify a NEW menu, so that the paths I create do not appear in "primary links" or "navigation" but in their own "custom module" menu?

# Answer
> 7 votes
You specify the menu\_name parameter.

*From the devel module:*

```
$items['devel/cache/clear'] = array(
  'title' => 'Empty cache',
  'page callback' => 'devel_cache_clear',
  'description' => 'Clear the CSS cache and all database cache tables which store page, node, theme and variable caches.',
  'access arguments' => array('access devel information'),
  'menu_name' => 'devel',
);

```

---
Tags: 7, routes, hooks
---


# Question
Title: Can I have a views field handler with an exposed form, or a filter handler with pre_query?
It's basically in the title, but here's the question:

I'm trying to create a way to allow the user looking at a view to control which columns are visible. This isn't very hard, provided I can get called in the right place. Specifically, I need to be called in three places:

* in some kind of configuration pane
* in the exposed form
* in the pre\_render function

Both field handlers and filter handlers get a configuration pane. But only filter handlers get to affect the exposed form, and only field handlers get access to the pre\_render function.

Although I might be able to get something working by combining a handler with various hooks, I would prefer everything to be together.

Does anyone know how to convince Views to either call a field handler when rendering the exposed form, or to call a filter handler for the pre\_render function?

# Answer
> 0 votes
It turns out that the `view` object has a property for each class of handlers that should be called. So to take a filter handler and have it be called as a field, you need to add it to the `field` array:

```
function query () {
    $this->view->field[$this->options['id']] = $this;
}

```

Your filter will then get called as a field. I found it useful, after I was done, to remove the filter from the set of field handlers:

```
function pre_render ($values) {
    // do stuff here

    unset($this->view->field[$this->options['id']]);
}

```

# Answer
> 1 votes
If I understand your question correctly, here's how I would go about this:

What you need to do is create a base node view. This should have all fields which are present regardless of other options selected. You'll want at least one exposed filter, so that views will render a form which you can hook into for form alter. Your process for modifying the view on the fly will be two fold.

* The first will be a hook\_form\_alter() in which you make any modifications needed to the exposed views form. Add in any custom form elements which you'll use to control the fields displayed in the view. In your submit handler, you'll need to stuff the form values into session, so you can access them later.
* The second is to use hook\_menu\_alter to override the default page handling in views and provide your own callback. In that callback you'll need to programmatically load and display the view. You can also add/remove additional fields to be displayed on the fly by calling $view-\>override\_option('fields', array($some\_fields));. I recommend looking at exported views to get the proper format for this, as anything you see in there is valid to do before executing the view. After you've added the fields you need, just return $view-\>execute\_display(); to render the view. You can see an example of where I do this at http://890234892342.privatepaste.com/6b72c3e011 -- In this case, I'm only swapping out views displays / filters / arguments on the fly, but the exact same method will work for adding/removing fields. Again -- looking at exported views code is a great method to understand how you can swap this stuff out on the fly. When trying to figure out the format for modifications I need to make, I actually modify the view, export it, look at the exported code, and then revert it back to what it was originally. This allows me to see how views is formatting various fields and what array I need to pass into $views-\>override\_options() to get the desired behavior.

It's not a particularly easy process to either explain nor do, but this is an effective method for programmatically altering views on the fly. Feel free to ask followup questions if there is something you don't understand.

---
Tags: 7, views
---


# Question
Title: In which cases should hook_process() and hook_process_HOOK() be used?
Considering that some modules implement hook\_process() to alter the content of some variables and replace their content with themed content, in which cases should a module implement `hook_process()` instead of hook\_preprocess() (or hook\_preprocess\_HOOK())?

```
function rdf_process(&$variables, $hook) {
  // Handles attributes needed for content not covered by title, content,
  // and field items. It does this by adjusting the variable sent to the
  // template so that the template doesn't have to worry about it. See
  // theme_rdf_template_variable_wrapper().
  if (!empty($variables['rdf_template_variable_attributes_array'])) {
    foreach ($variables['rdf_template_variable_attributes_array'] as $variable_name => $attributes) {
      $context = array(
        'hook' => $hook,
        'variable_name' => $variable_name,
        'variables' => $variables,
      );
      $variables[$variable_name] = theme('rdf_template_variable_wrapper', array('content' => $variables[$variable_name], 'attributes' => $attributes, 'context' => $context));
    }
  }
  // Handles additional attributes about a template entity that for RDF parsing
  // reasons, can't be placed into that template's $attributes variable. This
  // is "meta" information that is related to particular content, so render it
  // close to that content.
  if (!empty($variables['rdf_metadata_attributes_array'])) {
    if (!isset($variables['content']['#prefix'])) {
      $variables['content']['#prefix'] = '';
    }
    $variables['content']['#prefix'] = theme('rdf_metadata', array('metadata' => $variables['rdf_metadata_attributes_array'])) . $variables['content']['#prefix'];
  }
}

```

# Answer
I'll try to stay away from explaining the whole theme system. The order and use of the functions is best explained here.

Preprocessor functions run before process functions. You should run hook process for cases where you want to affect every theme call after all the preprocessors have run. (Well, I believe it is only every theme call with a .tpl file.)

RDF is a good example as it wants to insert meta data into every theme template. But in most cases it is not something you would want to do. Another example would be something like the Pirate module.

Preprocessors are more targeted. If you only want to change lists for example you could use a preprocess hook there. I believe that `hook_preprocess_HOOK()`s are run for templates and functions.

`hook_preprocess()` can be used in a theme if you wish to preprocess something which is not overridden in your theme, as the `theme_preprocess_HOOK()` won't trigger unless you do.
> 3 votes

---
Tags: theming, hooks
---


title: Version Control of a Content Type

text:
# Question
Title: Version Control of a Content Type
I'd like to create a content type. My problem is this content type will change frequently (every 6 months, I will add some fields and I will delete others).

How would you do it? I had thought several options:

1) Create a "version" field with a default value for every version I make. With the "hook\_form\_alter" I would hide or I would show fields according to the version.

2) Another option is to create a new content type for every version "contenttype\_10", "contenttype\_11", "contenttype\_20",... Is there any module that makes possible create a new content type copying all the fields of a existing content type?

What do you think about it? What version is the best for you?

# Answer
To be perfectly honest, if you're looking to actually keep the content you already have, this kind of meddling is best dealt with by simple augmentation and field visibility, in my opinion.

Having lots of content types is not really workable; there's a multitude of scenarios like search and views where pulling from multiple types is just not "working smart".

The way I see this is that, if I correctly understand it, CCK will basically create tables automatically for you for your fields; if you add fields, it adds more stuff to the schemas and tables. If you want to "remove" fields, CCK will scrap this data, ergo it will no longer exist.

The best way to go about this then, as I see it, is to periodically augment your one content type with the new fields, and simply hide the "old" fields with a field visibility module. If you're so inclined, you could do that programatically as you alluded to. Your old data is still available in the same type (and tables) in this manner.

For "versioning" output of your type, then yes, in theory you could add a version field to the type, but if you're periodically changing the fields (and consequently the node form) then it seems likely that you could just alter the output as easily. You would probably have to update various views and node templates in any case. Display suite module might help you accomplish that last bit more easily - UI to handle node display etc rather than keep getting your hands dirty in templates (useful if updating frequently?)

http://drupal.org/project/ds

http://grayside.org/field-permissions-plus
> 4 votes

# Answer
The Features module is designed for this sort of database content to code version control. You could create your content type and export it as a Feature. That feature could then be version controlled like any other source code (using Git, SVN, etc).

If you just wanted to duplicate content types, the CCK module in Drupal 6 has a Content Copy sub-module that allows just that. In Drupal 7, I'm not sure if this is built into core. I would accomplish this task using Features.
> 5 votes

---
Tags: 7, version-control
---


# Question
Title: How can nested subdirectories and symbolic links be used without conflict with a multi-site Drupal installation?
My question is basically a reflection of the question found here (which unfortunately does not have a clear answer): http://groups.drupal.org/node/20604

Please note that this is not a question about multi-site setup, but it is rather a question about a complicated edge-case; please read through before jumping to suggestions. Also, take a look at the link above if you need more info.

Note also multi-site works generally fine, just not this case.

Some truths:

* I am using symbolic links (on RHEL5 to be exact)
* I am using Drupal 6.20
* I am using Apache
* I am using subdirectories (NOT subdomains, switching to subdomains is *not* an acceptable answer)
* My Drupal site directories are nested two levels deep (e.g. `/campus/bus`, `/campus/news`)
* The Drupal sites all use the same code base in the `/campus` directory
* The Drupal sites all use different (their own) databases

In my case, there are dozens of sites, but the first conflict I noticed was as follows. There are two sites at urls such as the below structure:

```
drupal.drupalsite.com/campus/bus

drupal.drupalsite.com/campus/news

```

In the `sites/[foldername]` the respective folders are:

```
drupal.drupalsite.com.campus.bus

drupal.drupalsite.com.campus.news

```

The campus folder in the web root contains the Drupal install, and also the symbolic links, so in `/var/www/campus` there are e.g., `news -> ./`, `bus -> ./`.

On the 'bus' subsite, attempting to go to `https://drupalsite.com/campus/bus/news` makes Drupal confused. It seems to drop everything in the request after the last directory. e.g., `drupalsite.com/campus/bus/news` will instead resolve to `drupalsite.com/campus/bus` and `drupalsite.com/campus/bus/news/headlines` will return a `404 not found`.

For another data point, I put a `var_dump` on `$dir` in the `conf_path()` function to see how many directories were being looked at for each request. For a non-conflicting URL, such as bus/undergraduate-programs I got the following:

```
drupal.drupalsite.com.campus.bus

```

However for a conflicting URL such as bus/news/headlines I get

```
drupal.drupalsite.com.campus.bus.news
drupalsite.com.campus.bus.news
com.campus.bus.news
drupal.drupalsite.com.campus.bus

```

There is a patch which could allow the multi-site setup to be done via sites.php instead of via the method of using symbolic links, however it would involve hacking core, and thus I am not willing to entertain it, though for reference it is here: http://drupal.org/node/231298#comment-3769752

To note, I also tried most of the suggestions in the original groups.drupal.org. thread as well as numerous hacks in .htaccess and my `httpd.conf` file, all to no avail. Please comment if you need further information to answer the question.

# Answer
> 2 votes
Are you using just one rewrite? I have this exact setup, and I take care of it with a separate rewrite for each sub-directory. If you just use the default index.php rewrite, the path gets rewritten back to the default, like drupal.drupalsite.com/index.php?q=/campus/news which is where the 404 comes from. I also use aliases in the server level config instead of symbolic links. It makes things cleaner. (Alias /campus/bus /var/www/html/whatever)

```
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /campus/bus/
RewriteRule ^(.)$ /campus/bus/?q=$1  [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /campus/news/
RewriteRule ^(.)$ /campus/news/?q=$1  [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /
RewriteRule ^(.*)$ ?q=$1  [L,QSA]

```

# Answer
> 0 votes
I think the setup you have at the moment in sub directories, is a little non standard, and may not be widely supported.

Given that you are already of piste, a small patch to core may be worth trying. Especially as the patch is in D7.

Or you could just switch to D7. No core hackery needed.

---
Tags: 6, multi-sites
---


# Question
Title: How to support legacy url alias' and/or support multiple url alias' (Conditional Pathauto?)
I am migrating a site from wordpress and need to preserve my url structure whilst supporting native pathauto urls in the future (for new content)

Overall Drupal's clean url process is almost identical to wordpress but I am finding some small discrepancies and with around 2k posts to migrate over I need a programmatic way to do this that won't feel like I'm trying to roll a keg up hill.

I was thinking of inserting in the old wordpress url as `field_legacy_slug` and then I could create paths based on that, but... as far as I know pathauto doesn't have any conditional abilities and I'd want to use a `field_legacy_slug` only if it exists, else use a standard token based pathauto pattern (site.com/2011-01-01/title-of-post)

I also don't think creating multiple alias' for content is advisable (aka letting wordpress url alias' exist beside the native pathautos) - but I am course asking *you* for insight into this :)

Creating node paths on import myself and allowing pathauto to catch new nodes seems like my only option but I'd hate for someone to run an "Update path alias" and ruin it all.

# Answer
I believe the new-for-Drupal-7 Redirect module will provide what you need. Have not used it myself yet, but I used Path Redirect (which provides similar functionality for Drupal 6) to solve a similar problem. I generated a two-column table of values (old URL in one column, new URL in the other), and fed that to Path Redirect -- problem solved. Hope this helps.
> 2 votes

# Answer
You might want to look into Global Redirect. I use it to redirect all `/node/###` queries to the proper path. All the content could have the new URLs, but the old URLs would redirect to the canonical URL. This would solve your inadvertent 'Update path alias' problem, and also help with SEO magic.
> 1 votes

---
Tags: 7, path-aliases
---


# Question
Title: Why would my Views take longer to load when I'm logged in as a regular user than one I'm logged in as an administrator
I have a Views display that returns a 30 row table of node parameters that is taking about 16 seconds to load when I'm not logged in as either user 1 or one of the users with the administrator role. When I'm logged in as an administrator the views takes about 2 seconds to load.

What am I doing wrong here?

# **Update**

It's definitely user\_access issue... The next question will be, how do I configure the views so that it only checks for the restrictions placed on the views? Here are the SQL side by side

```
SELECT node.nid AS nid,
   node_data_field_lg_year.field_lg_year_value AS node_data_field_lg_year_field_lg_year_value,
   node.type AS node_type,
   node.vid AS node_vid,
   node_data_field_lg_year.field_lg_pl_value AS node_data_field_lg_year_field_lg_pl_value,
   node_data_field_lg_year.field_lg_act_value AS node_data_field_lg_year_field_lg_act_value,
   node_data_field_lg_year.field_lg_res_value AS node_data_field_lg_year_field_lg_res_value,
   node_data_field_lg_year.field_lg_sb_value AS node_data_field_lg_year_field_lg_sb_value,
   node_data_field_lg_year.field_lg_hb_value AS node_data_field_lg_year_field_lg_hb_value,
   node_data_field_lg_year.field_lg_session_value AS node_data_field_lg_year_field_lg_session_value,
   node.uid AS node_uid,
   node_revisions.format AS node_revisions_format,
   node.status AS node_status
 FROM {node} node
 LEFT JOIN {content_type_paleghist} node_data_field_lg_year ON node.vid = node_data_field_lg_year.vid
 LEFT JOIN {node_revisions} node_revisions ON node.vid = node_revisions.vid
 WHERE node.type in ('%s')
   ORDER BY node_data_field_lg_year_field_lg_year_value ASC

SELECT DISTINCT node.nid AS nid,
   node_data_field_lg_year.field_lg_year_value AS node_data_field_lg_year_field_lg_year_value,
   node.type AS node_type,
   node.vid AS node_vid,
   node_data_field_lg_year.field_lg_pl_value AS node_data_field_lg_year_field_lg_pl_value,
   node_data_field_lg_year.field_lg_act_value AS node_data_field_lg_year_field_lg_act_value,
   node_data_field_lg_year.field_lg_res_value AS node_data_field_lg_year_field_lg_res_value,
   node_data_field_lg_year.field_lg_sb_value AS node_data_field_lg_year_field_lg_sb_value,
   node_data_field_lg_year.field_lg_hb_value AS node_data_field_lg_year_field_lg_hb_value,
   node_data_field_lg_year.field_lg_session_value AS node_data_field_lg_year_field_lg_session_value,
   node.uid AS node_uid,
   node_revisions.format AS node_revisions_format,
   node.status AS node_status
 FROM node node
 LEFT JOIN content_type_paleghist node_data_field_lg_year ON node.vid = node_data_field_lg_year.vid
 LEFT JOIN node_revisions node_revisions ON node.vid = node_revisions.vid
  INNER JOIN node_access na ON na.nid = node.nid WHERE (na.grant_view >= 1 AND ((na.gid = 0 AND na.realm = 'all') OR (na.gid = 2 AND na.realm = 'members_only blog') OR (na.gid = 2 AND na.realm = 'all_view blog') OR (na.gid = 2 AND na.realm = 'members_only image') OR (na.gid = 2 AND na.realm = 'all_view image') OR (na.gid = 2 AND na.realm = 'members_only product') OR (na.gid = 2 AND na.realm = 'all_view product') OR (na.gid = 2 AND na.realm = 'members_only memberships') OR (na.gid = 2 AND na.realm = 'all_view memberships') OR (na.gid = 2 AND na.realm = 'members_only donation') OR (na.gid = 2 AND na.realm = 'all_view donation') OR (na.gid = 2 AND na.realm = 'members_only book_sale') OR (na.gid = 2 AND na.realm = 'all_view book_sale') OR (na.gid = 2 AND na.realm = 'members_only cle_class') OR (na.gid = 2 AND na.realm = 'all_view cle_class') OR (na.gid = 2 AND na.realm = 'members_only cle_class_event') OR (na.gid = 2 AND na.realm = 'all_view cle_class_event') OR (na.gid = 2 AND na.realm = 'members_only cle_instructor') OR (na.gid = 2 AND na.realm = 'all_view cle_instructor') OR (na.gid = 2 AND na.realm = 'members_only cle_registrant') OR (na.gid = 3 AND na.realm = 'checkout_item cle_registrant') OR (na.gid = 36 AND na.realm = 'checkout_item cle_registrant') OR (na.gid = 2 AND na.realm = 'members_only cle_roster') OR (na.gid = 3 AND na.realm = 'no_access cle_roster') OR (na.gid = 2 AND na.realm = 'members_only cle_student') OR (na.gid = 3 AND na.realm = 'node_specific cle_student') OR (na.gid = 2 AND na.realm = 'members_only event') OR (na.gid = 2 AND na.realm = 'all_view event') OR (na.gid = 2 AND na.realm = 'members_only jenkdb') OR (na.gid = 2 AND na.realm = 'all_view jenkdb') OR (na.gid = 2 AND na.realm = 'members_only nn') OR (na.gid = 2 AND na.realm = 'all_view nn') OR (na.gid = 2 AND na.realm = 'members_only asklib') OR (na.gid = 3 AND na.realm = 'no_access asklib') OR (na.gid = 1 AND na.realm = 'members_only paleghist') OR (na.gid = 1 AND na.realm = 'all_view paleghist') OR (na.gid = 2 AND na.realm = 'members_only membership_benefits') OR (na.gid = 2 AND na.realm = 'all_view membership_benefits') OR (na.gid = 2 AND na.realm = 'members_only member_directory') OR (na.gid = 2 AND na.realm = 'all_view member_directory') OR (na.gid = 2 AND na.realm = 'members_only page') OR (na.gid = 2 AND na.realm = 'all_view page') OR (na.gid = 2 AND na.realm = 'members_only jlldonate') OR (na.gid = 3 AND na.realm = 'checkout_item jlldonate') OR (na.gid = 36 AND na.realm = 'checkout_item jlldonate') OR (na.gid = 2 AND na.realm = 'members_only rb_case') OR (na.gid = 2 AND na.realm = 'all_view rb_case') OR (na.gid = 2 AND na.realm = 'members_only docdel') OR (na.gid = 3 AND na.realm = 'checkout_item docdel') OR (na.gid = 36 AND na.realm = 'checkout_item docdel') OR (na.gid = 2 AND na.realm = 'members_only book_suggestions') OR (na.gid = 3 AND na.realm = 'no_access book_suggestions') OR (na.gid = 1 AND na.realm = 'members_only document_download') OR (na.gid = 1 AND na.realm = 'no_access document_download') OR (na.gid = 2 AND na.realm = 'members_only form_info_nodes') OR (na.gid = 1 AND na.realm = 'members_only jllfileshare') OR (na.gid = 1 AND na.realm = 'node_specific jllfileshare') OR (na.gid = 2 AND na.realm = 'members_only story') OR (na.gid = 2 AND na.realm = 'all_view story') OR (na.gid = 2 AND na.realm = 'members_only suggestions') OR (na.gid = 3 AND na.realm = 'no_access suggestions'))) AND (  node.type in ('paleghist')
   )ORDER BY node_data_field_lg_year_field_lg_year_value ASC
 LIMIT 0, 30;

```

# Answer
> 4 votes
As you can see, Views needs to add a join to the node\_access table for users without the administer nodes (bypass node access in D7) to check which nodes they are allowed to see.

16 seconds is extremely long, how many nodes are there? Are you using multiple content access modules? Check the number of rows in {node\_access}. You an also let MySQL explain what it is doing with the query by executing `EXPLAIN query_here`. It will then show what indexes it is using and so on.

# Answer
> 1 votes
See the code for `user_access()`, it doesn't run any queries for UID 1.

---
Tags: 7, views
---


# Question
Title: Last form validation function is passing an error even though the first one registers the user
I wrote a custom user\_login form validation function that calls user\_external\_login\_register() to register and login the user, but the last validation function for the form calls form\_set\_error().

The form's #validate array looks like this:

```
validate (Array, 4 elements)

    * 0 (String, 32 characters ) vtiger_portal_user_form_validate
    * 1 (String, 24 characters ) user_login_name_validate
    * 2 (String, 32 characters ) user_login_authenticate_validate
    * 3 (String, 25 characters ) user_login_final_validate

```

user\_login\_final\_validate() is here: http://api.drupal.org/api/drupal/modules--user--user.module/function/user\_login\_final\_validate

Here is the code for vtiger\_portal\_user\_form\_validate() and the authentication function that it calls:

```
function vtiger_portal_user_form_validate($form, &$form_state) {
  if (!vtiger_portal_authenticate($form_state)) {
    // Not a portal user. Let the other validation handlers run.
  } else {
    global $user;
    if($user->uid) {
      dpm($user);
    }
  }
}

/**
 * Custom user authentication function
 */
function vtiger_portal_authenticate($form_state) {
  $username = $form_state['input']['name'];
  $password = $form_state['input']['pass'];
  $testname = drupal_substr(drupal_strtolower($username),0,4);
  if ($testname == "dave") {
    user_external_login_register($username, 'vtiger_portal');
    return TRUE;
  } else {
    return FALSE;
  }
}

```

I'm Seeing the "Sorry, unrecognized username or password. Have you forgotten your password?" error and at the same time, being successfully logged in. I have printed the $user object after calling user\_external\_login\_register() and it shows that the uid is 9.

Can anyone help me figure out why I'm seeing an error from user\_login\_final\_validate() when the user has obviously logged in successfully?

**Update: I've found the root of the problem.**

From the line 2121, user.module contains the following code.

```
// We are not limited by flood control, so try to authenticate.
// Set $form_state['uid'] as a flag for user_login_final_validate().
$form_state['uid'] = user_authenticate($form_state['values']['name'], $password);

```

user\_login\_authenticate\_validate() sets $form\_state\['uid'\] to FALSE so that later user\_login\_final\_validate() sends it's error message.

# Answer
The OP mistakenly pasted user\_login\_final\_validate() from D6 instead of D7. In D7, you avoid that error message by simply setting `$form_state['uid'] = [a number]`. You do that from within your custom #validate callback. Once you have done that, user\_login\_final\_validate() will not throw an error and your form submission proceeds and thus login proceeds.
> 2 votes

# Answer
It would appear that the `user_login_authenticate_validate()` function will actually log the user in. The workaround is to unset the `user_login_authenticate_validate()` callback, and call `user_authenticate()` from `vtiger_portal_authenticate()` once you have performed your additional validation.

In order to unset the `user_login_authenticate_validate()` callback, you'll need to implement `hook_form_alter()`:

```
vtiger_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'user_login') {
    $key = array_search('user_login_authenticate_validate', $form['#validate']);
    if ($key !== FALSE) {
      unset($form['#validate'][$key]);
    }
  }
}

```
> 0 votes

---
Tags: 7, forms
---


# Question
Title: Replace summary/description with another field in Views RSS output
I have a view for an RSS feed which uses the node output (only option it seems when RSS style is selected) so I cant choose custom fields. But, as the body field is 'text and summary' the RSS view uses that summary for the 'description' field but I'd like to use another field for that element in the feed.

Does that make sense?

An option is to just create another field-based view and my own templates to create an RSS output, but it just seems like such a trivial change to require so much work.

Would love to hear some thoughts.

Thanks in advance.

# Answer
> 5 votes
I worked it out. On the 'Manage Display' tab for a content type, there is a 'Custom Display Settings' section at the bottom. Opening that and selecting RSS gives you an RSS Display Fields area where you can change the fields to be used. Looks like it might just work for me.

# Answer
> 2 votes
Before rolling your own templates, you may be able to do what you want using the Views RSS module. This allows you to map fields to RSS elements, rather than being forced to use the node display.

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


# Question
Title: Detect the taxonomy term(s) of a node from within a template file
I have a Drupal 7 site with a content type of event.

I have a taxonomy called "event types" that has 5 options (Party, Conference, Meeting, etc)

I have one template named node--event.tpl.php for styling the standalone event nodes.

How can I detect which taxonomy terms apply to a given event node from within the template file? I need to change some of the presentation logic based on the taxonomy term associated with the event.

I am not using the taxonomy in the URL, so I need to find another method for detecting the event type. Devel doesn't seem to show me any values of taxonomy terms to work with.

# Answer
As alluded to in the first answer, you should use a preprocess function, but probably for the node template.

For the `node.tpl.php` template (and all derivatives) the function is defined as

```
MYTHEME_preprocess_node(&$vars) {
}
```

and should appear your theme's `template.php` file.

You must clear the Drupal cache in order to reset the theme registry such that Drupal recognizes and executes this function.

The `$vars` argument of the function is an array that contains all the template variables which subsequently appear in the tpl file (`$vars['foo']` will be leveraged as `<?php print $foo; ?>` in the tpl file).

This also includes the native `$node` object, which will allow you to inspect `$node->taxonomy`, and create any subsequent variables accordingly. You can leverage these in the tpl file.

The best way to inspect and discover the components of `$vars` is to use the Devel module's `dpm()` function, which nicely prints any variable to the theme's messages box.

So, enable devel, create the following in `template.php`, clear cache, refresh viewing a node, and work from there.

```
MYTHEME_preprocess_node(&$vars) {
  dpm($vars);
}
```

You may also be interested in my session on Drupal preprocess functions from Drupalcon Copenhagen or the Drupal handbook page.
> 2 votes

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


title: Building a Views Filter

text:
# Question
Title: Building a Views Filter
I want to build a filter for a custom module I built and have integrated with views. In essence, the module allows you to define types of relationships between different nodes. I'd like to create a filter for this so that I can display nodes of a certain type of relationship.

I'm not finding any documentation that describes filters in more detail and explaining the various parts to them. The API documentation is horrific in this regard.

Can anyone suggest a good resource/article on building View Filters in detail?

# Answer
> 6 votes
Have you tried http://views-help.doc.logrus.com/ or the advanced help module?

**Edit:**:
Unfortunately there is no deeper documentation that I know of. I wrote a custom field handler and got most info from other handlers that came with views. I would recommend looking at the views/handlers directory, especially all files beginning with 'views\_handlers\_filter\_'. At least that is what I did.

# Answer
> 4 votes
I think the reason that the documentation isn't as deep as you like is that once you get to the level of creating a filter, the onus is on you to understand what that means. The best Views' documentation is the basic filters that already exist. You should look at things like views\_handler\_filter\_string and views\_handler\_filter\_numeric to see how a really basic filter is structured. Most filters inherit from one of these, because most fields ultimately end up needing either string operators or numeric operators.

The second place to look is views/modules/node and check out the node filters. That handles your basic special filters for things like node types. Once you've figured out how the views\_handler\_filter\_in\_operator works, that's 99% of filters and you need to very little on your custom filters except use one of those.

# Answer
> 3 votes
The best documentation on Views API is most likely http://drupal-building-blocks.com/. So that might be an option if you can (and want to) afford it.

As EricSchaefer already said, your best bet except of that book is to use an existing filter that is as close as possible to what you want, copy it to your module, rename and start extending it.

A google search for "drupal create custom views filter" listed this as the first result and that had a link to this, both sound like they could be of use to you.

# Answer
> 2 votes
Here are the tutorials I found for creating Views filters:

They are pretty basic and you might still be left wondering about what's what. There's no other choice but to go clicking around Views functions and methods to investigate properties, inheritance, etc. If I find more tutorials I'll keep adding them.

# Answer
> 0 votes
There is a 2011 book, "Drupal's Building Blocks: Quickly Building Web Sites with CCK, Views, and Panels", that is excellent.

Also do a search on the web for: 110112-WebformInViews2.mov. It is an excellent step by step movie in creating a View.

Or, just make a copy of your view and filter out what you don't want.

---
Tags: 7, views
---