Internet Explorer hacks

.class {
width:200px; /* All browsers */
*width:250px; /* IE */
_width:300px; /* IE6 */
.width:200px; /* IE7 */
}

Arrays for PHP 5.4

Example #1 A simple array


<?php
$array 
= array(
"foo" => "bar",
"bar" => "foo",
);
 

// as of PHP 5.4
$array = [
"foo" => "bar",
"bar" => "foo",
];
?>

Constants php

Syntax

You can define a constant by using the define()-function or by using the const keyword outside a class definition as of PHP 5.3.0. Once a constant is defined, it can never be changed or undefined.

Note: Constants and (global) variables are in a different namespace. This implies that for example TRUE and $TRUE are generally different.

Example #1 Defining Constants

<?php
define
("CONSTANT""Hello world.");
echo 
CONSTANT// outputs "Hello world."
echo Constant// outputs "Constant" and issues a notice.
?>


Example #2 Defining Constants using the const keyword

<?php
// Works as of PHP 5.3.0
const CONSTANT 'Hello World';

echo CONSTANT;
?>

Conditional stylesheets

<!--[if lte IE 8]><link rel="stylesheet" href="lte-ie-8.css"><![endif]--> <!--[if lte IE 7]><link rel="stylesheet" href="lte-ie-7.css"><![endif]--> <!--[if lte IE 6]><link rel="stylesheet" href="lte-ie-6.css"><![endif]-->
**************************************************************************
/* Main stylesheet */ .foo { color: black; } /* lte-ie-8.css, for IE8 and older */ .foo { color: green; } /* lte-ie-7.css, for IE7 and older */ .foo { color: blue; } /* lte-ie-6.css, for IE6 and older */ .foo { color: red; }
**************************************************************************
<!--[if lt IE 7]><html><![endif]-->
<!--[if IE 7]>   <html><![endif]--> <!--[if IE 8]>   <html><![endif]--> <!--[if gt IE 8]><!--><html><!--<![endif]-->
**************************************************************************
.foo { color: black; }
.ie8 .foo { color: green; } /* IE8 */ .ie7 .foo { color: blue; } /* IE7 */ .ie6 .foo { color: red; } /* IE6 and IE5 (but who cares, right?) */
**************************************************************************
.foo {
  color: black;   color: green\9; /* IE8 and older, but there’s more… */   *color: blue; /* IE7 and older */   _color: red; /* IE6 and older */ }
**************************************************************************
 
 
 

Adding a ‘More’ link on Drupal

Main topic described: Block system, Render arrays, Menu system
Main function described: drupal_set_title()

With this last addition to the module, we will pull together what you have learned about the block system, the menu system, and render arrays, and throw in a workaround for a minor bug in the current version of Drupal 7.

It may have occurred to you that access to this page belongs not in the ‘Navigation’ menu, but through a ‘More’ link at the bottom of the ‘Current posts’ block. That was the plan all along, but we started with a menu link to show how it works.

If you looked at the Default theme implementations referenced back in Generating block content, you may have noticed the theme_more_link theme hook. We’ll use that, along with a theme hook suggestion, to theme the ‘More’ link for our block.

Child render elements

We’ll start by converting the call to theme_item_list into a render array as we did in the page function. We’ll also make it a child of block['content'] to allow for the ‘More’ link as a sibling. Here’s the revised code for the last section of current_posts_block_view:

