Drupal - custom module - Generate dynamic URL alias - drupal

I have a custom drupal module. I have a demo pages for different APIs I have. (Like, host.com/demo/abc or host.com/demo/bcd or host.com/demo/def ...)
hook_menu()
$items['demo/%'] = array(
'page callback' => 'xxx',
'page arguments' => array(1),
'access callback' => 'xxx',
....
);
I want to change the URL to host.com/abc/demo for all the demo pages. Since I cannot a wild card at the beginning of the hook (Like %/demo) I am considering URL alias. But how can I generate url alias dynamically for all the demo pages?

The best solution :
http://www.zyxware.com/articles/3636/drupal-how-to-create-url-alias-for-custom-menu-implementation-of-hook-pathauto
Otherwise :
Before you need to know that all dynamical solution available is not totally safe , take care before using it.
With url_alias you can try this, but you have to restrict by defined path to avoid flood insertion :
function mymodule_menu(){
$items= array();
$items['demo/%'] = array(
'page callback' => 'xxx',
'page arguments' => array(1),
'access callback' => 'xxx',
);
return $items;
}
function mymodule_init(){
global $language;
$path_allowed = array(
'abc',
'dbe'
); // restrict to avoid flood
if(arg(1) == 'demo' && in_array(arg(0), $path_allowed)) { // detect demo mode
$path = arg(1).'/'.arg(0);
$alias = arg(0).'/'.arg(1);
$a = db_query('SELECT alias FROM url_alias WHERE source = :source AND alias = :alias', array(':source' => $path, ':alias' => $alias))->fetchField();
if($a == null) ) {
db_insert('url_alias')->fields(array(
'source' => $path,
'alias' => $alias,
'language' => $language->language
))->execute();
}
}
}
Otherwise, I'm not sure but you can try this too , you can handle it from hook_init but it can cause some issue form all module loading init
function mymodule_init(){
if(arg(1) == 'demo') { // detect demo mode
$mycallbacks = array( // define your callback related
'abc' => 'mymodule_callback1',
'dbe' => 'mymodule_callback2',
);
if(isset($mycallbacks[arg(0)]) && function_exists($mycallbacks[arg(0)])) { // if callback is available
call_user_func($mycallbacks[arg(0)]); // call it
}
}
}
function mymodule_callback1(){ //do what you want }
function mymodule_callback2(){ //do what you want }
So , mysite.com/abc/demo will execute mymodule_callback1() and mysite.com/dbe/demo will execute mymodule_callback2()
Etc..
Clear all caches and see :)

Related

Drupal - using views_embed_view with an external Drupal site

I have two Drupal sites hosted on different servers. In the main they need to operate separately however site1 has one specific content type which I'd like to show in a list on site2.
I can't simply use feeds to import as the original has to remain and if edited, the changes be instantly reflected on both sites. Site2 has no requirement to edit the content - only show it.
The content is already being presented in a list on site1. The list was created using views.
My intention was to call the view on site2 using the following code in a custom module.
function site2_menu() {
$items = array();
$items['content-from-site1'] = array(
'title' => 'Content from Site1',
'page callback' => 'site_two_list',
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function site2_list() {
db_set_active('site1');
$content = views_embed_view('articles', 'default');
db_set_active('default');
return $content;
}
site1 DB is defined in the settings.php file.
However this isn't returning any data. Using the same approach on Site1 (without switching DBs) works fine.
Was I being over-optimistic in hoping this approach would work or am I missing something obvious?
If this isn't likely to work, what would the alternative be? I can do my own SQL query, but I'd prefer to use views for built in arguments, pagination, templates, etc.
Thanks.
I've not been able to use views_embed_view, however I have been able to use views_get_view to retrieve everything I need and iterate over the results myself. It's a very close second.
function site2_menu() {
$items = array();
$items['content-from-site1'] = array(
'title' => 'Content from Site1',
'page callback' => 'theme_site2_list',
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function site2_theme() {
return array (
'site2_list_page' => array(
'arguments' => array('content' => NULL),
'template' => 'templates/site2-list-page'
)
);
}
function theme_site2_list() {
db_set_active('site1');
$view = views_get_view('articles');
$view->base_database = "site1";
$view->init_display();
$view->pre_execute();
$view->execute();
db_set_active('default');
foreach ($view->result as $key => $data) {
$content[$key]['nid'] => $data->nid;
$content[$key]['title'] => $data->node_title;
$content[$key]['body'] => $data->field_body;
$content[$key]['image'] => $data->field_field_image;
}
return theme('site2_list_page', array('content' => $content));
}
Then in site2-list-page.tpl.php I can use the $content array to do what I need. It's not quite as clean as a simple views_embed_view, but it's a close second and allows the content from one site to be pulled to another fairly easily.

drupal module and php file

I'm trying to create a test module in drupal 6.x that loads php pages. I made a test.module and test.info file and also put inside the .php page. Below is the test.module code. But it doesnt work on my drupal_site/test I get page not found.
function test_perm() {
return array('access test content');
}
function test_contents() {
module_load_include('php', 'test', 'index');
}
function test_menu() {
$items = array();
$items['test'] = array(
'title' => t('Test'),
'description' => t('Test desc'),
'page callback' => 'test_page',
'access arguments' => array('access test content'),
'type' => MENU_NORMAL_ITEM
);
return $items;
}
function test_page() {
$page_array['test_arguments'] = array(
'#markup' => test_contents(),
);
return $page_array;
}
I'll take a guess that your test_contents() outputs HTML directly to the page buffer? This isn't the way Drupal works, it expects you to build up a string and return that in your $page_array variable.
Either change your test_contents() function to return the string not output it, or store the output in a temporary buffer and assign that to a string:
function test_page() {
// Start your buffer
ob_start();
// Output into the buffer
test_contents();
// Save the result to a string and close the buffer
$contents = ob_get_clean();
$page_array['test_arguments'] = array(
'#markup' => $contents,
);
return $page_array;
}

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 hook_menu_alter() for adding tabs

I want to add some tabs in the "node/%/edit" page from my module called "cssswitch".
When I click "Rebuild Menus", the two new tabs are displayed, but they are displayed for ALL nodes when editing them, not just for the node "cssswitch". I want these new tabs to be displayed only when editing node of type "cssswitch".
The other problem is when I clear all cache, the tabs completely dissapear from all edit pages. Below is the code I wrote.
function cssswitch_menu_alter(&$items) {
$node = menu_get_object();
//print_r($node);
//echo $node->type; //exit();
if ($node->type == 'cssswitch') {
$items['node/%/edit/schedulenew'] = array(
'title' => 'Schedule1',
'access callback'=>'user_access',
'access arguments'=>array('view cssswitch'),
'page callback' => 'cssswitch_schedule',
'page arguments' => array(1),
'type' => MENU_LOCAL_TASK,
'weight'=>4,
);
$items['node/%/edit/schedulenew2'] = array(
'title' => 'Schedule2',
'access callback'=>'user_access',
'access arguments'=>array('view cssswitch'),
'page callback' => 'cssswitch_test2',
'page arguments' => array(1),
'type' => MENU_LOCAL_TASK,
'weight'=>3,
);
}
}
function cssswitch_test(){
return 'test';
}
function cssswitch_test2(){
return 'test2';
}
Thanks for any help.
hook_menu_alter() is only called during the menu building process, so you can't do dynamic node type checks within that function.
However, to achieve what you want, you can do this with a custom access callback as follows:
// Note, I replaced the '%' in your original code with '%node'. See hook_menu() for details on this.
$items['node/%node/edit/schedulenew2'] = array(
...
'access callback'=>'cssswitch_schedulenew_access',
// This passes in the $node object as the argument.
'access arguments'=>array(1),
...
);
Then, in your new custom access callback:
function cssswitch_schedulenew_access($node) {
// Check that node is the proper type, and that the user has the proper permission.
return $node->type == 'cssswitch' && user_access('view cssswitch');
}
For other node types, this function will return false, thus denying access, and thus removing the tab.

Drupal problem, how to create a fast content module?

Hi I need to create a module in drupal to display some data, not being a drupal developer and after reading a couple of tutorials, i cant seem to display anything.
I have the next code:
<?php
function helloworld_perm() {
return array('access helloworld content');
}
function helloworld_listado(){
return "yea";
}
function helloworld_menu(){
$items = array();
$items["listado"] = array(
'title' => t('Listado de empresas'),
'callback' => 'helloworld_listado',
'access' => array('access helloworld content'),
'type' => MENU_NORMAL_ITEM
);
return $items;
}
When i enter /listado i get a Access denied
You are not authorized to access this page.
Any idea what im doing wrong?
If i go to the admin->module->permissions, i have checked the permision for all roles to access hellowold content.
Ty!
From the way that your menu array is structured in helloworld_menu(), I'm assuming that this is Drupal 6. If so, you need to rename 'access' to 'access arguments'. See http://api.drupal.org/api/function/hook_menu/6.
The Drupal API documentation also includes a heavily-commented page_example.module that's doing basically what you're doing here, which you might want to check out: http://api.drupal.org/api/file/developer/examples/page_example.module/6/source
Hope that helps!
Oh. And don't forget to clear your cache afterwards from the "Clear cache" button on Administer >> Site configuration >> Performance.
=> t('Listado de empresas'),
'page callback' => 'helloworld_listado',
'access arguments' => array('access helloworld content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
Note that , MENU_NORMAL_ITEM being the default value for type, you do not need to specify it.
Also, as our esteemed webchick just said
It seems you are using a mix of Drupal 5 (array contents) and Drupal 6 (no $may_cache, $items indexed by path) syntaxes for hook_menu.
If you are using Drupal 6, this should look like:
<?php
function helloworld_perm() {
return array('access helloworld content');
}
function helloworld_listado(){
return "yea";
}
function helloworld_menu(){
$items = array();
$items["listado"] = array(
'title' => t('Listado de empresas'),
'page callback' => 'helloworld_listado',
'access arguments' => array('access helloworld content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
?>
Note that, MENU_NORMAL_ITEM being the default value for 'type', you do not need to specify it.
Also, as our esteemed webchick just said, you can find a detailed explanation on the page she points to.
just FYI , above link moved to
http://api.drupal.org/api/examples/page_example--page_example.module/6

Resources