You want to add quick edit links to the teaser view of your nodes — one link to edit the node, and another to delete it, and you want these links to be shown only to users with the 'administer nodes' permission. Alternatively, you may want these links to be viewed only by the user with uid (user ID) 1.
Edit node.tpl.php to add an unordered list of 2 links, contained within a div with a class name (e.g. 'quick-edit-links') and...
style these links in your theme's style.css file.
Say you would like anyone who's logged-in and who has 'administer nodes' permission to see these two additional links below the teaser of every node: Edit [content-type-name] and Delete [content-type-name], like so:
Let's get to it.
In your theme folder, your file node.tpl.php may look like this before the edit (I am only providing a snippet of the template here):
<?php if ($links): ?>
<div class="links"><?php print $links; ?></div>
<?php endif; ?>
Below the above code, you will add your new 'quick edit' links like so:
<?php if ($teaser && user_access('administer nodes')): ?>
<?php $content_type_name = node_get_types('name', $node); ?>
<?php $quick_links['quick-edit'] = array('title' => 'Edit ' . $content_type_name, 'href' => 'node/' . $nid . '/edit'); ?>
<?php $quick_links['quick-delete'] = array('title' => 'Delete ' . $content_type_name, 'href' => 'node/' . $nid . '/delete'); ?>
<div class="links quick-edit-links">
<?php print theme('links', $quick_links, array('class' => 'links inline')); ?>
</div>
<?php endif; ?>
In the above snippet, you build a new array of links, $quick_links, and you theme that array with the function theme('links', ...).
You may prefer to write the markup yourself, using the Drupal function l(), like so:
<?php if ($teaser && user_access('administer nodes')): ?>
<?php $content_type_name = node_get_types('name', $node); ?>
<div class="links quick-edit-links">
<ul class="links inline">
<li class="first quick-edit"><?php print l('Edit ' . $content_type_name, 'node/' . $nid . '/edit'); ?></li>
<li class="last quick-delete"><?php print l('Delete ' . $content_type_name, 'node/' . $nid . '/delete'); ?></li>
</ul>
</div>
<?php endif; ?>
In template.php, using a preprocess function, add 2 new links to $node->links and re-theme (like a re-rince) $node->links to overwrite the existing $links variable. And... style as needed.
Let me show you what I mean. You may want to add the quick edit links next to the other node links, like so:
To achieve this, in your theme's template.php file, you will add a prepocess function for your node template. Open your theme template.php file in a text editor, and add the following code:
<?php
/**
* Override or insert PHPTemplate variables into the node template.
*/
function phptemplate_preprocess_node(&$vars) {
// If we are in teaser view and have administer nodes permission
if ($vars['teaser'] && user_access('administer nodes')) {
// get the human-readable name for the content type of the node
$content_type_name = node_get_types('name', $vars['node']);
// making a back-up of the old node links...
$links = $vars['node']->links;
// and adding the quick edit link
$links['quick-edit'] = array(
'title' => 'Edit ' . $content_type_name,
'href' => 'node/' . $vars['nid'] . '/edit',
);
// and then adding the quick delete link
$links['quick-delete'] = array(
'title' => 'Delete ' . $content_type_name,
'href' => 'node/' . $vars['nid'] . '/delete',
);
// overwriting the $links variable with our new links THEMED
$vars['links'] = theme('links', $links, array('class' => 'links inline'));
}
}
?>
Here's what you've done:
The first solution will work in Drupal 5 as well. Both solutions work only for PHPTemplate-powered themes. With the first solution, it's easy to place the additional links anywhere in the node view.
If you want your quick edit links to be viewed only by the all-mighty Administrator, in your file node.tpl.php, you will replace this code...
&& user_access('administer nodes')
... with that one:
&& ($user->uid == 1)
Showing these links to people with 'administer nodes' permission is quite restrictive: chances are only a handful of people — maybe one person — have access to the Administration section for content.
You may have a web site with many contributors. Some will have 'edit' permission to some or all of the site content, with or without a right to 'delete'. When the situation is relatively complex, and you do want quick edit links whenever possible, you can rely on the Drupal's function node_access($op, $node, $account = NULL) as Roger López points out in this comment. The preprocess function rewritten with the use of node_access() becomes:
<?php
/**
* Override or insert PHPTemplate variables into the node template.
*/
function phptemplate_preprocess_node(&$vars) {
// If we're in teaser view and have right to update(edit) the node
if ($vars['teaser'] && node_access('update', $vars['node'])) {
// get the human-readable name for the content type of the node
$content_type_name = node_get_types('name', $vars['node']);
// making a back-up of the old node links...
$links = $vars['node']->links;
// and adding the quick edit link
$links['quick-edit'] = array(
'title' => 'Edit ' . $content_type_name,
'href' => 'node/' . $vars['nid'] . '/edit',
);
// and then adding the quick delete link
// if we have the right to delete the node
if (node_access('delete', $vars['node'])) {
$links['quick-delete'] = array(
'title' => 'Delete ' . $content_type_name,
'href' => 'node/' . $vars['nid'] . '/delete',
);
}
// overwriting the $links variable with our new links THEMED
$vars['links'] = theme('links', $links, array('class' => 'links inline'));
}
}
?>
Comments
Very Useful.
I'll surely use it, thanks for such a handy tip.
node_access()
Great tip. I use a similar method on nearly every site I build. The biggest difference though is that I use node_access intead of user_access.
instead of user_access('administer nodes') you could also use node_access('update', $node) and node_access('delete', $node). This will allow anyone with access to update or delete the node, to be able to see these links. It will also take into account the node access tables, in the case that you are using some sort of access control module.
Why didn't I think of that...?
Actually I prefer your solution, totally. :-)
I am gonna write something up, in the post, and give you credit. I am not even sure there are more database queries with your solution (maybe one more for querying the {node_access} table... again) but with any involved web site that has more than one contributor (so NOT for a web site like mine), it is more suitable. Anything to make contributing and editing content easier... I am all for that.
I have edited the article
I have added to it. Thank you again, Roger.
... and edited it again
To add a missing parenthesis in the code snippet. (OH... MY... GOD...)
I also added some info on node_access().
So the new section I added is here.
I am playing with Wordpress
I installed Wordpress tonight, Version 2.5.1.
I wanted to look at how Wordpress deals with taxonomy out of the box in its latest version.
There are 2 'vocabularies' in Wordpress : free tagging, and what they call 'categories', and categories can be organized into a tree, that is, a category can have one category as parent. And a category can have many sub-categories.
I looked at a few WP themes, and I thought: That's where it comes from! The 'Tags: x, y, z | Filed under: x, y, z' I see in so many blogs! It's Wordpress wording.
In a Wordpress post, unlike in Drupal, terms are not lumped together. Each vocabulary has its own function, ie: the_tags(), and the_category(). And that will my next instalment: how to put some order in terms displayed in Drupal teasers.
I downloaded this one Wordpress theme, and here is what I found: a quick edit link for the post!
The code for the post info line in the template file is:
In Wordpress, if the user is logged in and has permission to edit the post, the function edit_post_link() displays a link to edit the current post. Example:
edit_post_link('edit', '<p>', '</p>');
one more thing...
I would also add one more thing to your code. If you put
'query' => drupal_get_destination()
to each of your link definitions, after the node has been edited or deleted, the user will be redirected back to the page where they originally clicked the link.Also, here is how you could do this in a module without having to fuss with the theme.
<?php
function mymodule_link($type, $node = NULL, $teaser = FALSE) {
$links = array();
if ($type == 'node' && $teaser) {
if (node_access('update', $node)) {
$links['node_edit'] = array(
'title' => t('edit'),
'href' => "node/$node->nid/edit",
'query' => drupal_get_destination(),
);
}
if (node_access('delete', $node)) {
$links['node_delete'] = array(
'title' => t('delete'),
'href' => "node/$node->nid/delete",
'query' => drupal_get_destination(),
);
}
}
return $links;
}
?>
p.s. It looks like your php/code filter is malfunctioning. Anytime i put a code or php tag anywhere in the post, the entire comment comes up blank.
drupal_get_destination()
Nice addition...
Full-blown like this, what started out as the need to add one quick edit link for Administrators looks like something that could be put in a module.
Because at first, here is what I had in mind. This is what I am using in my node.tpl.php template:
<?php if ($teaser && ($user == 1)): ?>
<div class="links"><?php print l('(Edit)', 'node/' . $nid . '/edit'); ?> | <?php print l('(Delete)', 'node/' . $nid . '/delete'); ?></div>
<?php endif; ?>
Which is printing something like this:
Tell me about it! :-( I can't figure out what's going on here. I did not touch that input format (filtered HTML) and the module I am using is the same. It's the one used on Drupal, e.g. Codefilter.
I fixed the input format conflict
Fixed.
New module Admin Links
Put up a quick little module so I didn't have to do any theme hacking: http://drupal.org/project/admin_links
Thank you, Dave
:-) Awesome.
add link on the fly
I need an executable code snippet that can add on the fly a new internal link to an existing node's link area. I need to execute the code through the Rules module triggered actions. Any clue is highly appreciated. thnx:dariush
What a script.
I was able to learn much from this.
What a website you have
I was about to click 'spam' but wanted to reply to you.
The title tag of your pathetic (and broken) website's home page contains all of this:
Your one testimonial is funny:
Your pathetic website:
how to add icon on each links?
this is very nice article... and it would be a lot cooler if you(could) show how to add some icon on each links... :)
thanks,
vsotto
I have done this already
I am doing so right here.
This site rocks, as a person
This site rocks, as a person who's still learning php and gets headaches when reading through the drupal API, let alone applying it, i find it refreshing to see illustrations and simple, yet easy to understand explanations. Kudos and thanks!
Thank you for providing the
Thank you for providing the step by step detail for this process. You did a fantastic job of explaining the details.
Great tutorial
Thanks for this great tutorial. Until now I just created a new array for additional links in phptemplate_preprocess_node that I then displayed in the template but modifying $links is what I really wanted (but never knew how to).
Another Option based on user roles
I have been using this for customphp fields in views or for directly in tpl files. It is based on user role instead of being able to administer nodes. The reason being when you enable the administer nodes permissions and a user edits or creates a nodes, they are given additional options (like revisions, publishing, etc), which you might not want them to have control over.