i need to alter the list of nodes displayed in the admin/content page (the basic administrative page for content) depending of the role of the user. For example if the user has a role, i want him to display only pages with content type = article.

I thought i could modify the query using hook_query_alter

function provintegra_query_alter(QueryAlterableInterface $query){

but i was wondering on how to add the condition i need and how to find the correct query to modify. Of course other solutions arre accepted, but i can't use views because i need to have a page that it's exactly like the one that is displayed normally (with the same filters and links for editing). I need to restrict visualization to certain content types (articles for example but also user defined content types) and if possible to content created by the user

  • Can you explain more why you can't use Views and what options do you need exactly ?
    – LLub
    Sep 14, 2011 at 13:52
  • i edited the question: i need to use that page because i think it's simpler to modify the query rather than creating a view from scratch: i just add a condition and i'm done. Sep 14, 2011 at 13:57
  • Do you want to limit access to certain content types for certain roles in general or only filter content types on this particular page ?
    – LLub
    Sep 14, 2011 at 14:01
  • Only filter content types on this particular page Sep 14, 2011 at 14:12

3 Answers 3


Instead of doing custom SQL query alters, why not use a drop in replacement for the administration pages?

Views Bulk Operations (VBO) does just that, and ships with a replacement for the node administration page. And because VBO is based off views, altering them is trivial, and tasks like 'hide items of type article' become easy (and also critically, more maintainable going forward)

  • Because some might say this should be achievable without plugging in more modules. Drupal core sections like this should be modifiable without adding in a rather large module like VBO. Not to say the answer isn't valid, because it is, but I have a module that adds small piece of data to nodes, and would like to do what the OP is asking without bringing VBO into the picture.
    – Kevin
    Oct 7, 2012 at 13:07
  • Well you can either write your own module to alter the default form (as mentioned below), or you can use VBO (or straight up views) to create a new form. Your call. I prefer using VBO as it requires no special development, and is maintainable by others.
    – wiifm
    Oct 7, 2012 at 19:37

I had this issue in Drupal 6 just now, on the "/admin/content/node" overview page. I wanted to hide certain content types -- and you can't do that with views per se because the admin page is a form, where you can easily bulk update. Sorry that I'm not putting a D7 answer -- this may not be exactly what you are looking for, but it works for me in 6, and maybe others will find it helpful:

 * hide child content types from /admin/content/node overview
function [your module]_db_rewrite_sql($query, $primary_table, $primary_field, $args){
    if(arg(0)=='admin'&&arg(1)=='content'&&arg(2)=='node'){ // /admin/content/node page
        if($primary_table=='n' && $primary_field == 'nid'){
            if(!user_access("[your access callback for viewing this type]")){
                  $return['where'] = 'type != "[type to hide machine name]"'; // or you could use type == type_name
                  return $return;

again.. that's D6, so I'm sorry but hopefully that will get you started

  • Although the question was specific to D7, this function should be helpful is driving toward a solution in D7. I needed to do something very similar to tmsimont in D6. This was a very helpful snippet. Mar 1, 2012 at 20:11

Best I can do. It works, but it's not pretty.

    function mymodule_query_alter(QueryAlterableInterface $query) {

      if (current_path() === 'admin/content') {

        // This bit avoids queries on the page that don't join the node table
        // Be careful if you have a node-related query in, say, a block on the page  
        $tables = $query->getTables();
        $node_exists = FALSE;
        foreach ($tables as $alias => $table) {
          if ($table['table'] == 'node') {
            $node_exists = TRUE;

        if ($node_exists) {
          // add an access check around this next line
          $query->where($alias.'.type IN (:types)', array(':types' => 'article'));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.