Routing algorithm for Wordpress - wordpress

I don't know the exact meaning of the question but someone asked me this question in interview. I just want to know that there's something like that, we use any route algorithm in Wordpress?

This could be a trick question because routing would mean mapping an HTTP request to trigger specific function or method that would handle the request which is not something that WordPress does (there is a section about WordPress at the bottom). In simple word, you read the HTTP request information to decide what function is going to be triggered.
Bit more details in simple words
if you are building a PHP project from scratch and want to display specific content or trigger a method/function there are usually two option (without routing)
Using POST , GET or REQUEST variables and complex conditional statements to achieve what you want, so a result URL could be something like this
http://example.com/index.php?view=pubications&per_page=5
Setting a PHP file for each type of content
http://example.com/publications.php?per_page=5
However, if you created a Router (Routing algorithm as you named it or routing system) then pushed all requests to index.php and have the latter include let's say something like this:
// Include the Router class
require('classes/router.php');
// Include functions responsible for display our content
require('view/display.php');
I'll not go into how to build a router, just giving examples assuming that you already have one just to give you an idea how routing works.
So assuming you have a router and function to display a contact form for example, you'd also include something like this:
Router::add('/contact-us', get_contact_form(),'get');
Router::add('/contact-us', handle_contact_form(),'post');
Then initialize the Router
Router::initialize('/');
Again assuming you have a complete Router, the above function would tell the index.php file to handle HTTP requests on this URL differently:
http://example.com/contact-us
If it's the default request type GET, trigger this function get_contact_form(), but if the request type is POST trigger this one handle_contact_form() which will act and display content differently depending on your needs.
That's great because it would be instead of something like
http://example.com/index.php?page=contact-us
index.php content would handle the request differently since there is no router.
// Include functions responsible for display our content
require('view/display.php');
if( isset($_GET['page']) && $_GET['page'] == 'contact-us'){
echo get_contact_form();
}
if( isset($_GET['page']) && $_GET['page'] == 'contact-us' && isset($_POST['contact_submit']) ){
echo handle_contact_form();
}
Imagine how long and ugly this would look like if you have a lot of pages and a complex site.
So back to WordPress
If you have a new installation you'd notice that the URLs looks something like this:
http://example.com/?p=62
http://example.com/?cat=1
http://example.com/?author=3
So it would just take URL parameters then build a WP_Query based on that, if is p then look for posts in database by ID, if cat then look for categories by ID and so on... (that's the simple explanation, there is a lot going on of course in the back-end, but just to give an idea).
You might notice after changing permalink structure that the above examples would now look something like this:
http://example.com/post-slug
http://example.com/author/name
http://example.com/category/uncategorized
This might look like routing, but it isn't, let's go in a bit more details about how this works.
When requesting a (pretty-link) URL on WordPress, first thing that happens is that the .htaccess looks for a folder/file with same name on the server, if it exists it will served, if not, it would send that request to the index.php file which does one thing:
/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wp-blog-header.php' );
loading the wp-blog-header.php file, which will make a small check to make sure the code only run once then the following:
// Load the WordPress library.
require_once( dirname(__FILE__) . '/wp-load.php' );
// Set up the WordPress query.
wp();
// Load the theme template.
require_once( ABSPATH . WPINC . '/template-loader.php' );
Let's not go deeper into these files, what's concerns us the most is what 'wp-load.php' and 'template-loader.php' does
wp-load.php
This one among other things, looks for wp-config, make sure everything is set correctly, then connect to the database, of course after a lot of initialization, setting up constants loading a lot files that handles different parts of WordPress structure. Part of this process is that WordPress tries to match the request URL with a large set of rule called rewrite rules which are set of regular expressions, when a match is found WordPress will translate that URL into a database query using [WP_Query][1] class which is located at wp-includes/class-wp-query.php and this class will save the query results among other things (query type...etc)
template-loader.php
This one handles the display part, it uses some WordPress function that make use of WP_Query (eg:is_home()) to find out what type of content is to be displayed, then loads the the correct template based on that, and finally the template will use WP_Query to show the result.

Related

Wordpress : Module with the GET/POST value accept?

In Wordpress, how to make a API like Module, which can accept the data being passed via POST arguments. I mean, the Wordpress should be able to accept the URL calls from external, and then process it.
I mean, as the external Application or myself manually, when i call:
http://www.wordpress-site.com/test?name=james&age=14
Then how to write a module to read such incoming POST values and process it (Save them into the Database or something)
It is actually a public API.
Try with this one:
In Base page it should seems something like this :
Click Here
In Destination page it should seems something like this :
<?php if(isset($_GET['name']) && isset($_GET['age'])){
echo "name=".$_GET['name'];
echo "age=".$_GET['age'];
}
?>
Thanks.
Take a look on WordPress | Accept incoming url with variable parameters
that helps you to get the incoming parameters and wp action hook might be helpful that you want to achieve.
wp action hook

Set PHP Variables for Drupal 7 Theme Files

I want to set custom php variables that can be used throughout my drupal theme (html.tpl.php, page.tpl.php etc.) I need the variables set based on the $title of the node. I'm not an expert on how Drupal works, the moduling and hooks, and I just need to know the simplest/easiest way to accomplish this. I keep reading about implementing some sort of hook in the template.php file where you can set variables, but I've been unsuccesful with everything I've tried.
So, basically, how would you accomplish this:
Get $title of Node
Set variables that will be passed along into theme files (for example, to do basic things like: if($title == 'news_page') { $siteSection = "news"; } )
Have $siteSection be available to use in theme files
Any help would be great.. thanks!
Before Drupal builds the HTML for a page from a theme's template (.tpl.php file), it runs preprocess "hooks". Hooks are basically a naming convention for functions that let modules and themes override or "hook" onto Drupal core processes.
E.g., if you want to display a message to a user when they log in, you can use hook_user_login.
function MODULENAME_user_login(&$edit, $account) {
drupal_set_message("Welcome, ". $account->name);
}
When a user logs in, Drupal looks for all loaded functions that end in "_user_login" and it runs them. If this function is in an enabled module, it has been loaded, so it will get run as well.
If you want to make a variable named $site_section available in your page.tpl.php file, you can hook into template_preprocess_page. This is a theme hook, so the name is a little different, but it functions pretty much the same way. To call this hook from your theme, you need to create a file called template.php in your theme's directory. Inside template.php, we'll add:
<?php
function THEMENAME_preprocess_page(&$vars){
switch (drupal_strtolower($vars['node']->title)) {
case "about page":
$site_section = "about";
break;
case "news page":
case "news page1":
case "news page2":
$site_section = "news";
break;
default:
$site_section = "none";
break;
}
$vars['site_section'] = $site_section;
}
The <?php is used to tell the server the treat all of the proceeding code as PHP. We then declare our hook function with the intention of loading Drupal's array of page variables into a local variable called $vars. By adding the & before $vars, we'll be allowed to modify the values for use outside of this function.
The switch statement will let us efficiently test the page title for multiple values. The value of the node's title may contain uppercase letters, lowercase letters, and symbols, so to avoid a case-sensitive mismatch, we're going to convert the title to lowercase and only test that (symbols will still be in the title, though). After the switch statement, we set the value of our $site_section local value into the referenced $vars array for use in page.tpl.php.
However, if it's just your intention to break the site up into sections for theming purposes, there are other ways of accomplishing that. My answer to a similar situation a few months ago might be helpful.

Using specific drupal-related functions in a non-drupal.php file INSIDE the drupal dir

Good morning all.
I'm having some issues while trying to make the function "field_file_load" work in a php script I've done to process an AJAX call.
I've read about bootstrapping drupal core elements inside, but it doesn't seem to work.
So far I've succesfully populated a Select Box using the data from another Select Box, making an AJAX call to this php file (which is in the drupal directory folder, in a theme to be precise)
<?php
$var = $_GET['q'];
$con = mysql_connect('*******', '******', '********');
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("drupal", $con);
$sql="SELECT DISTINCT xc.field_brand_value FROM node
INNER JOIN term_node AS tn ON node.vid = tn.vid
LEFT JOIN content_type_extra_content AS xc ON node.vid = xc.vid
WHERE tn.tid IN (SELECT th.tid FROM term_hierarchy AS th WHERE th.parent = '149')
AND xc.field_location_value = '".$var."'";
$result = mysql_query($sql);
echo(' <select name="brand" id="brand">
<option value="default" selected>Select a brand</option>
');
while($row = mysql_fetch_array($result))
{
echo('<option value="'.$row['field_brand_value'].'">'.$row['field_brand_value'].'</option>');
}
echo('</select>');
mysql_close($con);
?>
And this is working like a charm because all I have to do is connecting to the drupal db and fetch the desired values.
The problem arises when I want to fetch the url of some pictures (with a query that uses values from the first and second dropdown) and use the "file_field_load" to load the url of the given picture.
I get (obviously) a "call to undefined function" error.
So I tried bootstrapping drupal.
But it doesn't work anyway.
/** bootstrap Drupal **/
chdir("/path/to/drupal/site/htdocs");
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
Since I don't have full access to the server where the site is hosted, assuming that drupal is convenientrly installed in the root, how can I figure out the path to drupal site htdocs ?
Moreover, does calling a full bootstrap (instead of just the needed part) can cause some problems?
So, to be brief:
1] how can I call a drupal function (in this case which comes from the filefiled module) in a non-drupal php script which resides however in the drupal directory?
2] Which is the correct way of bootstrapping?
3] Do I need to connect to the db (like in the previous working example) IN ADDITION to bootstrapping?
Or, finally. there's a different, speedier way you know how to do what I need to do?
Thanks in advance for any reply.
Hmm that's weird. If the FileField module is enabled, the function should be available. So maybe FileField is not actually enabled?
If that's the case you're gonna have to manually add the file that contains the function definition, which is the field_file.inc file in the module's directory, so you'd add that dependency to your bootstrapping code:
<?php
/** bootstrap Drupal **/
chdir("/path/to/drupal/site/htdocs");
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
module_load_include('filefield', 'inc', 'field_file');
AFAIK what you're doing for bootstrapping Drupal from an outside script is the "correct" way.
Now, I'm not sure if, on a big picture level, whatever you're trying to do is a good idea at all... That is: You're making a little nonDrupal script which:
manually connects to the Drupal database with plain mysql functions instead of Drupal's DB API functions, in order to
fetch CCK information using a query that's 100% vulnerable to SQL injection, and
all of this put in a theme directory no less!
So you might want to rethink your angle of attack here, you know?. Maybe making a custom module for this.
But if you just have to do things this way (for reasons I can't think of), then at least use db_query so you don't have to do the whole mysql_connect() stuff, and do something like
<?php
db_query("YOUR BIG QUERY HERE... xc.field_location_value = '%s'", $var);
...for at least some degree of security.
I would also recommend that you browse the involved modules a bit (FileField, etc) to see if they have APIs (or at least some internal functions) that might return what you're trying to get through plain DB querying.

How do you use a view with arguments as the site front page in Drupal?

I have a Drupal site and I have setup a view to power the front page.
My goal is to be able to pass 0-2 arguments to the home page, that get passed into the view. However, I still need the normal Drupal pages to work. The list of arguments is known.
For example:
mysite.com/berlin/birds would pass in "berlin" as the first argument and "birds" as the second argument to the view that powers the front page.
mysite.com/berlin would just pass in one argument, "berlin"
mysite.com/admin would load the normal admin pages in Drupal
I'm not clear on how to achieve this. Is there a hook I can use? I can't find one or think of one. Is there a way to specify this in the argument for the view itself? Perhaps I can write a hook that interjects when the URL is being loaded, and rewrite in the background?
The solution I currently have is to add these paths (since my arguments are known) to the menu system. This works, except that when I the pages they aren't the front page, so the pages don't use the node themes I want (they use the node details theme).
I don't think you can really do this without custom code. The View needs a path before it starts taking arguments, and your URLs start with the arguments. What you can do is fake it with custom code. I've used something like this:
/**
* Implements hook_init().
*/
function mymodule_custom_init() {
$item = menu_get_item(); // Matching Drupal path
if (!$item) { // There is no matching Drupal path.
$_GET['q'] = 'view_path/' . $_GET['q']; // Fake path path.
} // if
} // mymodule_custom_init
Then you give the view a path of "view_path" and it responds to everything that doesn't match anything else in Drupal's paths.
There is a spot in the views UI for "Argument handling code" that takes a small snippet of php - http://drupal.org/node/70145
You could run some code there that checks to see if you are on the front page (or arguments are not present or whatever)and insert the arguments you want.
Another way is to set arguments via a hook_views_pre_view or hook_views_pre_build. Is better because you are sure you don't break other stuff (like another view block).
function MYMODULE_views_pre_view(&$view){
if ($view->name == 'your_view_name' && drupal_is_front_page()) {
$view->set_arguments(array('you_argument','you_second_argument'));
}
}

Drupal - Getting node id from view to customise link in block

How can I build a block in Drupal which is able to show the node ID of the view page the block is currently sitting on?
I'm using views to build a large chunk of my site, but I need to be able to make "intelligent" blocks in PHP mode which will have dynamic content depending on what the view is displaying.
How can I find the $nid which a view is currently displaying?
Here is a more-robust way of getting the node ID:
<?php
// Check that the current URL is for a specific node:
if(arg(0) == 'node' && is_numeric(arg(1))) {
return arg(1); // Return the NID
}
else { // Whatever it is we're looking at, it's not a node
return NULL; // Return an invalid NID
}
?>
This method works even if you have a custom path for your node with the path and/or pathauto modules.
Just for reference, if you don't turn on the path module, the default URLs that Drupal generates are called "system paths" in the documentation. If you do turn on the path module, you are able to set custom paths which are called "aliases" in the documentation.
Since I always have the path module turned on, one thing that confused me at first was whether it was ever possible for the arg function to return part of an alias rather than part of system path.
As it turns out, the arg function will always return a system path because the arg function is based on $_GET['q']... After a bit of research it seems that $_GET['q'] will always return a system path.
If you want to get the path from the actual page request, you need to use $_REQUEST['q']. If the path module is enabled, $_REQUEST['q'] may return either an alias or a system path.
For a solution, especially one that involves a view argument in the midst of a path like department/%/list, see the blog post Node ID as View Argument from SEO-friendly URL Path.
In the end this snippet did the job - it just stripped the clean URL and reported back the very last argument.
<?php
$refer= $_SERVER ['REQUEST_URI'];
$nid = explode("/", $refer);
$nid = $nid[3];
?>
Given the comment reply, the above was probably reduced to this, using the Drupal arg() function to get a part of the request path:
<?php
$nid = arg(3);
?>
You should considder the panels module. It is a very big module and requires some work before you really can tap into it's potential. So take that into considderation.
You can use it to setup a page containing several views/blocks that can be placed in different regions. It uses a concept called context which can be anything related to what you are viewing. You can use that context to determine which node is being viewed and not only change blocks but also layout. It is also a bit more clean since you can move the PHP code away from admin interface.
On a side note, it's also written by the views author.
There are a couple of ways to go about this:
You can make your blocks with Views and pass the nid in through an argument.
You can manually pass in the nid by accessing the $view object using the code below. It's an array at $view->result. Each row in the view is an object in that array, and the nid is in that object for each one. So you could run a foreach on that and get all of the nid of all rows in the view pretty easily.
The first option is a lot easier, so if that suits your needs I would go with that.
New about Drupal 7: The correct way to get the node id is using the function menu_get_object();
Example:
$node = menu_get_object();
$contentType = node_type_get_name($node);
Drupal 8 has another method. Check this out:
arg() is deprecated

Resources