Display node information in block - drupal

How can I create a custom block snippet (or download an available module) that would display a selected amount of information about a node in Drupal (6)? (i.e. author, creation date and published status)
I would later make this node available to admin user and only in certain content types, as a mean of seeing node information in-situ while browsing the web only as admin (this part I know how to achieve).
Thank you

I would use the Views & Context modules.
You can use a block display in Views to output the desired fields. Add an argument, then select the option to get the argument from the url.
Context module allows you to (among other things) set access rules based on roles.
I use both of these modules in all of my Drupal installs and find them quite helpful.
http://drupal.org/project/views
http://drupal.org/project/context

You can create a custom block (admin/build/block/add)
Make sure PHP Filter module is enabled already
For your block body select input filter as PHP Code
Add these lines in the body to load node information
<?php
if(arg(0) == 'node' && is_numeric(arg(1))){
$node = node_load(arg(1));
$user = user_load(array('uid' => $node->uid));
print "Author: " . l($user->name, 'user/' . $node->uid);
print "Creation date: " . date('m/d/y h:i:s', $node->created);
print "Publish Status: " . ($node->status) ? "Published" : "Unpublished";
}
?>

Views are totally advisable, writing custom code for something like that is a bad practice... In general the combination CCK & views is very poweerful in Drupal!

Related

Drupal user permissions & odd content types

I have a permissions problem in Drupal. I want users to be able to create a certain node type, but there are two different paths I need to give them permissions for to let them do this. The type is content created by a module called isbn2node, and there are two ways to make content through it, each with different paths:
?=node/add/isbn2node-book
?=node/add/isbn2node_book/isbn2node
One has an underscore and the other one has a hyphen. The first path leads to a form that lets users enter information on a book manually; the second path lets them enter an ISBN, searches for it, and populates the form for them based on the results.
I've changed permissions in the People menu so they can add isbn2node-book content manually using the first path, but there isn't an option to let them use the second method. Aliasing the url so it didn't have node/add in the path didn't work either.
Creating a duplicate content type seems like an ugly solution to this; is there a more elegant way to let users access that second path?
A little code in a custom module using hook_node_access should do it.
$node is either a node object or the machine name of the content type on which to perform the access check (if the node is being created then the $node object is not available so it will be a string instead).
So this should do it:
function MY_MODULE_node_access($node, $op, $account) {
if ($op == 'create') {
$type = $node;
if($type == 'book' && $account->uid) return NODE_ACCESS_ALLOW;
}
}
I figured this out, and the issues I was having were specific to this content type. The ISBN2Node module requires users to have the Administer Nodes permission to use its lookup and bulk import features.
There is some extra code for the module's hook_permission and hook_menu sections submitted as a fix in the module's issues thread.

show all contents of specific content type

For every taxonomy term I can access a page (I am not using the Views module) showing all contents that are tagged with the specific term by using the a path like this: www.example.com/taxonomy/term/1.
Now, I wonder if I could do the same with content-types (e.g. for showing all contents of content type article), using a URL such as www.example.com/content/type/1.
I'm assuming Views 3. You could create a View and supply a contextual filter in the URL to dynamically display all nodes of that content type.
Add "Content: Type" as a contextual filter. Under "When The Filter Is Not Available" section, select "Provide default value", and then Raw value from url. For your example, you would select "3" for the path component.
You can set the Path to "/content/type/%" where the % is the name of the content type. I'm not sure if it will work with numeric values, however.
Without using the Views module, you should create a custom module for doing that, which would be doing what Views is already doing.
If you don't need all the features present in Views, then you can create your own module, even if I would not suggest doing it when Views already exists.
Your module should associate a menu item to a path like "content/type/%" and render a page containing all the nodes of that content type.
For rendering the nodes you could use node_view_multiple(). For retrieving the list of the nodes, and rendering it, you could use code similar to the following one:
$query = new EntityFieldQuery();
$entities = $query->entityCondition('entity_type', 'node')
->entityCondition('bundle', $content_type)
->propertyCondition('status', 1)
->execute();
$nodes = entity_load('node', array_keys($entities['node']));
return node_view_multiple($nodes, 'teaser');
$content_type is the string passed to the menu item.
The code I reported would not use a pager, but it would show all the nodes in a single page.

How do I filter a block view by taxonomy argument in URL?

