Create a custom node tab with a custom path - drupal

Is there anyway I can customize the paths to a node's tabs?
When using either pathauto or hook_menu_alter, I can change the path to the node view to from node/node_id to, well pretty much anything, but let's say xyz/node_title.
The node tabs, however, still stay with the path /node/node_id/tab_name
I'm trying to add a custom tab to the node, and keep the custom path as well (e.g.: xyz/node_title/tab_name instead of node/node_id/tab_name).
I manage to add the custom tab via hook_menu:
$items['node/%node/members'] = array(
'title' => 'Manage Membership',
'page callback' => 'mymodule_members',
'page arguments' => array(1),
'access callback' => 'mymembers_members_access',
'access arguments' => array(1),
'type' => MENU_LOCAL_TASK
);
but if I try to customize the path, either at hook_menu or at hook_menu_alter, the tab just disappears.
Any ideas?
PS, I've posted the same question on the Drupal forums, no answer so far. I'll cross-update.

You can add two functions in settings.php: custom_url_rewrite_inbound(), and custom_url_rewrite_outbound().
The examples in those pages should make clear how to use them.
function custom_url_rewrite_inbound(&$result, $path, $path_language) {
global $user;
// Change all article/x requests to node/x
if (preg_match('|^article(/.*)|', $path, $matches)) {
$result = 'node'. $matches[1];
}
// Redirect a path called 'e' to the user's profile edit page.
if ($path == 'e') {
$result = 'user/'. $user->uid .'/edit';
}
}
function custom_url_rewrite_outbound(&$path, &$options, $original_path) {
global $user;
// Change all 'node' to 'article'.
if (preg_match('|^node(/.*)|', $path, $matches)) {
$path = 'article'. $matches[1];
}
// Create a path called 'e' which lands the user on her profile edit page.
if ($path == 'user/'. $user->uid .'/edit') {
$path = 'e';
}
}
Drupal 7 uses two new hooks, instead of those functions: hook_url_inbound_alter() and hook_url_outbound_alter().

I think this module will help you form the tab path the way you want: Sub-path URL Aliases.

Related

Custom Drupal 6 Module with multiple pages

