How to make a custom php output in drupal and fix it on a specific relative path? - drupal

I am trying to make a module which generates output at a specific relative path say mysite.com/newcomment/
What I am trying to do:
On client side I have coded JS which makes ajax request to "mysite.com/newcomment/". If there is any new comment, on "mysite.com/newcomment/" output " have done comment on " is generated and same is shown on client side in a pop-up.
What I have done previously:
If I am making a page/article, header and footer code is coming with output.
I have also made a endpoint for it via web service but i don't want that-much complexity.
Am I doing it the right way any pointers or clues will be helpful.

Your question is very confusing but from the title it sounds like your looking for hook_menu
Check out: api.drupal.org
Your custom url will be created with code that looks like:
function my_module_menu() {
$items['example/feed'] = array(
'title' => 'Example RSS feed',
'page callback' => 'my_module_page',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
Then output the code on the page callback:
my_module_page {
return '<h2 class=test>Hello World</h2>';
}
While you normally want html to be generated using theme functions for better caching this should at least get you started.
Edit:
To print only the data such as in an ajax call the function should look like this. Of course only include the code for your version of Drupal:
my_module_page {
// Drupal 7
print 'string';
drupal_exit();;
// Drupal 6
print 'string';
module_invoke_all('exit');
exit;
}

Related

Change cache settings programmatically in Drupal 7

I have a block which displays list of RSS feed from an external site. I want to keep caching other blocks except the mentioned block. Howto do that?
For example, I have blockA, blockB and blockC. I only want to change the blockB's cache settings permamently to DRUPAL_NO_CACHE and leave other blocks as they are and I want to do that programmatically.
You can change the caching roles in the specific module that creates youre block.
In the block info like beneath:
function pref_block_info() {
return array(
'pref_main' => array(
'info' => t('Display flash game for auth. users'),
'cache' => DRUPAL_NO_CACHE,
),
'pref_winner' => array(
'info' => t('Show the winner of the last week.'),
'cache' => DRUPAL_NO_CACHE,
),
'pref_leader' => array(
'info' => t('Show the leader of the current week.'),
'cache' => DRUPAL_NO_CACHE,
),
'pref_top' => array(
'info' => t('Show the top 10 of the current week.'),
'cache' => DRUPAL_NO_CACHE,
),
);
}
The answer given by Jurgo is perfectly right, if you are defining the block within your own module.
In case if you want to change the caching behavior of a block written by some other module then you can use the function mymodule_block_list_alter
function mymodule_block_list_alter(&$blocks, $theme, $code_blocks) {
// Remove the caching on rss feeds block.
// Here rss-feeds is the unique key for the block
$blocks['rss-feeds']['cache'] = DRUPAL_NO_CACHE;
}
Where do the blocks come from? That's important. As Jurgo said, you can specify it in hook_block_info if it's a custom module. If they are views blocks, there is a caching setting per display within views that handles this. If they are blocks provided by some other module, you'd need to directly query the database to change the block's caching setting.
As a general note, to display RSS feeds, just use Feeds and Views. Then you don't write custom code at all for any of this.
This will reduce the work by going to performance settings page (admin/settings/performance) & clicking "cleared cached data" by scrolling down.
But make sure that this page is only accessed by administrator.
For Drupal 7 is same as Drupal 6:
<?php
drupal_flush_all_caches();
drupal_set_message('cache flushed.');
?>

Drupal 6 - force page view to display a different view?

Kind-of a crazy question here...
I have a view display that's set up as a page. It looks great in theme A (desktop), but terrible in theme B (mobile). So I made a different version of the view for theme B. Since the desktop/mobile 'sites' are the same just with different themes, the url for this page will be the same regardless of hte theme selected.
So I would like to be able to point the user to:
mysite/this_crazy_view
and have the returned page select the proper view depending on which theme it's in. I know that if I were using blocks I would just assign the appropriate blocks to the page in question on a theme-by-theme basis, but since the displays are using page display I don't know what the right approach would be.
I would rather not rebuild the views as blocks if I can help it (if it can't be helped, so be it...) so I was hoping there was some way to conditionally load the view via the tpl.php file or something like that...
The code I'm using in my module (per #Clive 's recommendation below) is:
<?php
function bandes_custom_hook_menu() {
$items['charley_test'] = array(
'title' => 'Title',
'access arguments' => array('access content'),
'page callback' => 'bandes_custom_set_page_view',
'type' => MENU_NORMAL_ITEM );
return $items;
}
function bandes_custom_set_page_view() {
global $theme_key;
$view_name = $theme_key == 'mobile_jquery' ? 'course_views_mobile' : 'course_views';
$display_id = 'page_5';
return views_embed_view($view_name, $display_id);
}
?>
I've cleared the cache a number of times and tried a variety of different paths in the $items array. The course_views and course_views_mobile both definitely work on their own.
I was also wondering if I could just create a views-view--course-views--page-5.tpl.php which contains almost nothing aside from the views_embed_view(course_views_mobile, page_5) part? (Only on one of the two themes...)
Actually I think the answer was simpler than all of the above. The redirect thing was giving me fits, so I removed the module, reset the paths to what I had been using, and tried the template/theme approach instead.
This is: views-view--course-views--page-5.tpl.php, only used on the mobile theme, but referring to the non-mobile view (kinda gives me a headache, but it works)
<?php
//get the view
print "IM IN YR VUE, MESSING THNGZ UP!"; //yeah, I'm going to remove this part...
$view_name="course_views_mobile";
$display_id="page_5";
print views_embed_view($view_name, $display_id);
?>
Any reason that shouldn't work? (Or why it is a really bad idea?)
Me again :)
I just thought of an easy-ish way around this actually; if you can change the URL of your views to something other than the path you want to access them at (any path would do) you could implement a hook_menu() function in a custom module for that path, to make the choice depending on your theme:
function MYMODULE_hook_menu() {
$items['this_crazy_view'] = array(
'title' => 'Title',
'access arguments' => array('access content'),
'page callback' => 'MYMODULE_crazy_view_page',
'type' => MENU_CALLBACK // or MENU_NORMAL_ITEM if you want it to appear in menus as usual
);
return $items; // Forgot to add this orginally
}
function MYMODULE_crazy_view_page() {
global $theme_key;
$view_name = $theme_key == 'foo' ? 'theView' : 'theOtherView';
$display_id = 'page_1'; // Or whatever the page display is called
return views_embed_view($view_name, $display_id);
}
That should do the trick

drupal module pages

I'm having a conceptual sort of roadblock.
So, I'd like to make a custom Drupal module, with several different pages, each of which "does stuff".
I'm not understanding how to make/integrate different pages into my module, and what their URLS would be.
I do have this :
/* FILE : mymodule.module */
function mymodule_menu() {
$items = array();
$items['mymodule/landingpage'] = array(
'page callback' => 'mymodule_landing',
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function mymodule_landing() {
$title = 'Hello World';
$content ='This is a simple Hello World Proof of Concept';
return theme_box($tile, $content);
}
And when I go to mysite.com/mymodule/landingpage, I see the content generated by mymodule_landing().
But this doesn't seem like what I want to do because the content for landingpage is generated inside the mymodule.module, and it leaves me super confused about how I'd go about making my mysite.com/mymodule/step2, ... , mysite.com/mymodule/step99 pages
I have the gut feeling that the code for each page should be in it's own corresponding file, and I'm not understanding how to do it, this doesn't seem like the right way.
Can you explain how I should be doing it, where the file should go (with my other module files, right?), and what URL it would be viewable at?
What you are doing so far is mostly correct (The "title" key is required for each item, so be sure to include that). Since the page callback is directed at mymodule_landing(), the content returned from that function will be displayed as your content on the page.
To make more pages (like step2, step99, etc) you would continue with creating more paths in mymodule_menu() like:
$items['mymodule/step2'] = array(
'title' => 'Step 2', // Required
'page callback' => 'mymodule_step2',
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
And so forth... You could use the same page callback mymodule_landing() and simply pass "page arguments" or each can have its own page callback.
To put your function mymodule_landing() in a separate file, you can use the file and file path keys (see below)
$items['mymodule/landingpage'] = array(
'title' => 'Landing Page', // Required
'page callback' => 'mymodule_landing',
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
'file' => 'mymodule.pages.inc',
'file path' => drupal_get_path('module', 'mymodule'),
);
You should put these files in your module directory (or sub-directory inside module directory and set the correct file path) and can access each page at mysite.com/mymodule/landingpage, mysite.com/mymodule/step2, etc.
Best Practices for Page Handler Include Files (read more at http://drupal.org/node/146172):
Module developers are free to split off page handlers for their modules however they choose. However, the following guidelines and standards are recommended:
Any module that has more than ~50 lines of code for page handler functions (including form handling functions if applicable) should split them off into a separate file. That reduces the overhead for PHP when loading modules, and therefore speeds up every single request on the site.
Page include files should be named in the form modulename.key.inc, where "modulename" is the name of the module and "key" is a one-word descriptive term for the types of page handlers it includes.
For most modules, splitting page handlers into two files -- example.admin.inc (for administrator-only pages) and example.pages.inc (for pages accessible by non-administrator users) -- is sufficient, and is the recommended practice. If a module has no non-administrator pages, it should just have a single example.admin.inc file. If a module has no administrator-only pages, it should just have a single example.pages.inc file.
Modules that have a large number of page handlers may choose to separate out page handlers even further. If so, each file should be grouped logically by function (for instance, admin pages related to theming, admin pages related to logging, other admin pages, and user-accessible pages) and clearly marked. Remember that splitting the module's page handlers up too far makes maintenance more difficult, and only one page handler include file is ever loaded regardless of how finely-grained the handler functions are separated.
Added just for reference: hook_menu() documentation
The page_example.module may also be of help to you.

Drupal pass argument to page

I have a custom Drupal module displaying some data in a table. Each row has a link which if clicked will delete the relevant row. Specifically, when the link is clicked it will take the user to a confirmation page. This page is really just a drupal form which says 'are you sure' with two buttons: 'Yes', 'No'. I figure I will need to pass the rowID to the confirmation page.
My question: What is the typically way to pass data to a new page in Drupal 7? I guess I could just add the rowID to the URL and use the $_GET[] from the confirmation page... I don't think this is very safe and was wondering if there was a better 'Drupal' way.
Thanks!
You'd use something like the following
<?php
function yourmod_menu() {
// for examlple
$items['yourmod/foo/%/delete'] = array(
'title' => 'Delete a foo',
'page callback' => 'drupal_get_form',
'page arguments' => array('youmode_foo_delete_confirm', 2), // 2 is the position of foo_id
'access arguments' => array('delete foo rows'),
'type' => MENU_CALLBACK,
);
return $items;
}
function yourmod_foo_delete_confirm($form, &$form_state, $foo_id) {
// load the row
$foo = yourmod_get_foo($foo_id);
// build your form, if you need to add anything to the confirm form
// ....
// Then use drupal's confirm form
return confirm_form($form,
t('Are you sure you want to delete the foo %title?',
array('%title' => $foo->title)),
'path/to/redirect',
t('Some description.'),
t('Delete'),
t('Cancel'));
}
?>
You can look here for examples of how core modules do it (have look at node_delete_confirm)
The simplest solution would be to use an existing module created for this purpose:
http://drupal.org/project/entityreference_prepopulate (for entity references)
http://drupal.org/project/nodereference_url (for node references)
http://drupal.org/project/prepopulate (for other form values)
You can configure which form values can be set from the URL, then rewrite the fields displayed in your table to generate the necessary links.
If the data are nodes, you can make the link node/%/delete where % is the nid. Drupal knows how to handle the delete page, as its a core path. Then, the delete confirmation follows the rest of the system and is very 'Drupal'.
I am not sure if this changed at all in Drupal 7, but this is what I did for countless modules.

Drupal 6 passing variables from Forms to Content, how to?

I created a BLOCK (left) with this simple form.
Now I want to PROCESS and DISPLAY results on PAGE (center)
How can I do it ?
inputs:
name = James
surname = Bond
output I want :
<div style="color:red">Welcome, James Bond</div>
here is a BLOCK which i wrote and works.
<?php
echo drupal_get_form('myForm');
function myForm($form_state) {
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#size' => 20,
'#maxlength' => 10
);
$form['surname'] = array(
'#type' => 'textfield',
'#title' => t('Surname'),
'#size' => 20,
'#maxlength' => 10
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save')
);
return $form;
}
function myForm_submit($form,&$form_state)
{
//??
};
Now I need to display the output :).
Please don't suggest to use VIEWS or any other addon.
I want to learn Drupal from Inside out. Not the other way around ;)
Well, it depends a bit on how you want to do things. Since you are learning how to make a drupal module, you might want to start with an implementation of hook_menu(). This hook is used to define menu items, which basically means that you can register urls with that function. Going that route you can:
Implement hook_menu()
A general way of handling redirects is using drupal_goto(). However, in this case it is much more fitting to use the $form_state['redirect'] as Henrik explained in his comment.
For the url you are redirecting to, you should have a call back function which is where you put your logic, the way you setup the hook_menu and the callback function will determine how you get your variables available. You probably want to look into the arg() function which is what generally is used to get the values from the url.
Run the user input through a filter to make sure that they haven't posted nasty stuff like script tags ect, use check_plain
return a theme function, alternatively make your own, look at theme() and hook_theme()
There are quicker ways to do this, but doing it this way, you will generate urls for every search result that drupal can cache, which is nice. Also not being dependent on the post parameters people can bookmark the search results
Another thing is that you might want to put some basic validation to your form. That would be a good practice to learn. That would look something like this:
/**
* Validation handler for myForm.
*/
function myForm_validate($form, &$form_state) {
$name = $form_state['values']['name'];
// do some checks to $name.
if ($error) {
form_set_error('name', t('error message to be displayed, showing the value of the field: #name', array('#name' => $name);
}
};
You could implement AHAH in your form, and specify an element inside your page's content area as the 'wrapper' (the element in which the results of the callback function will be placed). But, you would need to understand the excellent advice of Mr. Opel before you even attempt it.
How about using drupal_set_html_head() to write a string of script to the head section of the page? I am doing this on specific pages (getting user latitude and longitude and passing them into my gMap function), but I am interested in dong the same thing directly from hook_form_submit(). I have made a few tries at it, and I am obviously outputting the script string but calling the function from submit doesn't seem to work.
if the submit function creates a page full of html output; what is the best way to pass this to a page callback? i doubt that passing as an arg on the url would work.
i stuffed into a session var but maybe a better way?

Resources