1. Trang chủ
  2. » Công Nghệ Thông Tin

Drupal 7 Module Development phần 4 doc

41 355 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Theming a Module
Trường học University of Example
Chuyên ngành Computer Science
Thể loại Bài báo
Năm xuất bản 2025
Thành phố Example City
Định dạng
Số trang 41
Dung lượng 1,77 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

What's new in Drupal 7 is that, due to Drupal's block and page caching and the capabilities of hook_page_alter, we now need to attach our stylesheet directly to the render element that w

Trang 1

drupal_render() on its contents.

Attaching CSS to render arrays

If you look at the screenshot of the first version, you can see that the default styling

of our block is less then inspiring, so let's tweak that by giving our content some sensible default styling by adding a CSS stylesheet

Since version 5, Drupal has had a drupal_add_css() function to add CSS stylesheets

to pages What's new in Drupal 7 is that, due to Drupal's block and page caching and the capabilities of hook_page_alter(), we now need to attach our stylesheet directly

to the render element that we are creating If we were to use drupal_add_css(), the stylesheet would not be cached with its block and it would also be considerably more difficult to alter the stylesheet if a hook_page_alter() implementation desired

to (For example if it removed the block and wanted to remove the CSS too.)

So instead of calling drupal_add_css() from within our

single_blog_block_view() function, we add it to the returned render array:

// Add a CSS file to style the block.

$block['content']['#attached']['css'][] = drupal_get_path('module', 'single_blog') '/single-blog.css';

We use drupal_get_path() to find the path to our module relative to the website root The #attached array can contain a list of CSS files and JS files to attach to our render element For JavaScript files, just append them to the js array via

Trang 2

One thing you'll need to be aware of when writing stylesheets is Drupal's support for

RTL languages, those languages that are read Right To Left, for example Arabic or

Hebrew Users of RTL websites expect everything about that website to flow to-left instead of English's normal left-to-right The convention used by websites that support both RTL and LTR languages is to flip the layout of the design horizontally depending on the directionality of the language

right-A great live example of how right-to-left website layouts are flipped is right-Amnesty International's website; compare the Arabic language version at http://www

amnesty.org/ar with the English language version at http://www.amnesty.org/en Notice how the sidebar changes sides depending on the language:

From a CSS standpoint, this means HTML elements whose left-side styling differs from their right-side styling need to have their styling altered when the current language is RTL If a RTL language is being displayed, Drupal will, for each

stylesheet, look for a supplemental RTL stylesheet to load So, if Hebrew is the active language, Drupal will look for single-blog-rtl.css to load in addition to (and just after) the requested single-blog.css file Since our -rtl stylesheet is loaded

in addition to the standard stylesheet, we simply need to include the rules and properties needed to override the LTR version of our styles To make it easier to keep track of those properties, Drupal modules should place a /*LTR*/ comment next to each property that needs to be overridden

Trang 3

Notice that the block-single-blog.contentul rule in the single-blog.css

stylesheet specifies a left padding Since that's the only property that is directional, it's the only one we need to override in the single-blog-rtl.css file

/* $Id$ */

.block-single-blog content ul {

padding-right: 0;

}

Note that if our original left padding was 10px, we would have needed to

override that in our RTL stylesheet by setting padding-left to 0 and then

setting padding-right to 10px The following is a screenshot of version two

of our module block:

If you look at the screenshot, you can see the new More link and how the display of

our block has improved

Trang 4

After all these modifications, the second draft of our single_blog_block_view()

function is now complete and should look like this:

// Set the block title.

$block['subject'] = t('Recent blog posts');

// Check if the user can access content.

Trang 5

Okay, now it's time to exorcise our lazy-developer habit and practice building

our own theme hook From Chapter 3, you should recall that we'll need to do the

following things:

1 Register the theme hook and define default variables

2 Build the default implementation of our theme hook

3 Re-build the theme registry

4 Build a render element to use the theme hook

Our current implementation of the Recent blog posts block simply shows a list of

blog titles But it would be nice to include the date of each post, as well as the author (if we have multiple people creating posts) So in this third and final version of our module, we're going to create a single-blog-block-item.tpl.php to render the contents of each item in our list of blog posts By convention in Drupal, any CSS, JavaScript, or template files needed by a module should use dashes instead

