Návod pro Drupal: nový modul v pěti minutách

Drupal je skvělý nejenom jako připravený redakční systém, ale také jako platforma pro další vývoj. Pomocí připravených funkcí Drupal API snadno vytvoříte nové moduly, třeba i s AHAH funkcionalitou. Jeden takový zkusíme v tomto článku.

Pro redakční systém Drupal existuje množství doplňkových modulů od vývojářů, kteří Drupal používají pro své projekty a nevadí jim podělit se o výsledky své práce s ostatními. Díky tomu je dnes Drupal mezi trojkou nejoblíbenějších systémů pro správu obsahu na webu.

Čas od času však narazíte na problém, který není možné řešit žádným z již existujících doplňkových modulů pro Drupal. Budete muset napsat svůj vlastní. Na drupal.org najdete online dokumentaci, která vás krok za krokem provede tvorbou nových modulů a seznámí vás s Drupal API. Pokud čtete raději v češtině, snad vám udělá radost následující návod pro vytvoření jednoduchého modulu pro Drupal, který navíc využije podporu AJAXu.

Nový modul pro Drupal - odstraňovač diakritiky

Výsledkem modulu vytvořeného v tomto návodu bude modulem generovaná stránka v Drupalu, která zobrazí formulář pro zadání nějakého textu. Po klepnutí na tlačítko pod formulářovým polem pak dojde k zobrazení zadaného textu bez diakritiky. Převod nebude vyžadovat opětovné načtení celé stránky, vše proběhne AJAXem, resp. pomocí AHAH - Asychronous HTML and http. Abychom nemuseli programovat celý proces pro odstranění diakritiky, využijeme služeb již existujícího modulu Transliteration, který tuto činnost provádí. Náš modul pouze poskytne uživatelské rozhraní.

Základní struktura modulu pro Drupal

Nový modul nazveme Diarem (zkratka pro Diacritic Remover). V sites/all/modules tedy vytvoříte složku diarem a v ní dva soubory diarem.info a diarem.module. Všimněte si zachování stejných názvů. V souboru diarem.info uvedete základní informace o modulu, podle kterých bude Drupal vědět, že je modul přítomen. Soubor diarem.module bude obsahovat vlastní kód modulu.

Struktura soubor diarem.info bude následující:

name = Diarem
description = Provides a form and removes diacritics from the given text.
core = 6.x
dependencies[] = transliteration
package = Polzer

V prvé řadě musíte Drupalu sdělit, jak se nový modul bude jmenovat a uvést nějaký popisek. Tyto informace se zobrazí v administraci modulů v Drupalu. Nezbytné je také uvedení verze jádra Drupalu, pro kterou je tento modul určen. Následující dva řádky jsou nepovinné. Pomocí dependencies určujete, na kterém modulu je ten váš závislý, pomocí package zase můžete svůj modul zařadit v administraci do nějaké sekce. Podrobněji viz Writing .info files (Drupal 6.x).

Vytvoření záznamu v menu a adresy stránky

Jakmile je soubor *.info vytvořen, můžete se pustit do samotného kódování v souboru *.module. Na úplný začátek zadejte <?php. Uzavírací znaky nejsou třeba, informaci o tom, že následuje skript v PHP, však nezapomeňte uvést, jinak modul nebude fungovat. Nyní můžete jen pro zajímavost kouknout do administrace modulů. U Transliteration se dozvíte, že je vyžadován modulem Diarem, u Diarem zase uvidíte informaci o tom, že je závislý na Transliteration. Zatím však nový modul nezapínejte.

Nyní v diarem.module vytvoříte funkci, která určuje adresy stránek generovaných novým modulem pro Drupal, a zároveň automaticky vkládá záznam do menu Navigace:

{syntaxhighlighter brush:php} function diarem_menu() { $items = array(); $items['diarem'] = array( 'title' => t('Diacritics remover'), 'description' => t('This will remove diacritics from the given text input'), 'page callback' => 'diarem_form', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); return $items; } {/syntaxhighlighter}

Všechny funkce modulu by měly začínat jeho jménem, aby se předešlo kolizím, a aby vše bez problémů fungovalo. Funkce diarem_menu() zajišťuje vygenerování záznamu v navigační nabídce. Všimněte si, že vše probíhá přes pole $items. Toto pole může mít více položek, podle toho, kolik stránek nebo odkazů v menu chcete modulem generovat. V našem případě bude modul generovat pouze stránku na adrese diarem, což je dáno zápisem $items['diarem']. V něm pak následuje upřesnění - nadpis vygenerované stránky, popisek pro záznam v menu, název funkce, která zajistí zobrazení obsahu stránky, uvedení přístupových oprávnění a typ položky v menu.

