1
2
3
4 """
5 The theme system, which controls the output of Drupal.
6 The theme system allows for nearly all output of the Drupy system to be
7 customized by user themes.
8
9 @package includes
10 @see <a href='http://drupy.net'>Drupy Homepage</a>
11 @see <a href='http://drupal.org'>Drupal Homepage</a>
12 @see <a href="http://drupal.org/node/253">Drupal Theme system</a>
13 @note Drupy is a port of the Drupal project.
14 @note This file was ported from Drupal's includes/theme.inc
15 @author Brendon Crawford
16 @copyright 2008 Brendon Crawford
17 @contact message144 at users dot sourceforge dot net
18 @created 2008-01-10
19 @version 0.1
20 @note License:
21
22 This program is free software; you can redistribute it and/or
23 modify it under the terms of the GNU General Public License
24 as published by the Free Software Foundation; either version 2
25 of the License, or (at your option) any later version.
26
27 This program is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public License
33 along with this program; if not, write to:
34
35 The Free Software Foundation, Inc.,
36 51 Franklin Street, Fifth Floor,
37 Boston, MA 02110-1301,
38 USA
39 """
40
41 __version__ = "$Revision: 1 $"
42
43 from lib.drupy import DrupyPHP as php
44 from lib.drupy import DrupyImport
45 import appglobals as lib_appglobals
46 import bootstrap as lib_bootstrap
47 import common as lib_common
48 import database as lib_database
49 import plugin as lib_plugin
50
51
52
53
54
55
56
57
58
59 MARK_READ = 0
60
61
62
63
64 MARK_NEW = 1
65
66
67
68
69 MARK_UPDATED = 2
70
71
72
73
74 processors = {}
75
76
77
112
113
114
115 -def _init_theme(theme_, base_theme = [], registry_callback = \
116 '_theme_load_registry'):
117 """
118 Initialize the theme system given already loaded information. This
119 function is useful to initialize a theme when no database is present.
120
121 @param this_theme
122 An object with the following information:
123 filename
124 The .info file for this theme. The 'path' to
125 the theme will be in this file's directory. (Required)
126 owner
127 The path to the .theme file or the .engine file to load for
128 the theme. (Required)
129 stylesheet
130 The primary stylesheet for the theme. (Optional)
131 engine
132 The name of theme engine to use. (Optional)
133 @param base_theme
134 An optional array of objects that represent the 'base theme' if the
135 theme is meant to be derivative of another theme. It requires
136 the same information as the theme object. It should be in
137 'oldest first' order, meaning the top level of the chain will
138 be first.
139 @param registry_callback
140 The callback to invoke to set the theme registry.
141 """
142 lib_appglobals.theme_info = theme_;
143 lib_appglobals.base_theme_info = base_theme;
144 lib_appglobals.theme_path = php.dirname(theme_.filename);
145
146
147
148 final_stylesheets = {};
149
150 for base in base_theme:
151 if (not php.empty(base.stylesheets)):
152 for media,stylesheets in base.stylesheets.items():
153 final_stylesheets[media] = {}
154 for name,stylesheet in stylesheets.items():
155 final_stylesheets[media][name] = stylesheet;
156
157 if (not php.empty(theme_.stylesheets)):
158 for media,stylesheets in theme_.stylesheets.items():
159 final_stylesheets[media] = {}
160 for name,stylesheet in stylesheets.items():
161 final_stylesheets[media][name] = stylesheet;
162
163 for media,stylesheets in final_stylesheets.items():
164 for stylesheet in stylesheets:
165 lib_common.drupal_add_css(stylesheet, 'theme', media);
166
167 final_scripts = {};
168
169 for base in base_theme:
170 if (not php.empty(base.scripts)):
171 for name,script in base.scripts.items():
172 final_scripts[name] = script;
173
174 if (not php.empty(theme_.scripts)):
175 for name,script in theme_.scripts.items():
176 final_scripts[name] = script;
177
178 for script in final_scripts:
179 lib_common.drupal_add_js(script, 'theme');
180 lib_appglobals.theme_engine = None;
181
182 if (php.isset(theme_, 'engine')):
183
184 processors[theme_.engine] = DrupyImport.import_file(theme_.owner)
185 lib_appglobals.theme_engine = theme_.engine;
186 if (php.function_exists('hook_init', processors[theme_.engine])):
187 this_hook = DrupyImport.getFunction(processors[theme_.engine],
188 'hook_init')
189 for base in base_theme:
190 php.call_user_func(this_hook, base);
191 php.call_user_func(this_hook, theme_);
192 else:
193
194 for base in base_theme:
195
196 if (not php.empty(base.owner)):
197 processors[base.engine] = DrupyImport.import_file(base.owner)
198
199 if (not php.empty(theme_.owner)):
200 processors[theme.engine] = DrupyImport.import_file(theme_.owner)
201 if (drupal_function_exists(registry_callback)):
202 registry_callback(theme_, \
203 base_theme, lib_appglobals.theme_engine)
204
205
206
208 """
209 Retrieve the stored theme registry. If the theme registry is already
210 in memory it will be returned; otherwise it will attempt to load the
211 registry from cache. If this fails, it will construct the registry and
212 cache it.
213 """
214 php.static(get_registry, 'theme_registry')
215 if (get_registry.theme_registry != None):
216 get_registry.theme_registry = registry;
217 return get_registry.theme_registry;
218
219
220
222 """
223 Store the theme registry in memory.
224 """
225
226 return theme_get_registry(registry);
227
228
229
231 """
232 Get the theme_registry cache from the database; if it doesn't exist, build
233 it.
234
235 @param theme
236 The loaded theme object.
237 @param base_theme
238 An array of loaded theme objects representing the ancestor themes in
239 oldest first order.
240 @param theme_engine
241 The name of the theme engine.
242 """
243
244 cache = cache_get("theme_registry:t%s" % theme.name, 'cache');
245 if (php.isset(cache, 'data')):
246 registry = cache.data;
247 else:
248
249 registry = _theme_build_registry(theme_, base_theme, theme_engine);
250 _theme_save_registry(theme_, registry);
251 _theme_set_registry(registry);
252
253
254
256 """
257 Write the theme_registry cache into the database.
258 """
259 cache_set("theme_registry:%s" % theme.name, registry);
260
261
262
264 """
265 Force the system to rebuild the theme registry; this should be called
266 when plugins are added to the system, or when a dynamic system needs
267 to add more theme hooks.
268 """
269 cache_clear_all('theme_registry', 'cache', True);
270
271
272
274 """
275 Process a single invocation of the theme hook. type will be one
276 of 'plugin', 'theme_engine' or 'theme' and it tells us some
277 important information.
278
279 Because cache is a reference, the cache will be continually
280 expanded upon; new entries will replace old entries in the
281 array_merge, but we are careful to ensure some data is carried
282 forward, such as the arguments a theme hook needs.
283
284 An override flag can be set for preprocess functions. When detected the
285 cached preprocessors for the hook will not be merged with the newly set.
286 This can be useful to themes and theme engines by giving them more control
287 over how and when the preprocess functions are run.
288 """
289 php.Reference.check(cache);
290 function = name + '_theme';
291 if (php.function_exists(function)):
292 result = function(cache, type_, theme_, path);
293 for hook,info in result.items():
294 result[hook]['type'] = type_;
295 result[hook]['theme path'] = path;
296
297
298 if (not php.isset(info, 'template') and not \
299 php.isset(info, 'function')):
300 result[hook]['function'] = ('theme_' if (type_ == 'plugin') else \
301 name + '_') + hook;
302
303
304
305
306
307 if (php.isset(info, 'file') and not php.isset(info['path'])):
308 result[hook]['file'] = path + '/' + info['file'];
309 php.include_once(result[hook]['file']);
310 elif (php.isset(info, 'file') and php.isset(info, 'path')):
311 php.include_once(info['path'] + '/' + info['file']);
312 if (php.isset(info, 'template') and not php.isset(info, 'path')):
313 result[hook]['template'] = path + '/' + info['template'];
314
315
316
317 if (not php.isset(info, 'arguments') and php.isset(cache, hook)):
318 result[hook]['arguments'] = cache[hook]['arguments'];
319
320
321
322
323 if (not php.isset(info, 'theme paths') and php.isset(cache, hook)):
324 result[hook]['theme paths'] = cache[hook]['theme paths'];
325
326 result[hook]['theme paths'].append( info['path'] if \
327 php.isset(info, 'path') else path );
328
329 if (not php.isset(info, 'preprocess functions') or not \
330 php.is_array(info['preprocess functions'])):
331 info['preprocess functions'] = [];
332 prefixes = [];
333 if (type == 'plugin'):
334
335 prefixes.append( 'template' );
336
337
338
339
340 prefixes += plugin_list();
341 elif (type_ == 'theme_engine'):
342
343
344 prefixes.append( name + '_engine' );
345
346
347 prefixes.append( name );
348 prefixes.append( theme_ );
349 else:
350
351
352 prefixes.append( name );
353 for prefix in prefixes:
354 if (php.function_exists(prefix + '_preprocess')):
355 info['preprocess functions'].append( prefix + '_preprocess' );
356 if (php.function_exists(prefix + '_preprocess_' + hook)):
357 info['preprocess functions'].append( prefix + \
358 '_preprocess_' + hook );
359
360
361
362
363 if (not php.empty(info['override preprocess functions'])):
364
365 del(result[hook]['override preprocess functions']);
366 elif (php.isset(cache[hook], 'preprocess functions') and \
367 php.is_array(cache[hook]['preprocess functions'])):
368 info['preprocess functions'] = \
369 php.array_merge(cache[hook]['preprocess functions'], \
370 info['preprocess functions']);
371 result[hook]['preprocess functions'] = info['preprocess functions'];
372
373 php.array_merge(cache, result, True);
374
375
376
378 """
379 Rebuild the hook theme_registry cache.
380
381 @param theme
382 The loaded theme object.
383 @param base_theme
384 An array of loaded theme objects representing the ancestor themes in
385 oldest first order.
386 @param theme_engine
387 The name of the theme engine.
388 """
389 cache = {};
390
391
392 for plugin in plugin_implements('theme'):
393 _theme_process_registry(cache, plugin, 'plugin', plugin, \
394 drupal_get_path('plugin', plugin));
395
396 for base in base_theme:
397
398 base_path = php.dirname(base.filename);
399 if (theme_engine):
400 _theme_process_registry(cache, theme_engine, 'base_theme_engine', \
401 base.name, base_path);
402 _theme_process_registry(cache, base.name, 'base_theme', base.name, \
403 base_path);
404
405 if (theme_engine):
406 _theme_process_registry(cache, theme_engine, 'theme_engine', \
407 theme.name, php.dirname(theme_.filename));
408
409 _theme_process_registry(cache, theme_.name, 'theme', theme_.name, \
410 php.dirname(theme_.filename));
411
412 drupal_alter('theme_registry', cache);
413 return cache;
414
415
416
418 """
419 Provides a list of currently available themes.
420
421 If the database is active then it will be retrieved from the database.
422 Otherwise it will retrieve a new list.
423
424 @param refresh
425 Whether to reload the list of themes from the database.
426 @return
427 An array of the currently available themes.
428 """
429 php.static(list_themes, 'list_', {})
430 if (refresh):
431 list_themes.list_ = {};
432 if (php.empty(list_themes.list_)):
433 themes = [];
434
435
436 if (lib_database.is_active() and not lib_bootstrap.MAINTENANCE_MODE):
437 result = lib_database.query(\
438 "SELECT * FROM {system} WHERE type = '%s'", 'theme');
439 while True:
440 this_theme = lib_database.fetch_object(result);
441 if this_theme == False or this_theme is None:
442 break;
443 if (php.file_exists(this_theme.filename)):
444 this_theme.info = php.unserialize(this_theme.info);
445
446
447
448 themes.append( this_theme );
449 else:
450
451 themes = lib_plugin.plugins['system']._theme_data();
452 for i_theme in themes:
453 i_theme.stylesheets = {}
454 i_theme.scripts = {}
455 for media,stylesheets in i_theme.info['stylesheets'].items():
456 i_theme.stylesheets[media] = {}
457 for stylesheet,path in stylesheets.items():
458 i_theme.stylesheets[media][stylesheet] = path;
459 for script,path in i_theme.info['scripts'].items():
460 if (php.file_exists(path)):
461 i_theme.scripts[script] = path;
462 if (php.isset(i_theme.info, 'engine')):
463 i_theme.engine = i_theme.info['engine'];
464 if (php.isset(i_theme.info, 'base theme')):
465 i_theme.base_theme = i_theme.info['base theme'];
466
467
468 if (not php.isset(i_theme, 'status')):
469 i_theme.status = 0;
470 list_themes.list_[i_theme.name] = i_theme;
471 return list_themes.list_;
472
473
475
476 """
477 Generate the themed output.
478
479 All requests for theme hooks must go through this function. It examines
480 the request and routes it to the appropriate theme function. The theme
481 registry is checked to determine which implementation to use, which may
482 be a function or a template.
483
484 If the implementation is a function, it is executed and its return value
485 passed along.
486
487 If the implementation is a template, the arguments are converted to a
488 variables array. This array is then modified by the plugin implementing
489 the hook, theme engine (if applicable) and the theme. The following
490 functions may be used to modify the variables array. They are processed in
491 this order when available:
492
493 - template_preprocess(&variables)
494 This sets a default set of variables for all template implementations.
495
496 - template_preprocess_HOOK(&variables)
497 This is the first preprocessor called specific to the hook; it should be
498 implemented by the plugin that registers it.
499
500 - MODULE_preprocess(&variables)
501 This will be called for all templates; it should only be used if there
502 is a real need. It's purpose is similar to template_preprocess().
503
504 - MODULE_preprocess_HOOK(&variables)
505 This is for plugins that want to alter or provide extra variables for
506 theming hooks not registered to itself. For example, if a plugin named
507 "foo" wanted to alter the submitted variable for the hook "node" a
508 preprocess function of foo_preprocess_node() can be created to intercept
509 and alter the variable.
510
511 - ENGINE_engine_preprocess(&variables)
512 This function should only be implemented by theme engines and exists
513 so that it can set necessary variables for all hooks.
514
515 - ENGINE_engine_preprocess_HOOK(&variables)
516 This is the same as the previous function, but it is called for a single
517 theming hook.
518
519 - ENGINE_preprocess(&variables)
520 This is meant to be used by themes that utilize a theme engine. It is
521 provided so that the preprocessor is not locked into a specific theme.
522 This makes it easy to share and transport code but theme authors must be
523 careful to prevent fatal re-declaration errors when using sub-themes that
524 have their own preprocessor named exactly the same as its base theme. In
525 the default theme engine (PHPTemplate), sub-themes will load their own
526 template.php file in addition to the one used for its parent theme. This
527 increases the risk for these errors. A good practice is to use the engine
528 name for the base theme and the theme name for the sub-themes to minimize
529 this possibility.
530
531 - ENGINE_preprocess_HOOK(&variables)
532 The same applies from the previous function, but it is called for a
533 specific hook.
534
535 - THEME_preprocess(&variables)
536 These functions are based upon the raw theme; they should primarily be
537 used by themes that do not use an engine or by sub-themes. It serves the
538 same purpose as ENGINE_preprocess().
539
540 - THEME_preprocess_HOOK(&variables)
541 The same applies from the previous function, but it is called for a
542 specific hook.
543
544 There are two special variables that these hooks can set:
545 'template_file' and 'template_files'. These will be merged together
546 to form a list of 'suggested' alternate template files to use, in
547 reverse order of priority. template_file will always be a higher
548 priority than items in template_files. theme() will then look for these
549 files, one at a time, and use the first one
550 that exists.
551 @param hook
552 The name of the theme function to call. May be an array, in which
553 case the first hook that actually has an implementation registered
554 will be used. This can be used to choose 'fallback' theme implementations,
555 so that if the specific theme hook isn't implemented anywhere, a more
556 generic one will be used. This can allow themes to create specific theme
557 implementations for named objects.
558 @param ...
559 Additional arguments to pass along to the theme function.
560 @return
561 An HTML string that generates the themed output.
562 """
563 php.static(theme, 'hooks')
564 hook = php.array_shift(args);
565 if (theme.hooks == None):
566 init_theme();
567 theme.hooks = get_registry();
568 if (php.is_array(hook)):
569 for candidate in hook:
570 if (php.isset(hooks, candidate)):
571 break;
572 hook = candidate;
573 if (not php.isset(theme.hooks, hook)):
574 return;
575 info = theme.hooks[hook];
576 temp = lib_appglobals.theme_path;
577
578 lib_appglobals.theme_path = info['theme path'];
579
580
581 if (not php.empty(info['file'])):
582 include_file = info['file'];
583 if (php.isset(info, 'path')):
584 include_file = info['path'] + '/' + include_file;
585 php.include_once(include_file);
586 if (php.isset(info, 'function')):
587
588 output = info['function'](*args);
589 else:
590
591 variables = {
592 'template_files' : []
593 };
594 if (not php.empty(info['arguments'])):
595 count = 0;
596 for name,default in info['arguments'].items():
597 variables[name] = (args[count] if php.isset(args, count) else default);
598 count += 1;
599
600 render_function = 'theme_render_template';
601 extension = '.tpl.py';
602
603 if (lib_appglobals.theme_engine is not None):
604
605
606 if (info['type'] != 'plugin'):
607 if (php.function_exists(\
608 lib_appglobals.theme_engine + '_render_template')):
609 render_function = lib_appglobals.theme_engine + '_render_template';
610 extension_function = lib_appglobals.theme_engine + '_extension';
611 if (php.function_exists(extension_function)):
612 extension = extension_function();
613 if (php.isset(info, 'preprocess functions') and \
614 php.is_array(info['preprocess functions'])):
615
616
617 variables_ = php.Reference(variables);
618 args = (variables_, hook);
619 for preprocess_function in info['preprocess functions']:
620 if (drupal_function_exists(preprocess_function)):
621 preprocess_function( *args );
622
623
624
625
626 suggestions = {};
627 if (php.isset(variables_, 'template_files')):
628 suggestions = variables_['template_files'];
629 if (php.isset(variables_, 'template_file')):
630 suggestions.append( variables_['template_file'] );
631 if (suggestions):
632 template_file = drupal_discover_template(info['theme paths'], \
633 suggestions, extension);
634 if (php.empty(template_file)):
635 template_file = info['template'] + extension;
636 if (php.isset(info, 'path')):
637 template_file = info['path'] + '/' + template_file;
638 output = render_function(template_file, variables);
639
640 lib_appglobals.theme_path = temp;
641 return output;
642
643
644
646 """
647 Choose which template file to actually render. These are all suggested
648 templates from themes and plugins. Theming implementations can occur on
649 multiple levels. All paths are checked to account for this.
650 """
651
652 suggestions = php.array_reverse(suggestions);
653 paths = php.array_reverse(paths);
654 for suggesiton in suggestions:
655 if (not php.empty(suggestion)):
656 for path in paths:
657 file = path + '/' + suggestion + extension;
658 if (php.file_exists(file)):
659 return file;
660
661
662
664 """
665 Return the path to the currently selected theme.
666 """
667 if (lib_appglobals.theme_path is None):
668 init_theme();
669 return lib_appglobals.theme_path;
670
671
672
674 """
675 Find overridden theme functions. Called by themes and/or theme engines to
676 easily discover theme functions.
677
678 @param cache
679 The existing cache of theme hooks to test against.
680 @param prefixes
681 An array of prefixes to test, in reverse order of importance.
682
683 @return templates
684 The functions found, suitable for returning from hook_theme;
685 """
686 templates = [];
687 functions = get_defined_functions();
688 for hook,info in cache.items():
689 for prefix in prefixes:
690 if (not php.empty(info['pattern'])):
691 matches = preg_grep('/^' + prefix + '_' + info['pattern'] + '/', \
692 functions['user']);
693 if (matches > 1):
694 for match in matches:
695 new_hook = php.str_replace(prefix + '_', '', match);
696 templates[new_hook] = {
697 'function' : match,
698 'arguments' : info['arguments'],
699 };
700 if (php.function_exists(prefix + '_' + hook)):
701 templates[hook] = {
702 'function' : prefix + '_' + hook,
703 };
704 return templates;
705
706
708 """
709 Find overridden theme templates. Called by themes and/or theme engines to
710 easily discover templates.
711
712 @param cache
713 The existing cache of theme hooks to test against.
714 @param extension
715 The extension that these templates will have.
716 @param path
717 The path to search.
718 """
719 templates = [];
720
721
722
723
724 for theme_info in list_themes():
725 if (not php.empty(theme_info.base_theme)):
726 theme_paths[theme_info.base_theme][theme_info.name] = \
727 php.dirname(theme_info.filename);
728 for basetheme,subthemes in theme_paths.items():
729 for subtheme,subtheme_path in subthemes.items():
730 if (php.isset(theme_paths, subtheme)):
731 theme_paths[basetheme] = php.array_merge(theme_paths[basetheme], \
732 theme_paths[subtheme]);
733 subtheme_paths = (theme_paths[theme] if \
734 php.isset(theme_paths, lib_appglobals.theme) else []);
735
736
737
738
739
740 for template,file in files.items():
741
742
743
744 continue;
745
746
747
748 pos = php.strpos(template, '.')
749 if (pos != False):
750 template = php.substr(template, 0, pos);
751
752
753 if (php.isset(cache, hook)):
754 templates[hook] = {
755 'template' : template,
756 'path' : php.dirname(file.filename),
757 };
758 patterns = php.array_keys(files);
759 for hook,info in cache.items():
760 if (not php.empty(info, 'pattern')):
761
762
763 pattern = php.strtr(info['pattern'], '_', '-');
764 matches = preg_grep('/^'+ pattern +'/', patterns);
765 if (matches):
766 for match in matches:
767 file = php.substr(match, 0, php.strpos(match, '.'));
768
769
770 templates[php.strtr(file, '-', '_')] = {
771 'template' : file,
772 'path' : php.dirname(files[match].filename),
773 'arguments' : info['arguments'],
774 };
775 return templates;
776
777
779 """
780 Retrieve an associative array containing the settings for a theme+ *
781 The final settings are arrived at by merging the default settings,
782 the site-wide settings, and the settings defined for the specific theme+ *
783 If no key was specified, only the site-wide theme defaults are retrieved+ *
784 The default values for each of settings are also defined in this function+
785 To add new settings, add their default values here, and then add
786 form elements
787 to system_theme_settings() in system.plugin+ *
788 @param key
789 The template/style value for a given theme+ *
790 @return
791 An associative array containing theme settings
792 """
793 defaults = {
794 'mission' : '',
795 'default_logo' : 1,
796 'logo_path' : '',
797 'default_favicon' : 1,
798 'favicon_path' : '',
799 'main_menu' : 1,
800 'secondary_menu' : 1,
801 'toggle_logo' : 1,
802 'toggle_favicon' : 1,
803 'toggle_name' : 1,
804 'toggle_search' : 1,
805 'toggle_slogan' : 0,
806 'toggle_mission' : 1,
807 'toggle_node_user_picture' : 0,
808 'toggle_comment_user_picture' : 0,
809 'toggle_main_menu' : 1,
810 'toggle_secondary_menu' : 1
811 };
812 if (plugin_exists('node')):
813 for type,name in node_get_types().items():
814 defaults['toggle_node_info_'+ type] = 1;
815 settings = php.array_merge(defaults, variable_get('theme_settings', array()))
816 if (key != None):
817 settings = php.array_merge(settings, \
818 variable_get(php.str_replace('/', '_', 'theme_'+ key +'_settings'), []))
819
820 if (not plugin_exists('search') or not user_access('search content')):
821 settings['toggle_search'] = 0;
822 return settings;
823
824
825
827 """
828 Retrieve a setting for the current theme+
829 This function is designed for use from within themes & engines
830 to determine theme settings made in the admin interface+ *
831 Caches values for speed (use refresh = True to refresh cache)
832
833 @param setting_name
834 The name of the setting to be retrieved+ *
835 @param refresh
836 Whether to reload the cache of settings+ *
837 @return
838 The value of the requested setting, None if the setting does not exist
839 """
840 php.static(theme_get_setting, 'settings')
841 if (theme_get_setting.settings == None or refresh):
842 theme_get_setting.settings = theme_get_settings(lib_appglobals.theme_key);
843 themes = list_themes();
844 theme_object = themes[lib_appglobals.theme_key];
845 if (theme_get_setting.settings['mission'] == ''):
846 theme_get_setting.settings['mission'] = variable_get('site_mission', '');
847 if (not theme_get_setting.settings['toggle_mission']):
848 theme_get_setting.settings['mission'] = '';
849 if (theme_get_setting.settings['toggle_logo']):
850 if (theme_get_setting.settings['default_logo']):
851 theme_get_setting.settings['logo'] = base_path() + \
852 php.dirname(theme_object.filename) +'/logo.png';
853 elif (theme_get_setting.settings['logo_path']):
854 theme_get_setting.settings['logo'] = base_path() + \
855 theme_get_setting.settings['logo_path'];
856 if (theme_get_setting.settings['toggle_favicon']):
857 if (theme_get_setting.settings['default_favicon']):
858 favicon = (php.dirname(theme_object.filename) +'/favicon.ico');
859 if (php.file_exists(favicon)):
860 theme_get_setting.settings['favicon'] = base_path() + favicon;
861 else:
862 theme_get_setting.settings['favicon'] = base_path() + \
863 'misc/favicon.ico';
864 elif (theme_get_setting.settings['favicon_path']):
865 theme_get_setting.settings['favicon'] = base_path() + \
866 theme_get_setting.settings['favicon_path'];
867 else:
868 theme_get_setting.settings['toggle_favicon'] = False;
869 return (theme_get_setting.settings[setting_name] if \
870 php.isset(theme_get_setting.settings, setting_name) else None);
871
872
873
875 """
876 Render a system default template, which is essentially a PHP template+ *
877 @param file
878 The filename of the template to render
879 @param variables
880 A keyed array of variables that will appear in the output+ *
881 @return
882 The output generated by the template
883 """
884 extract(variables, EXTR_SKIP);
885 ob_start();
886 php.include( "./file" );
887 contents = ob_get_contents();
888 ob_end_clean();
889 return contents;
890
891
892
893
894
895
896
897
899 """
900 Functions and templates that present output to the user, and can be
901 implemented by themes
902
903 Drupal's presentation layer is a pluggable system known as the theme
904 layer+ Each theme can take control over most of Drupal's output, and
905 has complete control over the CSS
906
907 Inside Drupal, the theme layer is utilized by the use of the theme()
908 function, which is passed the name of a component (the theme hook)
909 and several arguments+ For example, theme('table', php.header, rows);
910 Additionally, the theme() function can take an array of theme
911 hooks, which can be used to provide 'fallback' implementations to
912 allow for more specific control of output+ For example, the function:
913 theme(array('table__foo', 'table'), php.header, rows) would look to see if
914 'table__foo' is registered anywhere; if it is not, it would 'fall back'
915 to the generic 'table' implementation+ This can be used to attach specific
916 theme functions to named objects, allowing the themer more control over
917 specific types of output
918
919 As of Drupal 6, every theme hook is required to be registered by the
920 plugin that owns it, so that Drupal can tell what to do with it and
921 to make it simple for themes to identify and override the behavior
922 for these calls
923
924 The theme hooks are registered via hook_theme(), which returns an
925 array of arrays with information about the hook+ It describes the
926 arguments the function or template will need, and provides
927 defaults for the template in case they are not filled in+ If the default
928 implementation is a function, by convention it is named theme_HOOK()
929
930 Each plugin should provide a default implementation for theme_hooks that
931 it registers
932
933 This implementation may be either a function or a template;
934 if it is a function it must be specified via hook_theme()+ By convention,
935 default implementations of theme hooks are named theme_HOOK+ Default
936 template implementations are stored in the plugin directory+ *
937 Drupal's default template renderer is a simple PHP parsing engine that
938 includes the template and stores the output+ Drupal's theme engines
939 can provide alternate template engines, such as XTemplate, Smarty and
940 PHPTal+ The most common template engine is PHPTemplate (included with
941 Drupal and implemented in phptemplate.engine, which uses Drupal's default
942 template renderer
943
944 In order to create theme-specific implementations of these hooks,
945 themes can implement their own version of theme hooks, either as functions
946 or templates+ These implementations will be used instead of the default
947 implementation+ If using a pure +theme without an engine, the +theme is
948 required to implement its own version of hook_theme() to tell Drupal what
949 it is implementing; themes utilizing an engine will have their well-named
950 theming functions automatically registered for them+ While this can vary
951 based upon the theme engine, the standard set by phptemplate is that theme
952 functions should be named either phptemplate_HOOK or THEMENAME_HOOK+ For
953 example, for Drupal's default theme (Garland) to implement the 'table' hook,
954 the phptemplate.engine would find phptemplate_table() or garland_table()
955
956 The ENGINE_HOOK() syntax is preferred, as this can be used by sub-themes
957 (which are themes that share code but use different stylesheets)
958 The theme system is described and defined in theme.inc+ *
959 @see theme()
960 @see hook_theme()
961
962 Formats text for emphasized display in a placeholder inside a sentence
963 Used automatically by t()+ *
964 @param text
965 The text to format (plain-text)
966 @return
967 The formatted text (html)
968 """
969 return '<em>'+ check_plain(text) +'</em>';
970
971
972
973
975 """
976 Return a themed set of status and/or error messages
977 The messages are grouped by type
978
979 @param display
980 (optional) Set to 'status' or 'error' to display only messages
981 of that type+ *
982 @return
983 A string containing the messages+
984 """
985 output = '';
986 for type,messages in drupal_get_messages(display).items():
987 output += "<div class=\"messages type\">\n";
988 if (php.count(messages) > 1):
989 output += " <ul>\n";
990 for message in messages:
991 output += ' <li>'+ message +"</li>\n";
992 output += " </ul>\n";
993 else:
994 output += messages[0];
995 output += "</div>\n";
996 return output;
997
998
999
1000 -def links(links, attributes = {'class' : 'links'}):
1001 """
1002 Return a themed set of links+ *
1003 @param links
1004 A keyed array of links to be themed+ * @param attributes
1005 A keyed array of attributes
1006 @return
1007 A string containing an unordered list of links+
1008 """
1009 output = '';
1010 if (php.count(links) > 0):
1011 output = '<ul'+ drupal_attributes(attributes) +'>';
1012 num_links = php.count(links);
1013 i = 1;
1014 for key,link in links.items():
1015 class_ = key;
1016
1017 if (i == 1):
1018 class_ += ' first';
1019 if (i == num_links):
1020 class_ += ' last';
1021 if (php.isset(link['href']) and (link['href'] == php.GET['q'] or \
1022 (link['href'] == '<front>' and drupal_is_front_page()))):
1023 class_ += ' active';
1024 output += '<li' + drupal_attributes({'class' : class_}) + '>'
1025 if (php.isset(link['href'])):
1026
1027 output += l(link['title'], link['href'], link);
1028 elif (not php.empty(link, 'title')):
1029
1030
1031 if (php.empty(link, 'html')):
1032 link['title'] = check_plain(link['title']);
1033 span_attributes = '';
1034 if (php.isset(link, 'attributes')):
1035 span_attributes = drupal_attributes(link['attributes']);
1036 output += '<span'+ span_attributes +'>'+ link['title'] +'</span>';
1037 i += 1;
1038 output += "</li>\n";
1039 output += '</ul>';
1040 return output;
1041
1042
1043
1044 -def image(path, alt = '', title = '', attributes = None, getsize = True):
1045 """
1046 Return a themed image+ *
1047 @param path
1048 Either the path of the image file (relative to base_path())
1049 or a full URL
1050 @param alt
1051 The alternative text for text-based browsers
1052 @param title
1053 The title text is displayed when the image is hovered in some
1054 popular browsers
1055 @param attributes
1056 Associative array of attributes to be placed in the img tag
1057 @param getsize
1058 If set to True, the image's dimension are fetched and added as
1059 width/height attributes
1060 @return A string containing the image tag+
1061 """
1062 imageSize = php.getimagesize(path);
1063 if (not getsize or (php.is_file(path) and (imageSize != False))):
1064 width, height, type, image_attributes = imageSize;
1065 attributes = drupal_attributes(attributes);
1066 url = path if (url(path) == path) else (base_path() + path);
1067 return '<img src="'+ check_url(url) +'" alt="'+ check_plain(alt) + \
1068 '" title="'+ check_plain(title) +'" '+ (image_attributes if \
1069 not php.empty(image_attributes) else '') + attributes +' />';
1070
1071
1072
1074 """
1075 Return a themed breadcrumb trail+ *
1076 @param breadcrumb
1077 An array containing the breadcrumb links
1078 @return a string containing the breadcrumb output
1079 """
1080 if (not php.empty(breadcrumb)):
1081 return '<div class="breadcrumb">'+ \
1082 php.implode(' » ', breadcrumb) +'</div>';
1083
1084
1085
1087 """
1088 Return a themed help message+ *
1089 @return a string containing the helptext for the current page+
1090 """
1091 help = menu_get_active_help()
1092 if (help != False):
1093 return '<div class="help">'+ help +'</div>';
1094
1095
1096
1098 """
1099 Return a themed submenu, typically displayed under the tabs+ *
1100 @param links
1101 An array of links+
1102 """
1103 return '<div class="submenu">'+ php.implode(' | ', links) +'</div>';
1104
1105
1106 -def table(header_, rows, attributes = {}, caption = None, colgroups = {}):
1107 """
1108 Return a themed table.
1109
1110 @param php.header
1111 An array containing the table headers. Each element of the array can be
1112 either a localized string or an associative array with the following keys:
1113 - "data": The localized title of the table column.
1114 - "field": The database field represented in the table column (required if
1115 user is to be able to sort on this column).
1116 - "sort": A default sort order for this column ("asc" or "desc").
1117 - Any HTML attributes, such as "colspan", to apply to the
1118 column php.header cell.
1119 @param rows
1120 An array of table rows. Every row is an array of cells, or an associative
1121 array with the following keys:
1122 - "data": an array of cells
1123 - Any HTML attributes, such as "class", to apply to the table row.
1124
1125 Each cell can be either a string or an associative
1126 array with the following keys:
1127 - "data": The string to display in the table cell.
1128 - "php.header": Indicates this cell is a php.header.
1129 - Any HTML attributes, such as "colspan", to apply to the table cell.
1130
1131 Here's an example for rows:
1132 @verbatim
1133 rows = array(
1134 // Simple row
1135 array(
1136 'Cell 1', 'Cell 2', 'Cell 3'
1137 ),
1138 // Row with attributes on the row and some of its cells.
1139 array(
1140 'data' : array('Cell 1', array('data' : 'Cell 2', 'colspan' : 2)), \
1141 'class' : 'funky'
1142 )
1143 )
1144 @endverbatim
1145
1146 @param attributes
1147 An array of HTML attributes to apply to the table tag.
1148 @param caption
1149 A localized string to use for the <caption> tag.
1150 @param colgroups
1151 An array of column groups. Each element of the array can be either:
1152 - An array of columns, each of which is an associative array of
1153 HTML attributes
1154 applied to the COL element.
1155 - An array of attributes applied to the COLGROUP element, which
1156 must include a
1157 "data" attribute. To add attributes to COL elements, set the "data"
1158 attribute
1159 with an array of columns, each of which is an associative array of
1160 HTML attributes.
1161 Here's an example for colgroup:
1162 @verbatim
1163 colgroup = array(
1164 // COLGROUP with one COL element.
1165 array(
1166 array(
1167 'class' : 'funky', // Attribute for the COL element.
1168 ),
1169 ),
1170 // Colgroup with attributes and inner COL elements.
1171 array(
1172 'data' : array(
1173 array(
1174 'class' : 'funky', // Attribute for the COL element.
1175 ),
1176 ),
1177 'class' : 'jazzy', // Attribute for the COLGROUP element.
1178 ),
1179 )
1180 @endverbatim
1181 These optional tags are used to group and set properties on columns
1182 within a table. For example, one may easily group three columns and
1183 apply same background style to all.
1184 @return
1185 An HTML string representing the table.
1186 """
1187
1188 if (php.count(header_)):
1189 drupal_add_js('misc/tableheader.js')
1190
1191
1192 attributes['class'] = ('sticky-enabled' if \
1193 php.empty(attributes['class']) else \
1194 (attributes['class'] + ' sticky-enabled'))
1195 output = '<table' + drupal_attributes(attributes) + ">\n"
1196 if (php.isset(caption)):
1197 output += '<caption>' + caption + "</caption>\n"
1198
1199 if (php.count(colgroups)):
1200 for number,colgroup in colgroups.items():
1201 attributes = {}
1202
1203 if (php.isset(colgroup, 'data')):
1204 for key,value in colgroup.items():
1205 if (key == 'data'):
1206 cols = value
1207 else:
1208 attributes[key] = value
1209 else:
1210 cols = colgroup
1211
1212 if (php.is_array(cols) and php.count(cols)):
1213 output += ' <colgroup' + drupal_attributes(attributes) + '>'
1214 i = 0
1215 for col in cols:
1216 output += ' <col' + drupal_attributes(col) + ' />'
1217 output += " </colgroup>\n"
1218 else:
1219 output += ' <colgroup' + drupal_attributes(attributes) + " />\n"
1220
1221 if (php.count(header_) > 0):
1222 ts = tablesort_init(header_);
1223
1224
1225
1226 output += (' <thead><tr>' if (php.count(rows) > 1) else ' <tr>');
1227 for cell in header_:
1228 cell = tablesort_header(cell, header_, ts);
1229 output += _theme_table_cell(cell, True);
1230
1231
1232 output += (" </tr></thead>\n" if (php.count(rows) > 0) else "</tr>\n");
1233 else:
1234 ts = [];
1235
1236 if (php.count(rows) > 0):
1237 output += "<tbody>\n";
1238 flip = {'even' : 'odd', 'odd' : 'even'};
1239 class_ = 'even';
1240 for number,row in rows.items():
1241 attributes = [];
1242
1243 if (php.isset(row, 'data')):
1244 for key,value in row.items():
1245 if (key == 'data'):
1246 cells = value;
1247 else:
1248 attributes[key] = value;
1249 else:
1250 cells = row;
1251 if (php.count(cells) > 0):
1252
1253 class_ = flip[class_];
1254 if (php.isset(attributes, 'class')):
1255 attributes['class'] += ' '+ class_;
1256 else:
1257 attributes['class'] = class_;
1258
1259 output += ' <tr'+ drupal_attributes(attributes) +'>';
1260 i = 0;
1261 for cell in cells:
1262 cell = tablesort_cell(cell, header_, ts, i);
1263 i += 1;
1264 output += _theme_table_cell(cell);
1265 output += " </tr>\n";
1266 output += "</tbody>\n";
1267 output += "</table>\n";
1268 return output;
1269
1270
1271
1272
1274 """
1275 Returns a php.header cell for tables that have a select all functionality+
1276 """
1277 drupal_add_js('misc/tableselect.js');
1278 return {'class' : 'select-all'};
1279
1280
1282 """
1283 Return a themed sort icon+ *
1284 @param style
1285 Set to either asc or desc+
1286 This sets which icon to show+
1287 @return
1288 A themed sort icon+
1289 """
1290 if (style == "asc"):
1291 return theme('image', 'misc/arrow-asc.png', t('sort icon'), \
1292 t('sort ascending'));
1293 else:
1294 return theme('image', 'misc/arrow-desc.png', t('sort icon'), \
1295 t('sort descending'));
1296
1297
1298
1299 -def box(title, content, region = 'main'):
1300 """
1301 Return a themed box+ *
1302 @param title
1303 The subject of the box+
1304 @param content
1305 The content of the box+
1306 @param region
1307 The region in which the box is displayed+
1308 @return
1309 A string containing the box output+
1310 """
1311 output = '<h2 class="title">'+ title +'</h2><div>'+ content +'</div>';
1312 return output;
1313
1314
1316 """
1317 Return a themed marker, useful for marking new or updated
1318 content+ *
1319 @param type
1320 Number representing the marker type to display
1321 @see MARK_NEW, MARK_UPDATED, MARK_READ
1322 @return
1323 A string containing the marker+
1324 """
1325 if (lib_appglobals.user.uid > 0):
1326 if (type == MARK_NEW):
1327 return ' <span class="marker">'+ t('new') +'</span>';
1328 elif (type == MARK_UPDATED):
1329 return ' <span class="marker">'+ t('updated') +'</span>';
1330
1331
1332
1333 -def item_list(items = [], title = None, type = 'ul', attributes = []):
1334 """
1335 Return a themed list of items+ *
1336 @param items
1337 An array of items to be displayed in the list+ If an item is a string,
1338 then it is used as is+ If an item is an array, then the "data" element of
1339 the array is used as the contents of the list item+ If an item is an array
1340 with a "children" element, those children are displayed in a nested list+
1341 All other elements are treated as attributes of the list item element+
1342 @param title
1343 The title of the list+
1344 @param attributes
1345 The attributes applied to the list element+
1346 @param type
1347 The type of list to return (e.g+ "ul", "ol")
1348 @return
1349 A string containing the list output+
1350 """
1351 output = '<div class="item-list">';
1352 if (title != None):
1353 output += '<h3>'+ title +'</h3>';
1354 if (not php.empty(items)):
1355 output += "<type"+ drupal_attributes(attributes) +'>';
1356 num_items = php.count(items);
1357 for i,item in items.items():
1358 attributes = {};
1359 children = {};
1360 if (php.is_array(item)):
1361 for key,value in item.items():
1362 if (key == 'data'):
1363 data = value;
1364 elif (key == 'children'):
1365 children = value;
1366 else:
1367 attributes[key] = value;
1368 else:
1369 data = item;
1370 if (php.count(children) > 0):
1371
1372 data += theme_item_list(children, None, type, attributes);
1373 if (i == 0):
1374 attributes['class'] = ('first' if \
1375 php.empty(attributes['class']) else (attributes['class'] +' first'));
1376 if (i == num_items - 1):
1377 attributes['class'] = ('last' if \
1378 php.empty(attributes['class']) else (attributes['class'] +' last'));
1379 output += '<li'+ drupal_attributes(attributes) +'>'+ data +"</li>\n";
1380 output += "</type>";
1381 output += '</div>';
1382 return output;
1383
1384
1385
1387 """
1388 Returns code that emits the 'more help'-link+
1389 """
1390 return '<div class="more-help-link">' + t('<a href="@link">More help</a>', \
1391 {'@link' : check_url(url)}) + '</div>';
1392
1393
1394
1396 """
1397 Return code that emits an XML icon+ *
1398 For most use cases, this function has been superseded by theme_feed_icon()
1399 @see theme_feed_icon()
1400 @param url
1401 The url of the feed
1402 """
1403 image = theme('image', 'misc/xml.png', t('XML feed'), t('XML feed'));
1404 if (image):
1405 return '<a href="'+ check_url(url) +'" class="xml-icon">'+ image +'</a>';
1406
1407
1409 """
1410 Return code that emits an feed icon+ *
1411 @param url
1412 The url of the feed+ * @param title
1413 A descriptive title of the feed+
1414 """
1415 image = theme('image', 'misc/feed.png', t('Syndicate content'), title)
1416 if (image):
1417 return '<a href="'+ check_url(url) +'" class="feed-icon">'+ image +'</a>';
1418
1419
1421 """
1422 Returns code that emits the 'more' link used on blocks+ *
1423 @param url
1424 The url of the main page
1425 @param title
1426 A descriptive verb for the link, like 'Read more'
1427 """
1428 return '<div class="more-link">'+ \
1429 t('<a href="@link" title="@title">more</a>', \
1430 {'@link' : check_url(url), '@title' : title}) +'</div>';
1431
1432
1433
1435 """
1436 Execute hook_footer() which is run at the end of the page right before the
1437 close of the body tag+ *
1438 @param main (optional)
1439 Whether the current page is the front page of the site+ * @return
1440 A string containing the results of the hook_footer() calls+
1441 """
1442 footer = plugin_invoke_all('footer', main_);
1443 return php.implode("\n", footer) + drupal_get_js('footer');
1444
1445
1446
1448 """
1449 Return a set of blocks available for the current user+ *
1450 @param region
1451 Which set of blocks to retrieve+ * @return
1452 A string containing the themed blocks for this region+
1453 """
1454 output = '';
1455 list = block_list(region);
1456 if (list):
1457 for key,block in list.items():
1458
1459 output += theme('block', block);
1460
1461 output += drupal_get_content(region);
1462 return output;
1463
1464
1465
1467 """
1468 Format a username+ *
1469 @param object
1470 The user object to format, usually returned from user_load()+ * @return
1471 A string containing an HTML link to the user's page if the passed object
1472 suggests that this is a site user+
1473 Otherwise, only the username is returned
1474 """
1475 nameSet = (php.isset(object_, 'name') and not php.empty(object_.name));
1476 if (object_.uid > 0 and nameSet):
1477
1478 if (drupal_strlen(object_.name) > 20):
1479 name = drupal_substr(object_.name, 0, 15) +'...';
1480 else:
1481 name = object_.name;
1482 if (user_access('access user profiles')):
1483 output = l(name, 'user/' + object_.uid, {'attributes' : \
1484 {'title' : t('View user profile.')}})
1485 else:
1486 output = check_plain(name);
1487 elif (nameSet):
1488
1489
1490
1491
1492 if (php.isset(object_, 'homepage') and not php.empty(object_.homepage)):
1493 output = l(object_.name, object_.homepage, {'attributes' : \
1494 {'rel' : 'nofollow'}});
1495 else:
1496 output = check_plain(object_.name);
1497 output += ' ('+ t('not verified') +')';
1498 else:
1499 output = variable_get('anonymous', t('Anonymous'));
1500 return output;
1501
1502
1503
1505 """
1506 Return a themed progress bar+ *
1507 @param percent
1508 The percentage of the progress+
1509 @param message
1510 A string containing information to be displayed+
1511 @return
1512 A themed HTML string representing the progress bar
1513 """
1514 output = '<div id="progress" class="progress">';
1515 output += '<div class="bar"><div class="filled" style="width: '+ \
1516 percent +'%"></div></div>';
1517 output += '<div class="percentage">'+ percent +'%</div>';
1518 output += '<div class="message">'+ message +'</div>';
1519 output += '</div>';
1520 return output;
1521
1522
1523
1525 """
1526 Create a standard indentation div+ Used for drag and drop tables+ *
1527 @param size
1528 Optional+ The number of indentations to create+
1529 @return
1530 A string containing indentations+
1531 """
1532 output = '';
1533 for n in range(0, size):
1534 output += '<div class="indentation"> </div>';
1535 return output;
1536
1537
1538
1539
1540
1541
1542
1544 attributes = '';
1545 if (php.is_array(cell)):
1546 data = (cell['data'] if php.isset(cell, 'data') else '');
1547 header_ |= php.isset(cell, 'header');
1548 del(cell['data']);
1549 del(cell['header']);
1550 attributes = drupal_attributes(cell);
1551 else:
1552 data = cell;
1553 if (header_):
1554 output = "<th %(attributes)s>%(data)s</th>" % { 'data' : data, \
1555 'attributes' : attributes };
1556 else:
1557 output = "<td %(attributes)s>%(data)s</td>" % { 'data' : data, \
1558 'attributes' : attributes };
1559 return output;
1560
1561
1562
1600
1601
1602
1604 """
1605 Process variables for page.tpl.php
1606
1607 Most themes utilize their own copy of page.tpl.php+ The default is located
1608 inside "plugins/system/page.tpl.php"+ Look in there for the full list of
1609 variables+ *
1610 Uses the arg() function to generate a series of page template suggestions
1611 based on the current path+ *
1612 Any changes to variables in this preprocessor should also be changed inside
1613 template_preprocess_maintenance_page() to keep all them consistent+ *
1614 The variables array contains the following arguments:
1615 - content
1616 - show_blocks
1617
1618 @see page.tpl.php
1619 """
1620 php.Reference.check(variables_);
1621
1622 if (theme_get_setting('toggle_favicon')):
1623 drupal_set_html_head('<link rel="shortcut icon" href="'+ \
1624 check_url(theme_get_setting('favicon')) +'" type="image/x-icon" />');
1625
1626 regions = system_region_list(lib_appglobals.theme);
1627
1628 for region in php.array_keys(regions):
1629
1630
1631 if (not (not variables_['show_blocks'] and \
1632 (region == 'left' or region == 'right'))):
1633 blocks = theme('blocks', region);
1634 else:
1635 blocks = '';
1636
1637 if (php.isset(variables_, region)):
1638 variables_[region] += blocks
1639 else:
1640 variables_[region] = blocks;
1641
1642 variables_['layout'] = 'none';
1643 if (not php.empty(variables_['left'])):
1644 variables_['layout'] = 'left';
1645 if (not php.empty(variables_['right'])):
1646 variables_['layout'] = ('both' if \
1647 (variables_['layout'] == 'left') else 'right');
1648
1649 if (drupal_is_front_page()):
1650 mission = filter_xss_admin(theme_get_setting('mission'));
1651 else:
1652 mission = None;
1653
1654 if (drupal_get_title()):
1655 head_title = [strip_tags(drupal_get_title()), \
1656 variable_get('site_name', 'Drupal')];
1657 else:
1658 head_title = [variable_get('site_name', 'Drupal')];
1659 if (variable_get('site_slogan', '')):
1660 head_title.append( variable_get('site_slogan', '') );
1661 variables_['head_title'] = php.implode(' | ', head_title);
1662 variables_['base_path'] = base_path();
1663 variables_['front_page'] = url();
1664 variables_['breadcrumb'] = theme('breadcrumb', \
1665 drupal_get_breadcrumb());
1666 variables_['feed_icons'] = drupal_get_feeds();
1667 variables_['footer_message'] = \
1668 filter_xss_admin(variable_get('site_footer', False));
1669 variables_['head'] = drupal_get_html_head();
1670 variables_['help'] = theme('help');
1671 variables_['language'] = lib_appglobals.language;
1672 variables_['language'].dir = ('rtl' if \
1673 (php.isset(lib_appglobals.language, 'direction') and \
1674 not php.empty(lib_appglobals.language.direction)) else 'ltr');
1675 variables_['logo'] = theme_get_setting('logo');
1676 variables_['messages'] = (theme('status_messages') if \
1677 variables['show_messages'] else '');
1678 variables_['mission'] = (mission if (mission != None) else '');
1679 variables_['main_menu'] = (lib_menu.main_menu() if \
1680 theme_get_setting('toggle_main_menu') else []);
1681 variables_['secondary_menu'] = (lib_menu.secondary_menu() if \
1682 theme_get_setting('toggle_secondary_menu') else []);
1683 variables_['search_box'] = \
1684 (drupal_get_form('search_theme_form') if \
1685 theme_get_setting('toggle_search') else '');
1686 variables_['site_name'] = \
1687 (variable_get('site_name', 'Drupal') if \
1688 theme_get_setting('toggle_name') else '');
1689 variables_['site_slogan'] = \
1690 (variable_get('site_slogan', '') if \
1691 theme_get_setting('toggle_slogan') else '');
1692 variables_['css'] = drupal_add_css();
1693 variables_['styles'] = drupal_get_css();
1694 variables_['scripts'] = drupal_get_js();
1695 variables_['tabs'] = theme('menu_local_tasks');
1696 variables_['title'] = drupal_get_title();
1697
1698 variables_['closure'] = theme('closure');
1699 node = lib_menu.get_object();
1700 if (node):
1701 variables_['node'] = node;
1702
1703
1704
1705 body_classes = [];
1706
1707 body_classes.append( ('front' if \
1708 variables_['is_front'] else 'not-front') );
1709
1710
1711 body_classes.append( ('logged-in' if \
1712 variables_['logged_in'] else 'not-logged-in') );
1713
1714
1715
1716
1717
1718
1719
1720 body_classes.append(\
1721 php.preg_replace('not [^abcdefghijklmnopqrstuvwxyz0-9-_]+not s', '', \
1722 'page-'+ form_clean_id(drupal_strtolower(arg(0)))) );
1723
1724 if (php.isset(variables_, 'node') and variables_['node'].type_):
1725 body_classes.append( 'node-type-'+ \
1726 form_clean_id(variables_['node'].type_) );
1727
1728 if (variables_['layout'] == 'both'):
1729 body_classes.append( 'two-sidebars' );
1730 elif (variables_['layout'] == 'none'):
1731 body_classes.append( 'no-sidebars' );
1732 else:
1733 body_classes.append( 'one-sidebar sidebar-'+ variables_['layout'] );
1734
1735 variables_['body_classes'] = php.implode(' ', body_classes);
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746 i = 0;
1747 suggestion = 'page';
1748 suggestions = [];
1749 while True:
1750 arg_ = arg(i);
1751 if (arg_ == False or arg_ == None):
1752 break;
1753 else:
1754 i += 1;
1755 suggestions.append( suggestion +'-'+ arg_ );
1756 if (not php.is_numeric(arg_)):
1757 suggestion += '-'+ arg_;
1758 if (drupal_is_front_page()):
1759 suggestions.append( 'page-front' );
1760 if (not php.empty(suggestions)):
1761 variables_['template_files'] = suggestions;
1762
1763
1764
1765
1767 """
1768 Process variables for node.tpl.php
1769
1770 Most themes utilize their own copy of node.tpl.php+ The default is located
1771 inside "plugins/node/node.tpl.php"+ Look in there for the full list of
1772 variables+ *
1773 The variables array contains the following arguments:
1774 - node
1775 - teaser
1776 - page
1777
1778 @see node.tpl.php
1779 """
1780 php.Reference.check(variables);
1781 node = variables_['node'];
1782 if (plugin_exists('taxonomy')):
1783 variables_['taxonomy'] = taxonomy_link('taxonomy terms', node);
1784 else:
1785 variables_['taxonomy'] = {};
1786 if (variables_['teaser'] and node.teaser):
1787 variables_['content'] = node.teaser;
1788 elif (php.isset(node, 'body')):
1789 variables_['content'] = node.body;
1790 else:
1791 variables_['content'] = '';
1792 variables_['date'] = format_date(node.created);
1793 variables_['links'] = (theme('links', node.links, \
1794 {'class' : 'links inline'}) if (not php.empty(node.links)) else '');
1795 variables_['name'] = theme('username', node);
1796 variables_['node_url'] = url('node/'+ node.nid);
1797 variables_['terms'] = theme('links', variables_['taxonomy'], \
1798 {'class' : 'links inline'});
1799 variables_['title'] = check_plain(node.title);
1800
1801 variables_ = php.array_merge(drupy_array(node), variables_);
1802
1803 if (theme_get_setting('toggle_node_info_'+ node.type_)):
1804 variables_['submitted'] = theme('node_submitted', node);
1805 variables_['picture'] = (theme('user_picture', node) if \
1806 theme_get_setting('toggle_node_user_picture') else '');
1807 else:
1808 variables_['submitted'] = '';
1809 variables_['picture'] = '';
1810
1811 variables_['template_files'].append( 'node-' + \
1812 php.str_replace('_', '-', node.type_) )
1813 variables_['template_files'].append( 'node-' + node.nid )
1814
1815
1816
1817
1819 """
1820 Process variables for block.tpl.php
1821
1822 Prepare the values passed to the theme_block function to be passed
1823 into a pluggable template engine+ Uses block properties to generate a
1824 series of template file suggestions+ If none are found, the default
1825 block.tpl.php is used+ *
1826 Most themes utilize their own copy of block.tpl.php+ The default is located
1827 inside "plugins/system/block.tpl.php"+ Look in there for the full list of
1828 variables+ *
1829 The variables array contains the following arguments:
1830 - block
1831
1832 @see block.tpl.php
1833 """
1834 php.static(template_preprocess_block, 'block_counter', {})
1835 php.Reference.check(variables_);
1836
1837 if (not php.isset(template_preprocess_block.block_counter, \
1838 variables_['block'].region)):
1839 template_preprocess_block.block_counter[variables_['block'].region] = 1
1840
1841 variables_['block_zebra'] = ('odd' if \
1842 ((template_preprocess_block.block_counter[variables_['block'].region] \
1843 % 2) > 0) else 'even');
1844 variables_['block_id'] = \
1845 template_preprocess_block.block_counter[variables_['block'].region];
1846 template_preprocess_block.block_counter[variables_['block'].region] += 1;
1847 variables_['template_files'].append( \
1848 'block-'+ variables_['block'].region );
1849 variables_['template_files'].append( \
1850 'block-'+ variables_['block'].plugin );
1851 variables_['template_files'].append( \
1852 'block-'+ variables_['block'].plugin +'-'+ \
1853 variables_['block'].delta );
1854