1. 4.7.x themes/engines/phptemplate/phptemplate.engine
  2. 5.x themes/engines/phptemplate/phptemplate.engine
  3. 6.x themes/engines/phptemplate/phptemplate.engine
  4. 7.x themes/engines/phptemplate/phptemplate.engine

Handles integration of templates written in pure php with the Drupal theme system.

File

themes/engines/phptemplate/phptemplate.engine
View source
  1. <?php
  2. // $Id$
  3. /**
  4. * @file
  5. * Handles integration of templates written in pure php with the Drupal theme system.
  6. */
  7. function phptemplate_init($template) {
  8. $file = dirname($template->filename) . '/template.php';
  9. if (file_exists($file)) {
  10. include_once "./$file";
  11. }
  12. }
  13. function phptemplate_templates($directory = 'themes') {
  14. return drupal_system_listing('^page\.tpl\.php$', $directory, 'filename');
  15. }
  16. /**
  17. * Declare the available regions implemented by this engine.
  18. *
  19. * @return
  20. * An array of regions. The first array element will be used as the default region for themes.
  21. */
  22. function phptemplate_regions() {
  23. return array(
  24. 'left' => t('left sidebar'),
  25. 'right' => t('right sidebar'),
  26. 'content' => t('content'),
  27. 'header' => t('header'),
  28. 'footer' => t('footer')
  29. );
  30. }
  31. /**
  32. * Execute a template engine call.
  33. *
  34. * Each call to the template engine has two parts. Namely preparing
  35. * the variables, and then doing something with them.
  36. *
  37. * The first step is done by all template engines / themes, the second
  38. * step is dependent on the engine used.
  39. *
  40. * @param $hook
  41. * The name of the theme function being executed.
  42. * @param $variables
  43. * A sequential array of variables passed to the theme function.
  44. * @param $suggestions
  45. * An array of suggested template files to use. If none of the files are found, the
  46. * default $hook.tpl.php will be used.
  47. * @return
  48. * The HTML generated by the template system.
  49. */
  50. function _phptemplate_callback($hook, $variables = array(), $suggestions = array()) {
  51. global $theme_engine;
  52. $variables = array_merge($variables, _phptemplate_default_variables($hook, $variables));
  53. // Allow specified variables to be overridden
  54. $variables_function = '_'. $theme_engine .'_variables';
  55. if (function_exists($variables_function)) {
  56. $variables = array_merge($variables, call_user_func($variables_function, $hook, $variables));
  57. }
  58. if (isset($variables['template_files'])) {
  59. $suggestions = array_merge($suggestions, $variables['template_files']);
  60. }
  61. if (isset($variables['template_file'])) {
  62. $suggestions[] = $variables['template_file'];
  63. }
  64. $hook_function = '_'. $theme_engine .'_'. $hook;
  65. $default_function = '_'. $theme_engine .'_default';
  66. if (function_exists($hook_function)) {
  67. return call_user_func($hook_function, $variables, $suggestions);
  68. }
  69. elseif (function_exists($default_function)) {
  70. return call_user_func($default_function, $hook, $variables, $suggestions);
  71. }
  72. }
  73. /**
  74. * Adds additional helper variables to all templates.
  75. *
  76. * Counts how many times certain hooks have been called. Sidebar left / right are special cases.
  77. *
  78. * @param $hook
  79. * The name of the theme function being executed.
  80. * @param $variables
  81. * A sequential array of variables passed to the theme function.
  82. */
  83. function _phptemplate_default_variables($hook, $variables) {
  84. global $theme, $sidebar_indicator;
  85. static $count = array();
  86. $count[$hook] = isset($count[$hook]) && is_int($count[$hook]) ? $count[$hook] : 1;
  87. $variables['zebra'] = ($count[$hook] % 2) ? 'odd' : 'even';
  88. $variables['id'] = $count[$hook]++;
  89. if ($hook == 'block') {
  90. $count['block_counter'][$sidebar_indicator] = isset($count['block_counter'][$sidebar_indicator]) && is_int($count['block_counter'][$sidebar_indicator]) ? $count['block_counter'][$sidebar_indicator] : 1;
  91. $variables['block_zebra'] = ($count['block_counter'][$sidebar_indicator] % 2) ? 'odd' : 'even';
  92. $variables['block_id'] = $count['block_counter'][$sidebar_indicator]++;
  93. }
  94. elseif ($hook == 'page') {
  95. $regions = system_region_list($theme);
  96. // Load all region content assigned via blocks.
  97. foreach (array_keys($regions) as $region) {
  98. // Skip blocks in this region that have already been loaded.
  99. // This pre-loading is necessary because phptemplate uses variable names different from
  100. // the region names, e.g., 'sidebar_left' instead of 'left'.
  101. if (!in_array($region, array('left', 'right', 'footer'))) {
  102. $normal_blocks = (isset($variables['regions'])) ? $variables['regions'][$region] : theme('blocks', $region);
  103. isset($variables[$region]) ? $variables[$region] .= $normal_blocks : $variables[$region] = $normal_blocks;
  104. }
  105. }
  106. }
  107. // Tell all templates where they are located.
  108. $variables['directory'] = path_to_theme();
  109. $variables['is_front'] = drupal_is_front_page();
  110. return $variables;
  111. }
  112. /**
  113. * @return
  114. * Array of template features
  115. */
  116. function phptemplate_features() {
  117. return array(
  118. 'toggle_logo',
  119. 'toggle_comment_user_picture',
  120. 'toggle_favicon',
  121. 'toggle_mission',
  122. 'toggle_name',
  123. 'toggle_node_user_picture',
  124. 'toggle_search',
  125. 'toggle_slogan'
  126. );
  127. }
  128. /**
  129. * Prepare the values passed to the theme_page function to be passed
  130. * into a pluggable template engine. Uses the arg() function to
  131. * generate a series of page template files suggestions based on the
  132. * current path. If none are found, the default page.tpl.php is used.
  133. */
  134. function phptemplate_page($content, $show_blocks = TRUE) {
  135. global $theme;
  136. $regions = array_keys(system_region_list($theme));
  137. $variables = array('regions'=>array());
  138. /* Set title and breadcrumb to declared values */
  139. if (drupal_is_front_page()) {
  140. $mission = filter_xss_admin(theme_get_setting('mission'));
  141. }
  142. /* Add favicon */
  143. if (theme_get_setting('toggle_favicon')) {
  144. drupal_set_html_head('<link rel="shortcut icon" href="'. check_url(theme_get_setting('favicon')) .'" type="image/x-icon" />');
  145. }
  146. // Populate sidebars
  147. $layout = 'none';
  148. if ($show_blocks) {
  149. global $sidebar_indicator;
  150. // Load blocks early for adding header info
  151. foreach ($regions as $region) {
  152. // Sidebar_indicator tells the block counting code
  153. // to count sidebars separately.
  154. if ($region == 'left' || $region == 'right') {
  155. $sidebar_indicator = $region;
  156. }
  157. else {
  158. $sidebar_indicator = NULL;
  159. }
  160. $variables['regions'][$region] = theme('blocks', $region);
  161. }
  162. $sidebar_indicator = NULL;
  163. $sidebar_left = $variables['regions']['left'];
  164. if ($sidebar_left != '') {
  165. $layout = 'left';
  166. }
  167. $sidebar_right = $variables['regions']['right'];
  168. if ($sidebar_right != '') {
  169. $layout = ($layout == 'left') ? 'both' : 'right';
  170. }
  171. }
  172. else {
  173. // Add empty strings as default
  174. foreach($regions as $region) {
  175. $variables['regions'][$region] = '';
  176. }
  177. }
  178. // Construct page title
  179. if (drupal_get_title()) {
  180. $head_title = array(strip_tags(drupal_get_title()), variable_get('site_name', 'Drupal'));
  181. }
  182. else {
  183. $head_title = array(variable_get('site_name', 'Drupal'));
  184. if (variable_get('site_slogan', '')) {
  185. $head_title[] = variable_get('site_slogan', '');
  186. }
  187. }
  188. $variables = array_merge($variables, array(
  189. 'base_path' => base_path(),
  190. 'breadcrumb' => theme('breadcrumb', drupal_get_breadcrumb()),
  191. 'closure' => theme('closure'),
  192. 'content' => $content,
  193. 'feed_icons' => drupal_get_feeds(),
  194. 'footer_message' => filter_xss_admin(variable_get('site_footer', FALSE)) . "\n" . $variables['regions']['footer'],
  195. 'head' => drupal_get_html_head(),
  196. 'head_title' => implode(' | ', $head_title),
  197. 'help' => theme('help'),
  198. 'language' => $GLOBALS['locale'],
  199. 'layout' => $layout,
  200. 'logo' => theme_get_setting('logo'),
  201. 'messages' => theme('status_messages'),
  202. 'mission' => isset($mission) ? $mission : '',
  203. 'primary_links' => menu_primary_links(),
  204. 'search_box' => (theme_get_setting('toggle_search') ? drupal_get_form('search_theme_form') : ''),
  205. 'secondary_links' => menu_secondary_links(),
  206. 'sidebar_left' => $sidebar_left,
  207. 'sidebar_right' => $sidebar_right,
  208. 'site_name' => (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : ''),
  209. 'site_slogan' => (theme_get_setting('toggle_slogan') ? variable_get('site_slogan', '') : ''),
  210. 'css' => drupal_add_css(),
  211. 'styles' => drupal_get_css(),
  212. 'scripts' => drupal_get_js(),
  213. 'tabs' => theme('menu_local_tasks'),
  214. 'title' => drupal_get_title()
  215. ));
  216. if ((arg(0) == 'node') && is_numeric(arg(1))) {
  217. $variables['node'] = node_load(arg(1));
  218. }
  219. // Build a list of suggested template files in order of specificity. One
  220. // suggestion is made for every element of the current path, though
  221. // numeric elements are not carried to subsequent suggestions. For example,
  222. // http://www.example.com/node/1/edit would result in the following
  223. // suggestions:
  224. //
  225. // page-node-edit.tpl.php
  226. // page-node-1.tpl.php
  227. // page-node.tpl.php
  228. // page.tpl.php
  229. $i = 0;
  230. $suggestion = 'page';
  231. $suggestions = array($suggestion);
  232. while ($arg = arg($i++)) {
  233. $arg = str_replace(array("/", "\\", "\0"), '', $arg);
  234. $suggestions[] = $suggestion . '-' . $arg;
  235. if (!is_numeric($arg)) {
  236. $suggestion .= '-' . $arg;
  237. }
  238. }
  239. if (drupal_is_front_page()) {
  240. $suggestions[] = 'page-front';
  241. }
  242. return _phptemplate_callback('page', $variables, $suggestions);
  243. }
  244. /**
  245. * Prepare the values passed to the theme_node function to be passed
  246. * into a pluggable template engine.
  247. */
  248. function phptemplate_node($node, $teaser = 0, $page = 0) {
  249. if (module_exists('taxonomy')) {
  250. $taxonomy = taxonomy_link('taxonomy terms', $node);
  251. }
  252. else {
  253. $taxonomy = array();
  254. }
  255. $variables = array(
  256. 'content' => ($teaser && $node->teaser) ? $node->teaser : $node->body,
  257. 'date' => format_date($node->created),
  258. 'links' => $node->links ? theme('links', $node->links, array('class' => 'links inline')) : '',
  259. 'name' => theme('username', $node),
  260. 'node' => $node, // we pass the actual node to allow more customization
  261. 'node_url' => url('node/'. $node->nid),
  262. 'page' => $page,
  263. 'taxonomy' => $taxonomy,
  264. 'teaser' => $teaser,
  265. 'terms' => theme('links', $taxonomy, array('class' => 'links inline')),
  266. 'title' => check_plain($node->title)
  267. );
  268. // Flatten the node object's member fields.
  269. $variables = array_merge((array)$node, $variables);
  270. // Display info only on certain node types.
  271. if (theme_get_setting('toggle_node_info_' . $node->type)) {
  272. $variables['submitted'] = t('Submitted by !a on @b.', array('!a' => theme('username', $node), '@b' => format_date($node->created)));
  273. $variables['picture'] = theme_get_setting('toggle_node_user_picture') ? theme('user_picture', $node) : '';
  274. }
  275. else {
  276. $variables['submitted'] = '';
  277. $variables['picture'] = '';
  278. }
  279. return _phptemplate_callback('node', $variables, array('node-' . $node->type));
  280. }
  281. /**
  282. * Prepare the values passed to the theme_comment function to be passed
  283. * into a pluggable template engine.
  284. */
  285. function phptemplate_comment($comment, $links = 0) {
  286. return _phptemplate_callback('comment', array(
  287. 'author' => theme('username', $comment),
  288. 'comment' => $comment,
  289. 'content' => $comment->comment,
  290. 'date' => format_date($comment->timestamp),
  291. 'links' => isset($links) ? theme('links', $links) : '',
  292. 'new' => $comment->new ? t('new') : '',
  293. 'picture' => theme_get_setting('toggle_comment_user_picture') ? theme('user_picture', $comment) : '',
  294. 'submitted' => t('Submitted by !a on @b.',
  295. array('!a' => theme('username', $comment),
  296. '@b' => format_date($comment->timestamp))),
  297. 'title' => l($comment->subject, $_GET['q'], NULL, NULL, "comment-$comment->cid")
  298. ));
  299. }
  300. /**
  301. * Prepare the values passed to the theme_block function to be passed
  302. * into a pluggable template engine. Uses block properties to generate a
  303. * series of template file suggestions. If none are found, the default
  304. * block.tpl.php is used.
  305. */
  306. function phptemplate_block($block) {
  307. $suggestions[] = 'block';
  308. $suggestions[] = 'block-' . $block->region;
  309. $suggestions[] = 'block-' . $block->module;
  310. $suggestions[] = 'block-' . $block->module . '-' . $block->delta;
  311. return _phptemplate_callback('block', array('block' => $block), $suggestions);
  312. }
  313. /**
  314. * Prepare the values passed to the theme_box function to be passed
  315. * into a pluggable template engine.
  316. */
  317. function phptemplate_box($title, $content, $region = 'main') {
  318. return _phptemplate_callback('box', array(
  319. 'content' => $content,
  320. 'region' => $region,
  321. 'title' => $title
  322. ));
  323. }
  324. /**
  325. * Default callback for PHPTemplate.
  326. *
  327. * Load a template file, and pass the variable array to it.
  328. * If the suggested file is not found, PHPTemplate will attempt to use
  329. * a $hook.tpl.php file in the template directory, and failing that a
  330. * $hook.tpl.php in the PHPTemplate directory.
  331. *
  332. * @param $hook
  333. * The name of the theme function being executed.
  334. * @param $variables
  335. * A sequential array of variables passed to the theme function.
  336. * @param $suggestions
  337. * An array of suggested template files to use. This may include a path when
  338. * the suggested template is contained within a sub-directory of the theme.
  339. * They are set from _phptemplate_variables() or the theming hook invoking
  340. * _phptemplate_callback().
  341. */
  342. function _phptemplate_default($hook, $variables, $suggestions = array(), $extension = '.tpl.php') {
  343. global $theme_engine;
  344. // Loop through any suggestions in FIFO order.
  345. $suggestions = array_reverse($suggestions);
  346. foreach ($suggestions as $suggestion) {
  347. if (!empty($suggestion) && file_exists(path_to_theme() .'/'. $suggestion . $extension)) {
  348. $file = path_to_theme() .'/'. $suggestion . $extension;
  349. break;
  350. }
  351. }
  352. if (!isset($file)) {
  353. if (file_exists(path_to_theme() ."/$hook$extension")) {
  354. $file = path_to_theme() ."/$hook$extension";
  355. }
  356. else {
  357. if (in_array($hook, array('node', 'block', 'box', 'comment'))) {
  358. $file = path_to_engine() .'/'. $hook . $extension;
  359. }
  360. else {
  361. $variables['hook'] = $hook;
  362. watchdog('error', t('%engine.engine was instructed to override the %name theme function, but no valid template file was found.', array('%engine' => $theme_engine, '%name' => $hook)));
  363. $file = path_to_engine() .'/default'. $extension;
  364. }
  365. }
  366. }
  367. if (isset($file)) {
  368. return call_user_func('_'. $theme_engine .'_render', $file, $variables);
  369. }
  370. }
  371. function _phptemplate_render($file, $variables) {
  372. extract($variables, EXTR_SKIP); // Extract the variables to a local namespace
  373. ob_start(); // Start output buffering
  374. include "./$file"; // Include the file
  375. $contents = ob_get_contents(); // Get the contents of the buffer
  376. ob_end_clean(); // End buffering and discard
  377. return $contents; // Return the contents
  378. }

Functions

Namesort descending Description
phptemplate_block Prepare the values passed to the theme_block function to be passed into a pluggable template engine. Uses block properties to generate a series of template file suggestions. If none are found, the default block.tpl.php is used.
phptemplate_box Prepare the values passed to the theme_box function to be passed into a pluggable template engine.
phptemplate_comment Prepare the values passed to the theme_comment function to be passed into a pluggable template engine.
phptemplate_features
phptemplate_init
phptemplate_node Prepare the values passed to the theme_node function to be passed into a pluggable template engine.
phptemplate_page Prepare the values passed to the theme_page function to be passed into a pluggable template engine. Uses the arg() function to generate a series of page template files suggestions based on the current path. If none are found, the default page.tpl.php…
phptemplate_regions Declare the available regions implemented by this engine.
phptemplate_templates
_phptemplate_callback Execute a template engine call.
_phptemplate_default Default callback for PHPTemplate.
_phptemplate_default_variables Adds additional helper variables to all templates.
_phptemplate_render