# Question
Title: moving *.tpl into "templates" folder, but Drupal does not recognize them. How?
I am building a custom theme. Currently, I put all the overridden \*.tpl files under the theme root folder; it would be more clean and meaningful to put those files under "mytheme/templates", but Drupal does not recognize them after I move them. (I did clear the cache.)

Did I miss any steps?

# Answer
> 1 votes
I've also run into a situation where I had to create a **page.tpl.php** file before Drupal would recognize other **page--foo.tpl.php** files.

# Answer
> 0 votes
Did you use the new template suggestions with two hyphens instead of one ?

For instance, **page-front.tpl.php** becomes **page--front.tpl.php** in D7

More on drupal.org

# Answer
> 0 votes
I have a copy of Bartik Theme named Vartik.

In the templates folder I have the original page.tpl.php and I have created a page--node--add--CONTENT\_TYPE\_ID.tpl.php and it works.

Try it!

---
Tags: 7, theming
---


# Question
Title: Displaying external SQL-table as paginated list
The following code works well for displaying a paginated list of Drupal users.

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

  $result = $query->execute();

  $list = array();
  foreach ($result as $row) {
    $list[] = sprintf('<a href="/user.php?id=DE%u">%s</a>', $row->uid, $row->name);
  }

  $theme_args = array('items' => $list, 'type' => 'ul');
  return theme('item_list', $theme_args) . theme('pager');
}

```

I tried fetching from an external SQL-table using the following code.

```
function generate_list() {
  $query = db_select('pref_users', 'u')
    ->extend('PagerDefault')
    ->fields('u', array('first_name', 'id'))
    ->orderBy('created', 'DESC')
    ->limit(20);

  $result = $query->execute();

  $list = array();
  foreach ($result as $row) {
    $list[] = sprintf('<a href="/user.php?id=%s">%s</a>', $row->id, $row->first_name);
  }

  $theme_args = array('items' => $list, 'type' => 'ul');
  return theme('item_list', $theme_args) . theme('pager');
}

```

I get this error.

> PDOException: SQLSTATE\[42P01\]: Undefined table: 7
> ERROR: relation "drupal\_pref\_users" does not exist at character 67: SELECT COUNT(\*) AS expression FROM (SELECT 1 AS expression FROM {pref\_users} u) subquery; Array() in method PagerDefault-\>execute() (line 75 in file includes/pager.inc).

Does anybody please know a way to tell Drupal to fetch data from *pref\_users* and not from *{pref\_users}* at it seems to do?

# Answer
the squiggly brackets are used for escaping table names in drupal. For cases where you have multiple sites in one database.

I'm guessing that you have a db prefix set up for all of your Drupal tables to be drupal\_

You can set this on a db connection before `$result = $query->execute();` using the setprefix method

Something like

```
 $query->setprefix(array(
     'default'   => 'drupal_',
     'perf_users'     => ''));

```

*untested code*

may do it. However you are more likely to want to change your settings.php file and set table prefixs in there
> 1 votes

---
Tags: database, 7
---


# Question
Title: Login box on one site to log you into another site too
My client has a drupal 6 site. This is used with there clients to project manage projects. We are building a new main website for our client using drupal (6/7 yet to be decided). They wish to have a login box on the home page of there new website that will log you into the project manage site. So something like:

Go to main website Enter user name and password for project site Website changes to project site with user logged in.

Would this be possible? The user would not have a login on the main site.

Both sites would be running on the same machine. Part of me is thinking that maybe multi-site could be my answer.

# Answer
Sure it's possible. There are many ways to do this.

A simple solution, if both sites are running the same drupal version, would be to make a custom form, and connect to the other sites database, and get the login form. You would need to make sure that the submit path would go to the project manage site.

When the form is submitted, they would automatically go the that site, and if user/pass is correct, they would also be logged in.

*Disclaimer:* I haven't actually tried this before, but it should work just fine. Drupal wont know where the form was submitted, so should be the same as being on their project site and using the login form.
> 2 votes

# Answer
What you are looking for is called Single Sign On (SSO).
There are many modules that do this in various ways. If they are on the same server you could potentially use the shared table approach. If they are on different servers you would have to use another approach. The Bakery module is what Drupal.org uses to auto log in you into groups.drupal.org. However, I'm not sure that works across top level domains.
> 1 votes

---
Tags: users, multi-sites
---


# Question
Title: Redirect to an external site when accessing the page of a node meeting a set of condition
I need to redirect users to an external website when they access the node view page at `node/%node` of a node meeting some conditions.

What would the proper/best way to achieve this (using code) be?

# Answer
> 2 votes
I would use `hook_node_view`.

Remember to check the view mode along with the conditions, so you don't redirect on pages where only the teaser is shown.

It should look something like this:

```
module_node_view($node, $view_mode, $langcode) {
  if ($view_mode == 'full' && "Conditions") {
    drupal_goto('http://example.com');
  }
}

```

# Answer
> 0 votes
We created a content type using CCK Redirection and then external links could be treated like nodes. So you could use node access modules, the rules module, etc. It has worked quite well for us.

---
Tags: 7, redirection
---


title: Filtering CCK views by path

text:
# Question
Title: Filtering CCK views by path
I've created a View in Drupal 6 which I am using to display a list of events. I would like to be able to filter the view by year via the path like this:

```
http://www.mysite.com/events -> gives me all events
http://www.mysite.com/events/2011 -> gives me the events in 2011
http://www.mysite.com/events/2010 -> gives me the events in 2010

```

I see that you can specify arguments in the path, but I can't seem to be able to access that argument to use within the filter controls for the view. Any help would be greatly appreciated.

# Answer
> 3 votes
You want to add a filter and use "Date: Date (node)" not "Node: Date" for a CCK date field. Then, you can choose "Select" and granularity of "Year". Once you expose the filter, you will get a drop down list to choose a year to filter by. The paths will need to be arguments, as you've found out. But, they will work separately. If you want the drop-down to only work with those specific paths, I think you have to create your own select box.

---
Tags: entities, 6
---


# Question
Title: db_affected_rows in Drupal 7 for db_query
I just noticed that @Berdir was so nice to remove `db_affected_rows` from Drupal 7. I'm now wondering what the best practice is now to detect if the query you ran changed anything in the database.

A typical usecase would be to.

```
db_query(...);
if (!db_affected_rows()) {
  db_query(...);
}

```

I took a look at the query object returned from db\_query, but it didn't seem like much help.

**Update:**
I see I was a bit unclear as to what circumstances I needed the info.

My current use case, is a quite simple one. I have a table for a node type with a nid column and some data columns. I have a form an upon submitting the form, I want to either insert or update the row in the db.

The problem with `db_update`/`db_insert` is that, if I use update first, and insert if update returns 0, I wont catch the condition, where the form was submitted with the value in the db. If I use db\_insert first, that will raise en error if there already is a row in the db.

I suppose I in this specific condition could insert a blank value when the node is created and then only use update, but for some cases that might not be possible, if I needed to store info that was keyed to an external database. I would also like to avoid having to depend on database values for my code to function.

My usual strategy for such cases, has been to do a

```
db_query("INSERT IGNORE INTO ...")
if (!db_affected_rows()) {
  db_query("UPDATE ...");
}

```

Doing this is both simple and error free no matter what condition the db is in. The best option I can see right now, would be to handle it with SQL and do this:

```
db_query("INSERT ... ON DUPLICATE KEY UPDATE");

```

But I was hoping that the db API would be able to handle this.

# Answer
> 8 votes
After digging around, I found that Drupal supplies a ready named tool for my exact use case:

*Insert a row in the db, or update the existing if it's already there.*

This is called merge queries, which can be done atomically for some db engines.

The syntext is pretty simple:

```
db_merge('example')
  ->key(array('name' => $name))
  ->fields(array(
    'field1' => $value1,
    'field2' => $value2,
))
->execute();

```

# Answer
> 9 votes
That information is directly returned by the execute() method of Delete/UpdateQuery, see for example: UpdateQuery::execute().

```
<?php
$affected = db_update('some_table')
  ->fields(array(
    'some_field' => $value,
  ))
  ->condition('another_field', $id)
  ->execute();
?>

```

And InsertQuery::execute() returns the last insert id.

---
Tags: 7, database
---


# Question
Title: Error class not being set on form fields
I have a complex for that for various reasons I am validating in the \_submit hook instead of the \_validate. This is working great with the exception that the `error` class isn't getting added to the form elements.

Is there something simple I am missing or do I need to use `form_get_errors` and set the classes myself?

*(The reason I am doing validation in submit is because I want to save the form data regardless of if it is valid or not.)*

# Answer
The easiest thing to do, would be to save the form data in the validation step if the form has errors.

```
function form_validate(&$form, &$form_state) {
  // Validate
  if (form_get_errors()) {
    // This code is only run if the form has errors.
    // Save the form data
    db_query("...");
  }
}

```

Then you could raise the errors and let drupal do it's thing, and use the submit function for it's intended use: handle valid form data.

If you need to process the data this can be done in the validation step as well, as the info in the `$form_state` array will be carried to the form submit handler.
> 0 votes

---
Tags: forms
---


# Question
Title: Adding JavaScript and CSS to a particular menu page
I have set up a Drupal 7 web site with a few custom blocks and menus written by me.

I have a non-Drupal PHP script displaying users (some of them are external, i.e. not stored in drupal tables) as a table with the DataTables jQuery plugin.

I would like to rewrite that script as a Drupal menu, so that it can be called as http://preferans.de/top.

The content of **my.module** is the following.

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

```

The content of **my.top.inc** is the following.

```
function my_top_callback() {
  return array (
    'top_table' => array (
      '#type' => 'markup',
      '#markup' => generate_html_table_with_php(),
    ),
  );
}

```

My problem is that I don't understand how to add the CSS and JavaScript code, so that it is available for the **/top** page, but not for any other Drupal paths.

I should probably call:

```
   drupal_add_css('/demo_table_jui.css', 'file');
   drupal_add_css('/smoothness/jquery-ui-1.8.4.custom.css', 'file');
   drupal_add_js('/jquery.dataTables.min.js', 'file');
   drupal_add_js('
       $(document).ready(function() {
         $("#rating").dataTable( {
            "bJQueryUI": true,
            "sPaginationType": "full_numbers"
          });
        ', 'inline');

```

