Table of Contents
Preface
Chapter 1: Developing for Drupal 7
Chapter 2: Creating Your First Module
Chapter 3: Drupal's Theme Layer
Chapter 4: Theming a Module
Chapter 5: Building an Admin Interface
Chapter 6: Working with Content
Chapter 7: Creating New Fields
Chapter 8: Drupal Permissions and Security
Chapter 9: Node Access
Chapter 10: JavaScript in Drupal
Chapter 11: Working with Files and Images
Chapter 12: Installation Profiles
Appendix A: Database Access
Appendix B: Security
Index
- Chapter 1: Developing for Drupal 7
- Introducing Drupal (for developers)
- Technologies that drive Drupal
- PHP
- Databases and MySQL
- HTML, CSS, and JavaScript
- Other technologies
- The web server
- The Operating System
- Drupal architecture
- Drupal core libraries
- Drupal hooks
- Drupal core modules
- The database
- The theme system
- Drupal's major subsystems
- Themes
- Menus
- Nodes
- Files
- Users
- Comments
- Fields and entities
- Forms API
- Installation Profiles
- Simple test
- Blocks
- Other subsystems
- Tools for developing Drupal code
- Version control with Git and CVS
- The book's code and Git
- The API site and coding standards
- Developer-oriented modules
- The developer module
- Drush (the Drupal shell)
- Coder
- Summary
- Chapter 2: Creating Your First Module
- Our goal: a module with a block
- Creating a new module
- Module names
- Where does our module go?
- Creating the module directory
- Writing the .info file
- Creating a module file
- Source code standards
- Doxygen-style doc blocks
- The help hook
- The t() function and translations
- Working with the Block API
- The block info hook
- The block view hook
- The first module in action
- Writing automated tests
- Creating a test
- Starting out
- Writing a test case
- The basic pattern
- The getInfo() method
- Setting up the test case
- Writing a test method
- Summary
- Chapter 3: Drupal's Theme Layer
- Business logic versus presentation logic
- Data granularity
- Theme engines
- Two ways to theme
- Theme functions
- Preprocess functions
- Theme overrides
- Template files
- The preprocess zoo
- Render elements
- Render properties
- hook_element_info
- hook_page_alter()
- The power of theme()
- Theme hook suggestions
- Theme registry
- Variable default values
- hook_theme
- hook_theme_registry_alter
- What else?
- Summary
- Chapter 4: Theming a Module
- Reusing a default theme implementation
- Drupal blocks revisited
- Theming a Drupal block
- Render element and a theme hook suggestion
- Creating a pre_render function
- Attaching CSS to render arrays
- RTL languages
- Steps to build a default theme implementation
- hook_theme() implementations
- Variables versus render element
- Preprocess functions
- Template files
- Summary
- Chapter 5: Building an Admin Interface
- The User Warn module
- Starting our module
- The Drupal menu system
- Defining a page callback with hook_menu
- Using wildcards in menu paths
- Form API
- Using drupal_get_form()
- Building a form callback function
- Managing persistent data
- Form submission process
- A shortcut for system settings
- A shortcut for confirmation forms
- Sending mail with drupal_mail() and hook_mail()
- Calling drupal_mail()
- Implementing hook_mail()
- The token system
- What are tokens?
- Implementing tokens in your text
- Summary
- Chapter 6: Working with Content
- Why create your own entities
- The goal
- Bundles
- The Schema API
- Declaring our entity
- The entity declaration
- The entity controller
- Entity management
- Managing artwork types
- Adding artworks
- Adding new artwork
- Validation callback
- Submit callback
- Saving your artwork
- Handling revisions
- Viewing artworks
- Editing an artwork
- Deleting an artwork
- Summary
- Chapter 7: Creating New Fields
- Our goal: a "dimensions" field
- How Field API works
- Creating our new field type
- Declaring the field
- Defining the field structure
- Defining empty
- Field settings
- Field validation
- Exposing fields to the Form API with widgets
- Declaring a widget
- Simple widget forms
- Complex widgets
- Using formatters to display our field
- Declaring a formatter
- Single-value formatters
- Complex formatters
- Managing non-Field fields
- Finding entities and fields
- Summary
- Chapter 8: Drupal Permissions and Security
- Using user_access() to assert permissions
- Checking the proper user account
- Using hook_permission()
- Defining your module's permissions
- Writing hook_permission()
- Declaring your own access functions
- Responding when access is denied
- Enabling permissions programmatically
- Defining roles programmatically
- Securing forms in Drupal
- The Forms API
- Disabling form elements
- Passing secure data via forms
- Running access checks on forms
- Handling AJAX callbacks securely
- Using AJAX in forms
- Using AJAX in other contexts
- Summary
- Chapter 9: Node Access
- Node Access compared to user_access() and other permission checks
- How Drupal grants node permissions
- The node_access() function
- The access whitelist
- Caching the result for performance
- Invoking hook_node_access()
- Access to a user's own nodes
- Invoking the node access API
- hook_node_access() compared to {node_access}
- Using hook_node_access()
- A sample access control module
- A second access control module
- View operations and access control modules
- When to write a node access module
- The {node_access} table and its role
- {node_access} table schema explained
- Defining your module's access rules
- Creating the role access module
- Using hook_node_access_records()
- Using hook_node_grants()
- Security considerations
- Rebuilding the {node_access} table
- Modifying the behavior of other modules
- Using hook_node_grants_alter()
- Using hook_node_access_records_alter()
- Testing and debugging your module
- Using Devel Node Access
- Using hook_node_access_explain()
- Using the Devel Node Access by user block
- Summary
- Chapter 10: JavaScript in Drupal
- JavaScript inside Drupal
- Adding JavaScript
- Adding JavaScript and CSS files to .info files
- Using drupal_add_js()
- Adding JavaScript files
- Adding CSS files
- Passing variables from PHP to JavaScript
- Adding inline JavaScript
- Adding inline CSS
- Using the Library API
- Defining a library with hook_library
- Altering information in hook_library
- Using renderable arrays
- Altering JavaScript
- Altering CSS
- Drupal specific JavaScript
- Themeable presentation
- Translatable strings
- Behaviors
- AJAX helpers
- Adding AJAX to forms
- AJAX automatically applied
- AJAX commands
- ajax_command_after
- ajax_command_alert
- ajax_command_append
- ajax_command_before
- ajax_command_changed
- ajax_command_css
- ajax_command_data
- ajax_command_html
- ajax_command_prepend
- ajax_command_remove
- ajax_command_replace
- ajax_command_restripe
- ajax_command_settings
- Summary
- Chapter 11: Working with Files and Images
- The Twitpic and watermark modules
- Files in Drupal
- File API
- Stream wrappers
- Creating a stream wrapper
- Images in Drupal
- Image API
- Image Styles
- Creating image effects
- Creating image styles from a module
- Summary
- Chapter 12: Installation Profiles
- Introducing installation profiles
- Drupal distributions
- Setting up a distribution
- Standard and minimal profiles
- Creating a profile directory
- Profile modules and themes
- Creating profiles
- Enabling modules
- The install task system
- Choosing an install task or using hook_install
- Anatomy of an install task
- Creating a task
- Altering tasks
- Configuring blocks
- Variable settings
- Text filters
- Code placement
- Running the installer from the command line
- Summary
- Appendix A: Database Access
- Basic queries
- Result objects
- Dynamic queries
- Insert queries
- Update queries
- Delete queries
- Merge queries
- Advanced subjects
- Transactions
- Slave servers
- Summary
- Appendix B: Security
- Thinking securely
- Filtering versus escaping
- Filtering
- Escaping HTML
- SQL injection
- Node access control
- Handling insecure code
- Staying up to date
- Summary