1433 lines
44 KiB
PHP
1433 lines
44 KiB
PHP
<?php
|
|
// $Id$
|
|
|
|
/**
|
|
* @file
|
|
* The theme system, which controls the output of Drupal.
|
|
*
|
|
* The theme system allows for nearly all output of the Drupal system to be
|
|
* customized by user themes.
|
|
*
|
|
* @see <a href="http://drupal.org/node/253">Theme system</a>
|
|
* @see themeable
|
|
*/
|
|
|
|
/**
|
|
* @name Content markers
|
|
* @{
|
|
* Markers used by theme_mark() and node_mark() to designate content.
|
|
* @see theme_mark(), node_mark()
|
|
*/
|
|
define('MARK_READ', 0);
|
|
define('MARK_NEW', 1);
|
|
define('MARK_UPDATED', 2);
|
|
/**
|
|
* @} End of "Content markers".
|
|
*/
|
|
|
|
/**
|
|
* Initialize the theme system by loading the theme.
|
|
*
|
|
*/
|
|
function init_theme() {
|
|
global $theme, $user, $custom_theme, $theme_engine, $theme_key;
|
|
|
|
// If $theme is already set, assume the others are set, too, and do nothing
|
|
if (isset($theme)) {
|
|
return;
|
|
}
|
|
|
|
drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
|
|
$themes = list_themes();
|
|
|
|
// Only select the user selected theme if it is available in the
|
|
// list of enabled themes.
|
|
$theme = !empty($user->theme) && $themes[$user->theme]->status ? $user->theme : variable_get('theme_default', 'garland');
|
|
|
|
// Allow modules to override the present theme... only select custom theme
|
|
// if it is available in the list of installed themes.
|
|
$theme = $custom_theme && $themes[$custom_theme] ? $custom_theme : $theme;
|
|
|
|
// Store the identifier for retrieving theme settings with.
|
|
$theme_key = $theme;
|
|
|
|
// If we're using a style, load its appropriate theme,
|
|
// which is stored in the style's description field.
|
|
// Also add the stylesheet using drupal_add_css().
|
|
// Otherwise, load the theme.
|
|
if (strpos($themes[$theme]->filename, '.css')) {
|
|
// File is a style; loads its CSS.
|
|
// Set theme to its template/theme
|
|
drupal_add_css($themes[$theme]->filename, 'theme');
|
|
$theme = basename(dirname($themes[$theme]->description));
|
|
}
|
|
else {
|
|
// File is a template/theme
|
|
// Load its CSS, if it exists
|
|
if (file_exists($stylesheet = dirname($themes[$theme]->filename) .'/style.css')) {
|
|
drupal_add_css($stylesheet, 'theme');
|
|
}
|
|
}
|
|
|
|
if (strpos($themes[$theme]->filename, '.theme')) {
|
|
// file is a theme; include it
|
|
include_once './'. $themes[$theme]->filename;
|
|
_theme_load_registry($theme);
|
|
}
|
|
elseif (strpos($themes[$theme]->description, '.engine')) {
|
|
// file is a template; include its engine
|
|
include_once './'. $themes[$theme]->description;
|
|
$theme_engine = basename($themes[$theme]->description, '.engine');
|
|
if (function_exists($theme_engine .'_init')) {
|
|
call_user_func($theme_engine .'_init', $themes[$theme]);
|
|
}
|
|
_theme_load_registry($theme, $theme_engine);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the stored theme registry. If the theme registry is already
|
|
* in memory it will be returned; otherwise it will attempt to load the
|
|
* registry from cache. If this fails, it will construct the registry and
|
|
* cache it.
|
|
*/
|
|
function theme_get_registry($registry = NULL) {
|
|
static $theme_registry = NULL;
|
|
if (isset($registry)) {
|
|
$theme_registry = $registry;
|
|
}
|
|
|
|
return $theme_registry;
|
|
}
|
|
|
|
/**
|
|
* Store the theme registry in memory.
|
|
*/
|
|
function _theme_set_registry($registry) {
|
|
// Pass through for setting of static variable.
|
|
return theme_get_registry($registry);
|
|
}
|
|
|
|
/**
|
|
* Get the theme_registry cache from the database; if it doesn't exist, build
|
|
* it.
|
|
*/
|
|
function _theme_load_registry($theme, $theme_engine = NULL) {
|
|
$cache = cache_get("theme_registry:$theme", 'cache');
|
|
if (isset($cache->data)) {
|
|
$registry = unserialize($cache->data);
|
|
}
|
|
else {
|
|
$registry = _theme_build_registry($theme, $theme_engine);
|
|
_theme_save_registry($theme, $registry);
|
|
}
|
|
_theme_set_registry($registry);
|
|
}
|
|
|
|
/**
|
|
* Write the theme_registry cache into the database.
|
|
*/
|
|
function _theme_save_registry($theme, $registry) {
|
|
cache_set("theme_registry:$theme", 'cache', serialize($registry));
|
|
}
|
|
|
|
/**
|
|
* Force the system to rebuild the theme registry; this should be called
|
|
* when modules are added to the system, or when a dynamic system needs
|
|
* to add more theme hooks.
|
|
*/
|
|
function drupal_rebuild_theme_registry() {
|
|
cache_clear_all('theme_registry', 'cache', TRUE);
|
|
}
|
|
|
|
/**
|
|
* Process a single invocation of the theme hook.
|
|
*/
|
|
function _theme_process_registry(&$cache, $name, $type) {
|
|
$function = $name .'_theme';
|
|
if (function_exists($function)) {
|
|
$result = $function($cache);
|
|
|
|
// Automatically find paths
|
|
$path = drupal_get_path($type, $name);
|
|
foreach ($result as $hook => $info) {
|
|
$result[$hook]['type'] = $type;
|
|
// if function and file are left out, default to standard naming
|
|
// conventions.
|
|
if (!isset($info['file']) && !isset($info['function'])) {
|
|
$result[$hook]['function'] = ($type == 'module' ? 'theme_' : $name .'_') . $hook;
|
|
}
|
|
if (isset($info['file']) && !isset($info['path'])) {
|
|
$result[$hook]['file'] = $path .'/'. $info['file'];
|
|
}
|
|
// If 'arguments' have been defined previously, carry them forward.
|
|
// This should happen if a theme overrides a Drupal defined theme
|
|
// function, for example.
|
|
if (!isset($info['arguments']) && isset($cache[$hook])) {
|
|
$result[$hook]['arguments'] = $cache[$hook]['arguments'];
|
|
}
|
|
}
|
|
|
|
$cache = array_merge($cache, $result);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Rebuild the hook theme_registry cache.
|
|
*/
|
|
function _theme_build_registry($theme, $theme_engine) {
|
|
$cache = array();
|
|
foreach (module_implements('theme') as $module) {
|
|
_theme_process_registry($cache, $module, 'module');
|
|
}
|
|
|
|
if ($theme_engine) {
|
|
_theme_process_registry($cache, $theme_engine, 'theme_engine');
|
|
}
|
|
|
|
_theme_process_registry($cache, $theme, 'theme');
|
|
|
|
return $cache;
|
|
}
|
|
|
|
/**
|
|
* Provides a list of currently available themes.
|
|
*
|
|
* @param $refresh
|
|
* Whether to reload the list of themes from the database.
|
|
* @return
|
|
* An array of the currently available themes.
|
|
*/
|
|
function list_themes($refresh = FALSE) {
|
|
static $list = array();
|
|
|
|
if ($refresh) {
|
|
$list = array();
|
|
}
|
|
|
|
if (empty($list)) {
|
|
$list = array();
|
|
$result = db_query("SELECT * FROM {system} WHERE type = 'theme'");
|
|
while ($theme = db_fetch_object($result)) {
|
|
if (file_exists($theme->filename)) {
|
|
$list[$theme->name] = $theme;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* Provides a list of currently available theme engines
|
|
*
|
|
* @param $refresh
|
|
* Whether to reload the list of themes from the database.
|
|
* @return
|
|
* An array of the currently available theme engines.
|
|
*/
|
|
function list_theme_engines($refresh = FALSE) {
|
|
static $list;
|
|
|
|
if ($refresh) {
|
|
unset($list);
|
|
}
|
|
|
|
if (!$list) {
|
|
$list = array();
|
|
$result = db_query("SELECT * FROM {system} WHERE type = 'theme_engine' AND status = '1' ORDER BY name");
|
|
while ($engine = db_fetch_object($result)) {
|
|
if (file_exists($engine->filename)) {
|
|
$list[$engine->name] = $engine;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* Generate the themed output.
|
|
*
|
|
* All requests for theme hooks must go through this function. It examines
|
|
* the request and routes it to the appropriate theme function. The theme
|
|
* registry is checked to determine which implementation to use, which may
|
|
* be a function or a template.
|
|
*
|
|
* If the implementation is a function, it is executed and its return value
|
|
* passed along.
|
|
*
|
|
* If the implementation is a template, the arguments are converted to a
|
|
* $variables array. This array is then modified by the theme engine (if
|
|
* applicable) and the theme. The following functions may be used to modify
|
|
* the $variables array:
|
|
*
|
|
* ENGINE_engine_variables(&$variables)
|
|
* This function should only be implemented by theme engines and is exists
|
|
* so that the theme engine can set necessary variables. It is commonly
|
|
* used to set global variables such as $directory and $is_front_page.
|
|
* ENGINE_engine_variables_HOOK(&$variables)
|
|
* This is the same as the previous function, but is called only per hook.
|
|
* ENGINE_variables_HOOK(&$variables)
|
|
* ENGINE_variables(&$variables)
|
|
* This is meant to be used by themes that utilize a theme engine; as it is
|
|
* good practice for these themes to use the theme engine's name for
|
|
* their functions so that they may share code. In PHPTemplate, these
|
|
* functions will appear in template.php
|
|
* THEME_variables_HOOK(&$variables)
|
|
* THEME_variables(&$variables)
|
|
* These functions are based upon the raw theme; they should primarily be
|
|
* used by themes that do not use an engine or by themes that need small
|
|
* changes to what has already been established in the theme engine version
|
|
* of the function.
|
|
*
|
|
* There are two special variables that these hooks can set:
|
|
* 'template_file' and 'template_files'. These will be merged together
|
|
* to form a list of 'suggested' alternate template files to use, in
|
|
* reverse order of priority. template_file will always be a higher
|
|
* priority than items in template_files. theme() will then look for these
|
|
* files, one at a time, and use the first one
|
|
* that exists.
|
|
* @param $hook
|
|
* The name of the theme function to call.
|
|
* @param ...
|
|
* Additional arguments to pass along to the theme function.
|
|
* @return
|
|
* An HTML string that generates the themed output.
|
|
*/
|
|
function theme() {
|
|
$args = func_get_args();
|
|
$hook = array_shift($args);
|
|
|
|
static $hooks = NULL;
|
|
if (!isset($hooks)) {
|
|
init_theme();
|
|
$hooks = theme_get_registry();
|
|
}
|
|
|
|
if (!isset($hooks[$hook])) {
|
|
return;
|
|
}
|
|
|
|
$info = $hooks[$hook];
|
|
|
|
if (isset($info['function'])) {
|
|
// The theme call is a function.
|
|
// Include a file if this theme function is held elsewhere.
|
|
if (!empty($info['file'])) {
|
|
include_once($info['file']);
|
|
}
|
|
return call_user_func_array($info['function'], $args);
|
|
}
|
|
else {
|
|
// The theme call is a template.
|
|
$variables = array(
|
|
'template_files' => array()
|
|
);
|
|
if (!empty($info['arguments'])) {
|
|
$count = 0;
|
|
foreach ($info['arguments'] as $name => $default) {
|
|
$variables[$name] = isset($args[$count]) ? $args[$count] : $default;
|
|
$count++;
|
|
}
|
|
}
|
|
|
|
// default render function and extension.
|
|
$render_function = 'theme_render_template';
|
|
$extension = '.tpl.php';
|
|
$variables_list = array();
|
|
|
|
// Run through the theme engine variables, if necessary
|
|
global $theme_engine;
|
|
if (isset($theme_engine)) {
|
|
// Call each of our variable override functions. We allow
|
|
// several to create cleaner code.
|
|
$variables_list[] = $theme_engine .'_engine_variables';
|
|
$variables_list[] = $theme_engine .'_engine_variables_'. $hook;
|
|
$variables_list[] = $theme_engine .'_variables';
|
|
$variables_list[] = $theme_engine .'_variables_'. $hook;
|
|
|
|
// If theme or theme engine is implementing this, it may have
|
|
// a different extension and a different renderer.
|
|
if ($hooks[$hook]['type'] != 'module') {
|
|
if (function_exists($theme_engine .'_render_template')) {
|
|
$render_function = $theme_engine .'_render_template';
|
|
}
|
|
$extension_function = $theme_engine .'_extension';
|
|
if (function_exists($extension_function)) {
|
|
$extension = $extension_function();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add theme specific variable substitution:
|
|
global $theme;
|
|
$variables_list[] = $theme .'_variables';
|
|
$variables_list[] = $theme .'_variables_'. $hook;
|
|
|
|
// This construct ensures that we can keep a reference through
|
|
// call_user_func_array.
|
|
$args = array(&$variables, $hook);
|
|
foreach ($variables_list as $variables_function) {
|
|
if (function_exists($variables_function)) {
|
|
call_user_func_array($variables_function, $args);
|
|
}
|
|
}
|
|
|
|
// Get suggestions for alternate templates out of the variables
|
|
// that were set. This lets us dynamically choose a template
|
|
// from a list. The order is FILO, so this array is ordered from
|
|
// least appropriate first to most appropriate last.
|
|
$suggestions = array();
|
|
|
|
if (isset($variables['template_files'])) {
|
|
$suggestions = $variables['template_files'];
|
|
}
|
|
if (isset($variables['template_file'])) {
|
|
$suggestions[] = $variables['template_file'];
|
|
}
|
|
|
|
if ($suggestions) {
|
|
$template_file = drupal_discover_template($suggestions, $extension);
|
|
}
|
|
|
|
if (empty($template_file)) {
|
|
$template_file = $hooks[$hook]['file'] . $extension;
|
|
if (isset($hooks[$hook]['path'])) {
|
|
$template_file = $hooks[$hook]['path'] .'/'. $template_file;
|
|
}
|
|
}
|
|
return $render_function($template_file, $variables);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Choose which template file to actually render; these are all
|
|
* suggested templates from the theme.
|
|
*/
|
|
function drupal_discover_template($suggestions, $extension = '.tpl.php') {
|
|
global $theme_engine;
|
|
|
|
// Loop through any suggestions in FIFO order.
|
|
$suggestions = array_reverse($suggestions);
|
|
foreach ($suggestions as $suggestion) {
|
|
if (!empty($suggestion) && file_exists($file = path_to_theme() .'/'. $suggestion . $extension)) {
|
|
return $file;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return the path to the currently selected theme.
|
|
*/
|
|
function path_to_theme() {
|
|
global $theme;
|
|
|
|
if (!isset($theme)) {
|
|
init_theme();
|
|
}
|
|
|
|
$themes = list_themes();
|
|
|
|
return dirname($themes[$theme]->filename);
|
|
}
|
|
|
|
/**
|
|
* Return the path to the currently selected engine.
|
|
*/
|
|
function path_to_engine() {
|
|
global $theme, $theme_engine;
|
|
|
|
if (!isset($theme)) {
|
|
init_theme();
|
|
}
|
|
|
|
$engines = list_theme_engines();
|
|
|
|
return dirname($engines[$theme_engine]->filename);
|
|
}
|
|
|
|
/**
|
|
* Retrieve an associative array containing the settings for a theme.
|
|
*
|
|
* The final settings are arrived at by merging the default settings,
|
|
* the site-wide settings, and the settings defined for the specific theme.
|
|
* If no $key was specified, only the site-wide theme defaults are retrieved.
|
|
*
|
|
* The default values for each of settings are also defined in this function.
|
|
* To add new settings, add their default values here, and then add form elements
|
|
* to system_theme_settings() in system.module.
|
|
*
|
|
* @param $key
|
|
* The template/style value for a given theme.
|
|
*
|
|
* @return
|
|
* An associative array containing theme settings.
|
|
*/
|
|
function theme_get_settings($key = NULL) {
|
|
$defaults = array(
|
|
'mission' => '',
|
|
'default_logo' => 1,
|
|
'logo_path' => '',
|
|
'default_favicon' => 1,
|
|
'favicon_path' => '',
|
|
'toggle_logo' => 1,
|
|
'toggle_favicon' => 1,
|
|
'toggle_name' => 1,
|
|
'toggle_search' => 1,
|
|
'toggle_slogan' => 0,
|
|
'toggle_mission' => 1,
|
|
'toggle_node_user_picture' => 0,
|
|
'toggle_comment_user_picture' => 0,
|
|
);
|
|
|
|
if (module_exists('node')) {
|
|
foreach (node_get_types() as $type => $name) {
|
|
$defaults['toggle_node_info_'. $type] = 1;
|
|
}
|
|
}
|
|
$settings = array_merge($defaults, variable_get('theme_settings', array()));
|
|
|
|
if ($key) {
|
|
$settings = array_merge($settings, variable_get(str_replace('/', '_', 'theme_'. $key .'_settings'), array()));
|
|
}
|
|
|
|
// Only offer search box if search.module is enabled.
|
|
if (!module_exists('search') || !user_access('search content')) {
|
|
$settings['toggle_search'] = 0;
|
|
}
|
|
|
|
return $settings;
|
|
}
|
|
|
|
/**
|
|
* Retrieve a setting for the current theme.
|
|
* This function is designed for use from within themes & engines
|
|
* to determine theme settings made in the admin interface.
|
|
*
|
|
* Caches values for speed (use $refresh = TRUE to refresh cache)
|
|
*
|
|
* @param $setting_name
|
|
* The name of the setting to be retrieved.
|
|
*
|
|
* @param $refresh
|
|
* Whether to reload the cache of settings.
|
|
*
|
|
* @return
|
|
* The value of the requested setting, NULL if the setting does not exist.
|
|
*/
|
|
function theme_get_setting($setting_name, $refresh = FALSE) {
|
|
global $theme_key;
|
|
static $settings;
|
|
|
|
if (empty($settings) || $refresh) {
|
|
$settings = theme_get_settings($theme_key);
|
|
|
|
$themes = list_themes();
|
|
$theme_object = $themes[$theme_key];
|
|
|
|
if ($settings['mission'] == '') {
|
|
$settings['mission'] = variable_get('site_mission', '');
|
|
}
|
|
|
|
if (!$settings['toggle_mission']) {
|
|
$settings['mission'] = '';
|
|
}
|
|
|
|
if ($settings['toggle_logo']) {
|
|
if ($settings['default_logo']) {
|
|
$settings['logo'] = base_path() . dirname($theme_object->filename) .'/logo.png';
|
|
}
|
|
elseif ($settings['logo_path']) {
|
|
$settings['logo'] = base_path() . $settings['logo_path'];
|
|
}
|
|
}
|
|
|
|
if ($settings['toggle_favicon']) {
|
|
if ($settings['default_favicon']) {
|
|
if (file_exists($favicon = dirname($theme_object->filename) .'/favicon.ico')) {
|
|
$settings['favicon'] = base_path() . $favicon;
|
|
}
|
|
else {
|
|
$settings['favicon'] = base_path() .'misc/favicon.ico';
|
|
}
|
|
}
|
|
elseif ($settings['favicon_path']) {
|
|
$settings['favicon'] = base_path() . $settings['favicon_path'];
|
|
}
|
|
}
|
|
}
|
|
|
|
return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL;
|
|
}
|
|
|
|
/**
|
|
* Render a system default template, which is essentially a PHP template.
|
|
*
|
|
* @param $file
|
|
* The filename of the template to render.
|
|
* @param $variables
|
|
* A keyed array of variables that will appear in the output.
|
|
*
|
|
* @return
|
|
* The output generated by the template.
|
|
*/
|
|
function theme_render_template($file, $variables) {
|
|
extract($variables, EXTR_SKIP); // Extract the variables to a local namespace
|
|
ob_start(); // Start output buffering
|
|
include "./$file"; // Include the file
|
|
$contents = ob_get_contents(); // Get the contents of the buffer
|
|
ob_end_clean(); // End buffering and discard
|
|
return $contents; // Return the contents
|
|
}
|
|
|
|
/**
|
|
* @defgroup themeable Default theme implementations
|
|
* @{
|
|
* Functions and templates that present output to the user, and can be
|
|
* implemented by themes.
|
|
*
|
|
* Drupal's presentation layer is a pluggable system known as the theme
|
|
* layer. Each theme can take control over most of Drupal's output, and
|
|
* has complete control over the CSS.
|
|
*
|
|
* Inside Drupal, the theme layer is utilized by the use of the theme()
|
|
* function, which is passed the name of a component (the theme hook)
|
|
* and several arguments. For example, theme('table', $header, $rows);
|
|
*
|
|
* As of Drupal 6, every theme hook is required to be registered by the
|
|
* module that owns it, so that Drupal can tell what to do with it and
|
|
* to make it simple for themes to identify and override the behavior
|
|
* for these calls.
|
|
*
|
|
* The theme hooks are registered via hook_theme(), which returns an
|
|
* array of arrays with information about the hook. It describes the
|
|
* arguments the function or template will need, and provides
|
|
* defaults for the template in case they are not filled in. If the default
|
|
* implementation is a function, by convention it is named theme_HOOK().
|
|
*
|
|
* Each module should provide a default implementation for themes that
|
|
* it registers. This implementation may be either a function or a template;
|
|
* if it is a function it must be specified via hook_theme(). By convention,
|
|
* default implementations of theme hooks are named theme_HOOK. Default
|
|
* template implementations are stored in the module directory.
|
|
*
|
|
* Drupal's default template renderer is a simple PHP parsing engine that
|
|
* includes the template and stores the output. Drupal's theme engines
|
|
* can provide alternate template engines, such as XTemplate, Smarty and
|
|
* PHPTal. The most common template engine is PHPTemplate (included with
|
|
* Drupal and implemented in phptemplate.engine, which uses Drupal's default
|
|
* template renderer.
|
|
*
|
|
* In order to create theme-specific implementations of these hooks,
|
|
* themes can implement their own version of theme hooks, either as functions
|
|
* or templates. These implementations will be used instead of the default
|
|
* implementation. If using a pure .theme without an engine, the .theme is
|
|
* required to implement its own version of hook_theme() to tell Drupal what
|
|
* it is implementing; themes utilizing an engine will have their well-named
|
|
* theming functions automatically registered for them. While this can vary
|
|
* based upon the theme engine, the standard set by phptemplate is that theme
|
|
* functions should be named either phptemplate_HOOK or THEMENAME_HOOK. For
|
|
* example, for Drupal's default theme (Garland) to implement the 'table' hook,
|
|
* the phptemplate.engine would find phptemplate_table() or garland_table().
|
|
* The ENGINE_HOOK() syntax is preferred, as this can be used by sub-themes
|
|
* (which are themes that share code but use different stylesheets).
|
|
*
|
|
* The theme system is described and defined in theme.inc.
|
|
*
|
|
* @see theme()
|
|
* @see hook_theme()
|
|
*/
|
|
|
|
/**
|
|
* Formats text for emphasized display in a placeholder inside a sentence.
|
|
* Used automatically by t().
|
|
*
|
|
* @param $text
|
|
* The text to format (plain-text).
|
|
* @return
|
|
* The formatted text (html).
|
|
*/
|
|
function theme_placeholder($text) {
|
|
return '<em>'. check_plain($text) .'</em>';
|
|
}
|
|
|
|
/**
|
|
* Return an entire Drupal page displaying the supplied content.
|
|
*
|
|
* @param $content
|
|
* A string to display in the main content area of the page.
|
|
* @return
|
|
* A string containing the entire HTML page.
|
|
*/
|
|
function theme_page($content) {
|
|
// Get blocks before so that they can alter the header (JavaScript, Stylesheets etc.)
|
|
$blocks = theme('blocks', 'all');
|
|
|
|
$output = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
|
|
$output .= '<html xmlns="http://www.w3.org/1999/xhtml">';
|
|
$output .= '<head>';
|
|
$output .= ' <title>'. (drupal_get_title() ? strip_tags(drupal_get_title()) : variable_get('site_name', 'Drupal')) .'</title>';
|
|
$output .= drupal_get_html_head();
|
|
$output .= drupal_get_css();
|
|
$output .= drupal_get_js();
|
|
|
|
$output .= ' </head>';
|
|
$output .= ' <body style="background-color: #fff; color: #000;">';
|
|
$output .= '<table border="0" cellspacing="4" cellpadding="4"><tr><td style="vertical-align: top; width: 170px;">';
|
|
|
|
$output .= $blocks;
|
|
$output .= '</td><td style="vertical-align: top;">';
|
|
|
|
$output .= theme('breadcrumb', drupal_get_breadcrumb());
|
|
$output .= '<h1>'. drupal_get_title() .'</h1>';
|
|
|
|
if ($tabs = theme('menu_local_tasks')) {
|
|
$output .= $tabs;
|
|
}
|
|
|
|
$output .= theme('help');
|
|
|
|
$output .= theme('status_messages');
|
|
|
|
$output .= "\n<!-- begin content -->\n";
|
|
$output .= $content;
|
|
$output .= drupal_get_feeds();
|
|
$output .= "\n<!-- end content -->\n";
|
|
|
|
$output .= '</td></tr></table>';
|
|
$output .= theme('closure');
|
|
$output .= '</body></html>';
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Generate a themed maintenance page.
|
|
*
|
|
* Note: this function is not themable.
|
|
*
|
|
* @param $content
|
|
* The page content to show.
|
|
* @param $messages
|
|
* Whether to output status and error messages.
|
|
*/
|
|
function theme_maintenance_page($content, $messages = TRUE) {
|
|
// Set required headers.
|
|
drupal_set_header('Content-Type: text/html; charset=utf-8');
|
|
drupal_set_html_head('<style type="text/css" media="all">@import "'. base_path() .'misc/maintenance.css";</style>');
|
|
drupal_set_html_head('<style type="text/css" media="all">@import "'. base_path() . drupal_get_path('module', 'system') .'/defaults.css";</style>');
|
|
drupal_set_html_head('<style type="text/css" media="all">@import "'. base_path() . drupal_get_path('module', 'system') .'/system.css";</style>');
|
|
drupal_set_html_head('<link rel="shortcut icon" href="'. base_path() .'misc/favicon.ico" type="image/x-icon" />');
|
|
|
|
// Prepare variables.
|
|
$variables = array(
|
|
'head_title' => strip_tags(drupal_get_title()),
|
|
'head' => drupal_get_html_head(),
|
|
'styles' => '',
|
|
'scripts' => drupal_get_js(),
|
|
'sidebar_left' => drupal_get_content('left'),
|
|
'sidebar_right' => drupal_get_content('right'),
|
|
'base_path' => base_path(),
|
|
'path_to_theme' => base_path() .'themes/garland/minnelli',
|
|
'logo' => base_path() .'themes/garland/minnelli/logo.png',
|
|
'site_title' => t('Drupal'),
|
|
'title' => drupal_get_title(),
|
|
'messages' => theme('status_messages'),
|
|
'content' => $content,
|
|
);
|
|
|
|
$output = theme_render_template('misc/maintenance.tpl.php', $variables);
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Generate a themed installation page.
|
|
*
|
|
* Note: this function is not themable.
|
|
*
|
|
* @param $content
|
|
* The page content to show.
|
|
*/
|
|
function theme_install_page($content) {
|
|
drupal_set_header('Content-Type: text/html; charset=utf-8');
|
|
drupal_add_css('misc/maintenance.css', 'module', 'all', FALSE);
|
|
drupal_set_html_head('<link rel="shortcut icon" href="'. base_path() .'misc/favicon.ico" type="image/x-icon" />');
|
|
|
|
$variables = array(
|
|
'head_title' => strip_tags(drupal_get_title()),
|
|
'head' => drupal_get_html_head(),
|
|
'styles' => drupal_get_css(),
|
|
'scripts' => drupal_get_js(),
|
|
'sidebar_left' => drupal_get_content('left'),
|
|
'sidebar_right' => drupal_get_content('right'),
|
|
'base_path' => base_path(),
|
|
'path_to_theme' => base_path() .'themes/garland/minnelli',
|
|
'logo' => base_path() .'themes/garland/minnelli/logo.png',
|
|
'site_title' => st('Drupal Installation'),
|
|
'title' => drupal_get_title(),
|
|
'messages' => '',
|
|
'content' => $content,
|
|
);
|
|
|
|
// Special handling of error messages
|
|
$messages = drupal_set_message();
|
|
if (isset($messages['error'])) {
|
|
$title = count($messages['error']) > 1 ? st('The following errors must be resolved before you can continue the installation process') : st('The following error must be resolved before you can continue the installation process');
|
|
$variables['messages'] .= '<h3>'. $title .':</h3>';
|
|
$variables['messages'] .= theme('status_messages', 'error');
|
|
}
|
|
|
|
// Special handling of status messages
|
|
if (isset($messages['status'])) {
|
|
$warnings = count($messages['status']) > 1 ? st('The following installation warnings should be carefully reviewed, but in most cases may be safely ignored') : st('The following installation warning should be carefully reviewed, but in most cases may be safely ignored');
|
|
$variables['messages'] .= '<h4>'. $title .':</h4>';
|
|
$variables['messages'] .= theme('status_messages', 'status');
|
|
}
|
|
|
|
return theme_render_template('misc/maintenance.tpl.php', $variables);
|
|
}
|
|
|
|
/**
|
|
* Return a themed list of maintenance tasks to perform.
|
|
*
|
|
* Note: this function is not themable.
|
|
*/
|
|
function theme_task_list($items, $active = NULL) {
|
|
$done = isset($items[$active]) || $active == NULL;
|
|
$output = '<ol class="task-list">';
|
|
foreach ($items as $k => $item) {
|
|
if ($active == $k) {
|
|
$class = 'active';
|
|
$done = false;
|
|
}
|
|
else {
|
|
$class = $done ? 'done' : '';
|
|
}
|
|
$output .= '<li class="'. $class .'">'. $item .'</li>';
|
|
}
|
|
$output .= '</ol>';
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Return a themed set of status and/or error messages. The messages are grouped
|
|
* by type.
|
|
*
|
|
* @param $display
|
|
* (optional) Set to 'status' or 'error' to display only messages of that type.
|
|
*
|
|
* @return
|
|
* A string containing the messages.
|
|
*/
|
|
function theme_status_messages($display = NULL) {
|
|
$output = '';
|
|
foreach (drupal_get_messages($display) as $type => $messages) {
|
|
$output .= "<div class=\"messages $type\">\n";
|
|
if (count($messages) > 1) {
|
|
$output .= " <ul>\n";
|
|
foreach ($messages as $message) {
|
|
$output .= ' <li>'. $message ."</li>\n";
|
|
}
|
|
$output .= " </ul>\n";
|
|
}
|
|
else {
|
|
$output .= $messages[0];
|
|
}
|
|
$output .= "</div>\n";
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Return a themed set of links.
|
|
*
|
|
* @param $links
|
|
* A keyed array of links to be themed.
|
|
* @param $attributes
|
|
* A keyed array of attributes
|
|
* @return
|
|
* A string containing an unordered list of links.
|
|
*/
|
|
function theme_links($links, $attributes = array('class' => 'links')) {
|
|
$output = '';
|
|
|
|
if (count($links) > 0) {
|
|
$output = '<ul'. drupal_attributes($attributes) .'>';
|
|
|
|
$num_links = count($links);
|
|
$i = 1;
|
|
|
|
foreach ($links as $key => $link) {
|
|
$class = '';
|
|
|
|
// Automatically add a class to each link and also to each LI
|
|
if (isset($link['attributes']) && isset($link['attributes']['class'])) {
|
|
$link['attributes']['class'] .= ' '. $key;
|
|
$class = $key;
|
|
}
|
|
else {
|
|
$link['attributes']['class'] = $key;
|
|
$class = $key;
|
|
}
|
|
|
|
// Add first and last classes to the list of links to help out themers.
|
|
$extra_class = '';
|
|
if ($i == 1) {
|
|
$extra_class .= 'first ';
|
|
}
|
|
if ($i == $num_links) {
|
|
$extra_class .= 'last ';
|
|
}
|
|
$output .= '<li class="'. $extra_class . $class .'">';
|
|
|
|
if (isset($link['href'])) {
|
|
// Pass in $link as $options, they share the same keys.
|
|
$output .= l($link['title'], $link['href'], $link);
|
|
}
|
|
else if (!empty($link['title'])) {
|
|
// Some links are actually not links, but we wrap these in <span> for adding title and class attributes
|
|
if (empty($link['html'])) {
|
|
$link['title'] = check_plain($link['title']);
|
|
}
|
|
$output .= '<span'. drupal_attributes($link['attributes']) .'>'. $link['title'] .'</span>';
|
|
}
|
|
|
|
$i++;
|
|
$output .= "</li>\n";
|
|
}
|
|
|
|
$output .= '</ul>';
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Return a themed image.
|
|
*
|
|
* @param $path
|
|
* Either the path of the image file (relative to base_path()) or a full URL.
|
|
* @param $alt
|
|
* The alternative text for text-based browsers.
|
|
* @param $title
|
|
* The title text is displayed when the image is hovered in some popular browsers.
|
|
* @param $attributes
|
|
* Associative array of attributes to be placed in the img tag.
|
|
* @param $getsize
|
|
* If set to TRUE, the image's dimension are fetched and added as width/height attributes.
|
|
* @return
|
|
* A string containing the image tag.
|
|
*/
|
|
function theme_image($path, $alt = '', $title = '', $attributes = NULL, $getsize = TRUE) {
|
|
if (!$getsize || (is_file($path) && (list($width, $height, $type, $image_attributes) = @getimagesize($path)))) {
|
|
$attributes = drupal_attributes($attributes);
|
|
$url = (url($path) == $path) ? $path : (base_path() . $path);
|
|
return '<img src="'. check_url($url) .'" alt="'. check_plain($alt) .'" title="'. check_plain($title) .'" '. (isset($image_attributes) ? $image_attributes : '') . $attributes .' />';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return a themed breadcrumb trail.
|
|
*
|
|
* @param $breadcrumb
|
|
* An array containing the breadcrumb links.
|
|
* @return a string containing the breadcrumb output.
|
|
*/
|
|
function theme_breadcrumb($breadcrumb) {
|
|
if (!empty($breadcrumb)) {
|
|
return '<div class="breadcrumb">'. implode(' » ', $breadcrumb) .'</div>';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return a themed help message.
|
|
*
|
|
* @return a string containing the helptext for the current page.
|
|
*/
|
|
function theme_help() {
|
|
if ($help = menu_get_active_help()) {
|
|
return '<div class="help">'. $help .'</div>';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return a themed node.
|
|
*
|
|
* @param $node
|
|
* An object providing all relevant information for displaying a node:
|
|
* - $node->nid: The ID of the node.
|
|
* - $node->type: The content type (story, blog, forum...).
|
|
* - $node->title: The title of the node.
|
|
* - $node->created: The creation date, as a UNIX timestamp.
|
|
* - $node->teaser: A shortened version of the node body.
|
|
* - $node->body: The entire node contents.
|
|
* - $node->changed: The last modification date, as a UNIX timestamp.
|
|
* - $node->uid: The ID of the author.
|
|
* - $node->username: The username of the author.
|
|
* @param $teaser
|
|
* Whether to display the teaser only, as on the main page.
|
|
* @param $page
|
|
* Whether to display the node as a standalone page. If TRUE, do not display
|
|
* the title because it will be provided by the menu system.
|
|
* @return
|
|
* A string containing the node output.
|
|
*/
|
|
function theme_node($node, $teaser = FALSE, $page = FALSE) {
|
|
if (!$node->status) {
|
|
$output = '<div class="node-unpublished">';
|
|
}
|
|
|
|
if (module_exists('taxonomy')) {
|
|
$terms = taxonomy_link('taxonomy terms', $node);
|
|
}
|
|
|
|
if ($page == 0) {
|
|
$output .= t('!title by !name', array('!title' => '<h2 class="title">'. check_plain($node->title) .'</h2>', '!name' => theme('username', $node)));
|
|
}
|
|
else {
|
|
$output .= t('by !name', array('!name' => theme('username', $node)));
|
|
}
|
|
|
|
if (count($terms)) {
|
|
$output .= ' <small>('. theme('links', $terms) .')</small><br />';
|
|
}
|
|
|
|
if ($teaser && $node->teaser) {
|
|
$output .= $node->teaser;
|
|
}
|
|
else {
|
|
$output .= $node->body;
|
|
}
|
|
|
|
if ($node->links) {
|
|
$output .= '<div class="links">'. theme('links', $node->links) .'</div>';
|
|
}
|
|
|
|
if (!$node->status) {
|
|
$output .= '</div>';
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Return a themed submenu, typically displayed under the tabs.
|
|
*
|
|
* @param $links
|
|
* An array of links.
|
|
*/
|
|
function theme_submenu($links) {
|
|
return '<div class="submenu">'. implode(' | ', $links) .'</div>';
|
|
}
|
|
|
|
/**
|
|
* Return a themed table.
|
|
*
|
|
* @param $header
|
|
* An array containing the table headers. Each element of the array can be
|
|
* either a localized string or an associative array with the following keys:
|
|
* - "data": The localized title of the table column.
|
|
* - "field": The database field represented in the table column (required if
|
|
* user is to be able to sort on this column).
|
|
* - "sort": A default sort order for this column ("asc" or "desc").
|
|
* - Any HTML attributes, such as "colspan", to apply to the column header cell.
|
|
* @param $rows
|
|
* An array of table rows. Every row is an array of cells, or an associative
|
|
* array with the following keys:
|
|
* - "data": an array of cells
|
|
* - Any HTML attributes, such as "class", to apply to the table row.
|
|
*
|
|
* Each cell can be either a string or an associative array with the following keys:
|
|
* - "data": The string to display in the table cell.
|
|
* - "header": Indicates this cell is a header.
|
|
* - Any HTML attributes, such as "colspan", to apply to the table cell.
|
|
*
|
|
* Here's an example for $rows:
|
|
* @verbatim
|
|
* $rows = array(
|
|
* // Simple row
|
|
* array(
|
|
* 'Cell 1', 'Cell 2', 'Cell 3'
|
|
* ),
|
|
* // Row with attributes on the row and some of its cells.
|
|
* array(
|
|
* 'data' => array('Cell 1', array('data' => 'Cell 2', 'colspan' => 2)), 'class' => 'funky'
|
|
* )
|
|
* );
|
|
* @endverbatim
|
|
*
|
|
* @param $attributes
|
|
* An array of HTML attributes to apply to the table tag.
|
|
* @param $caption
|
|
* A localized string to use for the <caption> tag.
|
|
* @return
|
|
* An HTML string representing the table.
|
|
*/
|
|
function theme_table($header, $rows, $attributes = array(), $caption = NULL) {
|
|
$output = '<table'. drupal_attributes($attributes) .">\n";
|
|
|
|
if (isset($caption)) {
|
|
$output .= '<caption>'. $caption ."</caption>\n";
|
|
}
|
|
|
|
// Format the table header:
|
|
if (count($header)) {
|
|
// Include JS for sticky headers.
|
|
drupal_add_js('misc/tableheader.js');
|
|
|
|
$ts = tablesort_init($header);
|
|
$output .= ' <thead><tr>';
|
|
foreach ($header as $cell) {
|
|
$cell = tablesort_header($cell, $header, $ts);
|
|
$output .= _theme_table_cell($cell, TRUE);
|
|
}
|
|
$output .= " </tr></thead>\n";
|
|
}
|
|
else {
|
|
$ts = array();
|
|
}
|
|
|
|
// Format the table rows:
|
|
$output .= "<tbody>\n";
|
|
if (count($rows)) {
|
|
$flip = array('even' => 'odd', 'odd' => 'even');
|
|
$class = 'even';
|
|
foreach ($rows as $number => $row) {
|
|
$attributes = array();
|
|
|
|
// Check if we're dealing with a simple or complex row
|
|
if (isset($row['data'])) {
|
|
foreach ($row as $key => $value) {
|
|
if ($key == 'data') {
|
|
$cells = $value;
|
|
}
|
|
else {
|
|
$attributes[$key] = $value;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$cells = $row;
|
|
}
|
|
|
|
// Add odd/even class
|
|
$class = $flip[$class];
|
|
if (isset($attributes['class'])) {
|
|
$attributes['class'] .= ' '. $class;
|
|
}
|
|
else {
|
|
$attributes['class'] = $class;
|
|
}
|
|
|
|
// Build row
|
|
$output .= ' <tr'. drupal_attributes($attributes) .'>';
|
|
$i = 0;
|
|
foreach ($cells as $cell) {
|
|
$cell = tablesort_cell($cell, $header, $ts, $i++);
|
|
$output .= _theme_table_cell($cell);
|
|
}
|
|
$output .= " </tr>\n";
|
|
}
|
|
}
|
|
|
|
$output .= "</tbody></table>\n";
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Returns a header cell for tables that have a select all functionality.
|
|
*/
|
|
function theme_table_select_header_cell() {
|
|
drupal_add_js(array('tableSelect' => array('selectAll' => t('Select all rows in this table'), 'selectNone' => t('Deselect all rows in this table'))), 'setting');
|
|
drupal_add_js('misc/tableselect.js');
|
|
|
|
return array('class' => 'select-all');
|
|
}
|
|
|
|
/**
|
|
* Return a themed sort icon.
|
|
*
|
|
* @param $style
|
|
* Set to either asc or desc. This sets which icon to show.
|
|
* @return
|
|
* A themed sort icon.
|
|
*/
|
|
function theme_tablesort_indicator($style) {
|
|
if ($style == "asc") {
|
|
return theme('image', 'misc/arrow-asc.png', t('sort icon'), t('sort ascending'));
|
|
}
|
|
else {
|
|
return theme('image', 'misc/arrow-desc.png', t('sort icon'), t('sort descending'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return a themed box.
|
|
*
|
|
* @param $title
|
|
* The subject of the box.
|
|
* @param $content
|
|
* The content of the box.
|
|
* @param $region
|
|
* The region in which the box is displayed.
|
|
* @return
|
|
* A string containing the box output.
|
|
*/
|
|
function theme_box($title, $content, $region = 'main') {
|
|
$output = '<h2 class="title">'. $title .'</h2><div>'. $content .'</div>';
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Return a themed block.
|
|
*
|
|
* You can style your blocks by defining .block (all blocks),
|
|
* .block-<i>module</i> (all blocks of module <i>module</i>), and
|
|
* \#block-<i>module</i>-<i>delta</i> (specific block of module <i>module</i>
|
|
* with delta <i>delta</i>) in your theme's CSS.
|
|
*
|
|
* @param $block
|
|
* An object populated with fields from the "blocks" database table
|
|
* ($block->module, $block->delta ...) and fields returned by
|
|
* <i>module</i>_block('view') ($block->subject, $block->content, ...).
|
|
* @return
|
|
* A string containing the block output.
|
|
*/
|
|
function theme_block($block) {
|
|
$output = "<div class=\"block block-$block->module\" id=\"block-$block->module-$block->delta\">\n";
|
|
$output .= " <h2 class=\"title\">$block->subject</h2>\n";
|
|
$output .= " <div class=\"content\">$block->content</div>\n";
|
|
$output .= "</div>\n";
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Return a themed marker, useful for marking new or updated
|
|
* content.
|
|
*
|
|
* @param $type
|
|
* Number representing the marker type to display
|
|
* @see MARK_NEW, MARK_UPDATED, MARK_READ
|
|
* @return
|
|
* A string containing the marker.
|
|
*/
|
|
function theme_mark($type = MARK_NEW) {
|
|
global $user;
|
|
if ($user->uid) {
|
|
if ($type == MARK_NEW) {
|
|
return ' <span class="marker">'. t('new') .'</span>';
|
|
}
|
|
else if ($type == MARK_UPDATED) {
|
|
return ' <span class="marker">'. t('updated') .'</span>';
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return a themed list of items.
|
|
*
|
|
* @param $items
|
|
* An array of items to be displayed in the list. If an item is a string,
|
|
* then it is used as is. If an item is an array, then the "data" element of
|
|
* the array is used as the contents of the list item. If an item is an array
|
|
* with a "children" element, those children are displayed in a nested list.
|
|
* All other elements are treated as attributes of the list item element.
|
|
* @param $title
|
|
* The title of the list.
|
|
* @param $attributes
|
|
* The attributes applied to the list element.
|
|
* @param $type
|
|
* The type of list to return (e.g. "ul", "ol")
|
|
* @return
|
|
* A string containing the list output.
|
|
*/
|
|
function theme_item_list($items = array(), $title = NULL, $type = 'ul', $attributes = NULL) {
|
|
$output = '<div class="item-list">';
|
|
if (isset($title)) {
|
|
$output .= '<h3>'. $title .'</h3>';
|
|
}
|
|
|
|
if (!empty($items)) {
|
|
$output .= "<$type". drupal_attributes($attributes) .'>';
|
|
foreach ($items as $item) {
|
|
$attributes = array();
|
|
$children = array();
|
|
if (is_array($item)) {
|
|
foreach ($item as $key => $value) {
|
|
if ($key == 'data') {
|
|
$data = $value;
|
|
}
|
|
elseif ($key == 'children') {
|
|
$children = $value;
|
|
}
|
|
else {
|
|
$attributes[$key] = $value;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$data = $item;
|
|
}
|
|
if (count($children) > 0) {
|
|
$data .= theme_item_list($children, NULL, $type, $attributes); // Render nested list
|
|
}
|
|
$output .= '<li'. drupal_attributes($attributes) .'>'. $data .'</li>';
|
|
}
|
|
$output .= "</$type>";
|
|
}
|
|
$output .= '</div>';
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Returns code that emits the 'more help'-link.
|
|
*/
|
|
function theme_more_help_link($url) {
|
|
return '<div class="more-help-link">'. t('[<a href="@link">more help...</a>]', array('@link' => check_url($url))) .'</div>';
|
|
}
|
|
|
|
/**
|
|
* Return code that emits an XML icon.
|
|
*/
|
|
function theme_xml_icon($url) {
|
|
if ($image = theme('image', 'misc/xml.png', t('XML feed'), t('XML feed'))) {
|
|
return '<a href="'. check_url($url) .'" class="xml-icon">'. $image .'</a>';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return code that emits an feed icon.
|
|
*/
|
|
function theme_feed_icon($url) {
|
|
if ($image = theme('image', 'misc/feed.png', t('Syndicate content'), t('Syndicate content'))) {
|
|
return '<a href="'. check_url($url) .'" class="feed-icon">'. $image .'</a>';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Execute hook_footer() which is run at the end of the page right before the
|
|
* close of the body tag.
|
|
*
|
|
* @param $main (optional)
|
|
* Whether the current page is the front page of the site.
|
|
* @return
|
|
* A string containing the results of the hook_footer() calls.
|
|
*/
|
|
function theme_closure($main = 0) {
|
|
$footer = module_invoke_all('footer', $main);
|
|
return implode("\n", $footer) . drupal_get_js('footer');
|
|
}
|
|
|
|
/**
|
|
* Return a set of blocks available for the current user.
|
|
*
|
|
* @param $region
|
|
* Which set of blocks to retrieve.
|
|
* @return
|
|
* A string containing the themed blocks for this region.
|
|
*/
|
|
function theme_blocks($region) {
|
|
$output = '';
|
|
|
|
if ($list = block_list($region)) {
|
|
foreach ($list as $key => $block) {
|
|
// $key == <i>module</i>_<i>delta</i>
|
|
$output .= theme('block', $block);
|
|
}
|
|
}
|
|
|
|
// Add any content assigned to this region through drupal_set_content() calls.
|
|
$output .= drupal_get_content($region);
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Format a username.
|
|
*
|
|
* @param $object
|
|
* The user object to format, usually returned from user_load().
|
|
* @return
|
|
* A string containing an HTML link to the user's page if the passed object
|
|
* suggests that this is a site user. Otherwise, only the username is returned.
|
|
*/
|
|
function theme_username($object) {
|
|
|
|
if ($object->uid && $object->name) {
|
|
// Shorten the name when it is too long or it will break many tables.
|
|
if (drupal_strlen($object->name) > 20) {
|
|
$name = drupal_substr($object->name, 0, 15) .'...';
|
|
}
|
|
else {
|
|
$name = $object->name;
|
|
}
|
|
|
|
if (user_access('access user profiles')) {
|
|
$output = l($name, 'user/'. $object->uid, array('title' => t('View user profile.')));
|
|
}
|
|
else {
|
|
$output = check_plain($name);
|
|
}
|
|
}
|
|
else if ($object->name) {
|
|
// Sometimes modules display content composed by people who are
|
|
// not registered members of the site (e.g. mailing list or news
|
|
// aggregator modules). This clause enables modules to display
|
|
// the true author of the content.
|
|
if ($object->homepage) {
|
|
$output = l($object->name, $object->homepage);
|
|
}
|
|
else {
|
|
$output = check_plain($object->name);
|
|
}
|
|
|
|
$output .= ' ('. t('not verified') .')';
|
|
}
|
|
else {
|
|
$output = variable_get('anonymous', t('Anonymous'));
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
function theme_progress_bar($percent, $message) {
|
|
$output = '<div id="progress" class="progress">';
|
|
$output .= '<div class="percentage">'. $percent .'%</div>';
|
|
$output .= '<div class="status">'. $message .'</div>';
|
|
$output .= '<div class="bar"><div class="filled" style="width: '. $percent .'%"></div></div>';
|
|
$output .= '</div>';
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* @} End of "defgroup themeable".
|
|
*/
|
|
|
|
function _theme_table_cell($cell, $header = FALSE) {
|
|
$attributes = '';
|
|
|
|
if (is_array($cell)) {
|
|
$data = isset($cell['data']) ? $cell['data'] : '';
|
|
$header |= isset($cell['header']);
|
|
unset($cell['data']);
|
|
unset($cell['header']);
|
|
$attributes = drupal_attributes($cell);
|
|
}
|
|
else {
|
|
$data = $cell;
|
|
}
|
|
|
|
if ($header) {
|
|
$output = "<th$attributes>$data</th>";
|
|
}
|
|
else {
|
|
$output = "<td$attributes>$data</td>";
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|