I have some block views in my sidebar that show events marked as a highlight happening in certain cities. Nodes are organized into cities using taxonomy.
When I load a node directly I have an URL like www.host.com/events/new-york/name-of-my-nice-event
I have some other page views that show teasers for all events in a certain city: www.host.com/events/new-york
Also I have some static pages that are valid for all cities, e.g. www.host.com/about-us
The sidebar blocks showing the highlights are available throughout the whole website. Now I want to make sure that the blocks in my sidebar only show those nodes for the selected city based on the taxonomy provided in the URL. (except for the static pages as there is no taxonomy in the URL, but those are not that important)
So far I tried to pass my view the taxonomy term as an argument using PHP as standard argument:
if (arg(1)) {
$term = arg(1);
return $term;
}
This works fine on the above mentioned page views (e.g. www.host.com/events/new-york). But when I load a node directly www.host.com/events/new-york/name-of-my-nice-event my block only shows the empty text.
I thought that arguments are indexed like this:
events/new-york/name-of-my-nice-event
^0 ^1 ^2
So I don't understand why arg(1) does not return new-york when I am viewing the node detail.
First of all, with path and path auto what you see is not always what you get.
Fx I could setup pathauto for my articles nodes to generate urls like this
content/article/[title]
So if I wanted the title I should use arg(2) right?
No! (arg(2) is actually NULL in this case.)
The reason is that the url that's generated by path auto is a fake url, that gets translated into a Drupal url. In the case above what I get is node/[nid]. So eventhough the node title i in the url, I can't get it by using arg(), but I can get the nid by using arg(1)
I can't guess what your urls map to, it depends how you have set up your site what modules you use etc.
A good advice if you do a lot of these context aware things, is to look into panels. It's made to be able to tell modules like views about the context which it is present. Like fx terms, nodes, etc, and you could use this to pass arguments into views.
Panels can do a lot more and is quite complex, but if you need to do a lot of this stuff, it is probably worth the investment.
Solution to my problem:
if (arg(0) == 'node' && is_numeric(arg(1))) {
$node = node_load(arg(1));
if (count($node->taxonomy) > 0) {
foreach ($node->taxonomy as $term) {
$term = $term->name;
}
}
$term = strtolower($term); // for some reason needed in my case
}
else {
$term = arg(1);
$term = str_replace('-', ' ', $term); // for some reason needed in my case
}
return $term;
While this was technically possible with Views 2 as described in some of the other answers, Views 3 has this integration built in.
You can create an argument for the taxonomy term id and then choose "Provide default argument". This will then give you an option for "Taxonomy Term ID from URL" and "Load default argument from node page..."
This will allow you to take the taxonomy of a page and pass that as an argument to your view block.
Note: Views 3 is currently in Alpha 3 but in my experience is at a relatively stable state and I am using it on production sites. If it has features like the one above that you find useful please use it, test it and submit bugs/patches if you encounter any issues!

Drupal Taxonomy Block, Vocabulary Listing