(Please see the head-section of my original non-Drupal script).

How do I limit these calls to the **/top** page and where should I perform these calls? Should I put them in a hook, or by adding some properties to my menu?

# Answer
> 6 votes
Generally, CSS and JavaScript files are added with hook\_init(), which allows those files to be aggregated together, when aggregation is enabled.

Using `hook_init()` (I suggest you not to do this, anyway) you could conditionally add the files basing on the page being visited.

```
function my_init() {
  if (arg(0) == 'top') {
    // Add the files.
  }
}

```

The reason I don't suggest you to do this is that the hook would be called for every pages, including the ones you are not adding the files. `hook_init()` is generally used to add files to each page.

You can add those files in the menu callback (a.k.a., the page callback); if the menu callback is a form builder function, then you can use the `#attached` property, as the following code.

```
$form['#attached']['css'] = array(
  drupal_get_path('module', 'ajax_example') . '/ajax_example.css',
);

$form['#attached']['js'] = array(
  drupal_get_path('module', 'ajax_example') . '/ajax_example.js',
);

```

About the inline code you are adding, I would recommend you to put also that in a file, and to use Drupal behaviors instead of `$(document).ready()`. If you need to pass arguments to the JavaScript code, you can use JavaScript settings (see drupal\_add\_js() to understand in details how to pass settings to JavaScript code).
Managing JavaScript in Drupal 7 explains in details how to manage JavaScript code in Drupal 7, and the section titles *Behaviors* reports how Drupal behaviors are changed in the latest Drupal version.

# Answer
> 3 votes
You can add the code in your menu callback. Instead of adding the JS code inline, I would suggest that you create your own JS file.

```
function my_top_callback() {
  drupal_add_css('/demo_table_jui.css');
  drupal_add_css('/smoothness/jquery-ui-1.8.4.custom.css');
  drupal_add_js('/jquery.dataTables.min.js');
  drupal_add_js(drupal_get_path('module', 'my') . '/my.js');
  return array (
    'top_table' => array (
      '#type' => 'markup',
      '#markup' => generate_html_table_with_php(),
    ),
  );
}

```

You should then add the `my.js` file to your my module. Notice that `$`isn't a global variable in Drupal 7 instead use `jQuery`:

```
(function($) {
  $(document).ready(function() {
    $("#rating").dataTable( {
      "bJQueryUI": true,
      "sPaginationType": "full_numbers"
    });
  });
})(jQuery);

```

You could also make this into a JavaScript behavior which is the recommended thing to do. That would look something like this:

```
(function ($) {

  Drupal.behaviors.my = {
    attach: function(context, settings) {
      $("#rating").dataTable( {
        "bJQueryUI": true,
        "sPaginationType": "full_numbers"
      });
    }
  };
})(jQuery);

```

---
Tags: 7, javascript
---


# Question
Title: How to create new node programmatically, when a new user is created, in Drupal 7?
At the time when a new user is created, I want programmatically to create a new node (of some defined type) and make him the owner of that node.

How can I do this in Drupal 7 ?

# Answer
> 5 votes
It is correct that you need to implement hook\_user\_insert(). The code that needs to be implemented is different from the code you would implement in Drupal 6 because the node body is a field, in Drupal 7 (see Field API).

The implementation of `hook_user_insert()` should be similar to the following.

```
function mymodule_user_insert(&$edit, $account, $category) {
  $body_text = 'This is the text contained in the node body.'; // [1]
  $node = new stdClass();
  $node->type = 'article';  // [1]
  node_object_prepare($node);

  $node->language = LANGUAGE_NONE;

  $node->body[$node->language][0]['value']   = $body_text;
  $node->body[$node->language][0]['summary'] = text_summary($body_text);
  $node->body[$node->language][0]['format']  = 'filtered_html';

  $node->title    = 'Node Created Programmatically on ' . date('c'); // [1]
  $node->uid      = $account->uid;

  $path = 'content/programmatically_created_node_' . date('YmdHis'); // [1]
  $node->path = array('alias' => $path);

  node_save($node);
}

```

The lines marked with `[1]` are the parts that you need to personalize.

# Answer
> 2 votes
This is done pretty much as Drupal 6. Create an object with the required values, and use `node_save`. This should all happen in `hook_user` op `insert`:

```
module_user_insert(&$edit, $account, $category) {
  $node = new stdClass();
  $node->title = 'title'
  $node->uid = $account->uid;
  node_save($node);
}

```

# Answer
> 1 votes
You will need to create a new node inside an implementation of hook\_user\_insert.

---
Tags: 7, nodes
---


title: What's wrong with this code?

text:
# Question
Title: What's wrong with this code?
```
function welcome_menu() {
  $item=array();
  $item['welcome'] = array(
    'title' => 'welcome',
    'access callback' => 'welcome_init',
    'page callback' => 'welcome_test',
    'type' => MENU_CALLBACK,
  );

  return $item;
}

/*
 * Implements hook_init().
 */
function welcome_init() {
  if (empty($GLOBALS['user']->uid)&& arg(0)!='welcome') {
    drupal_goto('welcome');
  }
}

function welcome_test() {
  $output = 'welcome';
  return $output;
}

```

I want to auto redirect the anonymous users to the login page, and avoid that an authenticated user can see this page. how I use `user_login_block()` as page callback?

# Answer
An access callback must return a boolean value that is `TRUE` when users can access the page, and `FALSE` when they cannot access the page; it should not redirect users to other pages.

Drupal has a function that returns `TRUE` when the user is anonymous.

```
function welcome_menu() {
  $items = array();

  $items['welcome'] = array(
    'title' => 'welcome',
    'access callback' => 'user_is_anonymous',
    'page callback' => 'welcome_test',
    'type' => MENU_CALLBACK,
  );

  return $item;
}

```

The code is similar to the one used by the User module.

```
function user_menu() {
  // …

  $items['user/login'] = array(
    'title' => 'Log in',
    'access callback' => 'user_is_anonymous',
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );

  // …
  return $items;
}

```

To show the login block using your menu callback, you need to change your function code with the following one.

```
function welcome_test() {
  return drupal_get_form('user_login_block');
}

```

hook\_init() is not invoked for cached pages, and Drupal normally caches the pages for anonymous users (when it is set to do so).
> 1 votes

# Answer
The most obvious thing is that it does not follow Drupal's coding standards at all. It makes it very difficult to read.

hook\_init() is it's own hook, it should not be used as an access callbacks. Access callbacks need to return either TRUE or FALSE.
> 2 votes

---
Tags: 7, redirection
---


# Question
Title: What is the difference between "Path redirect" and "Global Redirect"
I read the description of Global Redirect and Path redirect, but I still don't understand what the difference between the modules is, and why *Path redirect* recommends *Global Redirect*.

What is the difference between the modules?

# Answer
> 5 votes
Global Redirect searches for an alias of the current URL and does a 301 redirects to it if found. This prevents content from being displayed on multiple urls when the path module is enabled. Displaying duplicate content at multiple url's can cause a loss of search engine site ranking.

Path Redirect allows you to specify a redirect from one path to another path or an external URL, using any HTTP redirect status. This is important if you want to change your url scheme for some reason and you don't want to break all exisiting links (search engines, user's bookmarks etc.)

---
Tags: 7, redirection
---


# Question
Title: How to avoid submitting a form when creating a new content, depending on some criteria?
Let's suppose I have a content type **Person**, and I don't want the field **Name** to contain the text **AAA**.

What would be the best way of avoid submitting the form if that happens?

For example:
\- Hiding the **Save** button
\- Submitting it, but return to the same page with that field marked as *red*, or just show a message...

**This is just an example**. I'm asking it because sometimes I need to do a query to the database and see if some records exist, or something like that...

**Edit**: I have edited the `template.php` file under the theme folder I'm using, and I have added the functions:

* `theme_theme()`
* `theme_formId($form)`

In the 2nd function, I've modified the form to see Drupal is calling this function, and yes, it works...

Then I did the following in the 2nd function:

`$form['#validate'] = array('my_validate_function');`

and under `my_validate_function($form, &$form_state)` I just wrote `form_set_error('', t('Testing...'));` and nothing seems to be happening: I can still create a new content without problems :(

**What am I missing here?**

# Answer
> 3 votes
You can add validation callbacks to any form in Drupal using the Form API. Specifically, you can use hook\_form\_alter to add a validation callback to the `$form['#validate']` element.

# Answer
> 0 votes
Add a custom validation handler, and define your criteria.

---
Tags: 7, nodes, forms
---


title: How can I output the Devel query log?

text:
# Question
Title: How can I output the Devel query log?
Is it possible to output the Devel generated query log in some way? By default, it prints to the bottom of the page which is fine until I need to send the results to someone else to review.

# Answer
The solution I came up with was to view the source on the page and to copy the query log `<div>` out and paste it into an html file. I then used Firebug to take out to copy the relevant css and add it to the html file as well. What ended up with was one, reasonably formatted, .html file that I could send to whoever needed to look at the query log. Not a particularly elegant solution but it served my purposes.
> 0 votes

# Answer
The devel module has an option to log the query times into the database, and you can then run your own analysis on this and do whatever you like with it.

This is something to be careful about as it is a lot of data and can add up quickly. However, for more sophisticated/aggregate analysis, it's quite useful.

After enabling query logging, you can see some results at http://yoursite.com/devel/queries
> 6 votes

---
Tags: 7, debugging
---


# Question
Title: Ideas on collecting payment before form submission?
I have a use case in which I wish to collect payments before users are allowed to fill a form; basically the form is an assessment form for which the provider (offering analysis) would like to charge money.
Currently I have the form setup using webforms, but I couldn't find a decent or well established way of collecting payment with webform submission. I already have Ubercart on the site so, if there is a Ubercart to webform bridge, I would definitely like to know about it as well (I couldn't find any). Lastly I am also open for any other approaches.

My use case is the following. Users pay for the assessment (service) using Paypal, and then they are given a link to submit a form; the submitted data need to go to the provider.
Do you have any ideas on how this could be implemented? I assume it should be a relatively common use case.

# Answer
> 3 votes
I believe you are looking for the "Ubercart event registration" technique and the Node Checkout module. Mainly because this technique is associated with "event ticketing" most people do not realize the general nature of what the Node Checkout module provides:

