I have a page that is only accessible by some people. It's entry in hook_menu
contains following:
$items['mymodule/mypage'] = array(
'title' => 'Edit Product',
'page callback' => 'mymodule_mypage',
'access arguments' => array('view mypage'),
'file' => 'pages/mypage.inc',
);
It works all right, it shows page when it should and throws 403 when needed. Now I need a link to it on some other page. Usually I would just use:
<div class="links">
<?php echo l('My Page', 'mymodule/mypage'); ?>
</div>
in tpl.php file where I need it. But I don't want it to be visible for people who will get 403 if they will click it. l()
does not test for permissions on it's own. And I feel reluctant about using logic in templates like this:
<?php if ( user_access('view mypage') ) : ?>
<div class="links">
<?php echo l('My Page', 'mymodule/mypage'); ?>
</div>
<?php endif; ?>
I always believed than if's in templates are only to provide things like odd/even, marking visible tabs and deciding if markup should be outputted, like if(!empty($header))
.
On the other hand, building this in the module and passing to the template seems like an overkill for such a simple task.
So what is the "canonical", cache-safe way to achieve this?
Additional information about what this link really is in this case:
Link is related to the page it is presented on, so block does not make sense.
Leaving it to the user to add link to the menu, so that menu system will take care about permissions, is not applicable, as it violates the "if something have to be done during install, always the same way, and requires no user input of any kind, don't leave it to the user" rule. If there is a way to automatically place it in menu in a way similar to node/%/edit
links shown on node/%
pages, all right. I'll be happy to accept that as an answer. But my question is general, without assumption that links share front part. In my exact case, they actually do not.
l()
oruser_access()
anywhere in a theme violates the separation of business logic versus presentation (or theming), and that your module should either define a block that can be placed somewhere or the end-user should put the link in a menu, which will then take care of the access check.