I looking for the best way to implement a block that lists all terms of a certain vocabulary. Each term should link to page that lists all nodes associated with that term. Any help would be greatly appreciated. Thanks!
See here for a great tutorial to achieve exactly what you want
http://chrisshattuck.com/blog/how-add-block-menu-tags-or-other-taxonomy-terms-drupal-site
The easiest way to approach this would probably be to use Views, and simply create a new view of the type "term". Here's a quick example which assumes that you have some basic familiarity with the Views UI:
Visit Views > Add (build/views/add), give your new view a name, and select Term from the "View type" radio buttons.
On the next page, start by adding a Taxonomy: Vocabulary filter and selecting your vocabulary in the filter settings.
Add a Taxonomy: Term field and enable the Link this field to its taxonomy term page option in the field settings. You might also want to remove the field's label, since this is just a simple listing.
You probably want your display to display all terms in your vocabulary, so change the "Items to display" 0 (unlimited). By default, new views only display 10 items at a time.
Check out the Live preview below to see if it's outputting what you need.
Add a new Block display using the dropdown on the left side of the Views UI.
Give your new block a name in the "Block settings" area. This is the description that will appear on Drupal's block admin page.
Save your view and visit admin/build/block to place and configure your block.
It's worth noting that Views does indeed have some overhead, but in my experience, its flexibility and ease-of-use far outweigh the relatively minor performance hit.
If you'd like to avoid using Views, you could write a pretty simple custom module using hook_block() and adapting http://drupal.org/node/247472. If you'd like, I can edit this answer with an example module based on that.
(Posting this as another answer, since this is a different approach than my first answer.)
As I mentioned above, here's another approach involving a custom module based on the code at http://drupal.org/node/247472. You could also just drop that code into a custom block with the "PHP" input format selected, but that's generally considered to be bad practice.
Add a new folder in sites/all/modules called vocabulary_block. Customize and add the following two files:
vocabulary_block.module
<?php
/**
* #file
* Exposes a block with a simple list of terms from [vocabulary].
* Each term is linked to its respective term page.
*/
/**
* Lists terms for a specific vocabulary without descriptions.
* Each term links to the corresponding /taxonomy/term/tid listing page.
*/
function vocabulary_block_get_terms($vid) {
$items = array();
$terms = taxonomy_get_tree($vid, 0, -1, 1);
foreach($terms as $term) {
$items[]= l($term->name, "taxonomy/term/$term->tid");
}
if(count($items)) {
return theme('item_list', $items);
}
}
/**
* Implementation of hook_block().
*/
function vocabulary_block_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$blocks[0]['info'] = t('List of [vocabulary] terms');
return $blocks;
case 'view':
if ($delta == 0) {
$vid = 43;
$block['subject'] = t('[Vocabulary]');
$block['content'] = vocabulary_block_get_terms($vid);
}
return $block;
}
}
vocabulary_block.info
name = Vocabulary Block
description = Exposes a block with a simple list of terms from [vocabulary]. Each term is linked to its respective term page.
; Core version (required)
core = 6.x
; Package name (see http://drupal.org/node/101009 for a list of names)
package = Taxonomy
; Module dependencies
dependencies[] = taxonomy
Notes
Be sure to change $vid = 43; to
reflect the ID of the vocabulary that
you'd like to load. You can find the
VID by visiting
admin/content/taxonomy and looking at
the destination of the edit
vocabulary link for your
vocabulary. The VID will be the last
fragment of that URL:
admin/content/taxonomy/edit/vocabulary/[vid].
I wouldn't normally hard-code the
$vid into the module itself. However,
setting up the necessary Drupal
variable and administration form (to
allow users to select a vocabulary
from the Drupal interface) would be
overkill for this answer.
For your own documentation purposes,
don't forget to search/replace
[vocabulary] in those two files and
use your own vocabulary's name
instead.
This method may not necessarily be more performant
than the Views method I described
earlier, especially once you start considering caching,
optimization, etc.
Since performance is a priority,
I recommend thoroughly testing a
variety of different methods on this page and
choosing whichever one is fastest for you.

Drupal - Getting node id from view to customise link in block

How can I build a block in Drupal which is able to show the node ID of the view page the block is currently sitting on?
I'm using views to build a large chunk of my site, but I need to be able to make "intelligent" blocks in PHP mode which will have dynamic content depending on what the view is displaying.
How can I find the $nid which a view is currently displaying?
Here is a more-robust way of getting the node ID:
<?php
// Check that the current URL is for a specific node:
if(arg(0) == 'node' && is_numeric(arg(1))) {
return arg(1); // Return the NID
}
else { // Whatever it is we're looking at, it's not a node
return NULL; // Return an invalid NID
}
?>
This method works even if you have a custom path for your node with the path and/or pathauto modules.
Just for reference, if you don't turn on the path module, the default URLs that Drupal generates are called "system paths" in the documentation. If you do turn on the path module, you are able to set custom paths which are called "aliases" in the documentation.
Since I always have the path module turned on, one thing that confused me at first was whether it was ever possible for the arg function to return part of an alias rather than part of system path.
As it turns out, the arg function will always return a system path because the arg function is based on $_GET['q']... After a bit of research it seems that $_GET['q'] will always return a system path.
If you want to get the path from the actual page request, you need to use $_REQUEST['q']. If the path module is enabled, $_REQUEST['q'] may return either an alias or a system path.
For a solution, especially one that involves a view argument in the midst of a path like department/%/list, see the blog post Node ID as View Argument from SEO-friendly URL Path.
In the end this snippet did the job - it just stripped the clean URL and reported back the very last argument.
<?php
$refer= $_SERVER ['REQUEST_URI'];
$nid = explode("/", $refer);
$nid = $nid[3];
?>
Given the comment reply, the above was probably reduced to this, using the Drupal arg() function to get a part of the request path:
<?php
$nid = arg(3);
?>
You should considder the panels module. It is a very big module and requires some work before you really can tap into it's potential. So take that into considderation.
You can use it to setup a page containing several views/blocks that can be placed in different regions. It uses a concept called context which can be anything related to what you are viewing. You can use that context to determine which node is being viewed and not only change blocks but also layout. It is also a bit more clean since you can move the PHP code away from admin interface.
On a side note, it's also written by the views author.
There are a couple of ways to go about this:
You can make your blocks with Views and pass the nid in through an argument.
You can manually pass in the nid by accessing the $view object using the code below. It's an array at $view->result. Each row in the view is an object in that array, and the nid is in that object for each one. So you could run a foreach on that and get all of the nid of all rows in the view pretty easily.
The first option is a lot easier, so if that suits your needs I would go with that.
New about Drupal 7: The correct way to get the node id is using the function menu_get_object();
Example:
$node = menu_get_object();
$contentType = node_type_get_name($node);
Drupal 8 has another method. Check this out:
arg() is deprecated

Resources