Node Checkout causes a "node creation form" to be presented to a user after adding an item to their cart. The idea being that someone is purchasing an event ticket, so they are presented with a form for capturing their name, address and other info so their identity can be verified at the event's ticket booth.

HOWEVER, this technique provides a few interesting things for developers:

1) these don't have to be event products, the "purchase" can be for anything

2) the information collected is entirely up to you, because you create a new content type for capturing this information, you can put text fields, checkboxes or whatever FAPI or CCK widgets you want on that form

3) due to the nature of how this technique works, you can trigger one or two "purchased item forms": the first one is automatically triggered by the Node Checkout module after the use clicks "add to cart", but part of this technique includes use of a Conditional Action to support identification of abandoned purchases where the "new purchase form" was filled out, but checkout never happened. You can use this Conditional Action moment to trigger a 2nd (or maybe in your case only) node form for collecting this information AFTER their purchase transaction completes.

I think if you only want a form to appear to the customer after the purchase transaction, you may not even need Node Checkout - you can do it all with a custom content type for your information collection, and use Conditional Actions to trigger the display of that form after purchase.

You'll have to do some mental translating to understand this technique, because the best tutorial explaining the technique is purely about event ticketing. But if you have a little imagination, you'll realize how generally useful asking the customers for information after a purchase can be.

Here's the best tutorial I've been able to find on this, step by step too:

http://drupaleasy.com/blogs/ultimike/2009/03/event-registration-ubercart

# Answer
> 2 votes
Have you tried the Ubercart Webform Checkout Pane module?

You could define a simple product and use the webform as part of the checkout process.

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

> This module allows you to define Webform nodes as checkout/order panes in Ubercart.
>
> This is useful if you want to collect additional information during the checkout process. For example, you may want a quick survey or require additional fields that apply to the entire order.
>
> Using the Webform module allows for many advantages: the forms/fields can easily be modified by an end-user; less development time is required to create database tables and code to store/retrieve the data; and the form will remember the user's previous answers.
>
> Furthermore, this module now provides tokens for every field in each of your enabled webforms, making it easy for you to insert the submitted values into confirmation emails, invoices, etc.

# Answer
> 1 votes
If I understand you correctly you could use Ubercart Event Registration. It creates a product class that is also a webform content type. The user fills in the webform first and then is taken to their cart. There's a hidden component in the webform for the payment status that gets updated automatically when payment's received, so it would be easy to filter out those who hadn't paid.

---
Tags: ubercart, webforms, payment-gateways
---


# Question
Title: How to create a node revision view with a "Node" row style?
Is it possible to create a node revision view with a "Node" row style?

This does not seem to be an option in the Views interface. "Fields" is the only options presented for this type of view. Is there a reason why this is not technically possible or is it just not currently implemented?

# Answer
I believe the answer to my original question is no, it is not possible (please update if Views changes to allow this).

To accomplish what I needed, I ended up creating a custom module instead of using Views. I lifted the query that Views had generated as this was essentially what I needed. After returning the nid's of the nodes in question, I have drupal theme the nodes:

```
theme('node', $node, $teaser, $page);

```

Add each themed node to an array, `$items`, and then theme that array into an unordered list:

```
$rendered_list = theme('item_list', $items, NULL, 'ul', array());

```

I then set the block's content to that returned list.

```
$block['content'] = $rendered_list;

```
> 1 votes

