Create additional menu page for node that can be accessed by the nodes' alias with /page? I created a block using hook_block_view() and hook_block_info(), then set-up the page with hook_menu() using page arguments but this seems to only work for node/id/page?

This is what I have right now:

$items['node/%node/text'] = array(
    'page callback' = 'my_module_function',
    'page arguments' = 'array(1)',
);


I need it to work for the nodes alias which might be article/node title/ or journal/node title/ - they are for two different content types. Going to just article/ or just journal/ shows a View page that displays all the articles or everything from the journal.

Currently whenever I try to go to:


  article/node title/page


the article/ Panel page is loaded. However disabling the panel for article/ then going to article/node title/page causes a Page not found error, so it seems it's something to do with my hook_menu() not registering the URL aliases of the nodes?

As node/node id/page works perfectly fine.

Edit: unsure how to reopen, see comments
You have two options.

1. Using the Sub-pathauto (Sub-path URL Aliases) module.

This is based on pathauto, and will create additional aliases for node sub-pages. 

This also works for other entity types such as user/123/contact -&gt; people/geronimo/contact, if user/123 has the alias people/geronimo.

2. Write a custom wildcard loader (far more work).

I am going to use the word "slug" here, which I remember from Wordpress.

The usual node path is node/%node, which will trigger the node_load() wildcard loader. This wildcard loader only takes node ids. It does not work with node titles. So, node_load(123) gets you the node with that id, but node_load('node title') will return NULL.

You could now create a new module "mymodule", and use hook_menu() to define a separate path article/%mymodule_article_slug, and sub-paths article/%mymodule_article_slug/page, article/%mymodule_article_slug/edit, etc.

This is going to be some work, you need to look into node.module and the hook_menu() implementation found there, and copy a lot from there. Or you could use hook_menu_alter() instead of hook_menu(), and copy some of the data already registered for node/% and friends.

The essential trick now is to define a wildcard loader for %mymodule_article_slug.

/**
 * Wildcard loader callback for '%mymodule_article_slug'.
 *
 * @param string $slug
 *   Part of the url identifying the node, e.g. "pink-elephant"
 * @return object|null
 *   The node object, usually an instance of stdClass, or
 *   NULL, if no such node exists.
 */
function mymodule_article_slug_load($slug) {
  // Load the node identified by $slug.
  $node = ...;
  return $node;
}


Now it gets insteresting. How do you load the node identified by the "slug"?
There are different ways.


You could store the slug in a field on the node, and then use EntityFieldQuery to load the node with that field value. You also need to decide what to do if more than one node has the same slug.
You could use path + pathauto and find the node where the alias is "article/" . $slug. drupal_get_normal_path() can help you with that.


With method 2, your code would look like this:

function mymodule_article_slug_load($slug) {
  // Load the node identified by $slug.
  $normalpath = drupal_get_normal_path('article/' . $slug);
  if ($normalpath &amp;&amp; preg_match('#/node\/(\d+)$/', $normalpath, $m)) {
    $nid = (int)$m[1];
    if ($nid &gt; 0) {
      return node_load($nid);
    }
  }
}


EDIT: This only works if the "slug" does not contain any slashes by itself!