Serve an HTML5 application as a Drupal Module - php

I manage a Drupal 7 based website for my College's Student's Association. Most of it is standard static pages. Each year we run a room ballot for people to choose their rooms and this process will need an application to display current room allocations (in real time) and wiki style information about what the different rooms are like.
I need to be able to serve up static pages of HTML, javascript and css; bypassing the theming module. I need the relative addressing in the html page which serves as the root of the application to work properly (e.g. "javascript/app.js" should pick up that file from within the module). I then need to serve up json data from php using all the drupal APIs for permissions and database access etc.
I have a fair bit of experience in HTML, Javascript etc. and some in PHP, but I'm fairly new to Drupal module development.

You should create a custom module as you suggest, and separately put your HTML5 application in a sub-folder of the module. When it's accessed it will use the same relative paths as you'd normally expect so javascript/app.js will work if the file exists in the path under your HTML5 app's folder.
For the JSON data your custom module will look something like this:
function mymodule_menu() {
$items['my/app/data'] = array(
'page callback' => 'mymodule_ajax_callback',
'access callback' => TRUE,
'type' => MENU_CALLBACK
);
return $items;
}
function mymodule_ajax_callback() {
$type = $_POST['type'];
$nodes = db_query("SELECT nid, title FROM {node} WHERE type = :type", array(':type' => $type))->fetchAllKeyed();
drupal_json_output($nodes);
drupal_exit();
}
That code defines a menu path (using hook_menu()) at mp/app/data which uses mymodule_ajax_callback() as it's page callback.
mymodule_ajax_callback() simply grabs all nodes from the database that match the type parameter passed in the AJAX $_POST and outputs their id and title in a JSON string to the page (which will then be returned as your AJAX response when you request /my/app/path).
Hope that helps

Related

Create new page in drupal

Iam new in drupal. I want to create a page and want to add data in page directly with out using backend content. I have created a page like this, page-test.tpl.php. How can I call this newly created page in browser?
First you have to create your own custom module.Let the module name be test.Create 2 files namely test.info and test.module.Declare a hook_menu function inside the test.module file.Since your module name is test your hook_menu will be named as test_menu.
Hook_menu enables modules to register paths in order to define how URL requests are handled. Paths may be registered for URL handling only, or they can register a link to be placed in a menu.
Test.module
function test_menu() {
$items = array();
$items['test'] = array(
'title' => 'My Page',
'description' => 'Study Hard',
'page callback' => 'test_simple', //Calls the function
'access arguments' => array('access content'),
);
return $items;
}
function test_simple() {
return array('#markup' => '<p>' . t('My Simple page') . '</p>');
}
Test.info
name = Test
description = Provides a sample page.
core = 7.x
After adding this try clearing the drupal cache and then navigate to /test.Try this link if you are a beginner.Try reading hook_theme which allows you to use your custom template.More about hook_theme here.Hope it might help u mate.. :)
Pages in drupal are stored in the database, not in actual code files like old websites used to. The template files (.tpl.php) are exactly that - templates. So for example, lets say you have blog content. You'd have to create a content type of 'Blog'. you could then create a template file (ex. node--blog.tpl.php) which would format the way the blog pages would look. But you would still need to add new pages through the drupal interface in order to add them to the site. You could always use an input type of PHP if you'd like to include php in the body of the page.
If you simply want to display a php file in your browser from your site, you can just upload a php file of your choice to your sites/default/files directory and access it directly via the file path.

How to display a Drupal 6.20 menu in WordPress?

