Többször előfordult már velem, hogy egy-egy node-ban pici speciális formázást szerettem volna használni. Ekkor az ember FULLHTML-re vált és betolja a kis html tagját. Ez nem túl kellemes, hisz így fel kell adnunk a kényelmes sortörés átalakítást és az URL beillesztést. Az egyéb kényelmi szűrőimről nem is beszélve. A másik amivel mostanában találkoztam, hogy egy webes űrlapot kellett készítenem. Ezt a webform modullal könnyedén megoldottam, de egy icipici viselkedésbeli változtatásra szükségem lett volna. Ez pedig az, hogy egy beviteli mezőt csak akkor kelljen kitölteni, amikor az előtte levő választó listában az “Egyéb” értéket választották. Ehhez egy icipici JavaScriptet kellett volna beszúrnom. A két problémát összefogva találtam ki, hogy írok egy icipici modulocskát ami megoldja ezeket. Mivel most olvasom, hogy más is hasonló problémákkal küzd úgy gondoltam érdemes lenne megosztani a megoldásom.

Node Look and Behavior nevet kapta vagyis Tartalom Kinézet és Viselkedés. Röviden NLB. Készítettem egy szösszenetnyi .info fájlt.

name = Node's look and behavior
core = 6.x

A tartalomhoz rendelt CSS-t és JavaScriptet az adatbázisban fogjuk tárolni. Ezért kellett egy .install fájl is.

<?php
// $Id$

function nlb_install() {
  drupal_install_schema('nlb');
}

function nlb_uninstall() {
  drupal_uninstall_schema('nlb');
}

function nlb_schema() {
  $schema = array();
  $schema['nlb'] = array(
    'description' => 'Store nlb data',
    'fields' => array(
      'nid' => array(
        'description' => 'The node identifier.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0),
      'vid' => array(
        'description' => 'The version identifier.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0),
      'javascript' => array(
        'type' => 'text',
        'not null' => TRUE,
        'default' => '',
        'description' => "Javascript",
      ),
      'css' => array(
        'type' => 'text',
        'not null' => TRUE,
        'default' => '',
        'description' => 'CSS',
      ),
    ),
    'indexes' => array(
      'nid' => array('nid'),
    ),
    'primary key' => array('vid'),
  );
  return $schema;
}
?>

Készítettem egy icipici .module fájlt is. Két hurkot valósítottam meg. A hook_form_alter() hozzáadja a szükséges mezőket a node beviteli űrlapokhoz. A hook_node_api() pedig az adatok kezelésével foglalkozik. Létrehoz, beolvas, változtat, töröl(CRUD) és megjelenít(view).

<?php

function nlb_form_alter(&$form, $form_state, $form_id) {
  if (isset($form['#node'])) {
    $form['nlb'] = array(
      '#type' => 'fieldset',
      '#title' => t('Look and behavior'),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#tree' => TRUE,
    );
    $form['nlb']['javascript'] = array(
      '#type' => 'textarea',
      '#title' => t('Javascript'),
      '#default_value' => isset($form['#node']->nlb['javascript'])?$form['#node']->nlb['javascript']:'',
      '#description' => check_plain(t('Do not use  tag.')),
    );
    $form['nlb']['css'] = array(
      '#type' => 'textarea',
      '#title' => t('CSS'),
      '#default_value' => isset($form['#node']->nlb['css'])?$form['#node']->nlb['css']:'',
      '#description' => check_plain(t('Do not use  tag.')),
    );
  }
}

function nlb_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  switch ($op) {
    case 'delete':
      db_query("DELETE FROM {nlb} WHERE nid=%d", $node->nid);
    break;
    case 'delete revision':
      db_query("DELETE FROM {nlb} WHERE vid=%d", $node->vid);
    break;
    case 'update':
      db_query("DELETE FROM {nlb} WHERE nid=%d and vid=%d", $node->nid, $node->vid);
    case 'insert' :
      db_query("INSERT INTO {nlb} (nid, vid, javascript, css) VALUES (%d, %d, '%s', '%s')",
                $node->nid, $node->vid, $node->nlb['javascript'], $node->nlb['css']);
    break;
    case 'load':
      $node->nlb = db_fetch_array(db_query("SELECT javascript, css FROM {nlb} WHERE nid=%d and vid=%d", $node->nid, $node->vid));
    break;
    case 'view':
      if (isset($node->nlb['javascript']) && !empty($node->nlb['javascript'])) {
        drupal_add_js($node->nlb['javascript'], 'inline');
      }
      if (isset($node->nlb['css']) && !empty($node->nlb['css'])) {
          drupal_set_html_head(''. $node->nlb['css'] .'');
      }
    break;
  }
}
?>

A használata rém egyszerű. A CSS kódról nem kívánok hosszasan értekezni, de álljon itt egy kis js ami lehetővé teszi egy beviteli mező engedélyezését/tíltását egy legördülő lista választásától függően. A szövegmező azonosítója legyen textarea a legördülő listáé pedig select. A node azonosítója legyen 12 az Egyéb értéke pedig legyen 0.

Drupal.behaviors.node12 = function(){
  if ($('#select').val() != 0) {
    $('#textarea').attr('readonly','readonly')
  }
  $('#select').change(function(){
    if($(this).val() == 0) {
      $('#textarea').attr('readonly','')
    }
    else {
      $('#textarea').attr('readonly','readonly')
    }
  })
}

Maga a kód talán érthető és a csatolt modul is használható. Tudom egy pici kódszépítés és megjegyzésekkel való bővítés ráférne, valamint az a három icipici függvény is hiányzik belőle amivel be lehetne állítani és biztosnságossá tenni. A korrekt README.txt fájlról nem is beszélve.

FIGYELEM! Ahol tartalom létrehozása jog van nem megbízható felhasználóknak XSS támadásra ad lehetőséget. Csak saját felelőségre használd!

Egy felhasználós rendszernél azonban szerintem egész jól használható ez a kis szösszenet.