You are previewing Pro Drupal 7 Development, Third Edition.
O'Reilly logo
Pro Drupal 7 Development, Third Edition

Book Description

Pro Drupal 7 Development updates the most popular development reference for the newest major release of Drupal. With several new and completely-rewritten essential APIs and improvements in Drupal 7, this book will not only teach developers how to write modules ranging from simple to complex, as well as learn how Drupal itself works.

  • Learn the Drupal APIs and major changes in Drupal 7

  • Learn how to write Drupal modules using the APIs

  • Learn proper development practices and how to become a contributing community member

Table of Contents

  1. Copyright
  2. Foreword
  3. About the Authors
  4. About the Technical Reviewers
  5. Acknowledgments
  6. Introduction
  7. 1. How Drupal Works
    1. 1.1. What Is Drupal?
    2. 1.2. Technology Stack
    3. 1.3. Core
    4. 1.4. Administrative Interface
    5. 1.5. Modules
    6. 1.6. Hooks
    7. 1.7. Themes
    8. 1.8. Nodes
    9. 1.9. Fields
    10. 1.10. Blocks
    11. 1.11. File Layout
    12. 1.12. Serving a Request
      1. 1.12.1. The Web Server's Role
      2. 1.12.2. The Bootstrap Process
      3. 1.12.3. Processing a Request
      4. 1.12.4. Theming the Data
    13. 1.13. Summary
  8. 2. Writing a Module
    1. 2.1. Creating the Files
    2. 2.2. Implementing a Hook
    3. 2.3. Adding Module-Specific Settings
    4. 2.4. Defining Your Own Administration Section
    5. 2.5. Presenting a Settings Form to the User
    6. 2.6. Validating User-Submitted Settings
    7. 2.7. Storing Settings
      1. 2.7.1. Using Drupal's variables Table
      2. 2.7.2. Retrieving Stored Values with variable_get()
    8. 2.8. Further Steps
    9. 2.9. Summary
  9. 3. Hooks, Actions, and Triggers
    1. 3.1. Understanding Events and Triggers
    2. 3.2. Understanding Actions
      1. 3.2.1. The Trigger User Interface
      2. 3.2.2. Your First Action
      3. 3.2.3. Assigning the Action
      4. 3.2.4. Changing Which Triggers an Action Supports
        1. 3.2.4.1. Actions That Support Any Trigger
        2. 3.2.4.2. Advanced Actions
    3. 3.3. Using the Context in Actions
      1. 3.3.1. How the Trigger Module Prepares the Context
      2. 3.3.2. Changing Existing Actions with action_info_alter()
      3. 3.3.3. Establishing the Context
    4. 3.4. How Actions Are Stored
      1. 3.4.1. The actions Table
      2. 3.4.2. Action IDs
    5. 3.5. Calling an Action Directly with actions_do()
    6. 3.6. Defining Your Own Triggers with hook_trigger_info()
    7. 3.7. Adding Triggers to Existing Hooks
    8. 3.8. Summary
  10. 4. The Menu System
    1. 4.1. Callback Mapping
    2. 4.2. Mapping URLs to Functions
    3. 4.3. Creating a Menu Item
    4. 4.4. Page Callback Arguments
    5. 4.5. Page Callbacks in Other Files
    6. 4.6. Adding a Link to the Navigation Block
    7. 4.7. Menu Nesting
    8. 4.8. Access Control
    9. 4.9. Title Localization and Customization
    10. 4.10. Defining a Title Callback
    11. 4.11. Wildcards in Menu Items
      1. 4.11.1. Basic Wildcards
      2. 4.11.2. Wildcards and Page Callback Parameters
      3. 4.11.3. Using the Value of a Wildcard
      4. 4.11.4. Wildcards and Parameter Replacement
      5. 4.11.5. Passing Additional Arguments to the Load Function
      6. 4.11.6. Special, Predefined Load Arguments: %map and %index
      7. 4.11.7. Building Paths from Wildcards Using to_arg() Functions
      8. 4.11.8. Special Cases for Wildcards and to_arg() Functions
    12. 4.12. Altering Menu Items from Other Modules
    13. 4.13. Altering Menu Links from Other Modules
    14. 4.14. Kinds of Menu Items
    15. 4.15. Common Tasks
      1. 4.15.1. Assigning Callbacks Without Adding a Link to the Menu
      2. 4.15.2. Displaying Menu Items As Tabs
      3. 4.15.3. Hiding Existing Menu Items
      4. 4.15.4. Using menu.module
      5. 4.15.5. Common Mistakes
    16. 4.16. Summary
  11. 5. Working with Databases
    1. 5.1. Defining Database Parameters
    2. 5.2. Understanding the Database Abstraction Layer
    3. 5.3. Connecting to the Database
    4. 5.4. Performing Simple Queries
    5. 5.5. Retrieving Query Results
      1. 5.5.1. Getting a Single Value
      2. 5.5.2. Getting Multiple Rows
      3. 5.5.3. Using the Query Builder and Query Objects
      4. 5.5.4. Getting a Limited Range of Results
      5. 5.5.5. Getting Results for Paged Display
      6. 5.5.6. Other Common Queries
    6. 5.6. Inserts and Updates with drupal_write_record()
    7. 5.7. The Schema API
      1. 5.7.1. Using Module .install Files
      2. 5.7.2. Creating Tables
      3. 5.7.3. Using the Schema Module
      4. 5.7.4. Field Type Mapping from Schema to Database
        1. 5.7.4.1. Textual
        2. 5.7.4.2. Varchar
        3. 5.7.4.3. Char
        4. 5.7.4.4. Text
        5. 5.7.4.5. Numerical
        6. 5.7.4.6. Integer
        7. 5.7.4.7. Serial
        8. 5.7.4.8. Float
        9. 5.7.4.9. Numeric
        10. 5.7.4.10. Date and Time: Datetime
        11. 5.7.4.11. Binary: Blob
      5. 5.7.5. Declaring a Specific Column Type with mysql_type
      6. 5.7.6. Maintaining Tables
      7. 5.7.7. Deleting Tables on Uninstall
      8. 5.7.8. Changing Existing Schemas with hook_schema_alter()
    8. 5.8. Modifying Other Modules' Queries with hook_query_alter()
    9. 5.9. Connecting to Multiple Databases Within Drupal
    10. 5.10. Using a Temporary Table
    11. 5.11. Writing Your Own Database Driver
    12. 5.12. Summary
  12. 6. Working with Users
    1. 6.1. The $user Object
    2. 6.2. Testing If a User Is Logged In
    3. 6.3. Introduction to user hooks
      1. 6.3.1. Understanding hook_user_view($account, $view_mode)
    4. 6.4. The User Registration Process
    5. 6.5. Using profile.module to Collect User Information
    6. 6.6. The Login Process
      1. 6.6.1. Adding Data to the $user Object at Load Time
      2. 6.6.2. Providing User Information Categories
    7. 6.7. External Login
    8. 6.8. Summary
  13. 7. Working with Nodes
    1. 7.1. So What Exactly Is a Node?
    2. 7.2. Not Everything Is a Node
    3. 7.3. Creating a Node Module
      1. 7.3.1. Creating the .install File
      2. 7.3.2. Creating the .info File
      3. 7.3.3. Creating the .module File
      4. 7.3.4. Providing Information About Our Node Type
      5. 7.3.5. Modifying the Menu Callback
      6. 7.3.6. Defining Node-Type–Specific Permissions with hook_permission()
      7. 7.3.7. Limiting Access to a Node Type with hook__node_access()
      8. 7.3.8. Customizing the Node Form for Our Node Type
      9. 7.3.9. Validating Fields with hook_validate()
      10. 7.3.10. Saving Our Data with hook_insert()
      11. 7.3.11. Keeping Data Current with hook_update()
      12. 7.3.12. Cleaning Up with hook_delete()
      13. 7.3.13. Modifying Nodes of Our Type with hook_load()
      14. 7.3.14. Using hook_view()
      15. 7.3.15. Manipulating Nodes That Are Not Our Type with hook_node_xxxxx()
    4. 7.4. How Nodes Are Stored
    5. 7.5. Creating a Node Type with Custom Content Types
    6. 7.6. Restricting Access to Nodes
      1. 7.6.1. Defining Node Grants
        1. 7.6.1.1. What Is a Realm?
        2. 7.6.1.2. What Is a Grant ID?
      2. 7.6.2. The Node Access Process
    7. 7.7. Summary
  14. 8. Working with Fields
    1. 8.1. Creating Content Types
    2. 8.2. Adding Fields to a Content Type
    3. 8.3. Creating a Custom Field
    4. 8.4. Adding Fields Programmatically
    5. 8.5. Summary
  15. 9. The Theme System
    1. 9.1. Themes
      1. 9.1.1. Installing an Off-the-Shelf Theme
      2. 9.1.2. Building a Theme
    2. 9.2. The .info File
      1. 9.2.1. Adding Regions to Your Theme
      2. 9.2.2. Adding CSS Files to Your Theme
      3. 9.2.3. Adding JavaScript Files
      4. 9.2.4. Adding Settings to Your Theme
    3. 9.3. Understanding Template Files
      1. 9.3.1. The Big Picture
      2. 9.3.2. The html.php.tpl File
        1. 9.3.2.1. The page.tpl.php File
        2. 9.3.2.2. The region.tpl.php File
        3. 9.3.2.3. The node.tpl.php File
        4. 9.3.2.4. The field.tpl.php File
        5. 9.3.2.5. The block.tpl.php File
      3. 9.3.3. Overriding Template Files
      4. 9.3.4. Other Template Files
        1. 9.3.4.1. Introducing the theme() Function
        2. 9.3.4.2. An Overview of How theme() Works
      5. 9.3.5. Overriding Themable Items
      6. 9.3.6. Overriding with Template Files
      7. 9.3.7. Adding and Manipulating Template Variables
      8. 9.3.8. Using the Theme Developer Module
    4. 9.4. Summary
  16. 10. Working with Blocks
    1. 10.1. What Is a Block?
    2. 10.2. Block Configuration Options
      1. 10.2.1. Block Placement
      2. 10.2.2. Defining a Block
      3. 10.2.3. Using the Block Hooks
    3. 10.3. Building a Block
    4. 10.4. Enabling a Block When a Module Is Installed
    5. 10.5. Block Visibility Examples
      1. 10.5.1. Displaying a Block to Logged-In Users Only
      2. 10.5.2. Displaying a Block to Anonymous Users Only
    6. 10.6. Summary
  17. 11. The Form API
    1. 11.1. Understanding Form Processing
      1. 11.1.1. Initializing the Process
      2. 11.1.2. Setting a Token
      3. 11.1.3. Setting an ID
      4. 11.1.4. Collecting All Possible Form Element Definitions
      5. 11.1.5. Looking for a Validation Function
      6. 11.1.6. Looking for a Submit Function
      7. 11.1.7. Allowing Modules to Alter the Form Before It's Built
      8. 11.1.8. Building the Form
      9. 11.1.9. Allowing Functions to Alter the Form After It's Built
      10. 11.1.10. Checking If the Form Has Been Submitted
      11. 11.1.11. Finding a Theme Function for the Form
      12. 11.1.12. Allowing Modules to Modify the Form Before It's Rendered
      13. 11.1.13. Rendering the Form
      14. 11.1.14. Validating the Form
        1. 11.1.14.1. Token Validation
        2. 11.1.14.2. Built-In Validation
        3. 11.1.14.3. Element-Specific Validation
        4. 11.1.14.4. Validation Callbacks
      15. 11.1.15. Submitting the Form
      16. 11.1.16. Redirecting the User
    2. 11.2. Creating Basic Forms
      1. 11.2.1. Form Properties
      2. 11.2.2. Form IDs
      3. 11.2.3. Fieldsets
      4. 11.2.4. Theming Forms
        1. 11.2.4.1. Using #prefix, #suffix, and #markup
        2. 11.2.4.2. Using a Theme Function
        3. 11.2.4.3. Telling Drupal Which Theme Function to Use
      5. 11.2.5. Specifying Validation and Submission Functions with hook_forms()
      6. 11.2.6. Call Order of Theme, Validation, and Submission Functions
      7. 11.2.7. Writing a Validation Function
        1. 11.2.7.1.
          1. 11.2.7.1.1. Using form_set_value() to Pass Data
          2. 11.2.7.1.2. Using $form_state to Pass Data
          3. 11.2.7.1.3. Element-Specific Validation
      8. 11.2.8. Form Rebuilding
      9. 11.2.9. Writing a Submit Function
      10. 11.2.10. Changing Forms with hook_form_alter()
        1. 11.2.10.1. Altering Any Form
        2. 11.2.10.2. Altering a Specific Form
      11. 11.2.11. Submitting Forms Programmatically with drupal_form_submit()
      12. 11.2.12. Dynamic Forms
    3. 11.3. Form API Properties
      1. 11.3.1. Properties for the Root of the Form
        1. 11.3.1.1. #action
        2. 11.3.1.2. #built
        3. 11.3.1.3. #method
      2. 11.3.2. Properties Added to All Elements
        1. 11.3.2.1. #description
        2. 11.3.2.2. #attributes
        3. 11.3.2.3. #required
        4. 11.3.2.4. #tree
      3. 11.3.3. Properties Allowed in All Elements
        1. 11.3.3.1. #type
        2. 11.3.3.2. #access
        3. 11.3.3.3. #after_build
        4. 11.3.3.4. #array_parents
        5. 11.3.3.5. #attached
        6. 11.3.3.6. #default_value
        7. 11.3.3.7. #disabled
        8. 11.3.3.8. #element_validate
        9. 11.3.3.9. #parents
        10. 11.3.3.10. #post_render
        11. 11.3.3.11. #prefix
        12. 11.3.3.12. #pre_render
        13. 11.3.3.13. #process
        14. 11.3.3.14. #states
        15. 11.3.3.15. #suffix
        16. 11.3.3.16. #theme
        17. 11.3.3.17. #theme_wrappers
        18. 11.3.3.18. #title
        19. 11.3.3.19. #tree
        20. 11.3.3.20. #weight
      4. 11.3.4. Form Elements
        1. 11.3.4.1. Text Field
        2. 11.3.4.2. Password
        3. 11.3.4.3. Password with Confirmation
        4. 11.3.4.4. Textarea
        5. 11.3.4.5. Select
        6. 11.3.4.6. Radio Buttons
        7. 11.3.4.7. Check Boxes
        8. 11.3.4.8. Value
        9. 11.3.4.9. Hidden
        10. 11.3.4.10. Date
        11. 11.3.4.11. Weight
        12. 11.3.4.12. File Upload
        13. 11.3.4.13. Fieldset
        14. 11.3.4.14. Submit
        15. 11.3.4.15. Button
        16. 11.3.4.16. Image Button
        17. 11.3.4.17. Markup
        18. 11.3.4.18. Item
        19. 11.3.4.19. #ajax Property
          1. 11.3.4.19.1. If Javascript is not supported
          2. 11.3.4.19.2. Additional AJAX features
          3. 11.3.4.19.3. Additional resources
    4. 11.4. Summary
  18. 12. Manipulating User Input: The Filter System
    1. 12.1. Filters
    2. 12.2. Filters and Text formats
      1. 12.2.1. Installing a Filter
      2. 12.2.2. Knowing When to Use Filters
    3. 12.3. Creating a Custom Filter
      1. 12.3.1. Implementing hook_filter_info()
      2. 12.3.2. The Process Function
      3. 12.3.3. Helper Function
    4. 12.4. Summary
  19. 13. Searching and Indexing Content
    1. 13.1. Building a Custom Search Page
      1. 13.1.1. The Default Search Form
      2. 13.1.2. The Advanced Search Form
      3. 13.1.3. Adding to the Search Form
        1. 13.1.3.1. Introducing the Search Hooks
        2. 13.1.3.2. Formatting Search Results with hook_search_page()
        3. 13.1.3.3. Making Path Aliases Searchable
    2. 13.2. Using the Search HTML Indexer
      1. 13.2.1. When to Use the Indexer
      2. 13.2.2. How the Indexer Works
        1. 13.2.2.1. Adding Metadata to Nodes: hook_node_update_index()
        2. 13.2.2.2. Indexing Content That Isn't a Node: hook_update_index()
    3. 13.3. Summary
  20. 14. Working with Files
    1. 14.1. How Drupal Serves Files
    2. 14.2. Managed and Unmanaged Drupal APIs
      1. 14.2.1. Public Files
      2. 14.2.2. Private Files
    3. 14.3. PHP Settings
    4. 14.4. Media Handling
      1. 14.4.1. Upload Field
      2. 14.4.2. Video and Audio
    5. 14.5. File API
      1. 14.5.1. Database Schema
      2. 14.5.2. Common Tasks and Functions
        1. 14.5.2.1. Finding the Default Files URI
          1. 14.5.2.1.1. Saving Data to a File
          2. 14.5.2.1.2. file_save_data($data, $destination = NULL, $replace = FILE_EXISTS_RENAME)
        2. 14.5.2.2. Copying and Moving Files
          1. 14.5.2.2.1. file_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME)
          2. 14.5.2.2.2. file_move($source, $destination = NULL, $replace = FILE_EXISTS_RENAME)
        3. 14.5.2.3. Checking Directories
        4. 14.5.2.4. Uploading Files
          1. 14.5.2.4.1. file_save_upload($source, $validators = array(), $destination = FALSE, $replace = FILE_EXISTS_RENAME)
          2. 14.5.2.4.2. file_validate_extensions($file, $extensions)
          3. 14.5.2.4.3. file_validate_is_image($file)
          4. 14.5.2.4.4. file_validate_image_resolution($file, $maximum_dimensions = 0, $minimum_dimensions = 0)
          5. 14.5.2.4.5. file_validate_name_length($file)
          6. 14.5.2.4.6. file_validate_size($file, $file_limit = 0, $user_limit = 0)
        5. 14.5.2.5. Getting the URL for a File
          1. 14.5.2.5.1. file_create_url($uri)
        6. 14.5.2.6. Finding Files in a Directory
          1. 14.5.2.6.1. file_scan_directory($dir, $mask, $options = array(), $depth = 0)
        7. 14.5.2.7. Finding the Temp Directory
        8. 14.5.2.8. Neutralizing Dangerous Files
          1. 14.5.2.8.1. file_munge_filename($filename, $extensions, $alerts = TRUE)
          2. 14.5.2.8.2. file_unmunge_filename($filename)
        9. 14.5.2.9. Checking Disk Space
          1. 14.5.2.9.1. file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT)
      3. 14.5.3. Authentication Hooks for Downloading
    6. 14.6. Summary
  21. 15. Working with Taxonomy
    1. 15.1. The Structure of Taxonomy
    2. 15.2. Creating a Vocabulary
    3. 15.3. Creating Terms
    4. 15.4. Assigning a Vocabulary to a Content Type
    5. 15.5. Kinds of Taxonomy
      1. 15.5.1. Flat
      2. 15.5.2. Hierarchical
      3. 15.5.3. Multiple Hierarchical
    6. 15.6. Viewing Content by Term
      1. 15.6.1. Using AND and OR in URLs
      2. 15.6.2. Specifying Depth for Hierarchical Vocabularies
      3. 15.6.3. Automatic RSS Feeds
    7. 15.7. Storing Taxonomies
    8. 15.8. Module-Based Vocabularies
      1. 15.8.1. Creating a Module-Based Vocabulary
      2. 15.8.2. Keeping Informed of Vocabulary Changes with Taxonomy Hooks
    9. 15.9. Common Tasks
      1. 15.9.1. Displaying Taxonomy Terms Associated with a Node
      2. 15.9.2. Building Your Own Taxonomy Queries
      3. 15.9.3. Using taxonomy_select_nodes()
    10. 15.10. Taxonomy Functions
      1. 15.10.1. Retrieving Information About Vocabularies
        1. 15.10.1.1. taxonomy_vocabulary_load($vid)
        2. 15.10.1.2. taxonomy_get_vocabularies()
      2. 15.10.2. Adding, Modifying, and Deleting Vocabularies
        1. 15.10.2.1. taxonomy_vocabulary_save($vocabulary)
        2. 15.10.2.2. taxonomy_vocabulary_delete($vid)
      3. 15.10.3. Retrieving Information About Terms
        1. 15.10.3.1. taxonomy_load_term($tid)
        2. 15.10.3.2. taxonomy_get_term_by_name($name)
      4. 15.10.4. Adding, Modifying, and Deleting Terms
        1. 15.10.4.1. taxonomy_term_save($term)
        2. 15.10.4.2. taxonomy_term_delete($tid)
      5. 15.10.5. Retrieving Information About Term Hierarchy
        1. 15.10.5.1. taxonomy_get_parents($tid, $key)
        2. 15.10.5.2. taxonomy_get_parents_all($tid)
        3. 15.10.5.3. taxonomy_get_children($tid, $vid, $key)
        4. 15.10.5.4. taxonomy_get_tree($vid, $parent, $max_depth, $load_entities = FALSE)
      6. 15.10.6. Finding Nodes with Certain Terms
    11. 15.11. Additional Resources
    12. 15.12. Summary
  22. 16. Caching
    1. 16.1. Knowing When to Cache
    2. 16.2. How Caching Works
    3. 16.3. How Caching Is Used Within Drupal Core
      1. 16.3.1. Menu System
      2. 16.3.2. Caching Filtered Text
      3. 16.3.3. Administration Variables and Module Settings
        1. 16.3.3.1. Disabling Caching
        2. 16.3.3.2. Page Caching
        3. 16.3.3.3. Static Page Caching
      4. 16.3.4. Blocks
      5. 16.3.5. Using the Cache API
        1. 16.3.5.1. Caching Data with cache_set()
        2. 16.3.5.2. Retrieving Cached Data with cache_get() and cache_get_multiple()
        3. 16.3.5.3. Checking to See If Cache Is Empty with cache_is_empty()
        4. 16.3.5.4. Clearing Cache with cache_clear_all()
          1. 16.3.5.4.1. Using the $reset Parameter
          2. 16.3.5.4.2. Using cache_clear_all()
          3. 16.3.5.4.3. Using hook_flush_caches()
    4. 16.4. Summary
  23. 17. Sessions
    1. 17.1. What Are Sessions?
    2. 17.2. Usage
    3. 17.3. Session-Related Settings
      1. 17.3.1. In .htaccess
      2. 17.3.2. In settings.php
      3. 17.3.3. In bootstrap.inc
      4. 17.3.4. Requiring Cookies
    4. 17.4. Storage
    5. 17.5. Session Life Cycle
    6. 17.6. Session Conversations
      1. 17.6.1. First Visit
      2. 17.6.2. Second Visit
      3. 17.6.3. User with an Account
    7. 17.7. Common Tasks
      1. 17.7.1. Changing the Length of Time Before a Cookie Expires
      2. 17.7.2. Changing the Name of the Session
      3. 17.7.3. Storing Data in the Session
    8. 17.8. Summary
  24. 18. Using jQuery
    1. 18.1. What Is jQuery?
    2. 18.2. The Old Way
    3. 18.3. How jQuery Works
      1. 18.3.1. Using a CSS ID Selector
      2. 18.3.2. Using a CSS Class Selector
    4. 18.4. jQuery Within Drupal
      1. 18.4.1. Your First jQuery Code
      2. 18.4.2. Targeting an Element by ID
      3. 18.4.3. Method Chaining
      4. 18.4.4. Adding or Removing a Class
      5. 18.4.5. Wrapping Existing Elements
      6. 18.4.6. Changing Values of CSS Elements
      7. 18.4.7. Where to Put JavaScript
        1. 18.4.7.1. Adding JavaScript via a Theme .info File
        2. 18.4.7.2. A Module That Uses jQuery
      8. 18.4.8. Overridable JavaScript
    5. 18.5. Building a jQuery Voting Widget
      1. 18.5.1. Building the Module
      2. 18.5.2. Using Drupal.behaviors
      3. 18.5.3. Ways to Extend This Module
      4. 18.5.4. Compatibility
    6. 18.6. Next Steps
    7. 18.7. Summary
  25. 19. Localization and Translation
    1. 19.1. Enabling the Locale Module
    2. 19.2. User Interface Translation
      1. 19.2.1. Strings
      2. 19.2.2. Translating Strings with t()
      3. 19.2.3. Replacing Built-In Strings with Custom Strings
        1. 19.2.3.1. String Overrides in settings.php
        2. 19.2.3.2. Replacing Strings with the Locale Module
        3. 19.2.3.3. Exporting Your Translation
          1. 19.2.3.3.1. Portable Object Files
          2. 19.2.3.3.2. Portable Object Templates
    3. 19.3. Starting a New Translation
      1. 19.3.1. Generating .pot Files with Translation Template Extractor
      2. 19.3.2. Creating a .pot File for Your Module
        1. 19.3.2.1. Using the Command Line
        2. 19.3.2.2. Using the Web-Based Extractor
      3. 19.3.3. Creating .pot Files for an Entire Site
    4. 19.4. Installing a Language Translation
      1. 19.4.1. Setting Up a Translation at Install Time
      2. 19.4.2. Installing a Translation on an Existing Site
    5. 19.5. Right-to-Left Language Support
    6. 19.6. Language Negotiation
      1. 19.6.1. Default
        1. 19.6.1.1. User-Preferred Language
        2. 19.6.1.2. The Global $language Object
      2. 19.6.2. Path Prefix Only
      3. 19.6.3. Path Prefix with Language Fallback
      4. 19.6.4. URL Only
    7. 19.7. Content Translation
      1. 19.7.1. Introducing the Content Translation Module
      2. 19.7.2. Multilingual Support
      3. 19.7.3. Multilingual Support with Translation
    8. 19.8. Localization- and Translation-Related Files
    9. 19.9. Additional Resources
    10. 19.10. Summary
  26. 20. XML-RPC
    1. 20.1. What Is XML-RPC?
    2. 20.2. Prerequisites for XML-RPC
    3. 20.3. XML-RPC Clients
      1. 20.3.1. XML-RPC Client Example: Getting the Time
      2. 20.3.2. XML-RPC Client Example: Getting the Name of a State
      3. 20.3.3. Handling XML-RPC Client Errors
        1. 20.3.3.1. Network Errors
        2. 20.3.3.2. HTTP Errors
        3. 20.3.3.3. Call Syntax Errors
    4. 20.4. A Simple XML-RPC Server
      1. 20.4.1. Mapping Your Method with hook_xmlrpc()
      2. 20.4.2. Automatic Parameter Type Validation with hook_xmlrpc()
    5. 20.5. Built-In XML-RPC Methods
      1. 20.5.1. system.listMethods
      2. 20.5.2. system.methodSignature
      3. 20.5.3. system.methodHelp
      4. 20.5.4. system.getCapabilities
      5. 20.5.5. system.multiCall
    6. 20.6. Summary
  27. 21. Writing Secure Code
    1. 21.1. Handling User Input
      1. 21.1.1. Thinking About Data Types
        1. 21.1.1.1. Plain Text
        2. 21.1.1.2. HTML Text
        3. 21.1.1.3. Rich Text
        4. 21.1.1.4. URL
      2. 21.1.2. Using check_plain() and t() to Sanitize Output
      3. 21.1.3. Using filter_xss() to Prevent Cross-Site Scripting Attacks
      4. 21.1.4. Using filter_xss_admin()
    2. 21.2. Handling URLs Securely
    3. 21.3. Making Queries Secure with db_query()
    4. 21.4. Keeping Private Data Private with hook_query_alter()
    5. 21.5. Dynamic Queries
    6. 21.6. Permissions and Page Callbacks
    7. 21.7. Cross-Site Request Forgeries (CSRF)
    8. 21.8. File Security
      1. 21.8.1. File Permissions
      2. 21.8.2. Protected Files
      3. 21.8.3. File Uploads
      4. 21.8.4. Filenames and Paths
    9. 21.9. Encoding Mail Headers
    10. 21.10. Files for Production Environments
    11. 21.11. SSL Support
    12. 21.12. Stand-Alone PHP
    13. 21.13. AJAX Security, a.k.a. Request Replay Attack
    14. 21.14. Form API Security
    15. 21.15. Protecting the Superuser Account
    16. 21.16. Summary
  28. 22. Development Best Practices
    1. 22.1. Coding Standards
      1. 22.1.1. Line Indention and Whitespace
      2. 22.1.2. Operators
    2. 22.2. Casting
    3. 22.3. Control Structures
      1. 22.3.1. Function Calls
      2. 22.3.2. Function Declarations
      3. 22.3.3. Function Names
      4. 22.3.4. Class Constructor Calls
      5. 22.3.5. Arrays
      6. 22.3.6. Quotes
      7. 22.3.7. String Concatenators
    4. 22.4. Comments
      1. 22.4.1. Documentation Examples
      2. 22.4.2. Documenting Constants
      3. 22.4.3. Documenting Functions
      4. 22.4.4. Documenting Hook Implementations
      5. 22.4.5. Including Code
      6. 22.4.6. PHP Code Tags
      7. 22.4.7. Semicolons
      8. 22.4.8. Example URLs
    5. 22.5. Naming Conventions
    6. 22.6. Checking Your Coding Style with Coder Module
    7. 22.7. Finding Your Way Around Code with grep
    8. 22.8. Summary
  29. 23. Optimizing Drupal
    1. 23.1. Caching Is the Key to Drupal Performance
    2. 23.2. Optimizing PHP
      1. 23.2.1. Setting PHP Opcode Cache File to /dev/zero
      2. 23.2.2. PHP Process Pool Settings
    3. 23.3. Tuning Apache
      1. 23.3.1. mod_expires
      2. 23.3.2. Moving Directives from .htaccess to httpd.conf
      3. 23.3.3. MPM Prefork vs. Apache MPM Worker
      4. 23.3.4. Balancing the Apache Pool Size
      5. 23.3.5. Decreasing Apache Timeout
      6. 23.3.6. Disabling Unused Apache Modules
    4. 23.4. Using Nginx Instead of Apache
    5. 23.5. Using Pressflow
    6. 23.6. Varnish
      1. 23.6.1. Normalizing incoming requests for better Varnish hits
      2. 23.6.2. Varnish: finding extraneous cookies
    7. 23.7. Boost
    8. 23.8. Boost vs. Varnish
    9. 23.9. Linux System Tuning for High Traffic Servers
    10. 23.10. Using Fast File Systems
    11. 23.11. Dedicated Servers vs. Virtual Servers
    12. 23.12. Avoiding Calling External Web Services
    13. 23.13. Decreasing Server Timeouts
    14. 23.14. Database Optimization
      1. 23.14.1. Enabling MySQL's Query Cache
      2. 23.14.2. MySQL InnoDB Performance on Windows
    15. 23.15. Drupal Performance
      1. 23.15.1. Eliminating 404 Errors
      2. 23.15.2. Disabling Modules You're Not Using
    16. 23.16. Drupal-Specific Optimizations
      1. 23.16.1. Page Caching
      2. 23.16.2. Bandwidth Optimization
      3. 23.16.3. Pruning the Sessions Table
      4. 23.16.4. Managing the Traffic of Authenticated Users
        1. 23.16.4.1. Logging to the Database
        2. 23.16.4.2. Logging to Syslog
      5. 23.16.5. Running cron
    17. 23.17. Architectures
      1. 23.17.1. Single Server
      2. 23.17.2. Separate Database Server
      3. 23.17.3. Separate Database Server and a Web Server Cluster
        1. 23.17.3.1. Load Balancing
        2. 23.17.3.2. File Uploads and Synchronization
          1. 23.17.3.2.1. Using a Shared, Mounted File System
          2. 23.17.3.2.2. Beyond a Single File System
      4. 23.17.4. Multiple Database Servers
        1. 23.17.4.1. Database Replication
        2. 23.17.4.2. Database Partitioning
    18. 23.18. Finding the Bottleneck
      1. 23.18.1.
        1. 23.18.1.1. Web Server Running Out of CPU
        2. 23.18.1.2. Web Server Running Out of RAM
        3. 23.18.1.3. Identifying Expensive Database Queries
        4. 23.18.1.4. Identifying Expensive Pages
        5. 23.18.1.5. Identifying Expensive Code
        6. 23.18.1.6. Optimizing Tables
        7. 23.18.1.7. Caching Queries Manually
        8. 23.18.1.8. Changing the Table Type from MyISAM to InnoDB
    19. 23.19. Summary
  30. 24. Installation Profiles
    1. 24.1. Creating a New Installation Profile
      1. 24.1.1. The enhanced.info File
      2. 24.1.2. The enhanced.profile File
      3. 24.1.3. The enhanced.install File
    2. 24.2. Using hook_install_tasks and hook_install_tasks_alter
    3. 24.3. Summary
  31. 25. Testing
    1. 25.1. Setting Up the Test Environment
    2. 25.2. How Tests Are Defined
    3. 25.3. Test Functions
    4. 25.4. Test Assertions
    5. 25.5. Summary
  32. A. Database Table Reference
  33. B. Resources
    1. B.1. Code
      1. B.1.1. The Drupal Source Code Repository on GIT
      2. B.1.2. Examples
      3. B.1.3. Drupal API Reference
      4. B.1.4. Security Advisories
      5. B.1.5. Updating Modules
      6. B.1.6. Updating Themes
    2. B.2. Handbooks
    3. B.3. Forums
    4. B.4. Mailing Lists
      1. B.4.1. Development
      2. B.4.2. Themes
      3. B.4.3. Translations
    5. B.5. User Groups and Interest Groups
    6. B.6. Internet Relay Chat
      1. B.6.1. North America
      2. B.6.2. Europe
      3. B.6.3. Asia
      4. B.6.4. Latin America / Caribbean
      5. B.6.5. Oceania
      6. B.6.6. Africa
    7. B.7. Videocasts
    8. B.8. Weblogs
    9. B.9. Conferences
    10. B.10. Contribute