Is is possible to display (via php) the main menu of a Drupal 6.20 site in a WordPress theme template file located in a subdirectory on the same domain?
Right now, I'm displaying the menu by copying the static html from the Drupal site and adding it to header.php in the WordPress template in the site located in mydomain.com/blog/. But of course that's not going to work when another menu item is added to the Drupal site, or the Drupal menu is changed in any way.
So is there a Drupal php function that will pull the menu into the WP file?
Failing that, is there a way with php to parse a Drupal page for the html of the menu (yes, this would be ugly) and display it in WP?
The first part of the challenge is to output only the menu, with as little (or none) of the surrounding HTML as possible, so you have as little work to do in parsing the HTML as possible.
The second part is to take that output from Drupal and actually display it on your WordPress site.
You could add the Drupal database as a secondary database in WordPress using the a new instance of the $wpdb object, write the query to get the right content from the tables, and format the results. That could work, but might be overkill.
An alternative workable option may be to use JSON to format the output of the primary links, using the drupal_json function in Drupal, then consume the JSON feed in Wordpress.
I'm assuming:
you have admin access to login to the Drupal site, which you'll need to create nodes, and clear the theme cache
you want to output the Primary Links menu, which 90%+ of Drupal sites use. This is probably true, but it is possible your site uses custom menus. If so, this is still possible, you'd just write slightly different code in step 3.
The steps would be:
Create a Drupal node (you can call it anything, it's just a placeholder)
Get the node id of your dummy page (ie., node/234). From the node id, create a one-off page template in your Drupal site's themes folder. It should be called page-node-xxxx.tpl.php, with xxxx being your node id
Add this code to page-node-xxxx.tpl.php:
<?php
drupal_json(menu_navigation_links(variable_get('menu_primary_links_source', 'primary-links')));
?>
This will create a JSON feed of your menu items.
Clear the theme cache of your Drupal site by visiting http://yoursite.com/admin/build/themes and visit http://yoursite.com/node/xxxx to see the raw JSON feed.
You should now be able to use a jQuery method like $.getJSON or $.ajax in your Wordpress theme to consume and display the JSON feed, or possibly use json_decode and curl to output your array as HTML.
A good thing about Drupal's drupal_json function is that it already sends the correct JSON headers, so now all you have to do is write the jQuery or PHP that does what you need.
I'm assumed you are more of a Wordpress specialist and have a working knowledge of Drupal but maybe not a lot of familiarity with its inner workings. So, sorry if it seemed too basic (or not basic enough :).
The Drupal theming engine is very modular - you may be able to make an appropriate PHP call into Drupal to get just the menu rendered, then emit that HTML as a part of your WordPress page.
g_thom's answer is very good and if you wish to create a very simple module to output the main navigation you can write something like this:
<?php
function getmenus_help($path, $arg) {
// implementing the help hook ... well, not doing anything with it just now actually
}
function getmenus_all() {
$page_content = '';
$page_content = json_encode(menu_navigation_links(variable_get('menu_primary_links_source', 'primary-links')));
// fill $page_content with the menu html
print $page_content;
return NULL;
}
function getmenus_menu() {
$items = array();
$items['getmenus'] = array(
'title' => 'Get Menus',
'page callback' => 'getmenus_all',
'access arguments' => array('access getmenus'),
'type' => MENU_CALLBACK,
);
return $items;
}
// permissions
function getmenus_perm() {
return array('access getmenus');
}
In your PHP code you can then write something like:
function primary_links() {
$primary_links = file_get_contents(SITE_URL . '/getmenus');
$primary_links = json_decode($primary_links);
$primary_links = (array)$primary_links;
$i = 0;
$last = count($primary_links);
$output = '';
foreach ($primary_links as $pm) {
$href = $pm->href;
if (strpos($pm->href, 'http://') === FALSE) {
if ($pm->href == '<front>') {
$href = SITE_URL . '/';
} else {
$href = SITE_URL . '/' . $pm->href;
}
}
$output .= '
<li>
'.$pm->title.'</li>';
$i++;
}
return $output;
}
I hope this helps!
PS: Make sure you update the module's permissions to allow anonymous users to have access to the path you set in your module - otherwise you will get a 403 Permission Denied.

Drupal 7 - Update node fields via ajax/frontpage

I have a few jQueryUI draggable objects that represent nodes generated on my front page in Drupal.
I want to grab when a user drops an element and save the x/y coordinates to the server so when the next user opens the page it will still be where it was last left at.
I created two integer fields, homex and homey, but I can't seem to figure out or find enough documentation to learn how to tell Drupal to update the values for a given node.
I'm fairly familiar with how to create modules in Drupal, and ajax in general - but combining the two in this case is perplexing me.
Can someone help me understand how to attach to Drupal so I can save the coordinates dynamically?
What would be preferable is if I could just write a simple handler module for Drupal that takes the x/y pair in a get/post request then updates them in the database and responds with a success/json. Really if it wasn't being done in Drupal this would be a fairly simple setup.
It seems all I had to do was create a hook_menu() and a hook_ajax_callback() (sorry couldn't find a link) in a module.
Here's what I ended up with (more less, leaving in three different return methods I was playing with):
<?php
function homepage_coords_menu(){
return array(//$items
'homepage_coords/%node/%/%' => array(
'page callback' => 'homepage_coords_ajax_callback',
'page arguments' => array(1,2,3),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
)
);
}
function homepage_coords_ajax_callback($node,$x=0,$y=0){
if(!is_numeric($x) || !is_numeric($y)){
ajax_deliver(json_encode(array(
'status'=>'fail'
)));
}
$node->field_homepagex = array('und'=>array(array('value'=>$x)));
$node->field_homepagey = array('und'=>array(array('value'=>$y)));
node_save($node);
ajax_deliver(json_encode(array(
'status'=>'win'
)));
}
?>
When you say that you are familiar with ajax, you mean jquery's ajax or Drupal 7 ajax framework. You can read more about the Drupal 7 Ajax here http://drupal.org/node/752056
I suppose homex is a hidden form element. Maybe you could hook_form_alter it, adding a #ajax attribute with an ajax callback triggered by a "change" event for example or any other Jquery event, and in that ajax callback, execute node_form_submit_build_node

How to use wildcards in drupal

I have a website where drupal manage the contents, but another application handle the e-commerce (my customer doesnt like to change his own e-commerce)
I dont like to have the e-commerce to looks differently from the rest of the websites, so i've made a drupal Page node with php code in the body, that simply include the external app and initialize it.
It works well, but the problem is the other link the e-commerce generate:
http://example.com/shop #The Page node i've created, this work
http://example.com/shop/catalog/fruit/ #here comes the trouble!
The external app handle the url by its own, so what i need is to tell drupal to redirect all the url that begin with shop to his shop Page node... something like
http://example.com/shop/* => load http://example.com/shop
What is the best practices to do that?
If you create a module rather than a node this will be quite easy.
use hook_menu() to match the URL string
function example_menu() {
$menu = array()
$menu['shop'] = array(
'page callback' = 'example_callback';
)
}
function example_callback() {
// use arg() to get arguments.
return shop_php();
}
Creating a callback with hook menu allows you to call your own code, the value returned by the callback will be displayed in the page. When drupal sees a URL which matches shop* it will call the function example_callback. In this function you can put the code you currently have in your page node. And return the content you wish to display in the page.
After googlin around, i found the Drupal custom_url_rewrite_inbound that does exactly what i need.
I inserted the function in my /sites/default/settings.php:
function custom_url_rewrite_inbound(&$result, $path, $path_language) {
if(preg_match("/^shop(\/)/", $path, $matches)) {
$result = 'node/XX'; //XX is the ID of my Page Node with the ecommerce code.
}
}
It works like a charm!

Drupal - Automate a Content Form Submission

I would like to programatically (using php) fill out an existing drupal form to create a content type that is included in a contributed module.
Details: The module is SimpleFeed and the content type is Feed. I would like to call the module's functions to accomplish this. The method I am interested in is hook_insert which appears to require vid and nid which I am unsure what these are.
Any help is appreciated.
can you provide a bit more information (which modules?). generally, i'd probably suggest calling the modules functions to create the content type, instead of trying to pass it through a form programatically. this way you don't have to worry about implementation, and can trust that if the module works, it'll work for your script too :)
of course this does tie your module to theirs, so any changes in their functions could affect yours. (but then again, you run that risk if they update their database structure too)
ex.
// your file.php
function mymodule_do_stuff() {
cck_create_field('something'); // as an example, i doubt this
// is a real CCK function :)
}
edit: vid and nid are node ID's, vid is the revision id, and nid is the primary key of a particular node. because this is an actual node, you may have to do two operations.
programatically create a node
you'll have to reference the database for all the exact fields (tables node and node_revisions), but this should get you a basic working node:
$node = (object) array(
'nid' => '', // empty nid will force a new node to be created
'vid' => '',
'type' => 'simplefeed'. // or whatever this node is actually called
'title' => 'title of node',
'uid' => 1, // your user id
'status' => 1, // make it active
'body' => 'actual content',
'format' => 1,
// these next 3 fields are the simplefeed ones
'url' => 'simplefeed url',
'expires' => 'whatever value',
'refresh' => 'ditto',
);
node_save($node);
now i think it should automatically call simplefeed's hook_insert() at this point. if not, then go on to 2. but i'd check to see if it worked out already.
call it yourself!
simplefeed_insert($node);
edit2: drupal_execute() isn't a bad idea either, as you can get back some validation, but this way you don't have to deal with the forms API if you're not comfortable with it. i'm pretty sure node_save() invokes all hooks anyhow, so you should really only have to do step 1 under this method.
The drupal api provides drupal_execute() to do exactly this. I would suggest you avoid calling the functions directly to create the node (unless there is a performance reason). By using drupal_execute() all the proper hooks in other modules will be called and your code is far more likely to continue to work through future versions of drupal.
Note that a classic bug in using this method is not first calling something like
module_load_include('inc', 'node', 'node.pages')
which will load the code for your node creation form.
Calling node_save directly is generally considered deprecated and could leave you with broken code in future versions of drupal.
There is a nice example at this lullabot post

Categories