of underscores in their filenames

Trang 6

Before we begin building the required single_blog_block_item theme hook, let's first add all the data we will need for the third version of our module Looking back

at how we generate the items for our list, we can see that all the data we want is in the $node variable

// Create links for each blog entry.

Trang 7

of the template file, single-blog-block-item Drupal will automatically add the

.tpl.php to the end of the base name when looking for the file, so we shouldn't include it

Variables versus render element

In Chapter 3, we learned about the differences between using the variables key and using the renderelement key in your hook_theme() One and only one of those keys must be present in each theme hook declaration However it still can be somewhat confusing as to which to use when you are building your theme implementation.There is only one situation in which you could use the renderelement key: if your data could be represented by a single render element or by a single renderable array containing nested render elements If that is not the case, then you must specify the

variables key and specify the variables you will be passed to theme() and their default values

So does our data conform to the render element requirement above? Our $node

variable is just a partial node object and not a render element, so we must use the

variables key and specify the default values for all our variables

As a side note, if we instead look at the way we've built the data element in the

second version of our module (a link#type render element), we can see that we could go ahead and use renderelement as the key if our second version of the module had a hook_theme() implementation

Since the node variable is an object, we set the default value to simply be the

NULL value

Trang 8

That's actually the purpose of the preprocess function: to transform raw data into variables needed for a theme hook's template or theme function (Also, recall that preprocess functions should never query for raw data; the raw data should be passed as variables.)

Since we own this theme hook, we'll need to define our preprocess function with

To make it easier to access all the object properties of our node variable, we're going

to first create a $node local variable which we'll use inside the preprocess function: // Create a renderable array for the title.

// in a variable for themer convenience.

$variables['user'] = user_load($node->uid);

Trang 9

// Theme the username.

$variables['name'] = theme('username', array(

'account' => $variables['user']));

}

And finally, we'll pass the $user object of the author and theme the username.All that's left is to order the variables the way we desire in our template file! However, since we've made the last change to our module file, let's look at the finished product:

// After you learn Form API in Chapter 5, you'll be able to

// make these settings configurable.

Trang 10

// The array key defines the $delta parameter used in all

// other block hooks.

$blocks['recent'] = array(

// The name of the block on the blocks administration page.

'info' => t('Recent blog posts'),

// Set the block title.

$block['subject'] = t('Recent blog posts');

// Check if the user can access content.

if (user_access('access content')) {

// Retrieve the most recent nodes.

$result = single_blog_list(SINGLE_BLOG_LIST_COUNT);

Trang 11

// Create links for each blog entry.

// Add a link to the full list of blog entries.

foreach (array_keys($elements['#items']) AS $key) {

// Take the renderable array that we set in

Trang 12

// single_blog_block_view() and render it into the string

// that theme_item_list() expects.

// Create a renderable array for the title.

Trang 13

// Load the account object with the node's creator and store

// in a variable for themer convenience.

$variables['user'] = user_load($node->uid);

// Theme the username.

$variables['name'] = theme('username', array(

<?phpprintt('string');?> snippet

Lastly, the show(), hide(), and render() functions are special themer-convenience functions that should only be used in template files; they should never be used in preprocess functions, theme functions or anywhere else render() is basically the same thing as the drupal_render() function we've already learned about The

hide() function can be used on a render array's child element earlier in the template before the render array calls render(); this will prevent the child element from being included with the rest of the render array when it is rendered For example (from Bartik's node.tpl.php):

Trang 14

// Only display the wrapper div if there are links.

* - $classes: String of classes that can be used to

* style contextually through CSS It can be manipulated

* through the variable $classes_array from preprocess functions.

* The default values can be one or more of the following:

* - single-blog-block-item: The current template type,

* i.e., "theming hook".

* - $date: Formatted creation date Preprocess functions can

* reformat it by calling format_date() with the desired

* parameters on the $created variable.

* - $title: A renderable array that that provides a title and link to the node.

* - $name: Themed username of node author output from

* theme_username().

*

* - $classes_array: Array of html class attribute values

* It is flattened into a string within the

* variable $classes.

*

* Other variables:

* The following variables are provided for contextual information.

* - $node: Partial node object Contains data that may not be safe.

* - $created: Time the node was published formatted in Unix

* timestamp.

Trang 15

* - $user: The user object of the node author.

*

* @see template_preprocess_single_blog_block_item()

*/

?>

<div class="<?php print $classes; ?>">

<div class="date"><?php print $date; ?>:</div>

The only variable that we didn't explicitly create in our preprocess function was the $classes variable This is a string that contains useful CSS classes that should

be placed in the outer-most wrapping HTML element in our template file The

$classes variable is created by template_processs() and its corresponding

$classes_array variable is created by template_preprocess() If we want to add additional classes to the $classes string, we should append an array element to the

$classes_array variable during our preprocess function and it will automatically

be added to the $classes string before reaching the template file

The string passed to the t() function, by!username includes the !username

token to give context to translators when trying to translate "by"; see the t() API documentation for more information

The last thing we should do, since we've updated the HTML markup returned by our block, is to also update the stylesheet:

/* $Id$ */

.block-single-blog content ul {

padding-left: 0; /* LTR */

}

Trang 16

Congratulations! We're done!

Take a look at our accomplishment shown in the following screenshot:

Trang 17

In this chapter we used our previous concepts and built an example theme

implementation using real-world situations In addition to the review of the theming concepts, you should have picked up on some of the strategies commonly used by Drupal developers and learned a little bit about contributing your experiences and knowledge back to the Drupal community

In the next chapter, you'll learn about building admin interfaces for your module

So while the Single Blog module used slightly-funky constants that defined some hard-coded settings, the module in the next chapter will have a rich administrative interface to allow site admins to configure its settings

Trang 18

Building an Admin Interface

In this chapter we will create a module with an administrative interface This module will build upon many of the module creation concepts that were introduced in

Chapter 2 Some of the concepts we will cover in this chapter are:

Mapping Drupal functions to menu items using hook_menu()

Creating basic forms with the Form API

Managing Drupal settings using variable_set() and variable_get()

Sending mail using drupal_mail() and hook_mail()

Using Drupal 7's new token system

After this chapter is finished you should have a good handle on many concepts that are at the core of almost every module you will write in the future

The User Warn module

In this chapter we will be creating the User Warn module This module allows administrators to send users a warning via e-mail when that user violates a site's terms of service or otherwise behaves in a way that is inappropriate The User Warn module will implement the following features:

The module will expose configuration settings to site administrators,

including default mail text

This e-mail will include Drupal tokens, which allow the admin to replace and/or add site-specific variables to the e-mail

Site administrators will be able to send a user mail via a new tab on their user profile page

Warning e-mails will be sent using Drupal's default mail implementation

Trang 19

Starting our module

We will begin as we did in Chapter 2, by creating a new folder for our module called

user_warn in the sites/default/modules directory in our Drupal installation We can then create a user_warn.info file as shown in the following:

;$Id$

name = User Warn

description = Exposes an admin interface to send behavior warning e-mails to users.

* This module allows site administrators to send a stock warning

* e-mail to a specified user or users through the admin interface

Trang 20

The Drupal menu system

Drupal's menu system is deceptively named The name implies that it is responsible for the navigation of your site, and while this is true it does a great deal more At its core, the menu system is responsible for mapping Drupal paths to the functions that generate the contents of the requested page The menu system is also responsible for controlling access to Drupal pages, acting as one of the central gatekeepers of Drupal security

Drupal module developers can map paths to Drupal functions by implementing

hook_menu(), which adds paths to the menu system, assigns them access rules, and optionally creates navigational elements for them

Defining a page callback with hook_menu

For our module we will need to implement two new pages—a configuration page for the User Warn module, and a tab in the user profile area where administrators can go to send the actual e-mails to a specific user These will each require their own

hook_menu() implementation as defined in the following example

This example only scratches the surface of the options available in the

menu system For more details, developers should check out the API

'title' => 'User Warn',

'description' => 'Configuration for the User Warn module.',

'page callback' => 'drupal_get_form',

'page arguments' => array('user_warn_form'),

'access arguments' => array('administer users'),

'type' => MENU_NORMAL_ITEM,

);

Ngày đăng: 14/08/2014, 11:20

TỪ KHÓA LIÊN QUAN