<?php
else {
//Pass data through theme function.
$block['content']['posts'] = array(
‘#theme’ => ‘item_list__current_posts__block’,
‘#items’ => $items,
);
?>

Remember not to include the PHP markers in your code.

We move the item list code to $block['content']['posts'], making it a child element. You can name the child element whatever you like, as long as it doesn’t start with a hash mark (#). We convert the call to theme_item_list into a render array, then add the __current_posts theme hook suggestion. This we follow with a second suggestion in case a themer wants to render the lists in the block and page differently.

Here’s new code for the ‘More’ link to add directly after the last listing:

<?php
//Add a link to the page for more entries.
$block['content']['more'] = array(
‘#theme’ => ‘more_link__current_posts’,
‘#url’ => ‘current_posts’,
‘#title’ => t(‘See the full list of current posts.’),
);
}
?>

Here we make the ‘More’ link a sibling to the posts array and provide the two parameters this theme hook requires, the path and title. The title provides text which will appear as a tooltip when the mouse hovers over the link. We give this theme hook a suggestion as well.

Edit current_posts_menu()

At this point, we have links to the page both in our block and in the ‘Navigation’ menu. We don’t want a link in the menu, so we’ll edit current_posts_menu() to take it off. All you need to do is change the type attribute for the page item. Delete MENU_NORMAL_ITEM and replace it with MENU_CALLBACK. This type provides a path and attributes only, with no menu link. Should you have your module enabled, you’ll need to disable then re-enable it for this change to take effect.

Page title fix

Enable your module and follow the ‘More’ link in the block, then note the page title. ‘Home’? Not what we had in mind. This is caused by a bug in the first version of Drupal 7. (If you see the ‘Current posts’ title, you are using a later version that is not in release at the time of this writing.) There is a patch in the works, but we need to code for the current release. Even when the bug is fixed, we can’t be certain that our module won’t be used on an installation that has not been updated.

The workaround is to use the function drupal_set_title(). Add the following to the beginning of your _current_posts_page() function:

<?php
drupal_set_title(‘Current posts’);
?>

With this addition, you can be sure the correct title will appear on the page, no matter which version of Drupal 7 your module is installed in.

Check

Check your module functionality one final time. If you have been following along, the last thing to check is the corrected page title, ‘Current posts’. If you have problems getting your code additions to appear, try clearing the caches or disabling then re-enabling your module.

View the code

You can view all the code for the .module file here: current_posts.module

See also

Adapting the query

Main topic described: Database API

The new page function will do almost the same work as current_posts_block_view, which derives its data from our custom function, current_posts_contents. Now the benefit of writing a separate function for our database query becomes apparent. All we need to do is edit it to take an argument and adjust some of the query code, and it will be ready to go for the page.

Here’s the edited code:

<?php
function current_posts_contents($display){   //$display argument is new.
//Get today’s date.
$today = getdate();
//Calculate midnight a week ago.
$start_time = mktime(0, 0, 0,$today['mon'],($today['mday'] – 7), $today['year']);
//Get all posts from one week ago to the present.
$end_time = time();

$max_num = variable_get(‘current_posts_max’, 3);

//Use Database API to retrieve current posts.
$query = db_select(‘node’, ‘n’)
->fields(‘n’, array(‘nid’, ‘title’, ‘created’))
->condition(‘status’, 1) //Published.
->condition(‘created’, array($start_time, $end_time), ‘BETWEEN’)
->orderBy(‘created’, ‘DESC’); //Most recent first. Query paused here.

if ($display == ‘block’){
// Restrict the range if called with ‘block’ argument.
$query->range(0, $max_num);
} //Now proceeds to execute().
//If called by page, query proceeds directly to execute().

return $query->execute();
}
?>

First of all, we add the $display argument to the function. Then, in the query statements, we pause building the query by adding a semi-colon after the orderBy method. We then get the function’s argument value and decide how to continue. If the argument is from the block, we pick up the query object and restrict the range, then proceed to execute. If it’s from the page, we exclude the range() method and proceed straight to execute, thus including all the available posts.

Editing current_posts_block_view

To make this code work as it did in the current_posts_block_view function before the change, we must add one word to one line of code:

<?php
$result = current_posts_contents(‘block’);
?>

Adding the word ‘block’ as an argument to the function call is all it takes.

Specifying a custom permission for a new page

Specifying a custom permission for a new page

Drupal hooks described: hook_permission(), hook_menu()

So far we have our working block and a settings form. The block displays a maximum number of links. However, there may be more links than the maximum we show. So we’ll create a page that lists all the content that was created in the last week.

Custom permission

First, we’ll create a custom permission, using hook_permission(). The permissions this hook defines can be configured at People > Permissions (tab), or http://example.com/admin/people/permissions. Only user roles with this permission granted will have access to the page we will create.

Add this to your .module file:

<?php
/**
* Implements hook_permission().
*/
function current_posts_permission(){
return array(
‘access current_posts content’ => array(
‘title’ => t(‘Access content for the Current posts module’),

); 
}
?>

This hook follows the typical Drupal pattern of attributes defined in arrays. The main key is the machine readable name of the permission, which we will use in our hook_menu() implementation. ‘title’ provides the human-readable name of the permission, to be shown on the permission administration page. This should be wrapped in the t() function for translation. See hook_permission() for all the available options.

Registering the URL and naming the page function

We’ll need to edit current_posts_menu() to establish a path and name for the new page. A quick note on function naming conventions in Drupal: If you are creating a strictly private function (i.e. no other module should rely on it being a stable function or call it), start the function name with an underscore: “_your_module_name_”. If your function is public (i.e. it would be okay for another module to call it, and you don’t intend to change its argument signature or behavior often), start the function name with “your_module_name_” (no underscore). If you are implementing a Drupal hook, you must always name the function “your_module_name_hookname”. Likewise, if you are not implementing a Drupal hook, check the hooks to be sure you have not accidentally picked a function name matching a hook.

Page callbacks are good candidates for strictly private functions, so we will start with an underscore, then the module name, and finally the word, ‘page’. Add the following code to your current_posts_menu() function as the second item in the $items array. Be sure the code, return $items; is the final line of the function, and remember not to include the php markers.

<?php
$items['current_posts'] = array(
‘title’ => ‘Current posts’,
‘page callback’ => ‘_current_posts_page’,
‘access arguments’ => array(‘access current_posts content’),
‘type’ => MENU_NORMAL_ITEM, //Will appear in Navigation menu.
);
?>

This listing mirrors the previous menu item with a couple of exceptions. The first needed a description for the Configuration page. That’s less important here, and we are not including it. Because we are creating a page function and not calling drupal_get_form, we have no page arguments to pass. The new permission becomes the access argument. Since we are not using the admin/config path, our item will appear in the Navigation menu.

Check

Enable your module again and check the Navigation menu. You should see a listing for Current posts. If it’s not there, try clearing the caches. Because we have not yet written the page function, the link leads to a blank page, and you may get an error message. Remember to disable your module before continuing.

See also

Previous Older Entries

Follow

Get every new post delivered to your Inbox.

Join 723 other followers

%d bloggers like this: