I have a number of nodes with individually restricted permissions. Logged-in users only see a selection of nodes depending upon their permission roles.

My view lists the taxonomy terms of the nodes, but only shows the terms containing nodes the user has permission to see by a relationship between the term and node (which is a good thing).

However, I have some instances where the following is the case:

Parent term (no nodes visible to user in this category)
    Child term 1 (10 nodes visible to user in this category)
    Child term 2 (no nodes visible to user in this category)

And the taxonomy view only lists "Child term 1", but I would also like to list "Parent term". How is this possible?


1 Answer 1


In case anyone has the same issue, I gave up in the end and wrote a custom module since I find views a pain in the ass.

My module uses nested queries which is embarassing, but it's still fast to run (unless you have a massive list of taxononomy terms) so it doesn't matter too much for this purposes.

The module outputs a Drupal block, the content of which comes from this function:

function list_of_resource_tags(){

// Retrieve the logged in user
global $user;

// Select all "Metadata" terms for the nodes the logged in user
// has permission to see    
$sql_terms = '
SELECT DISTINCT(term_data.tid) AS term_id, term_data.name, term_hierarchy.parent, term_data.weight
FROM node_access 
INNER JOIN node ON node_access.nid = node.nid 
INNER JOIN term_node ON node.nid = term_node.nid
INNER JOIN term_data ON term_node.tid = term_data.tid
INNER JOIN term_hierarchy ON term_data.tid = term_hierarchy.tid
WHERE node_access.grant_view = 1 
AND node.status = 1 /* Published nodes */
AND term_data.vid = 9 /* Taxonomy terms of "Metadata" vocabulary only */
AND node_access.gid IN (SELECT rid AS roles FROM users_roles WHERE uid = %d) /* Logged-in user is granted permission to these nodes */
ORDER BY term_data.weight';

$result_terms = db_query($sql_terms, $user->uid);

$displayed_terms = array();
$output = '';
while ($row = db_fetch_object($result_terms)) {
    // If tag is top-level, just display and put in array
    if ($row->parent == 0 && in_array($row->term_id, $displayed_terms) == FALSE){
        $output .= '<div class="views-row"><a href="taxonomy/term/'.$row->term_id.'">'.$row->name.'</a></div>';
        $displayed_terms[] = $row->term_id;
    // Test if we've already displayed the tags parent, if not, retrieve it
    else if (in_array($row->parent, $displayed_terms) == FALSE){
        $sql_parent = '
        SELECT *
        FROM term_data
        WHERE tid = %d';

        $result_parent = db_query($sql_parent, $row->parent);
        $row_parent = db_fetch_object($result_parent);

        $output .= '<div class="views-row"><a href="taxonomy/term/'.$row_parent->tid.'">'.$row_parent->name.'</div>';
        $displayed_terms[] = $row_parent->tid;          

return $output;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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