# Answer
If you can call node\_view on a revision loaded node (ie call node\_load via node\_load($nid, $vid) instead of node\_load($nid) and get correctly themed results, then should be possible to make this, but yea, not currently implemented tmk.

(I think core should generally be fine, but may have some contrib that don't play along).
> 0 votes

---
Tags: 7, views
---


# Question
Title: Different style when listing nodes and displaying a single node
I'm new at Drupal, coming from the PHP framework world, and I'm having some problems understanding the the template hierarchy in Drupal 7.

I've created a template called 'node--article.tpl.php' and can style my single article nodes. The problem is that this affects the front page as well. I want to style the node list different then when displaying single nodes. How can I do this?

# Answer
Berdir's suggestion (coolest imho):

> you can even provide custom template suggestions based on the view mode. See for example drupal.org/node/223440 and bri-space.com/content/creating-drupal-template-suggestions

Also within node-article.tpl.php you can inspect `$view_mode` and decide what to do. You could either include the logic of both templates in the one file, or create different templates and include the appropriate one based on the value of `$view_mode`

You might also find Display suite interesting.
> 4 votes

# Answer
By using Views module, you can create custom displays of node lists (and many other things). This is your master page builder tool for Drupal. http://drupal.org/project/views

With views, you can define the type of view (normal node teaser view, list using select fields, etc.), filters (e.g., show only article nodes, not other node types), sorting order, and so on. Views also has this power for listing users, comments, taxonomy… And you can define these views for pages (where the view you define is the content in the main content area), blocks that appear on any page, and even RSS feeds.
> 2 votes

---
Tags: nodes, theming
---


# Question
Title: How to set the language for the user while it is created?
How to set the language for a user while it is created from `admin/people/create`?

# Answer
Drupal 7 doesn't need third-party modules to have a language selector for user profiles.

* Enable the Local module.
* Enable one or more languages in /admin/config/regional/language; the settings page initially shows only English, generally. It would show another language if Drupal has been installed using a different language.
* When you now edit a user profile, you can set the language associated with the user by choosing between the languages you enabled.
> 1 votes

# Answer
Actually it was a simple thing, just that I didn't enabled the language. So the steps are:

* install and activate i18n module
* go to `admin/config/regional/language` and add the languages you want
* then in `admin/people/create` you will have a language selector.
> 2 votes

---
Tags: users, 7, i18n-l10n
---


title: Best method for custom login/register

text:
# Question
Title: Best method for custom login/register
I want to create a custom login and register page. I want both forms to show on the frontpage in the content area of my template above each other and not on separate nodes. Also, I would like to try to reuse the already existing code for validation of the forms.

I have looked around and found different ways to achieve this so I wonder what's the best way to do this..custom block, module or inside template or...?

Links to content or particular examples would be appreciated.

# Answer
```
drupal_get_form('user_login');

```

And

```
drupal_get_form('user_register_form');

```

Will return the form for you and will deal with all the form stuff that needs to be dealt with. You just need to print whatever is returned by that function out and it should work.

Note: You did not specify the Drupal version, when using 7, drupal\_get\_form() returns an array which you need to pass through drupal\_render() first to get a string that you can print.
> 8 votes

# Answer
Below are the name suggestions for tpl files used for user login, password reset, and user registration.

page-user-login.tpl.php page-user-password.tpl.php page-user-register.tpl.php

in the above you can use drupal\_get\_form('user\_login'), drupal\_get\_form('user\_pass'), drupal\_get\_form('user\_register') to display the form.
> 1 votes

---
Tags: theming, users
---


# Question
Title: How should I upgrade a customized theme?
I have made some custom changes to my theme files template, CSS and tpl files. Is there a best practice method of updating the theme besides going line by line and re-inserting my custom changes after uploading the new theme? Is there a better way to approach this in the future?

# Answer
> 11 votes
You asked "Is there a better way to approach this in the future?".

An alternative to modifying the theme you're basing things on (which I favour) is subthemeing, with which you extend the existing theme by overriding only the aspects you wish to change. This allows you to upgrade the original theme and retain your code separately.

This approach isn't entirely a free pass against maintenance, though.

* If a fix is applied to the core theme and you've copied the (previously broken) code to your subtheme, then you'll retain the broken code as an override.
* If a change is made to the base theme which your subtheme doesn't account for, you'll need to handle that.

So - you will still need to review updates to the core theme, but this approach (for me) makes the most sense, means I'm maintaining the smallest amount of code, and provides a fairly straightforward way to build on the existing themes Drupal offers.

# Answer
> 3 votes
If you don't have to, don't do it.

I used to do it when Zen 1.x was in development, I would simply run a Diff tool (Changes App) over the latest Starterkit and my sub-theme, and then where necessary over the original source files and the renamed/modified file.

It is a major hassle to do so and a perfect case on why you should not use a Development module for purposes other than helping test and develop.

Themes, unlike modules, generally don't hold enough of a security risk or must have features when they are updated and therefore there really is no need to update to the latest. If it ain't broke...

# Answer
> 0 votes
If you're not interested in reinventing your theme by making it a subtheme of a base theme, you can go step by step through http://drupal.org/update/themes/6/7 to update your theme. It may seem like a lot, but if you work it methodically you should meet with success. It would probably take a few hours to go through all the markup, depending upon your theme's complexity. Updating your css may take more time. That really depends upon how much has changed in the ids and classes you targeted, as some modules and core functions have renamed classes and ids in their D7 ports.

---
Tags: theming
---


# Question
Title: Alter submitted by text and retain RDF tags
I am looking to change the submitted by text from:

```
<span rel="sioc:has_creator" datatype="xsd:dateTime" content="2011-03-20T22:54:29+13:00" property="dc:date dc:created">Submitted by <a property="foaf:name" typeof="sioc:UserAccount" about="/users/author" xml:lang="" class="username" title="View user profile." href="/users/author">author</a> on Sun, 20/03/2011 - 22:54</span>

```

to:

```
<span datatype="xsd:dateTime" content="2011-03-20T22:54:29+13:00" property="dc:date dc:created">Date posted: 20 March 2011</span>

```

I know how to alter the text in node.tpl.php but I do not know the function that will return the date formatted with the RDF tags around it. Does anyone have experience in this area?

# Answer
> 1 votes
The function that returns the content of that tag is date\_iso8601().
To understand how those tags are output, you should look at rdf\_preprocess\_node() and rdf\_process().

---
Tags: theming, 7, rdf
---


title: Creating a View filter for a CCK field

text:
# Question
Title: Creating a View filter for a CCK field
I have created a custom filter which displays some select options to the user in order to filter a view. However, I am uncertain how to add this using the hook\_views\_data() hook, being that the table which the filter is being applied to is a CCK table called content\_type\_sm\_mention.

Currently I have the following, which I am not sure is right. What is missing?

```
function smd_views_data()
{
    $data = array();
    $data['content_type_sm_mention']['sentiment'] = array(
      'title' => t('Sentiment'),
      'help' => t('Filter by mention sentiment.'),
      'real field' => 'field_mention_sentiment_value',
      'group' => t('Content'),
      'filter' => array(
        'handler' => 'views_handler_filter_sentiment',
      ),
    );
    return $data;
}
function smd_views_handlers() {
  return array(
    'info' => array(
      'path' => drupal_get_path('module', 'smd') . '/includes/views',
    ),
    'handlers' => array(
      'views_handler_filter_sentiment' => array(
        'parent' => 'views_handler_filter',
      ),
    ),
  );
}

```

# Answer
> 1 votes
To find out what is missing, implement `hook_views_data_alter()` and `dsm($data)` in the function to find the right path for your field.

# Answer
> 0 votes
I would look at `content_views_data()` in the cck module to see if you can figure out what it is returning.

---
Tags: views
---


title: Add a drop-down list to a pager

text:
# Question
Title: Add a drop-down list to a pager
I want to add drop-down list that allows users to select which page they want to visit.

How can I accomplish this?
What code should I use?

# Answer
If you want to replace the whole site pager with a drop-down list, you should write a custom module (see 1 and 2). If you want to show it only for some pages, you just invoke the module (see 2):
1. Declare this in the template.php of your theme (replace `YOURTHEMENAME` and `YOURMODULENAME` with the appropriate theme/module name):

```
function YOURTHEMENAME_pager($tags = array(), $limit = 10, $element = 0, $parameters = array(), $quantity = 9) {
  global $pager_page_array, $pager_total;
  // Calculate various markers within this pager piece:
  // current is the page we are currently paged to
  $pager_current = $pager_page_array[$element] + 1;
  // max is the maximum page number
  $pager_max = $pager_total[$element];
  // End of marker calculations.

  return drupal_get_form('YOURMODULENAME_pagerform', $_GET['q'], $pager_max, $pager_current);
}

```

2. Create a custom module, adding the following code to the YOURMODULENAME.module file:

```
function YOURMODULENAME_pagerform(&$form_state, $path, $pager_max, $pager_current = 0) {
  $form = array();
  $pagers = array();

  for ($i=0;$i<$pager_max;$i++) {
    $pagers[$i] = $i+1;
  }

  $form['pager'] = array(
    '#type' => 'select',
    '#title' => t('Current page'),
    '#options' => $pagers,
    '#default_value' => $pager_current,
    '#attributes' => array('onchange' => 'this.form.submit();'),
  );
  $form['path'] = array(
    '#type' => 'value',
    '#value' => $path,
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
    '#attributes' => array('style' => 'display: none;')
  );

  return $form;
}

function YOURMODULENAME_pagerform_submit($form, &$form_state) {
  drupal_goto($form_state['values']['path'], 'page='.$form_state['values']['pager']);
}

```

p.s. The code was quickly written in browser without any debugging, so may be some errors happen, but it's should give "idea".
> 2 votes

# Answer
Try using the Jump module. It's documentation is here.
> 1 votes

---
Tags: 7, paging
---


# Question
Title: What's wrong with the fetch rss feed code?
The `hook_block()` code is the following.

```
   // …
   case 'view':
      $url = 'http://example.com/feed'; //the site's rss url
      $blocks['subject'] = t('on the bookshelf');
      $blocks['content'] = _mymodule_fetch_feed($url);
      return $blocks;
   // …

function _mymodule_fetch_feed($url,$num_itmes=3){
  $http_result = drupal_http_request($url);

  if ($http_result->code == 200) {
      $doc = simplexml_load_string($http_result->data);
      if ($doc === FALSE) {
        $msg = "error parsing booksheld xml for %url: %msg.";
        $vars = array('%url'=>$url,'%msg'=>$e->getMessage());
        watchdog('goodreads', $msg, $vars, WATCHDOG_WARNING);
        return t("Getting the bookshelf resulted in an error.");
      }

      return _mymodule_block_content($doc, $num_items);
    }
    else {
      $msg = 'No content from %url.';
      $vars = array('%url' => $url);
      watchdog('goodreads', $msg, $vars, WATCHDOG_WARNING);

      return t("The bookshelf is not accessible.");
    }
  }
}

function _mymodule_block_content($doc, $num_items = 3) {
  $items = $doc->channel->item;
  $count_items = count($items);
  $len = ($count_items < $num_items) ? $count_items : $num_items;
  $template = '<div class="goodreads-item">'.'<img src="%s"/><br/>%s<br/>by%s</div>'; // Default image: 'no cover'.
  $default_img = 'http://www.example.com/images/nocover-60x80.jpg';
  $default_link = 'http://example.com/feed';
  $out = '';
  foreach ($items as $item) {
    $author = check_plain($item->author_name);
    $title = strip_tags($item->title);
    $link = check_url(trim($item->link));
    $img = check_url(trim($item->book_image_url));

    if (empty($author)) {
      $author = '';
    }

    if (empty($title)) {
      $title = '';
    }
    if (empty($link)!== 0) {
      $link = $default_link;
    }
    if (empty($img)) {
      $img = $default_img;
    }

    $book_link = l($title, $link);
    $out .= sprintf($template, $img, $book_link, $author);
  }

  $out .= '<br/><div class="goodreads-more">'. l('Goodreads.com', http://example.com').'</div>';
  return $out;
}

```

I put this code in my module; it can get the data, but the links are all the same.(http://example.com). How can I make it work?

# Answer
```
if (empty($link)!== 0) {
  $link = $default_link;
}

```

That condition makes no sense. empty() never returns 0, it return TRUE or FALSE. Just use `if (empty($link)) {`.

Also, you probably want to use the Aggregator, or Feeds module.
> 1 votes

---
Tags: 7, feeds
---


# Question
Title: Drupal 7: adding an image and a link to a user page
I have a new Drupal 7 website with user profile pages like this one.

I'm new to Drupal and do not want to install any modules besides the core ones and the few written by me - because this will keep the site easy to maintain and upgrade for me at the beginning.

I have already written the 3 blocks displayed at my site's Triptych.

Now I'd like to add an image (will be a static Google map with a marker at user's city, for example: http://maps.google.com/maps/api/staticmap?sensor=false&markers=color:0x336699|Bern&&size=300x300 ) and a dynamic link to the user profile pages (i.e. the link depends on the user's id).

I.e. I know how to get user's city for my map:

```
$result = db_query('select field_city_value from {field_data_field_city} where entity_id=:uid', array(':uid' => array($viewer_id)));
$city   = $result->fetchField();

```

but I don't know how to extend the user profile page.

Please give me few hints on how to do it, which hook to use here and maybe few lines code.

And maybe anyone also knows how to add a Tab to a user profile page as well?

# Answer
For images, just enable the Image module and add an Image field to your users just like you already did with other fields.

For a link, assuming you want that to actually display it as a link and not just as text, I really suggest you have a look at http://drupal.org/project/link. I know you said you don't want any contrib modules but again, there is no reason to not do that. Drupal only really gets it's power from contributed modules. Upgrading minor versions is pretty much always trivial and Drupal 8 is most likely still years away and Drupal 7 will be supported until Drupal 9 is released, so you don't have to worry about that for quite some time. Using link.module will certainly be better than trying to develop your own module. link.module has already been tested on 2000 other D7 sites (and 70k D6 sites..).

The Tab question is something completely different, so I suggest you create a new question for that. For a start, you will need to implement hook\_menu() and add a 'user/%user/something' menu item of type MENU\_LOCAL\_TASK.
> 3 votes

---
Tags: 7
---


title: module_invoke() and the performance

text:
# Question
Title: module_invoke() and the performance
I am using `module_invoke()` many times in the front page to invoke lots of block. Does this effect the site performance? Thank you.

# Answer
module\_invoke() is essentially using three functions: `function_get_args()`, `function_exists()` and `call_user_func_array()`. As it doesn't invoke any database API function, it doesn't influence the performance a lot.
Using `module_invoke()` allows to write code that is compatible with future versions of the module or Drupal. There is a feature report on drupal.org which asks to use a different schema for the hook names; if that would be implemented (it could happen in Drupal 8), then the code that invokes directly the hooks should be changed.

In specific cases, where (for example) you are invoking the same hook implemented by the same module many times in row, it is possible to change the code to do something similar to:

* verify the module implements the hook you need, once, at the beginning
* call the hook directly when you need the value returned by the hook

This should be done if the module is really invoking the same hook implemented from the same module many times in row (which doesn't exclude the hook is being invoked in a loop).

To notice that `module_invoke()` cannot be used when one of the parameters needs to be passed by reference. There are specific functions that invoke hook implementations in that cases (e.g. comment\_invoke\_comment(), but those functions invoke the hook implemented by all the modules.
> 0 votes

---
Tags: 7
---


# Question
Title: How to add jQuery.LocalScroll to Drupal 7?
I'm trying to add smooth scrolling within a page. I did find out it could be done using jQuery.LocalScroll.

What I've done so far:
1. I use Zen subtheme, so into my **.info** file I put:
`scripts[] = js/jquery.scrollTo.js
scripts[] = js/jquery.localscroll.js`
2. I put **jquery.scrollTo.js** and **jquery.localscroll.js** into **js** folder of my theme.

Unfortunately scrolling does not work properly. I don't know much about jQuery and integrating it into Drupal. If someone is kind enough to guide me step by step how to make it work, I'll be very grateful.

# Answer
> 1 votes
When you view the source are the js files you added in the head? If not you'll need to clear your cache. Changes to theme .info files do not take effect until you clear your cache.

If it's a js error then it would be helpful to have some more details.

---
Tags: 7, javascript
---


title: Dependant dropdown list

text:
# Question
Title: Dependant dropdown list
I have 2 fields, *state* and *city*. I would like to change the *city* field when I select the *state* field. I tried to use "hs\_nodereference", but this module shows the *state* and *city* fields as follows.

```
statename: statelist
cityname: statelist  citylist

```

I want them to be shown as follows.

```
statename: statelist
cityname:  citylist

```

Does anyone know a solution for this?

# Answer
> 2 votes
Make a vocabulary with states at zero level and cities at deepest level for each state. Then install hierarchical\_select module.

Enjoy :)

# Answer
> 1 votes
I think you need to create a view with the display that'd you like (i.e. a view that is formatted so just `citylist` appears) then reference the view from the custom field. also it's possible that the view may need to have the same name as your reference field

to reference a view, under content types \> fields \> select the field you want \> configure

I'm actually using "Node reference views" module so maybe this advice is for that

---
Tags: 7
---


title: How to use the Tabs module?

text:
# Question
Title: How to use the Tabs module?
I've installed the Tabs module, but I don't know how to use it.

Can anyone help me, please?

# Answer
> 2 votes
I guess you're talking about **tabs**

As it is written on the page :

> The tabs module integrates the jQuery UI tabs plugin, providing client-side interactive tabs. This is a helper module. It doesn't do anything on its own. **Rather, it is used by other modules that provide tabs.**

If you are not a coder, don't use this module.
If there is not any module that ask you to install this module, don't use this module.

If you want some tabs to break long pages into smaller ones, have a look on **paging** module.

If you just want to add some tabs like "Views," "Edit," etc on nodes, this is handled by core code; have a look to the **API**, especially **hook\_menu()**.

# Answer
> 1 votes
Tabs module does not do much on its own. I suggest you to look at Views tabs; this is an awesome module that groups page templates created by Views.
It works like this:

1. You create a view with many page templates
2. You go to Site Setting -\> Views Tabs module administration page and select the pages of a view you want to be displayed in tabs.

I know this is a very short explanation; it just covers the general concepts.

---
Tags: 7
---


# Question
Title: I want to modify the drop down menus for Marinelli (a Drupal theme)
I have the Marinelli menu setup in a website I am internal testing.
I want to modify the drop down menu (I know it uses jQuery), but I have no idea what to do to show the drop down all nested.

In other words, instead of having this in the Marinelli theme

* MENU1
* submenu
* underMenu
* undermenu
* submenu
* undermenu

I want to have the menu like the corolla theme

* MENU1
* submenu
* submenu

and when I hover a submenu:

* SUBMENU
* undermenu
* undermenu

Any help is welcome.

# Answer
> 1 votes
The marinelli\_menu.js on the marinelli theme folder is controlling the JavaScript.

The primary-links.css file is handling the theming.

Armed with this knowledge you can use Firebug to easily tweak the CSS and find out how it looks without having to save the file. And with Firebug's command line and debugging you can explore how those JavaScript functions behave and what's the best way to modify them if necessary.

If you don't know JavaScript or CSS then you have bigger issues.

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


# Question
Title: Is there a module? Or: How to alter the Drupal pager to get this?
I want to add to alter the output of `theme_pager()`, and add a `<li>` tag, as the following:

```
<li class="pager_go_input last">to <input type="text" id="pager_go_input_1" class="form_text pager_form_go_input" alt="1" value="1">
  page
</li>

```

How is possible to do this?

**Update of the question:**

I want to change the Drupal pager to this style: http://www.dedecms.com/knowledge/servers/windows/list\_66\_1.html. Is there a module? Or: How to alter the `theme_pager` to get that? the pager is located at the bottom of the pager. as this displays(`首页 1 2 3 4 下一页 末页 the selected downlist 共 4页33条`). Compare this to the Drupal default pager. It adds a selected downlist, when selects a page from the downlist, the site then auto redirect to the specific page. The whole count pager (how many the pager have pages?) and the count of all the records in the pager.

# Answer
> 2 votes
You need to look at the code above and understand what it is doing. Where does li.pager-last come from? Notice that the last line uses `theme('item_list')` to build the result and it passes in `$items`. Just above that you'll see the code which adds an item to the `$items` array with `'class' => 'pager-last'`:

```
if ($li_last) {
  $items[] = array(
    'class' => 'pager-last',
    'data' => $li_last,
  );
}

```

If you want to add another item after `li.pager-last`, you might try duplicating these 5 lines and modifying them to do what you want.

# Answer
> 1 votes
In *template.php*

```
function THEMENAME_pager($tags = array(), $limit = 10, $element = 0, $parameters = array(), $quantity = 9) {
  global $pager_page_array, $pager_total;

  // Calculate various markers within this pager piece:
  // Middle is used to "center" pages around the current page.
  $pager_middle = ceil($quantity / 2);
  // current is the page we are currently paged to
  $pager_current = $pager_page_array[$element] + 1;
  // first is the first page listed by this pager piece (re quantity)
  $pager_first = $pager_current - $pager_middle + 1;
  // last is the last page listed by this pager piece (re quantity)
  $pager_last = $pager_current + $quantity - $pager_middle;
  // max is the maximum page number
  $pager_max = $pager_total[$element];
  // End of marker calculations.

  // Prepare for generation loop.
  $i = $pager_first;
  if ($pager_last > $pager_max) {
    // Adjust "center" if at end of query.
    $i = $i + ($pager_max - $pager_last);
    $pager_last = $pager_max;
  }
  if ($i <= 0) {
    // Adjust "center" if at start of query.
    $pager_last = $pager_last + (1 - $i);
    $i = 1;
  }
  // End of generation loop preparation.

  $li_first = theme('pager_first', (isset($tags[0]) ? $tags[0] : t('« first')), $limit, $element, $parameters);
  $li_previous = theme('pager_previous', (isset($tags[1]) ? $tags[1] : t('‹ previous')), $limit, $element, 1, $parameters);
  $li_next = theme('pager_next', (isset($tags[3]) ? $tags[3] : t('next ›')), $limit, $element, 1, $parameters);
  $li_last = theme('pager_last', (isset($tags[4]) ? $tags[4] : t('last »')), $limit, $element, $parameters);

  if ($pager_total[$element] > 1) {
    if ($li_first) {
      $items[] = array(
        'class' => 'pager-first',
        'data' => $li_first,
      );
    }
    if ($li_previous) {
      $items[] = array(
        'class' => 'pager-previous',
        'data' => $li_previous,
      );
    }

    // When there is more than one page, create the pager list.
    if ($i != $pager_max) {
      if ($i > 1) {
        $items[] = array(
          'class' => 'pager-ellipsis',
          'data' => '…',
        );
      }
      // Now generate the actual pager piece.
      for (; $i <= $pager_last && $i <= $pager_max; $i++) {
        if ($i < $pager_current) {
          $items[] = array(
            'class' => 'pager-item',
            'data' => theme('pager_previous', $i, $limit, $element, ($pager_current - $i), $parameters),
          );
        }
        if ($i == $pager_current) {
          $items[] = array(
            'class' => 'pager-current',
            'data' => $i,
          );
        }
        if ($i > $pager_current) {
          $items[] = array(
            'class' => 'pager-item',
            'data' => theme('pager_next', $i, $limit, $element, ($i - $pager_current), $parameters),
          );
        }
      }
      if ($i < $pager_max) {
        $items[] = array(
          'class' => 'pager-ellipsis',
          'data' => '…',
        );
      }
    }
    // End generation.
    if ($li_next) {
      $items[] = array(
        'class' => 'pager-next',
        'data' => $li_next,
      );
    }
    if ($li_last) {
      $items[] = array(
        'class' => 'pager-last',
        'data' => $li_last,
      );
    }
    return theme('item_list', $items, NULL, 'ul', array('class' => 'pager'));
  }
}

```

---
Tags: 7, theming
---


# Question
Title: How to create groups and assign users to them?
I want to allow the administrator and manager roles to be able to create groups (for example different jobs within a company) and be able to assign users to the groups. I want this to be a one-to-many relationship so that user1 can be assigned to job1 and job2 (or no job) but user1 can't be assigned twice to the same job.

How would I go about starting this or what is a good module and/or resource to utilize?

# Answer
This sounds like a clear use case for the Organic Groups module. Organic Groups is great if you have a need to create a container for content and then associate users with that container.

However, if you don't have a need for any content-oriented aspects of OG (such as access control), then maybe all you need to do is make the associations visible, rather than a part of the site's information architecture. In that case, it sounds like you might want to use the Content Profile so you can leverage CCK Node Reference fields, which can be one:many arrangements, and using the bundled content\_permissions module or Field Permissions, restricted to roles with specific permissions for editing the field.
> 8 votes

---
Tags: 7
---


title: Which method to set up pay to register?

text:
# Question
Title: Which method to set up pay to register?
I am building a site that requires payment, from paypal for instance, as part of the user registration. What approach should I take?

# Answer
Does it *have* to be registration? You might find it easier to set up one or more roles with the privileges you want to grant to paying users and then use Ubercart to grant these roles to users who buy the appropriate products.

If this sounds good, look at using the `uc_roles` module that comes with Ubercart. The Ubercart documentation contains a pretty good overview: on selling site access with role assignment.
> 4 votes

# Answer
For such a use case, I would add a submit hook to the user registration form, that would save info about the user and make a redirect to the payment after registration. Either on or off site.

You should set the users to be blocked/inactive when created, and when the payment is completed, remove the block.

There are various modules for paypal which might help integrating with paypal.
> 3 votes

---
Tags: 7, users, commerce
---


# Question
Title: Remove "required" status from the Date field
I have a field that is currently marked as required. However, I want this to be required for all roles but the Admin. I've made a module that implements `hook_form_alter()`, and I have been able to remove the required status for all fields but the Date fields. Any idea what settings I need to change?

Also, I've tried altering it in `hook_form_alter()`, as well as doing it in the '#after\_build'. I had no luck there either.

# Answer
This is most probably because you don't just use a simple datefield, but one provided by e.g. the Date Module.

You should make sure that the module implementing your custom `hook_form_alter` runs last. That way, no other module can change it back to "required" again.

Furthermore, some modules implement a different "required" allthogether. E.g. the business-logic "if start-date is set then end-date is required too" cannot be implemented with simple "required" flags but will fire on the `hook_validations` for that form.

To override that, you will need to either exclude certain validations from running, by removing them from the `element_validate` or from the entire forms `#validate`.

You might want to replace these original validations with your own copies, to be sure you don't change ugly behaviour.
> 3 votes

---
Tags: entities, datetime, 7
---


# Question
Title: What are the photo gallery/album module choices?
I am looking to make a Flickr like site that user can create albums, upload photos. With Drupal 6, this can be easily done by CCK, Node Reference, Views.

For Drupal 7, it seems difficult since Node Reference is not available yet. (There is a module called Reference, but it only has a development snapshot release.)

So are there any modules that can achieve the ugc photo albums functionality?

Thanks.

# Answer
> 5 votes
An album essentially is a grouping of like nodes.

In drupal this grouping can be done a number of ways. I would suggest using a fixed taxonomy (not free tagging) for the album. This way views can list list all photos (nodes) from a particular tag and you can create thumbnails for instance for display.

You could also group by author for another group of nodes (e.g. 'my photos')

# Answer
> 5 votes
There's the Media Gallery module. Haven't used it so I'm not sure how good its Views integration is. Here is an excerpt about it from the module's project page:

> Uses the Media module to provide a rich media gallery. It currently supports images and YouTube videos well. Other file types may or may not work as well, but the facility is there to add them.

# Answer
> 1 votes
Field Permissions should be able to do it.

I am using the 7.x version; I have not used it to set View Own content, but to block others from viewing it. It should be viable, though. Use this with a content type and an image field module of your choice and it might do what you want it to do.

---
Tags: 7, media
---


title: Views as definition list?

text:
# Question
Title: Views as definition list?
Is there a way to output the content of a view as a definition list? Example:

```
<dl>
  <dt>Nodes title</dt>
  <dd>Nodes content</dd>
  <dt>Another nodes title</dt>
  <dd>Another nodes content</dd>
</dl>

```

Any ideas?

# Answer
You can also create a new template for how the Views row style works for your View: Views 2 theming.
> 2 votes

# Answer
You should be able to achieve this using Semantic Views, which allows you to define the markup that is output by Views.
> 1 votes

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


# Question
Title: Pointing the Views handler for Node Body at another field handler
I want to be able to use a CCK field as my node body without affecting interoperability with Views generated by independent modules. Using `hook_data_alter()`, I have attempt to re-target the Views node body handler to look at the handler CCK has generated for my field, `field_body`. Unfortunately, I get some errors when I try to make use of my proposed solution.

```
/**
 * Implementation of hook_views_data_alter().
 */
function fieldbody_views_data_alter(&$data) {
  // When node_revisions table is added, join in content_field_body too.
  $data['node_revisions']['table']['join']['content_field_body'] = array(
    'left_field' => 'vid',
    'field' => 'vid',
  );

  // Use field_body handler info for node body.
  $data['node_revisions']['body'] =
    $data['node_data_field_body']['field_body_value'];

  // Really emphasize that we are using a different table.
  // Since this isn't doing anything, it may be redundant.
  $data['node_revisions']['body']['table'] = 'content_field_body';

  // A couple tweaks so it's a friendly Node Body replacement in the UI.
  $data['node_revisions']['body']['group'] = t('Node');
  $data['node_revisions']['body']['help'] =
    t('Full body text of the node.');
}

```

**This code appears to work, but when I try to use the handler in practice, I get a warning:**

```
user warning: Unknown column 'node_revisions.field_body_value' in 'field list' query: SELECT DISTINCT node.nid AS nid, node_revisions.field_body_value AS node_revisions_field_body_value, node_revisions.field_body_format AS node_revisions_field_body_format, node.type AS node_type, node.vid AS node_vid FROM node node LEFT JOIN node_revisions node_revisions ON node.vid = node_revisions.vid LIMIT 0, 10 in ../workspace/oa/profiles/openatrium/modules/contrib/views/includes/view.inc on line 771.

```

My interpretation of this is that the code is not pulling in the content\_field\_body table when the field is used, instead it just tries to use node\_revisions.field\_body\_value.

Looking for any answers that resolve this problem or suggest a better strategy for my goal.

**EDIT: Ugly Fallback Option**

Use hook\_views\_default\_views\_alter() to scan every View for a defined body field, and swap it out for a standard CCK field. However, this will break all kinds of things, and not be very performance on cache clears.

# Answer
As the database field you are using is external to the `node_revisions` table, you should probably declare a relationship, in the same way done from Views for the `uid` field.

```
// uid field
$data['node_revisions']['uid'] = array(
  'title' => t('User'),
  'help' => t('Relate a node revision to the user who created the revision.'),
  'relationship' => array(
    'handler' => 'views_handler_relationship',
    'base' => 'users',
    'base field' => 'uid',
    'label' => t('user'),
  ),
);

```
> 1 votes

---
Tags: 7, views
---


# Question
Title: Is it possible to make the Book Outline a mandatory field when creating a new book page?
I would like to make sure that certain content types **always** have a parent book/page.

Is there a way to do this, by JavaScript, by modifying the book module or whatever?

# Answer
Yes, it is possible to do it, without to modify book.module. (Modifying Drupal files is never a good idea.)

You can create a custom module that contains code similar to the following:

```
/**
 * Implements hook_BASE_FORM_ID_alter().
 */
function mymodule_form_node_form_alter(&$form, &$form_state, $form_id) {
  if (!empty($form['book']['bid'])) {
    $form['book']['bid']['#element_validate'][] = 'mymodule_book_validate';
  }
}

/**
 * Form validation handler for book_form_node_form_alter().
 */
function mymodule_book_validate($element, $form_state) {
  // Check other conditions you need to check.
  if ($element['#value'] == 0) {
    form_error($element, t('You must select a book.'));
  }
}

```

The code I wrote allows you to check other conditions before to report the error; for example, you could allow users with the permission to administer books to not assign a book to the book page. You could also verify other conditions like the node title, the permissions assigned to the user who is creating the book page, the presence of keywords in the text used as body of the node, etc.
> 2 votes

# Answer
**EDIT: On review, I see this question is D7 specific. There may be subtle things wrong with my code snippet. It should be fundamentally the same.**

If something should never happen, I prefer to make it never-an-option.

If you want to make all book pages default to being new books:

```
/**
 * Implementation of hook_form_FORM_ID_alter() for node_form.
 */
function mymodule_form_node_form_alter(&$form, &$form_state) {
  if (book_type_is_allowed($form['#node']->type)) {
    // Remove the "none" option.
    unset($form['book']['bid']['#options'][0]);
  }
}

```

Once that's done, you can leave it be or set `$form['book']['bid']['#default_value']` explicitly to be a new book, or a specified book bid of your choice. It will probably naturally fall into creating new books, as that is the first option in the selector after you remove *none*.
> 3 votes

---
Tags: 7, nodes
---


# Question
Title: Set the reply address for the contact form to user's mail address
I have a Drupal 7 site with only few modifications and I have the **/contact** form enabled for anonymous and registered users, so that they can contact the admin (i.e. me) easily.

What irritates me is that their messages always have my own mail address as the reply address. And so in order to reply to them, I have to search my "Sent items" folder for the user name (I relay the mails through gmail at my CentOS server).

Isn't there a way to set the reply addresses to the ones of registered users and why isn't it done by default?

I've added **apache** to /etc/mail/trusted-users to get rid of the following mail header:

> X-Authentication-Warning: mysite.com: apache set sender to my@email.com using -f

But still, I see the "From" header is always set to the admin mail address.

# Answer
> Isn't there a way to set the reply addresses to the ones of registered users and why isn't it done by default?

When authenticated users send a message using the system contact form, the email address assigned to the sent message is the one set for their user account; I just tested it on my Drupal 7 test site, and I can confirm it works that way.

The issue you are seeing is probably caused by the fact you are relaying the emails through Gmail. If you need to add any header to the email sent from Drupal to resolve this problem, then you can implement hook\_mail\_alter() in a custom module.
> 1 votes

---
Tags: 7, users
---


# Question
Title: When viewing a user, display their content profile
When I go to /user/uid I want it to go to /content/content-profileID by default. This is a node typer that is used by content profile.

How can I go about doing this?

# Answer
> 1 votes
```
function MYMODULE_user($op, &$edit, &$account, $category = NULL) {
  switch ($op) {
    case 'view':
      profile_load_profile($account);
      // Now $account will contains all profile data;
      // some code
      break;
    }
  }
}

```

# Answer
> 0 votes
I created a function that given a uid it would return the profile nid. I then added to hook\_user to redirect to node/profileID on view.

```
function MY_MODULE_USER($op, &$edit, &$account, $category = NULL){
    switch ($op){
        case 'view':
            $profileNid = MY_MODULE_getProfileNidFromUid($account->uid);
            drupal_goto("node/" . $profileNid);
            break;
    }
}

function MY_MODULE_getProfileNidFromUid($uid){
    $sql = "SELECT nid FROM node WHERE TYPE =  'profile' AND uid =" . $uid;
    $profileNid = "";
    $dbResults = db_query($sql);

    while ($result = db_result($dbResults )) {
        $profileNid = $result;
    }
    return $profileNid;
}

```

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


title: Group ID Filter in Block?

text:
# Question
Title: Group ID Filter in Block?
I want to show teasers of content posted to an OG group. I want public and private groups, so the user must have view access to that group to see the content. I have a Group (named "Group") and a content type ("Topic") that users can post to the group.

I create a block in views and place it bellow content, then when the group is displayed the block is displayed. Currently the block will show ALL content, I do not know how to show content for CURRENT GID. The GID is different then the NID (example nid = 3, gid = 1).

* I installed Pathauto and gave the rule to group/\[node:nid\].
* I then created a block and want the block to show all Group Content. I set it only to display on group and group/\* This is associated with og\_members block & og\_nodes block won't display content but unfortunately the individual did not mention his views filter (or contextual filter).
* I can get all content to show up in this block, but I do not know how to filter the current nodes group id from the block.

# Answer
Updating views to views 3 Beta 3 created 2 new OG views, OG Nodes was one of them and it fixed the issue.

Note: Adding blocks to "Content" would ignore weight (order) of the blocks, I had to create a content-top and content-bottom area in page.tpl.php!
> 2 votes

---
Tags: 7, nodes, views, organic-groups
---


# Question
Title: og_members block & og_nodes block won't display content
OG Version: 7.x-1.x-dev

My problem is that I can't get the og\_members block & og\_nodes block to show up under a group page.

Breakdown of my process:

* A fresh install of D7, necessary modules
* Created a new Content Type: Country: Specified as "Group type", "Not a group content type".
* Add a new country: "England".
* Createt a new Content Type: News: Specified as "Not a group type", "Group content type".
* Add a News, title "Hello World", select England in "Group audience".
* In Views page, I add block display for og\_members, og\_nodes. (All use default setting, no modification to the Views)
* Assign og\_members block, og\_nodes block to sidebar left. (Bartik)
* I go to "England" page, og\_members block not show up, og\_nodes block shows me "There is no content in this group."

I am pretty sure that the views setup correctly, as I pass the gid into the live preview, it does show the result. (See screent shot)

But the block just can't show up in a group page. I am guessing in the page, gid not passed to the block or what?

Am I missing any steps?

Thanks in advanced!!

**Update:** I found the solution by enabling the OG context module.

# Answer
> 0 votes
og\_nodes and og\_members did not exist prior to views 3 beta 3's release. The user must have been using a dev version at this time because I was unable to reproduce this until views beta 3 came out today.

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


title: drush make and drupalcode patches

text:
# Question
Title: drush make and drupalcode patches
I would like to download the stable version of a project and apply a patch. This patch was not submitted but applied directly to the project. I have the following drush make file (just a test snippet)

```
; Drush make script for the level platform install profile and features
core = 6.20
api = 2
projects[drupal][type] = core

projects[flot][dir] = "contrib"
projects[flot][version] = "1.2"
projects[flot][patch][] = "http://drupalcode.org/project/flot.git/patch/0b9d38d28e9f66cee239e7f92ccd2a368ce377c7"

```

This tells me that the patch has failed. If I download the file and use patch -p0 it will patch correctly.

Anyone have an idea why this is not working, and how to fix it?

# Answer
> 2 votes
This looks like a git based patch, I believe that you with drush need to use generic patched, which with git can be created like this:

```
git diff --no-prefix > file.patch

```

---
Tags: version-control, drush
---


# Question
Title: What are the array keys of $content that can be hidden?
I see that with drupal 7 theming, we can mark elements of the `$content` array as hidden.

From http://drupal.org/update/themes/6/7 :

```
  <?php
    // We hide the comments and links now so that we can render them later.
    hide($content['comments']);
    hide($content['links']);
    print render($content);
  ?>

```

What other keys always exist? Or if they are dynamically generated, what is the best way to check the hideable content elements?

Thanks

**Edit**
With the devel module enabled, I found that the information I was looking for roughly corresponds to the information found at the location `/node/your_nid/devel/render`. Or using PHP directly, `dprint_r(array_keys($content));`

# Answer
> 3 votes
Yes, it is dynamical, all modules can add new elements.

Install http://drupal.org/project/devel and then use dpm($content); Note that when you do this inside a page, you will probably only see it after another reload.

# Answer
> 2 votes
Install Devel Themer too...

---
Tags: 7, theming
---


title: Is Drupal 7 a good fit for my site?

text:
# Question
Title: Is Drupal 7 a good fit for my site?
I started creating my site in Wordpress 3.1, and I have hit a speed bump. I am considering switching to EE or Drupal 7, in hopes of achieving my vision of the site.

The problem I am having is excluding terms in the dropdown menu query. Currently I have taxonomies for CarMake, CarModel, Year, etc... My problem is when I select Honda, the menu does not exclude non Honda cars, so you get a giant list of car models.

The search menu then would return all "posts" that include those taxonomy terms in the "Videos" custom post type. Each "post" was essentially a blog post with a very short description and a youtube video.

Before I invest countless hours learning Drupal or EE, I would like to find out how hard this menu/search would be to implement. An example of the menu I would like to re-create is here

# Answer
> 6 votes
The Hierarchical Select module does exactly what you describe. Here is a demo that even uses car brands as the example.

# Answer
> 2 votes
From your last comment on tim.plunkett's answer, I think you're pretty much there. You can use a single taxonomy with Hierarchical Select for the Make, Model and Trim. Then you can use a separate taxonomy for the Category dropdown. Since the Category terms aren't specific to a car, they should go into a separate taxonomy.

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


# Question
Title: Documentation for the API exposed from Pressflow
Reading How do Pressflow Drupal sites handle user Cookies? I discovered that Pressflow 6 has a function that is not present in Drupal 6, but that is defined in Drupal 7; although, the code used by Pressflow 6 is different from the code used by the homonym function in Drupal 7.

Should developers use only the functions that are defined from the equivalent Drupal version (e.g. Drupal 6 for Pressflow 6)?

# Answer
Pressflow is designed to be API compatible with Drupal. As a consequence you should only use the API functions of Drupal 6 when developing for Pressflow 6.
> 4 votes

---
Tags: 6
---


# Question
Title: How to embed username and password in a URL?
We have a form that users need to fill out, but it is accessible only to authenticated users. We want to send a mass email to all users with an username and a password embedded in an URL, so that users can just click on that URL and log in to Drupal. The username and password will be common for all users.

Is it possible to log in to Drupal through this way?

# Answer
Clearly there are too many good options.

There is also http://drupal.org/project/tokenauth. This would allow you to craft a link for email that would auto-login the user for whichever pages you configured to be accessible via token.

Some details from the module's project page:

> Token Authentication provides a token for use in the URL to authenticate users to your site. It only works on paths configured in the settings page.
>
> Originally this module was intended to offer simple authentication for RSS feeds to allow feed readers to pull customized content listings. You can now use it to provide a simple browsing experience of any Drupal content.
>
> Be careful with what paths you expose to Token Authentication, as it is effectively a very simple, very low security password mechanism. You can expose Administration pages through bad configuration.
> 6 votes

# Answer
There is currently a sandbox module called URL Login waiting to get approved to become a full project. See the project page and the full project application issue.

That module provides a secure way to log in through an URL. If that module is useful to you, I suggest you mention that in the linked issue so that it can become a full project soon.
> 6 votes

# Answer
Are you looking for one-time logins, allowing new users to login and set their own password? Try http://drupal.org/project/one\_time\_login

Some details from the module's project page:

> This module adds two operations to the form at Administration \>\> People: "Send one-time login link to the selected users" and "Download CSV of one-time login URLs for the selected users".
>
> This module also provides a Views field handler for one-time login URL and a "Send one-time login link to user" action for use with Views Bulk Operations.
> 2 votes

# Answer
I believe you are looking for the Secure Site module.

Although depending on your needs the Webserver Authentication module might work well also.
> 0 votes

---
Tags: 7, users
---


# Question
Title: developing a site in drupal made a mess in modules .. is there better way?
When I develop a site in Drupal, I test a couple of modules to see what best suits my needs. The problem is that, if it is a large site, I find myself with a lot of modules and patches (disabled / uninstalled), which still exist in the modules folder. There are a lot of modules that don't have an uninstall feature; the result is that I get many unused tables in the database, and many used files to delete.

Is there a better solution, or way to proceed for testing modules?

# Answer
> 3 votes
You can of course create a test site to experiment with certain modules and patches before adding them to the real site.

Version control is also really helpful, because it allows you to revert to a previous version of your code. However you need to keep in mind that your database is not under version control, so you need to take a snapshot of that as well to do a proper rollback.

A more advanced solution is to use drush make and the features module. The features module allows you to store a lot of configuration in code. When combined with drush make, it allows you to roll out a fresh copy of your code again and again.

# Answer
> 1 votes
You can use the Schema module to compare the schemas defined by your currently installed modules to what is actually in your database.

With this module you will be able to identify:

1. Extras: Tables that are not present in the schema. This indicates previously installed modules that are disabled but not un-installed or modules that do not use the Schema API.
2. Mismatches: Tables for which the schema and database are different.
3. Missing: Tables in the schema that are not present in the database.

Please note that Schema requires MySQL 5.

---
Tags: 7, database
---


# Question
Title: Altering a URL alias without using a module
Is there a way to alter a URL alias without using a module? Somebody told me to write a record into database table, but I don't know how to do it.

# Answer
> 2 votes
Drupal allows to add (and alter) a path alias using the user interface. Generally, there is no reason to alter a database table directly, especially when a Drupal core module allows to do what you are trying to achieve through an administrative page.

If you need to do it from code, then you can use `path_set_alias()` function as pointed out from tim.plunkett. Differently, Drupal user interface is preferable for such tasks.

The query used by `path_set_alias()` to update an existing alias is similar to the following (I simplified the query by removing the reference to the language field):

```
UPDATE {url_alias} SET src = '<alias>', dst = '<destination>' WHERE dst = '<old_destination>'

```

If your Drupal site is using table prefixes (e.g. `dr6_`) then you need to replace `{url_alias}` with `dr6_url_alias`; if your Drupal site is not using table prefixes, then replace `{url_alias}` with `url_alias`.
Replace also `<alias>` in the query I wrote with the path alias, `<destination>` with the path to alias, and `<old_destination>` with the old path (which can also be the same value used for `<destination>`).

If there isn't a path alias, then the query becomes the following one:

```
INSERT INTO {url_alias} (src, dst) VALUES ('<alias>', '<destination>')

```

`<alias>` and `<destination>` have the same meaning I reported before.

# Answer
> 1 votes
Inserting values directly into the database is a poor choice when there is an API available. The function you are looking for is path\_set\_alias().

If you absolutely insist on inserting rows directly into the database, the table is {url\_alias}.

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


# Question
Title: Is the "access" table removed during upgrade?
When a site is upgraded from Drupal 6 to Drupal 7 (or any higher version), do the update hooks remove the access table?

I am developing a module that could import the content of that table, and I need to know if after updating to Drupal 7 that database table is not anymore present.

# Answer
> 4 votes
The access rules function has been largely removed from core. From the CHANGELOG:

> Refactored the "access rules" component of user module: The user module now provides a simple interface for blocking single IP addresses. The previous functionality in the user module for restricting certain e-mail addresses and usernames is now available as a contributed module. Further, IP address range blocking is no longer supported and should be implemented at the operating system level.

The upgrade path do not remove the `{access}` table. It migrates the entries it can to the new `{blocked_ips}` table, but otherwise keep the content of the `{access}` table in place. See `system_update_7002()` and `system_update_7003()`.

Parent issue: http://drupal.org/node/228594. Possible replacement for Drupal 7: http://drupal.org/project/user\_restrictions.

---
Tags: 7, upgrading
---


title: Altering the "Status report" page

text:
# Question
Title: Altering the "Status report" page
The hosting provider I user for my site disabled the `phpinfo()` function and, as consequence, the link that would normally appear in the status report page is not anymore shown, replaced by a warning message.

I would like to create a custom module to remove that message, and show a link to a page that, similarly to the page shown by `phpinfo()`, reports information about PHP and the enabled extensions.
Is there a way to alter the information about PHP system\_requirements() normally shows in that page?

# Answer
You may not be able to alter the system\_requirements array directly, but you can hack around it in the theme layer by implementing theme\_status\_report.

```
 theme('status_report', array('requirements' => $requirements));

```
> 3 votes

---
Tags: 7
---


title: How to test a MySQL connection

text:
# Question
Title: How to test a MySQL connection
How can I test for active MySQL connections? I am trying to move one site to windows platform, and MySQL connections are failing; `db_query()` returns `FALSE`.
I am not sure how to use `drupal_test_mysqli()`.

# Answer
> 3 votes
The function is invoked with code similar to:

```
$success = array();
$url = 'mysqli://username:password@localhost/databasename';

require_once './includes/install.mysqli.inc';
$err = drupal_test_mysqli($url, $success);

```

Replace `username`, `password`, `localhost`, and `databasename` with the values correct for your site.
The variable `$success` will contain an array with a value for each SQL instruction that has been executed with success.

---
Tags: 6, database
---


# Question
Title: Dynamic ordering of views based on argument
I'm sure this is possible, I'm just looking for some advice on the best way to approach it.

Here's the situation:

We have some English content. If the user is in Australia, we want to **show them all content, with Australian tagged content sticky at the top**. If the user is from another English speaking country, we will just **show them all content in normal reverse chronological order.**

At present, we are tagging content with Locations using locations.module. I have some code in hook\_init which identifies the user's country, which is stored in their session.

I figure using an argument to locations.module's views argument support is the best way to do this, but we can happily use another solution like taxonomy if that is more appropriate.

Any ideas on how best to configure a view like this?

# Answer
> 3 votes
I ended up using this code to get the desired functionality:

```
function mymodule_views_query_alter(&$view, &$query) {
  // in my case I'm pulling info from the user object to decide the sort,
  // but obviously you could check anything here. Use arg($x) to read URL arguments.
  global $user;
  if ($user->country == 'AU') {
    // Note in this case NULL is above AU, so descending order it is.
    $query->orderby = array_merge(array('location_country DESC'), $query->orderby);
  }
}

```

I'd love to hear any other thoughts on good ways to do this, particuarly some guidance with adding sort objects to the view using hook\_views\_pre\_execute or similar.

---
Tags: views
---


# Question
Title: Using node_view() to display a node doesn't print local menu items
When using node\_view() to display a node (via return from a function that's called in hook\_menu()) the usual View/Edit tabs are missing.

Is this expected behaviour?

# Answer
> 3 votes
Yes this is expected. The reason they are there, is because the path of view a node is at `node/[nid]` and the edit/view is at `node/[nid]/edit`. If you changed the default node path with hook\_menu\_alter the tabs on all nodes would disappear.

The reason they are there, is because they are of type, `MENU_LOCAL_TASK`, check out the documentation on `hook_menu`, if you need to know more.

# Answer
> 3 votes
It is the expected behavior. node\_view()'s purpose is to build the node view, not to create also the other tabs that you normally see at `http://example.com/node/<nid>`.

If you want to emulate what done in a node page, you should define the following menu structure (I have chosen `page` randomly):

```
/**
 * Implements hook_menu().
 */
function mymodule_menu() {
  $items['page/%node'] = array(
    'title callback' => 'node_page_title',
    'title arguments' => array(1),
    'page callback' => 'mymodule_page_view',
    'page arguments' => array(1),
    'access callback' => 'node_access',
    'access arguments' => array('view', 1),
    'type' => MENU_CALLBACK,
  );
  $items['page/%node/view'] = array(
    'title' => 'View',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  );
  $items['page/%node/edit'] = array(
    'title' => 'Edit',
    'page callback' => 'mymodule_page_edit',
    'page arguments' => array(1),
    'access callback' => 'node_access',
    'access arguments' => array('update', 1),
    'weight' => 1,
    'file' => 'node.pages.inc',
    'file path' => drupal_get_path('module', 'node'),
    'type' => MENU_LOCAL_TASK,
  );

  return $items;
}

```

`mymodule_page_view()` is the page callback that would call `node_view()`.

# Answer
> 1 votes
To move all potential tabs added by modules to a node, and make them visible on another new custom path alter the links dynamically when the menu cache router is re-built.

Stick the following in a module:

```
    /**
 * Implementation of hook_menu_alter().
 */
function example_menu_alter(&$callbacks) {
  foreach($callbacks as $path => $menu) {
    $callbacks[$path];

    if (strpos($path, 'node/%node/') !== FALSE) {
      $newpath = str_replace('node/%node/', 'customurl/%/%/%/%node/', $path);
      $callbacks[$newpath] = $menu;
      unset ($callbacks[$path]);
    }
  }
}

```

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


# Question
Title: Block that shows nodes based on node type
I want to create a module that displays nodes of a certain node type. Can this be done, and can anyone point me to a place where I can find how to do this?

# Answer
> 1 votes
First thing you should be looking into is module development in general. Everyone has their own way of researching such things, it could be a book such as "Pro Drupal Development" or a online video series such as http://buildamodule.com/

Are you looking to build the module for Drupal 6 / 7 etc all needs to be taken into consideration too.

To answer your question yes, I would imagine creating a block module to display certain node types be fairly easy. However you might be able to do this with views much easier... Just create a new view, filter by node type and add a block display.

# Answer
> 2 votes
There's currently 12,966 sites using the beta3 release of Views 7 (http://drupal.org/project/usage/views). I'd suggest that you install the module and try to produce what you're describing as I suspect it will work fine. A beta3 release suggests that the module is nearing a production release with no new functionality being added.

Be brave, adopt the new software rather than painting yourself in a corner by writing your own custom code.

# Answer
> 0 votes
This is very easy to do in views.module. Just create a view that filters by your desired node type, then create a 'Block' display type. The block will then show in the block admin page and you'll be able to place it on your site as appropriate.

---
Tags: 7, nodes
---


# Question
Title: Why does the page callback have two arguments?
```
function menufun_menu() {
  $items['menufun/%/bar/baz'] = array(
    'title' => 'Hi',
    'page callback' => 'menufun_hello',
    'page arguments' => array(1), // The matched wildcard.
    'access callback' => TRUE,
  );

  return $items;
}

/**
* Page callback.
*/
function menufun_hello($a = NULL, $b = NULL) {
  return t('Hello. $a is @a and $b is @b', array('@a' => $a, '@b' => $b));
}

```

In the `menufun_menu()` function, the page argument for the `menufun_hello` callback is only one. Why does `menufun_hello()` have two parameters?

# Answer
Menu callbacks are passed first the arguments defined in `page arguments` then excess arguments from the url.

So in the above example:

```
menufun/1/bar/baz

```

Will provide these vars:

```
$a = 1;
$b = NULL;

```

If you however provide an extra argument in the url:

```
menufun/1/bar/baz/2

```

You will transfer it to the menu callback:

```
$a = 1;
$b = 2;

```

The other advantedge is like tim writes, that it allows reuse of the same code for various cases, making the module more maintainable.
> 7 votes

# Answer
In this case, `menufun_hello()` takes up to two arguments, but as little as zero, since it provides defaults. This means that `menufun_menu()` could later pass another argument, and the function signature wouldn't have to change.
> 1 votes

---
Tags: 7, routes
---


# Question
Title: Serving CSS, images and JavaScript in Drupal
Does the whole Drupal stack get fired up (bootstrapped) each time one of these static content types gets requested?

# Answer
> 3 votes
Nope, it does not. But if you have let's say in one of your stylesheet files a reference to a missing image, or your code is trying to load a missing js file then because of the Rewrite Rules in .htaccess this requests are redirected to index.php and that causes the bootstrapping of the whole system to render the 404 page.

---
Tags: 7, performance
---


title: Does drush fire hook_exit()

text:
# Question
Title: Does drush fire hook_exit()
I am trying to write my own drush command. I have a hunch that something is not quite working right. I can't see documentation saying whether drush fires hook\_exit()

Anyone know this?

# Answer
> 2 votes
Judging by `grep -R exit *` in the drush folder, I think not. However, there is hook\_drush\_exit(), see docs/drush.api.php.

---
Tags: drush
---


# Question
Title: Views2 Handlers: Fatal Error Class 'views_handler_field' not found
I am working on a module and want exposing some fields to Views and provide some custom filters. But I can't extend any Views classes without drawing a fatal error. My code looks something like this. It all works fine until I try to extend views\_handler\_field.

```
<?php
// $Id$
/**
 * @files
 *  Provide functionality for views.
 */
/**
 * Get some data and set some handlers.
 */
 function custom_views_data() {
      $data = array();
    $data['custom']['table']['group']  = t('custom');
    $data['custom']['table']['join'] = array(
      'node' => array(
        'left_field' => 'nid',
        'field' => 'nid',
      ),
    );
    // Has form
    $data['custom']['is_checked'] = array(
      'title' => t('Has contest form'),
      'help' => t('Filter based on presence of a contest form. Nodes with contest forms will equal 1.'),
      'field' => array(
        'handler' => 'views_handler_field',
        'click sortable' => FALSE,
      ),
      'filter' => array(
        'handler' => 'views_handler_filter_string',
      )
    );
    return $data;
 }

 // If you remove everything below here, things work as expected

 /**
  *
  * Define custom handlers.
  */
 function custom_views_handlers() {
      return array(
        'info' => array(
          'path' => drupal_get_path('module', 'custom')
        ),
        'handlers' => array(
          'custom_handler_is_checked_field' => array(
            'parent' => 'views_handler_field'
          )
        )
      );

 }

 /**
  * This class fails with Fatal error: Class 'views_handler_field' not found
  *
  */
class custom_handler_is_checked_field extends views_handler_field {}

```

# Answer
Is your class code in the same file as your hook, aka the .module or .views.inc file? That doesn't work because views\_handler\_field is in a separate file and only loaded when required.

You need to move it in a separate file which as the same name as your class and the ending ".inc", inside the folder that you defined in 'path'. (in your case, your module directory, for large modules with many files, it's recommended to place them in a views directory)

Then, views will automatically include your class *including* the file that contains views\_handler\_field (because you defined the parent relationship in your hook) when required.
> 1 votes

---
Tags: 7, views
---