I am trying to write my first Drupal custom module (using drupal 6). I got the basic module working but I would like to add another page to the project. For example, right now my module's path looks like this: www.mysite.com/my_custom_module. I would like to add another page like this: www.mysite.com/my_custom_module/my_sub_page. I've tried adding a new .module and .info file but this does not work. I've also tried adding new items to the menu hook, like this:
my_custom_module.module:
function my_custom_module_menu(){
$items = array();
$items['my_custom_module'] = array(
'title' => "My Custom Module",
'page callback' => "my_custom_module_info",
'access callback' => true,
'type' => MENU_NORMAL_ITEM,
);
$items['my_custom_module/my_sub_page'] = array(
'title' => "My Sub Page",
'page callback' => "my_custom_module_sub_page_info",
'access callback' => true,
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function my_custom_module_info(){
$result = 'My Page URL was hit';
return $result;
}
function my_custom_module_sub_page_info(){
$result = 'My Sub Page URL was hit';
return $result;
}
In this example, if I go to .../my_custom_module it works fine. But, if I go to .../my_custom_module/my_sub_page, it still load, and displays my_custom_module. When I debug with a break point in each function, only my_custom_module_info is hit. Not the sub page. What am I doing wrong? I this even the correct way to create multi pages in a module? Just an FYI, each of these pages will have different audiences. The first page is to allow a user to submit some form data. The second is to allow an elevated user view the data.
Thanks
jason

How to create a second login page on Drupal Commerce

I am using Commerce Kickstart to create an e-commerce marketplace and I am wondering how I can create a second login page that can be used by the merchants.
The standard login page is generated at http://website.com/user/login. How would I be able to create another login page at let's say http://website.com/user/merchant_login. The page itself will function exactly the same as the login, with slight changes in aesthetics, like taking off the register link, as we will generate the login information for the merchants.
I can see that the form is being generated at commerce_kickstart_user_form_alter through specified form_ids so I should be able to simply add the details for the merchant form there. My main question is how will the page/form be generated when they visit a url of my choosing?
You just need to create a custom page:
Assuming that your custom module is called custom_merchant the code should be something like this:
function custom_merchant_menu() {
$items = array();
$items['user/merchant_login'] = array(
'page callback' => 'custom_merchant_login_callback',
'page arguments' => array(true),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
function custom_merchant_login_menu_alter(&$items) {
$items['user']['page callback'] = 'custom_login_user_page';
}
function custom_merchant_login_callback($show = false) {
global $user;
if ($user->uid) {
menu_set_active_item('user/'. $user->uid);
return menu_execute_active_handler();
} else if ($show) {
return drupal_get_form('user_login');
}
drupal_not_found();
}

Replace the node-edit menu in Drupal

How can I change (unset or add) a new button in my edit-node menu? In this case, I would like to diable the 'Settings'-menu and add a new menu... I looked in the $form and the $form_state, but no luck there. At least, that's what I think...
EDIT
Module name: publication
Install: publication.install
File: publication.module
function publication_menu_alter(&$items) {
unset($items['node/%node/edit']);
}
EDIT 2
function publication_menu() {
$items['node/add/fiche'] = array(
'title' => 'New linked fiche',
'type' => MENU_LOCAL_TASK
);
return $items;
}
EDIT 3
What I'm trying to do is to allow my users to add some more content to existing content. So they are not allowed to edit the current content, only to add some details. So I thought, I delete the edit-button and replace it with an add-button and the add-button links to a page where he can create more content. That's it :)
You should use hook_menu_alter to unset menu.
function publication_menu_alter(&$items) {
// print_r($items);
// Find path you want to unset then unset it.
// Should be something like:
unset($items['your/menu/path']);
}
And hook_menu for defining new one. In your case I believe it should be menu type MENU_LOCAL_TASK since you want to add a new tab. Isn't it?
function publication_menu() {
$items['node/%node/something_else'] = array(
'title' => 'My title',
'page callback' => 'mymodule_abc_view',
'page arguments' => array(1),
'access arguments' => array('access content'),
'type' => MENU_LOCAL_TASK
);
return $items;
}
function mymodule_abc_view($nid = NULL) {
return 'This node ID is '. $nid;
}

Drupal: Passing custom variable from custom module to my template

I realize this question has been asked, but I either simply don't understand or the previous answers don't apply (or I don't understand how to apply them) to my circumstance. Here goes:
I have a custom module named:
"my_module" in /sites/all/modules/custom/my_module
I have a module file:
/sites/all/modules/custom/my_module/my_module.module
I have a page template name "page-mypage" which is NOT in my module:
/sites/all/themes/mytheme/pages/page-mypath-mypage.tpl.php
I made the hook menu for this:
$items['mypath/mypage'] = array(
'title' => 'My Page!',
'page callback' => 'my_module_mypage',
'page arguments' => array(1,2),
'access callback' => true,
'type' => MENU_CALLBACK,
);
In the function, I build up some content like so:
function my_module_mypage($x, $y) {
$output = "foo AND bar!";
return $output;
}
In the template (again, NOT in my module folder, but in the THEME subfolder "pages", I have:
<?php print $content ?>
When I go to http://mysite/mypath/mypage I get "foo AND bar!"
Now for the question. I want a new variable, defined in my_module_mypage(), called '$moar_content'. I want to output $moar_content in my page-mypath-mypage.tpl.php. I only need to do this for this module and for this template. I do not need it theme-wide, so I don't think using mytheme's 'template.php' is appropriate.
I think I need to use some kind of preprocessing, but everything I try fails, and everything I read seems to be missing some kind of magic ingredient.
My thinking was:
function my_module_preprocess_page_mypath_mypage(&$variables) {
$variables['moar_content'] = 'OATMEAL';
}
or
function my_module_preprocess_my_module_mypage(&$variables) {
$variables['moar_content'] = 'OATMEAL';
}
or something. I'm pretty sure I'm on the right track, but I'm hitting a brick wall.
To do the job, you must follow Drupal's best practices, supposing you are using D6, so you can insert some variables to your template like this :
// You menu path is good
$items['mypath/mypage'] = array(
'title' => 'My Page!',
'page callback' => 'my_module_mypage',
'page arguments' => array(1,2),
'access callback' => true,
'type' => MENU_CALLBACK,
);
Second thing, we define the theme hook for our page
// We define here a new theme file for your your page
// Your theme file must be located in your module's folder
// you can use a subfolder to group all your module's theme files
// E.g : themes/my-module-theme.tpl.php
// Note that in theme files, we change _ by -
function my_module_theme() {
return array(
'my_module_theme' => array( // Keep that name in your mind
'template' => 'my_module_theme',
'arguments' => array(
'my_var' => NULL,
'my_var2' => NULL,
),
)
);
}
Now we can create a file "my-module-theme.tpl.php" in the root folder of our module, and paste something like "foo AND bar!"
Back to our my_module.module, the callback must be something like :
function my_module_mypage($x, $y) {
// $x and $y are optionnal, so this is the first manner
// to inject variables into your theme's file
$output = theme("my_module_theme", $x, $y);
return $output;
}
Also you can use preprocess hook to insert variables
// The hook must be named like this : template_preprocess_NAME_OF_THEME_FILE
// where NAME_OF_THEME_FILE is the name that you kept in your mind ;)
function template_preprocess_my_module_theme(&$variables) {
// Do some job
$var1 = 'Foobar';
// So in "my-module-theme.tpl.php", $my_var1 will print Foobar
$variables['my_var1'] = $var1;
}

access global variable of drupal into another php files

I want to access global variable of drupal (like user variable in
drupal) into another php files
I Create a new module for example test module.
my test module have 3 files . test.info , test.module , main.php
I want to use global variable of drupal into main.php as following code
global $user;
please guide me how can i access this drupal variable in my page?
thanks
If you want main.php to be separate from the Drupal system you'll have to Bootstrap Drupal in your custom file, but depending on what you're trying to do there may be an easier way.
If you're just trying to output some HTML/text without the Drupal theme then just implement a menu hook in your module and call exit() from your page callback. Something like this:
function mymodule_menu() {
$items['path/to/page'] = array(
'title' => 'Title',
'page callback' => 'mymodule_page',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK
);
}
function mymodule_page() {
// You have access to the full Drupal bootstrap here as normal
global $user;
$content = 'Some Content';
echo $content;
exit();
}

Resources