Přístupová oprávnění nám pomohou určit, kteří uživatelé budou moci danou stránku/adresu zobrazit. Názvy oprávnění získáte ze stránky Uživatelé> Oprávnění, odpovídají popiskům v anglické verzi. Převaděč diakritiky v Drupalu zpřístupníme všem uživatelům, kteří mohou zobrazovat obsah.

Zajímavá je ještě položka type. Pokud byste chtěli modulem vytvořit nějakou stránku (míněno adresu, nikoli stránku jako obsahový uzel) v Drupalu, ale nedávat přitom záznam do menu, pak MENU_NORMAL_ITEM vyměňte za MENU_CALLBACK.

Všechny řetězce v modulu by měly být psány anglicky a uzavřeny ve funkci t(), která zajistí, že je bude možné přeložit v překladovém rozhraní Drupalu. Pro jednoduchost budu ve zbytku kódu používat v této funkci rovnou češtinu.

Vygenerování stránky na zadané adrese

Ve výše uvedené funkci jsme vytvořili záznam o tom, že obsah stránky na adrese diarem vygeneruje funkce nazvaná diarem_form(). Proto ji nyní vytvoříme:

{syntaxhighlighter brush:php} function diarem_form(){ $pagecontent = '

Zadejte text do následujícího formuláře a klepněte na tlačítko pro odstranění diakritiky.

'; return $pagecontent; } {/syntaxhighlighter}

Výstupem této funkce je textový řetězec s HTML kódem, který Drupal zobrazí v těle vygenerované stránky (čili v regionu $content) na adrese, jež je uvedena ve funkci region_menu(). Nyní můžete modul zapnout a podívat se na adresu vaseurl.tld/diarem. Uvidíte nadpis stránky odpovídající tomu, co je uvedeno ve funkci diarem_menu() a zatím jen jeden řádek textu bez formuláře, který jsme vytvořili ve funkci diarem_form().

Vygenerování formuláře v Drupalu

Výstup funkce diarem_form() nyní doplníme o vygenerování HTML formuláře. Nebudeme jej však vypisovat ručně pomocí HTML značek, ale necháme jej vytvořit Drupal. Funkci diarem_form() tedy upravte tak, že k úvodnímu textu doplníte vygenerování formuláře. Nezapomeňte, že rovnítko z prvního řádku se mění na zápis pro přidání do řetězce, tedy na tečku s rovnítkem.

{syntaxhighlighter brush:php} function diarem_form(){ $pagecontent = '

Zadejte text do následujícího formuláře a klepněte na tlačítko pro odstranění diakritiky.

'; $pagecontent .= drupal_get_form('diarem_text_form'); return $pagecontent; } {/syntaxhighlighter}

Funkce drupal_get_form() vyžaduje jako parametr řetězec s názvem funkce, která poskytuje informaci o tom, jak má formulář vypadat. Z výše uvedeného kódu tedy vyplývá, že si musíme vytvořit funkci diarem_text_form(). Protože požadujeme vstupní pole pro zadání textu, tlačítko pro zpracování formuláře a AHAH funkcionalitu, bude obsah funkce následující:

{syntaxhighlighter brush:php} function diarem_text_form(){ $form = array(); $form['diarem_form_input'] = array( '#type' => 'textarea', '#title' => t('Vstupní text'), '#default_value' => '', '#required' => TRUE ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Převést'), '#ahah' => array( 'wrapper' => 'diarem_form_output', 'method' => 'replace', 'path' => 'diarem/transliterate', 'event' => 'click', 'effect' => 'fade', ), ); $form['diarem_form_result'] = array( '#type' => 'markup', '#value' => '

Převedený text

 

', ); return $form; } {/syntaxhighlighter}

Opět se všimněte, že výstupem funkce poskytující formulář je pole. Toto pole obsahuje tolik záznamů, kolik je položek ve formuláři. Každá položka musí být nějak pojmenována, například hned první se jmenuje diarem_form_input. Drupal na základě tohoto pojmenování generuje příslušné části HTML kódu formuláře. U každé položky je nutné uvést typ a její nadpis. Seznam dostupných typů formulářových polí je ve Forms API Reference. Podle uvážení můžeme uvést výchozí hodnotu a dále určíme, zda je danou položku formuláře potřeby vyplnit nebo ne. Každý typ formulářových polí reaguje na jiné vlastnosti.

Náš modul tedy nejprve vytvoří vstupní textové pole, pod něj umístíme tlačítko pro zpracování formuláře. Jako typ musí tedy být uvedeno submit. Abychom zajistili, že po odeslání nebude stránka znovu načítána, doplníme ještě zápis pro #ahah. Drupal pak zpracování formuláře provede asynchronně. V AHAH je důležitá položka wrapper. V ní říkáte, do jakého HTML elementu s příslušným ID bude výstup formuláře zapsán. V našem případě bude AHAH hledat element s ID diarem_form_output a jeho stávající text prostě nahradí.

Poslední položkou formuláře je jednoduchý HTML výstup daný typem markup. Do hodnoty tohoto formulářového prvku prostě uvedete řetězec s běžným HTML. V našem případě poslouží k vypsání DIVu s ID, do kterého bude zpracování formuláře generovat svůj výstup.

Zpracování formuláře v Drupalu

Nyní vše uložte a opět si prohlédněte na adrese vaseurl.tld/diarem aktuální podobu výstupu modulu. Blížíme se do finále a zbývá napsat funkci, která text z formuláře zpracuje. Kde se její výstup zobrazí, to jsme již vyřešili při generování formuláře.

Nejjednodušším způsobem, jak zajistit zpracování formuláře, je vytvoření funkce se stejným názvem jako je základní formulářová funkce (tj. v našem případě diarem_text_form()) a doplnit do jejího názvu _submit. Funkce pro zpracování formuláře v našem modulu by tedy mohla mít následující strukturu:

{syntaxhighlighter brush:php} function diarem_text_form_submit($form, &$form_state){ //nějaký kód } {/syntaxhighlighter}

Obsah formulářových polí by byl přístupný skrze pole $form_state['values']. Protože však zpracováváme AHAH, bude následující postup trošku odlišný. U definice AHAH jsme určili, že zpracování zajistí adresa diarem/transliterate. Do funkce diarem_menu() tedy musíme přidat volání, které tuto adresu vytvoří a zároveň určí funkci, která bude tuto adresu generovat:

    $items['diarem/transliterate'] = array(
        'page callback' => 'diarem_transliterate',
        'access arguments' => array('access content'),
        'type' => MENU_CALLBACK,
    ); 

Z výše uvedeného tedy vyplývá, že jsme funkci pro zpracování AHAH volání z formuláře pojmenovali diarem_transliterate. Nyní ji vytvoříme a data nějakým způsobem zpracujeme.

{syntaxhighlighter brush:php} function diarem_transliterate(){ $form_state = array('values' => $_POST); $output = filter_xss($form_state['values']['diarem_form_input']); $output = transliteration_get($output); print drupal_to_js(array('status' => TRUE, 'data' => $output)); } {/syntaxhighlighter}

V první řadě vložíme data z proměnné $_POST, tedy data z formuláře odeslaného přes AHAH do $form_state['values'], abychom s nimi mohli pracovat stejným způsobem jako při zpracování běžného formuláře v Drupalu. Není to nutné, ale doporučuji, budete tak stále pracovat stejným stylem.

Poté do proměnné $output přiřadíme obsah textového políčka z formuláře. Všimněte si, že je snadno dostupný přes $form_state['values'], ke kterému přidáte název formulářového prvku definovaný výše v kódu. Funkce filter_xss() se postará o odstranění případného škodlivého kódu.

Poté využijeme funkci z modulu Transliteration, která odstraňuje diakritiku ze zadaného řetězce. Nakonec upravený obsah proměnné $output vypíšeme. Zajistí to speciální volání v posledním řádku funkce, kterým docílíme toho, že výstup bude zobrazen tam, kde jsme si to definovali při konstrukci AHAH volání formuláře.

To je vše. Výsledek si můžete prohlédnout třeba na adrese www.maxiorel.cz/diarem, ovšem nezaručuji, že modul nechám zapnutý navždy. Kompletní finální zdrojové kódy modulu z příkladu si můžete stáhnout odkazem níže. Pokud si chcete o tvorbě modulů v Drupalu přečíst v češtině něco více, doporučuji mou nejnovější knihu 333 tipů a triků pro Drupal.

Pokud při testování modulu v různých částech jeho tvorby narazíte na problém s nedostupností nějaké adresy generované modulem (nebo na chybovou hlášku JavaScriptu při zpracování formuláře), zkuste resetovat cache pro menu, a to nejlépe pomocí modulu Administration menu, který na to má funkci umístěnou hned na začátku pod ikonkou webu.

Příloha Velikost
diarem.zip 1.12 KB
Tagy

Buďme ve spojení, přihlaste se k newsletteru

Odesláním formuláře souhlasíte s podmínkami zpracováním osobních údajů. 
Více informací v Ochrana osobních údajů.

Autor článku: Jan Polzer

Tvůrce webů z Brna se specializací na Drupal, WordPress a Symfony. Acquia Certified Developer & Site Builder. Autor několika knih o Drupalu.
Web Development Director v Lesensky.cz. Ve volných chvílích podnikám výlety na souši i po vodě. Více se dozvíte na polzer.cz a mém LinkedIn profilu.

Komentáře k článku

návštěvník

tak mne to nefunguje,

miesto vykreslenia formularu sa zobrazi Array

mam Drupal 7, zeby tam boli nejake zmeny?

pise to toto:

Diacritics remover

Zadejte text do následujícího formuláře a klepněte na tlačítko pro odstranění diakritiky.

Array

Profile picture for user Jan Polzer

Ano, návod je určen pro Drupal 6, je už staršího data. Pokud máte sedmičku, asi Vás zatím odkážu na knížku, na Maxiorlovi zatím návod na tvorbu modulu pro Drupal 7 nemám. (tedy měl jsem pocit, že ano, ale nikde jej nevidím :-) )

Profile picture for user Jan Polzer

Dobrý den, přijde na to, jaká data máte na mysli.

Nějaké nastavení do tabulky variables? Ze systemového formuláře se ukládají samy, případně je můžete uložit funkcí variable_set().

Pořebujete prostě něco na zápis do databáze? Pak koukněte na drupal_write_record().

Potřebujete uložit celý uzel? Pak Vás bude zajímat funkce node_save().

Jinak vřele doporučuji kouknout na příklady, viz modul Examples for Developers.

návštěvník

Jde o to že mám takový jednoduchý modul, v bloku se zobrazuje textové pole (textarea) a tlačítko na uložení, text se ukládá do samostatné tabulky a zároveň se vypisuje pod tím textovým polem, v podstatě je to takový jednoduchý chat. Všechno funguje ale potřeboval bych aby se to ukládalo tak aniž by se pokažné načítala celá stránka.

Profile picture for user Jan Polzer

No tak pak v události obsluhované tím AJAXem použijte k uložení dat drupal_write_record().

Profile picture for user Jan Polzer

Teď v nejbližších dvou týdnech ne, výhledově možná jo, ale asi jen pro Drupal 7.

návštěvník

 

Dobrý den, chtěl bych něco podobného vytvořit v D7 ale jak se píše tady http://drupal.org/node/224333#unrendered tak v sedmičce zobrazuje funkce drupal_get_form() pole místo řetězce a je potřeba použít funkci drupal_render() jestli jsem to správně pochopil. Nevíte jaký je v tomto případě postup. Moc jsem se v tom nezorientoval. Ve Vaší knížce jsem to bohužel nenašel.

 

Předem díky 

 

 

<code>

 

/**

 * Implements hook_menu().

  */

 

function opravy_menu() {

 

  $items['opravy-page-form'] = array(

    'title' => 'Opravy - výpis',

    'description' => 'Popis',

    'page callback' => 'opravy_page_form',

    'access arguments' => array('access content'),

    'type' => MENU_NORMAL_ITEM,  

  );       

 

  return $items;

}

 

function opravy_page_form() {

  $output = "Nějaký text 1.<br />";

  $output .= drupal_get_form('opravy_page_form2');

  $output .= "<br />Nějaký text 2.";

  return $output;

}

 

function opravy_page_form2($form, &$form_state) {

 

  $form = array();

  $form['jmeno'] = array(

    '#type' => 'textfield',

    '#title' => 'Jméno',

    '#description' => 'popis',

    '#required' => FALSE,     

  );  

 

  $form['submit'] = array(

    '#value' => 'Odeslat',

    '#type' => 'submit',

  );

 

  return $form;

}

 

</code>

 

 

 

Přidat komentář

Odesláním komentáře souhlasíte s podmínkami Ochrany osobních údajů

reklama
Moje kniha o CMS Drupal

 

Kniha 333 tipů a triků pro Drupal 9


Více na KnihyPolzer.cz

Sledujte Maxiorla na Facebooku

Maxiorel na Facebooku

Hosting pro Drupal a WordPress

Hledáte český webhosting vhodný nejenom pro redakční systém Drupal? Tak vyzkoušejte Webhosting C4 za 1200 Kč na rok s doménou v ceně, 20 GB prostoru a automatické navyšováním o 2 GB každý rok. Podrobnosti zde.

@maxiorel na Twitteru

Maxiorel na Twitteru