/[drupal]/contributions/modules/node_style/node_style.module
ViewVC logotype

Contents of /contributions/modules/node_style/node_style.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.22 - (show annotations) (download) (as text)
Wed Feb 28 08:12:35 2007 UTC (2 years, 9 months ago) by karthik
Branch: MAIN
CVS Tags: HEAD
Changes since 1.21: +2 -2 lines
File MIME type: text/x-php
No t() for variables.
1 <?php
2 // $Id: node_style.module,v 1.21 2007/02/09 14:37:59 karthik Exp $
3
4 /**
5 * @file
6 * Allows for node specific customisations at the theme level.
7 * @author
8 * Karthik Kumar/Zen [ http://drupal.org/user/21209 ].
9 * @todo
10 * Discern custom regions.
11 * Integration with _a_ "signals" module.
12 * Make module usable with more than just nodes.
13 */
14
15 /**
16 * Implementation of hook_help().
17 */
18 function node_style_help($section) {
19 switch ($section) {
20 case 'admin/help#node_style':
21 return t('This module allows for node specific style customisations. Its primary uses include:
22 <ul>
23 <li>Controlling the display of node and page elements such as sidebars, links, titles etc. A common use of this feature is in front/welcome pages.</li>
24 <li>Setting a custom theme for certain nodes.</li>
25 <li>Injecting HTML in the &lt;head /&gt; block for specific nodes. A common use of this feature is to introduce node-specific styles or javascript.</li>
26 </ul>');
27 case 'admin/build/node_style':
28 return t('This module allows for node specific style customisations.');
29 case 'admin/build/node_style/configure':
30 return t('The inner workings of this module involve the use of a function that is ocassionally also used in certain themes. The Garland and Minnelli themes, for e.g., use this function and this can generated an unsightly error message. To resolve this issue, please follow the following steps:
31 <ul>
32 <li>In the conflicting theme, look for the function <em>_phptemplate_variables()</em>. This is almost always present in template.php. (If it is not, it will have to be moved into that file.)</li>
33 <li>Rename the function <em>_phptemplate_variables_theme_key</em> where theme_key is a representation of the theme, commonly its name. For e.g., in the case of the Garland theme, rename it to <em>_phptemplate_variables_garland</em>.</li>
34 <li>Save the file.</li>
35 <li>Check the <em>Theme compatibility</em> check box below and save the change.</li>
36 </ul>
37 Compatibility mode will be deactivated whenever themes are enabled or disabled.');
38 }
39 }
40
41 /**
42 * Implementation of hook_menu().
43 */
44 function node_style_menu($may_cache) {
45 global $node_style;
46
47 $items = array();
48
49 if ($may_cache) {
50 $items[] = array(
51 'path' => 'admin/build/node_style',
52 'title' => t('Node style'),
53 'callback' => '_node_style_schemes',
54 'access' => user_access('administer node styles')
55 );
56 $items[] = array(
57 'path' => 'admin/build/node_style/schemes',
58 'title' => t('Schemes'),
59 'callback' => '_node_style_schemes',
60 'access' => user_access('administer node styles'),
61 'type' => MENU_DEFAULT_LOCAL_TASK,
62 'weight' => -1
63 );
64 $items[] = array(
65 'path' => 'admin/build/node_style/add',
66 'title' => t('Add scheme'),
67 'callback' => 'drupal_get_form',
68 'callback arguments' => array('_node_style_schemes_add'),
69 'access' => user_access('administer node styles'),
70 'type' => MENU_LOCAL_TASK
71 );
72 $items[] = array(
73 'path' => 'admin/build/node_style/configure',
74 'title' => t('Configure'),
75 'callback' => 'drupal_get_form',
76 'callback arguments' => array('_node_style_configure'),
77 'access' => user_access('administer node styles'),
78 'type' => MENU_LOCAL_TASK
79 );
80 $items[] = array(
81 'path' => 'admin/build/node_style/edit',
82 'title' => t('Edit scheme'),
83 'callback' => 'drupal_get_form',
84 'callback arguments' => array('_node_style_schemes_edit'),
85 'access' => user_access('administer node styles'),
86 'type' => MENU_CALLBACK
87 );
88 $items[] = array(
89 'path' => 'admin/build/node_style/delete',
90 'title' => t('Delete scheme'),
91 'callback' => 'drupal_get_form',
92 'callback arguments' => array('_node_style_schemes_delete'),
93 'access' => user_access('administer node styles'),
94 'type' => MENU_CALLBACK
95 );
96 }
97 else {
98 // node_style configurations need to be loaded in hook_menu to allow for
99 // cached pages. Workarounds for the global are welcome.
100 if (arg(0) == 'node') {
101 if (is_numeric(arg(1)) && empty($_POST)) {
102 $node_style = _node_style_get_node_style(arg(1));
103 _node_style_set_custom_theme($node_style);
104 }
105 elseif (!empty($_POST) && (arg(1) == 'add' || arg(2) == 'edit') && isset($_POST['op']) && $_POST['op'] == 'Preview' && isset($_POST['node_style_scheme'])) {
106 // Since this is a node form preview, initialise $node_style to ensure
107 // that previews work properly for existing nodes that are being edited.
108 $node_style = array();
109 // Hack: Access $_POST to retrieve the node_style scheme. Due to the
110 // fact that $custom_theme cannot be set in hook_nodeapi, this is the
111 // only workable solution for allowing node_style previews.
112 // If the situation arises where theme overrides have become more
113 // flexible, this block can be shoved into hook_nodeapi.
114 if ($_POST['node_style_scheme']) {
115 $node_style = _node_style_get_scheme((int) $_POST['node_style_scheme']);
116 // Set custom theme if enabled.
117 _node_style_set_custom_theme($node_style);
118 }
119 }
120 }
121 // node_style.inc includes the _phptemplate_variables call. This function
122 // has been isolated as possibilities exist where the same function might be
123 // declared elsewhere.
124 if (variable_get('node_style_mode', 0) && (arg(2) != 'node_style')) {
125 include 'node_style.inc';
126 }
127 }
128
129 return $items;
130 }
131
132 /**
133 * Implementation of hook_perm().
134 */
135 function node_style_perm() {
136 return array('customise node styles', 'administer node styles');
137 }
138
139 /**
140 * Implementation of hook_form_alter().
141 */
142 function node_style_form_alter($form_id, &$form) {
143 if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id && user_access('customise node styles')) {
144 $node = $form['#node'];
145
146 $schemes = array('0' => t('None')) + _node_style_get_schemes();
147
148 $form['node_style'] = array(
149 '#type' => 'fieldset',
150 '#title' => 'Node style',
151 '#collapsible' => TRUE,
152 '#collapsed' => empty($node->node_style),
153 '#weight' => 30
154 );
155 $form['node_style']['node_style_scheme'] = array(
156 '#type' => 'select',
157 '#title' => t('Node style scheme'),
158 '#description' => t('Select the <a href="!scheme">style scheme</a> to associate with this node.', array('!scheme' => url('admin/build/node_style'))),
159 '#options' => $schemes,
160 '#default_value' => (isset($node->node_style) ? $node->node_style['sid'] : 0)
161 );
162 }
163 elseif ($form_id == 'system_themes') {
164 // To disable theme compatibility mode when changes are made to the theme
165 // screen, inject a submit handler.
166 $form['#submit']['node_style_alter_mode_submit'] = array();
167 }
168 }
169
170 /**
171 * Process system_theme function submissions.
172 */
173 function node_style_alter_mode_submit($form_id, $form_values) {
174 // Delete compatibility variable.
175 variable_del('node_style_mode');
176 // Point user to the configuration screen.
177 drupal_set_message(t('Node style: <a href="!theme-compatibility">Theme compatibility mode</a> has been switched off.', array('!theme-compatibility' => url('admin/build/node_style/configure'))));
178 }
179
180 /**
181 * Implementation of hook_nodeapi().
182 */
183 function node_style_nodeapi(&$node, $op, $arg) {
184 if (user_access('customise node styles')) {
185 switch ($op) {
186 case 'load':
187 if (isset($node->nid) && !isset($GLOBALS['node_style'])) {
188 $node->node_style = $GLOBALS['node_style'] = _node_style_get_node_style($node->nid);
189 }
190 break;
191 case 'delete':
192 _node_style_delete_node_style($node->nid);
193 break;
194 case 'update':
195 _node_style_delete_node_style($node->nid);
196 // Fall through.
197 case 'insert':
198 if (!empty($node->node_style_scheme)) {
199 _node_style_add_node_style($node->nid, $node->node_style_scheme);
200 }
201 }
202 }
203 }
204
205 /**
206 * Menu callback: Display a table of available schemes.
207 */
208 function _node_style_schemes() {
209 $result = db_query("SELECT s.name, s.sid, COUNT(m.sid) AS count FROM {node_style_schemes} s LEFT JOIN {node_style_maps} m USING (sid) GROUP BY s.sid ORDER BY s.name");
210 $rows = array();
211 while ($row = db_fetch_array($result)) {
212 $rows[] = array($row['name'], $row['count'], l('edit', 'admin/build/node_style/edit/'. $row['sid']), l('delete', 'admin/build/node_style/delete/'. $row['sid']));
213 }
214 if (empty($rows)) {
215 $rows[] = array(array('data' => t('No schemes found.'), 'colspan' => 4));
216 }
217 $header = array(t('Scheme'), t('Use count'), array('data' => t('Operations'), 'colspan' => 2));
218
219 return theme('table', $header, $rows);
220 }
221
222 /**
223 * Menu callback: Add a theme compatibility configuration screen.
224 */
225 function _node_style_configure() {
226 $form['mode'] = array(
227 '#type' => 'checkbox',
228 '#title' => t('Theme compatibility'),
229 '#description' => t('If checked, indicates that all themes on this site are compatible with this module.'),
230 '#default_value' => variable_get('node_style_mode', 0)
231 );
232
233 $form['submit'] = array('#type' => 'submit', '#value' => t('Save configuration'));
234
235 return $form;
236 }
237
238 /**
239 * Process the theme compatibility configuration form.
240 */
241 function _node_style_configure_submit($form_id, $form_values) {
242 variable_set('node_style_mode', $form_values['mode']);
243
244 drupal_set_message(t('Configuration saved.'));
245
246 return 'admin/build/node_style';
247 }
248
249 /**
250 * Menu callback: Add a new scheme.
251 */
252 function _node_style_schemes_add($sid = NULL) {
253 $hide_array = _node_style_get_arrays();
254
255 if (isset($sid)) {
256 $scheme = _node_style_get_scheme($sid);
257 if (isset($scheme)) {
258 $form['sid'] = array('#type' => 'value', '#value' => $sid);
259 }
260 }
261
262 $form['name'] = array(
263 '#type' => 'textfield',
264 '#title' => t('Scheme name'),
265 '#description' => t('A name to identify this scheme in a node form.'),
266 '#default_value' => $scheme['name'],
267 '#required' => TRUE
268 );
269 $form['display'] = array(
270 '#type' => 'fieldset',
271 '#title' => t('Display settings'),
272 '#tree' => TRUE,
273 '#collapsible' => TRUE,
274 '#collapsed' => FALSE
275 );
276 foreach ($hide_array as $hook => $values) {
277 $form['display'][$hook] = array(
278 '#type' => 'checkboxes',
279 '#title' => t('Hide the following %hook elements', array('%hook' => $hook)),
280 '#options' => $hide_array[$hook],
281 '#default_value' => isset($scheme['variables']['display'][$hook]) ? $scheme['variables']['display'][$hook] : array(),
282 );
283 }
284
285 $themes = list_themes();
286 $options = array();
287 foreach ($themes as $id => $theme) {
288 // There is a possibility of discrepancies here if a selected theme is
289 // disabled in the theme admin pages after being enabled here.
290 if ($theme->status == 1) {
291 $options[$id] = $theme->name;
292 }
293 }
294 asort($options);
295 $options = array('default' => t('default')) + $options;
296
297 $form['misc'] = array(
298 '#type' => 'fieldset',
299 '#title' => t('Miscellaneous settings'),
300 '#tree' => TRUE,
301 '#collapsible' => TRUE,
302 '#collapsed' => FALSE
303 );
304 $form['misc']['theme'] = array(
305 '#type' => 'select',
306 '#title' => t('Select a theme to display for this node'),
307 '#description' => t('Select default to use the default theme.'),
308 '#options' => $options,
309 '#default_value' => $scheme['variables']['misc']['theme']
310 );
311 $form['misc']['head'] = array(
312 '#type' => 'textarea',
313 '#title' => t('Insert mark-up into &lt;head&gt;&lt;head/&gt;'),
314 '#description' => t('e.g. Add a stylesheet: &lt;style type="text/css" media="all"&gt;@import "/misc/drupal.css";&lt;/style&gt; or a Javascript file etc.'),
315 '#default_value' => $scheme['variables']['misc']['head'],
316 '#rows' => 6,
317 '#resizable' => TRUE
318 );
319
320 $form['submit'] = array('#type' => 'submit', '#value' => 'Save scheme');
321 $form['#base'] = 'node_style_scheme';
322
323 return $form;
324 }
325
326 /**
327 * Menu callback: Edit a scheme.
328 */
329 function _node_style_schemes_edit($sid = NULL) {
330 if (isset($sid)) {
331 return _node_style_schemes_add($sid);
332 }
333 else {
334 drupal_set_message(t('Scheme not found.'), 'error');
335 drupal_goto('admin/build/node_style');
336 }
337 }
338
339 /**
340 * Process a scheme add / edit form submission.
341 */
342 function node_style_scheme_submit($form_id, $form_values) {
343 $scheme = array('display' => array(), 'misc' => array());
344
345 $scheme['display']['node'] = array_filter($form_values['display']['node']);
346 $scheme['display']['node'] = array_keys($scheme['display']['node']);
347 $scheme['display']['page'] = array_filter($form_values['display']['page']);
348 $scheme['display']['page'] = array_keys($scheme['display']['page']);
349 $scheme['misc']['theme'] = $form_values['misc']['theme'];
350 $scheme['misc']['head'] = $form_values['misc']['head'];
351
352 if (isset($form_values['sid'])) {
353 _node_style_update_scheme($form_values['sid'], $form_values['name'], $scheme);
354 drupal_set_message(t('Style scheme %name updated successfully.', array('%name' => $name)));
355 }
356 else {
357 _node_style_add_scheme($form_values['name'], $scheme);
358 drupal_set_message(t('Style scheme %name added successfully.', array('%name' => $name)));
359 }
360
361 cache_clear_all();
362
363 return 'admin/build/node_style';
364 }
365
366 /**
367 * Menu callback: Delete a scheme.
368 */
369 function _node_style_schemes_delete($sid = NULL) {
370 if (is_numeric($sid)) {
371 $scheme = _node_style_get_scheme($sid);
372 $form['sid'] = array('#type' => 'value', '#value' => $sid);
373 $form['scheme_name'] = array('#type' => 'value', '#value' => $scheme['name']);
374
375 return confirm_form($form,
376 t('Are you sure you want to delete the scheme %title?', array('%title' => $scheme['name'])),
377 'admin/build/node_style/',
378 t('This action cannot be undone.'),
379 t('Delete'),
380 t('Cancel')
381 );
382 }
383 else {
384 drupal_set_message(t('Scheme not found'), 'error');
385 }
386 }
387
388 /**
389 * Process a scheme deletion form submission.
390 */
391 function _node_style_schemes_delete_submit($form_id, $form_values) {
392 db_query("DELETE FROM {node_style_maps} WHERE sid = %d", $form_values['sid']);
393 db_query("DELETE FROM {node_style_schemes} WHERE sid = %d", $form_values['sid']);
394
395 drupal_set_message(t('The scheme %title has been deleted.', array('%title' => $form_values['scheme_name'])));
396 watchdog('content', t('The scheme %title has been deleted.', array('%title' => $form_values['scheme_name'])));
397
398 cache_clear_all();
399
400 return 'admin/build/node_style';
401 }
402
403 /**
404 * Returns a PHPTemplate variables array based on $hook. Called from node_style.inc.
405 *
406 * @see _phptemplate_variables
407 */
408 function node_style_return_vars($hook, $variables) {
409 global $node_style;
410
411 if (!empty($node_style)) {
412 $scheme = $node_style['variables'];
413 if (isset($scheme['display'][$hook])) {
414 foreach ($scheme['display'][$hook] as $var) {
415 // Only affect existing variables.
416 if (isset($variables[$var])) {
417 // Set to null rather than '' or array() to ensure that no data type
418 // mismatches occur.
419 $variables[$var] = null;
420 }
421 }
422 }
423 if ($hook == 'page') {
424 // Rather than appending to "head", append to styles, thereby allowing for
425 // overrides of existing stylesheets.
426 $variables['styles'] .= trim($scheme['misc']['head']);
427 _node_style_set_custom_theme($node_style);
428 }
429 }
430
431 return $variables;
432 }
433
434 /**
435 * Insert node_style settings into the database.
436 */
437 function _node_style_add_node_style($nid, $sid) {
438 db_query("INSERT INTO {node_style_maps} (nid, sid) VALUES (%d, %d)", $nid, $sid);
439 }
440
441 /**
442 * Delete node_style settings associated with a node.
443 */
444 function _node_style_delete_node_style($nid) {
445 db_query('DELETE FROM {node_style_maps} WHERE nid = %d', $nid);
446 }
447
448 /**
449 * Retrieve any node_style settings for a node from the database.
450 */
451 function _node_style_get_node_style($nid) {
452 static $node_style = NULL;
453
454 if (!isset($node_style)) {
455 $node_style = array();
456
457 $result = db_query("SELECT m.sid, s.variables FROM {node_style_maps} m LEFT JOIN {node_style_schemes} s USING (sid) WHERE m.nid = %d", $nid);
458 if ($node_style = db_fetch_array($result)) {
459 $node_style['variables'] = unserialize($node_style['variables']);
460 }
461 }
462
463 return $node_style;
464 }
465
466 /**
467 * Insert a scheme into the database.
468 */
469 function _node_style_add_scheme($name, $scheme) {
470 db_query("INSERT INTO {node_style_schemes} (name, variables) VALUES ('%s', '%s')", $name, serialize($scheme));
471 }
472
473 /**
474 * Update an existing scheme.
475 */
476 function _node_style_update_scheme($sid, $name, $scheme) {
477 db_query("UPDATE {node_style_schemes} SET name = '%s', variables = '%s' WHERE sid = %d", $name, serialize($scheme), $sid);
478 }
479
480 /**
481 * Retrieve a scheme.
482 */
483 function _node_style_get_scheme($sid) {
484 $result = db_query('SELECT name, variables FROM {node_style_schemes} WHERE sid = %d', $sid);
485 if ($scheme = db_fetch_array($result)) {
486 $scheme['variables'] = unserialize($scheme['variables']);
487 }
488
489 return $scheme;
490 }
491
492 /**
493 * Retrieve all schemes.
494 */
495 function _node_style_get_schemes() {
496 $result = db_query('SELECT sid, name FROM {node_style_schemes} ORDER BY name');
497 $schemes = array();
498 while ($scheme = db_fetch_array($result)) {
499 // The scheme name is translated only for the node form.
500 $schemes[$scheme['sid']] = check_plain($scheme['name']);
501 }
502
503 return $schemes;
504 }
505
506 /**
507 * Return PHPTemplate variables array.
508 */
509 function _node_style_get_arrays() {
510 $hide_array = array();
511 $hide_array['node'] = array(
512 'links' => t('Node links'),
513 'terms' => t('Taxonomy terms'),
514 'picture' => t('User picture'),
515 'submitted' => t('Submission information')
516 );
517 $hide_array['page'] = array(
518 'breadcrumb' => t('Breadcrumb'),
519 'closure' => t('Closure message'),
520 'footer_message' => t('Footer message'),
521 'primary_links' => t('Links: primary'),
522 'secondary_links' => t('Links: secondary'),
523 'logo' => t('Logo'),
524 'mission' => t('Mission'),
525 'search_box' => t('Search box'),
526 'sidebar_left' => t('Sidebar: left'),
527 'sidebar_right' => t('Sidebar: right'),
528 'site_name' => t('Site name'),
529 'site_slogan' => t('Site slogan'),
530 'title' => t('Title (content)'),
531 'head_title' => t('Title (title bar)')
532 );
533
534 return $hide_array;
535 }
536
537 /**
538 * Check the node style and override the theme if necessary.
539 */
540 function _node_style_set_custom_theme($node_style) {
541 global $custom_theme;
542
543 if (isset($node_style['variables']['misc']['theme']) && $node_style['variables']['misc']['theme'] != 'default') {
544 // The current theme is overridden regardless of whether the theme is active
545 // or not. This is a matter for core to deal with, not this module.
546 $custom_theme = $node_style['variables']['misc']['theme'];
547 }
548 }

  ViewVC Help
Powered by ViewVC 1.1.2