Osobní zkušenosti s bezplatným systémem pro správu webového obsahu Drupal šířeným pod GPL licencí.
Drupal je univerzální systém (CMF – Content Management Framework) pro správu webového obsahu bez konkrétní oblasti zaměření. Jedná se o nástroj umožňující vytvářet vlastní datovou strukturu. Drupal nabízí možnost úplného oddělení obsahové části od vzhledu, což umožňuje jednoduchou změnu výsledného vzhledu.
Drupal si můžete ihned vyzkoušet:
Drupal není jen obyčený CMS – Content Management System. Vzhledem ke své univerzálnosti je vhodný zejména pro zakázkové řešení přesně na míru dle požadavků zákazníka např.:
node/nid
)Novinky:
Tipy:
Patch:
CSS
.toolbar-tray { margin-top: 39px; }
Budoucnost:
Historie:
Předpokladem instalace je funkční lokální server, nebo webhosting (en) s podporou PHP a MySQL (PostgresSQL).
Nejen pro vývojáře webu je vhodné použít virtuální obraz Quickstart pro Virtualbox obsahující:
K rychlé instalaci je možné využít instalační profil nebo distribuci, který provede prvotní nastavení za Vás.
Distribuce – většinou obsahuje vybrané moduly, ukázkový obsah, téma vzhledu a prvotní konfiguraci.
Instalační profil:
/profiles/
. Pokud to instalační profil vyžaduje, nakopírujte na web do příslušných adresářu požadované moduly, témata, lokalizace atd.Vlastní instalační profil je možné si vytvořit ručně nebo např. pomocí modulu Profiler Builder.
Z bezpečnostních důvodů můžete u všech souborů (kořen webu, modules, sites, themes atd.), které mají celý název psán velkými písmeny zakázat pomocí oprávnění k souboru jejich zobrazení přes webový prohlížeč.
Přidáním skriptu Install Drupal from command line using Drush do souboru .bashrc (linux) je možné instalaci Drupalu usnadnit.
Full LAMP & Drupal + Drush installation for Windows, Mac OSX and Linux :)
Nastavení:
$settings['trusted_host_patterns'] = array( '^example\.com$', '^www\.example\.com$', );
Adresa odkazu u souborů ukazuje přímo na místo, kde jsou soubory na serveru umístěny.
Umístění souborů na serveru není možné zjistit přímo z adresy odkazu, protože do adres odkazů na soubor vkládá Drupal automaticky proměnnou system.
Výhody:
Při umístění souborů mimo veřejný prostor webu je většinou nutné požádat poskytovatele webhostingu o posunutí Open_basedir restrikce.
Deny from all
dle nastavení serveru je někdy nutné zakomentovat
#Options None #Options +FollowSymLinks
Order Deny,Allow
Deny from all
Order Deny,Allow
Pokdu jste již na web vložili nějaké soubory (přílohy, obrázky atd.), metodu stahování již neměňte!
Pokud potřebujete změnit umístění adresáře files je třeba upravit i cesty v databázových tabulkách files, node_revisions, users a variable případně využijte modul Site Directory Migrate.
Pozor!
Automatickou kontrolu a import překladů usnadňuje modul Localization update.
Nabízí se dva různé způsoby překladu vícejazyčného obsahu:
Poznámka:
Příloha 6.x obsahuje oficiální překlady jádra sloučené do jediného souboru.
Příloha 7.x obsahuje neoficiální překlady.
Příloha | Velikost |
---|---|
cs-6.x-1.8-2008-Apr-27.zip | 195.78 KB |
cs-drupal-7.x-2014.po_.zip | 436.8 KB |
Některé moduly vyžadují službu cron. Zvolte si proto jednu z následujících možností:
Je spouštěn na základě návštěv uživatelů webu. V admin/config/system/cron (Konfigurace, Cron) je možné nastavit pravidelnost opakování.
Vestavěný cron je vhodné "vypnout" (zrychlí se tak první načtení stránky) a nastavit cron jiným způsobem (webhosting, server atd.).
Další rozšíření:
Většina poskytovatelů nabízí zapnutí služby cron v administraci webhostingu. Po nastavení této služby vypněte spouštění vestavěného cronu v konfiguraci Drupalu.
Použijte modul Drupalu s názvem Poormanscron.
Zaregistrujte se na stránkách www.webcron.org a vytvořte si novou úlohu pro Váš web.
Do souboru /etc/crontab vložte (YOURKEY je možné zjistit v admin/reports/status (Logy, Hlášení stavu)
0,30 * * * * root /usr/bin/wget -O - -q http://example.com/cron.php?cron_key=YOURKEY
Do souboru /etc/crontab vložte
0 * * * * root /usr/bin/wget -O - -q http://example.com/cron.php?cron_key=YOURKEY
Jiný způsob:
Čtení | Zápis | Spouštění | |
---|---|---|---|
Vlastník | Ano | Ano | Ano |
Skupina | Ano | Ne | Ano |
Ostatni | Ano | Ne | Ano |
#!/bin/sh
/usr/bin/wget -O - -q http://example.com/cron.php?cron_key=YOURKEY
Pokud máte přístup k serveru omezen pouze na některé IP adresy, je vhodné příkazu wget nařídit použití lokálního rozhraní:
#!/bin/sh
/usr/bin/wget -O - -q --bind-address=127.0.0.1
http://example.com/cron.php?cron_key=YOURKEY
Čtení | Zápis | Spouštění | |
---|---|---|---|
Vlastník | Ano | Ano | Ano |
Skupina | Ne | Ne | Ne |
Ostatni | Ne | Ne | Ne |
<?php require('http://example.com/cron.php?cron_key=YOURKEY'); ?>
nebo (záleží na webhostingu)
<?php file_get_contents('http://example.com/cron.php?cron_key=YOURKEY'); ?>
Bližší info viz Drupal 7: Running cron from the command line.
#!/usr/bin/env /usr/php53/bin/php <?php // Checks that the arguments are supplied, if not display help information. if (in_array($argv, array('--help')) || $argc != 5) { ?> <?php } else { // Loop through arguments and extract the cron key and drupal root path. for ($i = 1; $i < $argc; $i++) { switch ($argv[$i]) { case '--key': $i++; $key = $argv[$i]; break; case '--root': $i++; $path = $argv[$i]; break; } } chdir($path); // Sets script name $_SERVER['SCRIPT_NAME'] = $argv[0]; // Values as copied from drupal.sh $_SERVER['HTTP_HOST'] = 'default'; $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; $_SERVER['SERVER_SOFTWARE'] = NULL; $_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['QUERY_STRING'] = ''; $_SERVER['HTTP_USER_AGENT'] = 'console'; // Set cron key get variable to use below code with as // little modification as possible. $_GET['cron_key'] = $key; define('DRUPAL_ROOT', $path); // Code below is almost verbatim from cron.php, just the messages for // watchdog have been changed to indicate that the problem originated from // this script. include_once DRUPAL_ROOT . '/includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); if (!isset($_GET['cron_key']) || variable_get('cron_key', 'drupal') != $_GET['cron_key']) { watchdog('cron', "Cron could not run via $argv[0] because an invalid key was used.", array(), WATCHDOG_NOTICE); drupal_access_denied(); } elseif (variable_get('maintenance_mode', 0)) { watchdog('cron', "Cron could not run via $argv[0] because the site is in maintenance mode.", array(), WATCHDOG_NOTICE); drupal_access_denied(); } else { drupal_cron_run(); } }
<?php shell_exec("/usr/php53/bin/php /data/web/hosting.com/sub/website.com/sites/localcron.php --key IFEVzAgi8f93LzbHIH8Tz_teLnU7qF456OZRabpxAMg --root '/data/web/hosting.com/sub/website.com/' ");
V admin/config/media/image-toolkit (Konfigurace, Toolkit pro práci s obrázky) nastavte kvalitu JPEG obrázků na 90 %.
Obecně se kategorizace obsahu nazývá Taxonomie:
Správné navržení struktury webu je velmi obtížné a většinou vzniká postupně.
Filmové novinky:
Zpravodajský web:
Osobní blog:
Sociální média:
Inzeráty:
Doporučení:
V admin/config/content/formats (Konfigurace, Formáty textu) určuje první řádek výchozí filtr:
style
<a> <em> <strong> <cite> <blockquote> <quote> <code> <ul> <ol> <li> <dl> <dt> <dd> <p> <div> <span> <pre> <address> <h2> <h3> <h4> <h5> <h6> <hr> <del> <ins> <sub> <sup>
<img>
Další vstupní formáty je možné vytvořit pomocí modulů:
Pokud používáte modul CKEditor (FCKeditor) je doporučeno pro lepší kontrolu nad konci řádků vypnout u všech vstupních formátů, kde se bude CKEditor používat filtr Převést odřádkování do HTML (tj. <br> a <p>).
Vzhled:
Favicona:
Základní (base) téma vzhledu se stará o běžné úkoly jako je např. rozložní stránky, normalizaci (reset) CSS atd.
Tipy:
Základní témata vzhledu | Přístupnost | Strukturovaná data | Resposive Layout | Respond.js nebo mediaqueries.js (IE8-) |
HTML5 | Sass, Less, Compass | Grid | Normalize (sjednocení vzhledu prvků) | IE conditional |
Detekce schopností prohlížeče |
---|---|---|---|---|---|---|---|---|---|---|
Omega | mediaqueries.js | modul Conditional Stylesheets | HTML5 Shiv | |||||||
AdaptiveTheme | WCAG 2.0 level AA | RDFa | respond.js | Modernizr | ||||||
Zen | respond.js | HTML5 Shiv / Modernizr | ||||||||
Boilerplate | Modernizr | |||||||||
Arctica | ||||||||||
Mothership | ||||||||||
Basic | ||||||||||
Square Grid theme | ||||||||||
Bootstrap | ||||||||||
TB Nucleus (TB Simply, TB Neris, TB Hadelis, TB Mollise, TB Palicico, TB Events, TB Sirate, TB Methys, TB Rave, TB Blog, TB Purity) | ||||||||||
Foundation | ||||||||||
FontFolio | ||||||||||
Professional Theme | ||||||||||
Premium Responsive | ||||||||||
Responsive Business | ||||||||||
Responsive Blog | ||||||||||
Skeleton | ||||||||||
Concept (komerční) | ||||||||||
SooperThemes (komerční) | ||||||||||
LayoutStudio (rychlá změna rozvržení) |
Omega:
AdaptiveTheme:
Zen:
Boilerplate:
Arctica (dokumentace):
Mothership:
SooperThemes:
Tipy na zajímavá témata:
Moduly:
Definice Media Queries:
V nastavení viditelnosti bloku platí logický součin (všechny zvolené podmínky musí platit současně).
Bloky sdružují obsah, který lze na stránce volně přemisťovat:
Tipy:
<?php print file_get_contents("./sites/folder/file.html"); ?>
Node (uzel, jednotka) je obecný objekt reprezentující libovolný obsah. Každý node má jedinečné číslo (nid), verzi (vid), metadata, název (title) a obsah (většinou body).
V admin/structure/types (Struktura, Typy obsahu) je možné nastavit výchozí hodnoty pro jednotlivé typy obsahu:
Pro duplikaci (vytvoření podobného) typu obsahu a jeho nastavení je možné využít modul Node clone.
V admin/config/system/site-information (Konfigurace, Informace o webu) je možné upravit:
Při vytváření obsahu můžete pomocí revizí vytvářet různé verze (ukládat historii) stejného obsahu a sledovat rozdíly mezi jednotlivými verzemi. Revize doporučuji zapnout u všech ručně vytvářených typů obsahů.
Užitečným pomocníkem pro revize je modul Diff.
V admin/config/people/accounts (Konfigurace, Nastavení účtu) je možné nastavit způsob registrace, podpisy, podporu obrázků uživatelů a upozorňovací e-maily:
V admin/structure/types (Struktura, Typy obsahu) je možné zvolit u kterého typu obsahu se bude zobrazovat autor (případně i jeho obrázek). Viz sekce Nastavení zobrazení.
Viz nastavení modulu Path.
Viz nastavení modulu Menu.
Pokud v souboru /sites/default/settings.php odkomentujete níže uvedenou proměnnou, může být uživatel přihlášen při přechodu mezi všemi doménami multisite webu.
$cookie_domain = 'example.com';
U produkčních stránek je doporučeno chybová hlášení zaznamenávat pouze do logů a nezobrazovat je:
V případě, že potřebujete sledovat veškeré odesílané e-maily, nainstalujte si modul Maillog / Mail Developer.
V admin/config/development/performance (Konfigurace, Výkon) je možné nastavit:
Výkon Drupalu je možné zvýšit moduly:
Výkon web serveru je možné zvýšit:
Další informace:
Obecná doporučení:
Mezipaměť (cache) CMS:
Databáze:
Cron:
Server:
Kontrola (včetně doporučení ke zvýšení výkonu):
Doporučení:
Odvozené téma:
base theme: false
base theme: stable
base theme: classy
Externí odkazy v libraries.yml:
example: css: theme: # External URL. 'http://example.com/test.css': type: external # Absolute path. /tmp/test.css: {} # Protocol free. //cdn.com/test.css: {} # Stream wrapper URI. 'public://test.css': {} 'example://test2.css': {}
Tipy:
Při vytváření vlastního vzhledu je vhodné vycházet z některého ze základních témat vzhledu, které jsou uloženy v adresáři themes a z příručky Theme Guide (en). Pro výuku jsou také vhodná témata Zen (nejepší dokumentace) a Basic (jednoduché).
Konfigurační soubor .info (en) obsahuje základní informace a je vyžadován u každého tématu vzhledu. Název souboru musí být shodný s názvem adresáře.
Soubor musí obsahovat klíče:
name = Moje vlastní téma vzhledu core = 6.x
Příklad:
name = Moje vlastní téma vzhledu description = Popis tématu<br /><a href="http://tomas.dankovi.info/">Tomáš Daněk</a> core = 6.x engine = phptemplate stylesheets[all][] = styles/all.css stylesheets[screen, projection][] = styles/layout.css stylesheets[screen, projection][] = styles/decoration.css stylesheets[screen, projection][] = styles/modules.css stylesheets[screen, projection][] = styles/fckeditor.css stylesheets[print][] = styles/print.css
Další regiony viz regions.
Empty square brackets between the "[media]" and "= styleName.css" are always empty and denote that each stylesheet is appended to an array, as in php. Viz Adding style sheets.
Soubor modules/system/html.tpl.php
obsahuje základní HTML strukturu stránky.
Soubor modules/system/page.tpl.php
obsahuje šablonu stránky.
Drupal 5 | Drupal 6 | Poznámky | |
---|---|---|---|
Globální proměnné | |||
$base_path | Adresa instalace Drupalu (vetšinou /) | ||
$css | Pole CSS souborů aktuální stránky | ||
$directory | Adresář aktuálního tématu vzhledu | ||
$is_front | TRUE pokud je aktuální stránka úvodní stránkou (používá se společně s $mission) | ||
$logged_in | TRUE pokud je uživatel přihlášen | ||
$is_admin | TRUE pokud má uživatel oprávnění přístupu k administrační stránce | ||
Metadata stránky | |||
$language | $language->language | Textová reprezentace jazyka (en, cs...) | |
$language->dir | Směr textu (ltr, rtl) | ||
$head_title | Modifikovaná verze názvu stránky pro použití v elementu <title> | ||
$head | Metadata, klíčová slova atd. | ||
$styles | Připojení všech CSS stylů stránky (moduly, téma vzhledu atd.) | ||
$scripts | Načtení JavaScript souborů a nastavení stránky | ||
|
$body_classes | Aktuální CSS třídy stránky: front / not-front, logged-in / not-logged-in, page-... (node, admin, user...), node-type-... (page, story...), two-sidebars / one-sidebar sidebar-left / one-sidebar sidebar-right / no-sidebars | |
Identita stránky | |||
$base_path | $front_page | Adresa úvodní stránky | |
$logo | Cesta k logu webu | ||
$site_name | Název webu (zobrazení je možné povolit / zakázat v nastavení tématu vzhledu) | ||
$site_slogan | Slogan webu (zobrazení je možné povolit / zakázat v nastavení tématu vzhledu) | ||
$mission | Poslání webu (zobrazení je možné povolit / zakázat v nastavení tématu vzhledu) | ||
Navigace | |||
$search_box | Vyhledávací formulář (zobrazení je možné povolit / zakázat v nastavení tématu vzhledu) | ||
$primary_links | Primární odkazy navigace (pokud jsou nastaveny) | ||
$secondary_links | Sekundární odkazy navigace (pokud jsou nastaveny) | ||
$sidebar_left | $left | Levý postranní pruh | |
$sidebar_right | $right | Pravý postranní pruh | |
Obsah stránky | |||
$header | Identifikace bloku hlavičky | ||
$breadcrumb | "Drobečková" navigace aktuální stránky | ||
$tabs | Záložky s možnostmi aktuální stránky (např. Zobrazit, Upravit...) | ||
$tabs2 | |||
$title | Název aktuální stránky | ||
|
$show_messages | ||
$messages | Stav a chybová hlášení (zvýrazněte pomocí CSS) | ||
$help | Dynamický text nápovědy (většinou pro stránky administrace) | ||
$content | Hlavní obsah aktuální stránky | ||
$feed_icons | Řetězec všech ikonek aktuální stránky (např. Syndikovaný obsah RSS) | ||
Patička | |||
$footer_message | Zápatí webu definované v administraci stránek (Informace o webu) | ||
|
$footer | Oblast zápatí webu | |
Uzavírací data | |||
$closure | Závěrečná uzavírací značka pro všechny moduly, které mění stránku (uvádějte až za veškerým dynamickým obsahem) |
Poznámka:
Pomocí snippetů můžete např. zobrazit uvítání uživatele, nebo upozornit na to, že uživatel ještě není registrován.
Šablona template.php (en) umožňuje předefinovat výchozí a vytvářet vlastních funkce.
Odpovídající funkce je možné vyhledat na stránkce Default theme implementations (en).
Výraz "template" nahraďte za název tématu.
<?php function template_preprocess_page(&$variables) { //If front page remove title and breadcrumb if (drupal_is_front_page()) { $variables['breadcrumb'] = ''; $variables['title'] = ''; } } ?>
Téma vzheldu může nahradit CSS soubory definované jádrem a moduly přidáním stylopisu stejného jména a použitím funkce drupal_add_css(). Toto umožňuje tématům potlačit veškeré CSS soubory pokud je to nutné.
Například pokud chcete styl modules/system/system-menus.css definovaný jádrem nahradit (potlačit pro určitá média) vlastním:
<?php drupal_add_css(path_to_theme() .'/styles/system-menus.css', 'theme', 'screen, projection', TRUE); ?>
Výše uvedený příklad se načte pouze pro dané téma, tj. nenačte se pro případná podtémata. Pokud potřebujete používat přepis stylu i v podtématech přidejte jej přímo do .info souboru.
/** * Used to remove certain elements from the $head output within html.tpl.php * * @see http://api.drupal.org/api/drupal/modules--system--system.api.php/functio... * @param array $head_elements */ function YOUR_THEME_NAME_html_head_alter(&$head_elements) { $remove = array( 'system_meta_generator', 'metatag_canonical', 'metatag_shortlink' ); foreach ($remove as $key) { if (isset($head_elements[$key])) { unset($head_elements[$key]); } } // Use this loop to find out which keys are available. /* -- Delete this line to execute this loop echo '<pre>'; foreach ($head_elements as $key => $element) { echo $key ."\n"; } echo '</pre>'; // */ }
Pro přidání aktuální uživatelské role a cesty (verze A) do pole $body_classes stačí do souboru template.php v používaném tématu vzhledu vložit níže uvedený snippet a změňte MYTHEMENAME na aktuální název tématu vzhledu:
Verze A
/** * Add current user's role and path to $body_classes shown in <body> */ function MYTHEMENAME_preprocess_html(&$vars) { //$body_classes = array($vars['classes_array']); // normal theme $body_classes = array($vars['attributes_array']['class']); // omega theme if ($vars['user']) { foreach($vars['user']->roles as $key => $role) { $role_class = 'role-' . str_replace(' ', '-', $role); //$vars['classes_array'][] = $role_class; // normal theme $vars['attributes_array']['class'][] = $role_class; // omega theme } } $path = drupal_get_path_alias($_GET['q']); $aliases = explode('/', $path); foreach($aliases as $alias) { //$vars['classes_array'][] = drupal_clean_css_identifier($alias); // normal theme $vars['attributes_array']['class'][] = drupal_clean_css_identifier($alias); // omega theme } }
Verze B
/** * Add current user's role to $body_classes shown in <body> */ function MYTHEMENAME_preprocess_page(&$vars) { if ($vars['user']) { foreach($vars['user']->roles as $key => $role){ $vars['class'][] = 'role-' . drupal_html_class($role); } } }
/** * Add current user's role to $body_classes shown in <body> */ function MYTHEMENAME_preprocess_page(&$vars, $hook) { $body_classes = array($vars['body_classes']); if ($vars['user']) { foreach($vars['user']->roles as $key => $role){ $role_class = 'role-' . str_replace(' ', '-', $role); $body_classes[] = $role_class; } } $vars['body_classes'] = implode(' ', $body_classes); // Concatenate with spaces }
Všechny funkce začínající slovem template_ nebo theme_ (např. theme_username) vytvářejí HTML výstup a je možné je upravit pomocí souboru template.php.
var_dump($variables);
kpr($variables);
Přesměrování uživatele na stránku Dashboard ihned po přihlášení:
/** * Redirect user to a specific page after they login */ function MYTHEMENAME_user_login(&$edit, $account) { $edit['redirect'] = 'admin/dashboard'; }
/** * Redirect user to a specific page after they login if they belong to a certain role */ function MYTHEMENAME_user_login(&$edit, $account) { if (!isset($_POST['form_id']) || $_POST['form_id'] != 'user_pass_reset' || variable_get('login_destination_immediate_redirect', FALSE)) { if(in_array('administrator',$account->roles)) { drupal_goto('admin/dashboard'); } else { drupal_goto('user/'.$account->uid); } } }
Přepis výstupu polí
function MYTHEMENAME_preprocess_field(&$variables, $hook) { //kpr($variables); // For field type "boolean" if ($element['#field_type'] == 'list_boolean') { // Add CSS class and change in Value if ($variables['element']['#items'][0]['value'] == 1) { $variables['classes_array'][] = 'true'; $variables['items'][0]['#markup'] = t('Yes'); } else { $variables['classes_array'][] = 'false'; $variables['items'][0]['#markup'] = t('No'); } } // For all field except specific type and name if($variables['element']['#field_type'] !== 'text_with_summary' && $variables['element']['#field_type'] !== 'text_long' && $variables['element']['#field_name'] !== 'field_price' { // For each item foreach ($variables['items'] as $delta => $item) { if (!empty($variables['items'][$delta]['#markup'])) { // Add tag <strong> $variables['items'][$delta]['#markup'] = '<strong>'. $variables['items'][$delta]['#markup'] .'</strong>'; } } } }
Náhrada nulové ceny za slovo zdarma ve výpisu Views:
/** * Replace price 0 to free */ function MYTHEMENAME_preprocess_views_view_fields(&$variables) { //kpr($variables); if($variables['fields']['field_price']->content == 0) { $variables['fields']['field_price']->content = t('free'); } }
Úprava řetězce "Submitted by [name] on [date]":
<?php function MYTHEMENAME_preprocess_node(&$variables) { $variables['submitted'] = t('Submitted by !username on !datetime', array('!username' => $variables['name'], '!datetime' => $variables['date'])); // only username //$variables['submitted'] = t('Submitted by !username', array('!username' => $variables['name'])); // only date //$variables['submitted'] = t('Submitted on !datetime', array('!datetime' => $variables['date'])); // Drupal date formats (long, medium, short) //$variables['date'] = format_date($variables['node']->created, 'short'); // Custom format types //$variables['date'] = format_date($variables['node']->created, 'custom', 'F j, Y'); // DateCreated-> Changed //$variables['date'] = format_date($node->changed); // DateCreated-> Changed + custom username and date /*$variables['date'] = format_date($node->changed); if (variable_get('node_submitted_' . $node->type, TRUE)) { $variables['display_submitted'] = TRUE; $variables['submitted'] = t('Edited by !username on !datetime', array('!username' => $variables['name'], '!datetime' => $variables['date'])); $variables['user_picture'] = theme_get_setting('toggle_node_user_picture') ? theme('user_picture', array('account' => $node)) : ''; } else { $variables['display_submitted'] = FALSE; $variables['submitted'] = ''; $variables['user_picture'] = ''; }*/ } ?>
Úprava délky uživatelského jména:
/** * Implements hook_preprocess_username(). */ function MYTHEMENAME_preprocess_username(&$variables) { $account = $variables['account']; $variables['extra'] = ''; if (empty($account->uid)) { $variables['uid'] = 0; if (theme_get_setting('toggle_comment_user_verification')) { $variables['extra'] = ' (' . t('not verified') . ')'; } } else { $variables['uid'] = (int) $account->uid; $user = user_load($account->uid); if (isset($user->field_fullname['und'][0]['value'])) { $name = $variables['name_raw'] = $user->field_fullname ['und'][0]['safe_value']; } else { // Set the name to a formatted name that is safe for printing and // that won't break tables by being too long. Keep an unshortened, // unsanitized version, in case other preprocess functions want to implement // their own shortening logic or add markup. If they do so, they must ensure // that $variables['name'] is safe for printing. $name = $variables['name_raw'] = format_username($account); } } if (drupal_strlen($name) > 20) { //$name = drupal_substr($name, 0, 15) . '...'; } $variables['name'] = check_plain($name); $variables['profile_access'] = user_access('access user profiles'); $variables['link_attributes'] = array(); // Populate link path and attributes if appropriate. if ($variables['uid'] && $variables['profile_access']) { // We are linking to a local user. $variables['link_attributes'] = array('title' => t('View user profile.')); $variables['link_path'] = 'user/' . $variables['uid']; } elseif (!empty($account->homepage)) { // Like the 'class' attribute, the 'rel' attribute can hold a // space-separated set of values, so initialize it as an array to make it // easier for other preprocess functions to append to it. $variables['link_attributes'] = array('rel' => array('nofollow')); $variables['link_path'] = $account->homepage; $variables['homepage'] = $account->homepage; } // We do not want the l() function to check_plain() a second time. $variables['link_options']['html'] = TRUE; // Set a default class. $variables['attributes_array'] = array('class' => array('username')); }
function theme_username($object) { if ($object->uid && $object->name) { // Shorten the name when it is too long or it will break many tables. if (drupal_strlen($object->name) > 20) { $name = drupal_substr($object->name, 0, 15) .'...'; } ...
např. na:
function MYTHEMENAME_username($object) { if ($object->uid && $object->name) { // Shorten the name when it is too long or it will break many tables. if (drupal_strlen($object->name) > 30) { $name = drupal_substr($object->name, 0, 25) .'...'; } ...
Místo phptemplate je z hlediska výkonu vhodnější psát název tématu.
Pro přidání CSS atributů k menu odkazům použijte modul Menu Attributes.
Pokud potřebujete přidat třídy položkám LI použijte funkci theme_menu_link.
function YOURTHEME_menu_link__main_menu($variables){
}
Pokud potřebujete přidat třídy seznamu UL použijte funkci theme_menu_tree.
Doplnění CSS do navigace:
/** * Overrides theme_menu_tree(). * Add bootstrap 'navbar-nav' class to Top Navigation menu */ function YOURTHEME_menu_tree__menu_top_navigation(&$variables) { return '<ul class="menu nav navbar-nav">' . $variables['tree'] . '</ul>'; }
Získání argumentů z URL:
$url = arg(); print_r($url); //print $url[0] .'|'. $url[1];
Získání query parametrů z URL:
$query = drupal_get_query_parameters(); //print_r $query; print $query['page'];
Doplnění počtu položek menu:
/** * Process variables for menu-block-wrapper.tpl.php. * * @see menu-block-wrapper.tpl.php */ function THEMENAME_preprocess_menu_block_wrapper(&$variables) { //$variables['classes_array'][] = 'menu-block-' . $variables['delta']; $variables['classes_array'][] = 'menu-level-count-'. count(element_children($variables['content'])); }
Připojení CSS pro Internet Explorer:
/** * Generates IE CSS links for LTR and RTL languages. */ function phptemplate_get_ie_styles() { global $language; $iecss = "\n"; $iecss .= '<!--[if (lte IE 7)&(gte IE 5)]>'."\n "; $iecss .= '<link type="text/css" rel="stylesheet" media="screen, projection" href="'. base_path() . path_to_theme() .'/styles/ie-7.css" />'."\n "; if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) { $iecss .= '<link type="text/css" rel="stylesheet" media="screen, projection" href="'. base_path() . path_to_theme() .'/styles/ie-7-rtl.css" />'."\n "; } $iecss .= '<![if lt IE 7]>'."\n "; $iecss .= '<link type="text/css" rel="stylesheet" media="screen, projection" href="'. base_path() . path_to_theme() .'/styles/ie-6.css" />'."\n "; if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) { $iecss .= '<link type="text/css" rel="stylesheet" media="screen, projection" href="'. base_path() . path_to_theme() .'/styles/ie-6-rtl.css" />'."\n "; } $iecss .= '<![if lt IE 6]>'."\n "; $iecss .= '<link type="text/css" rel="stylesheet" media="screen, projection" href="'. base_path() . path_to_theme() .'/styles/ie-5.5.css" />'."\n "; if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) { $iecss .= '<link type="text/css" rel="stylesheet" media="screen, projection" href="'. base_path() . path_to_theme() .'/styles/ie-5.5-rtl.css" />'."\n "; } $iecss .= '<![if lt IE 5.5]>'."\n "; $iecss .= '<link type="text/css" rel="stylesheet" media="screen, projection" href="'. base_path() . path_to_theme() .'/styles/ie-5.css" />'."\n "; if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) { $iecss .= " ".'<link type="text/css" rel="stylesheet" media="screen, projection" href="'. base_path() . path_to_theme() .'/styles/ie-5-rtl.css" />'."\n "; } $iecss .= '<![endif]>'."\n "; $iecss .= '<![endif]>'."\n "; $iecss .= '<![endif]>'."\n"; $iecss .= '<![endif]-->'."\n"; return $iecss; }
V používaném tématu vzhledu vytvořte (upravte) soubor template.php, do kterého vložte požadovanou funkci nalezenou přímo v Drupalu nebo na api.drupal.org:
/** * Implements HOOK_form_alter() */ function MYTHEMENAME_form_alter(&$form, &$form_state, $form_id) { //kpr($form); // require Devel modul //dpm($form_id); // require Devel modul //drupal_set_message($form_id); // print form ID to messages //drupal_set_message(print_r($form, TRUE)); // print array to messages //var_dump($form); //echo $form_id .", "; }
/** * Implements HOOK_form_FORM_ID_alter() */ function MYTHEMENAME_form_search_block_form_alter(&$form, &$form_state, $form_id) { //kpr($form); // require Devel modul //var_dump($form); //kpr(); // require Devel modul }
Např. modifikace atributů a textu tlačítek:
/** * Implements HOOK_form_alter() */ function MYMODUELNAME_form_alter(&$form, &$form_state, $form_id) { if($form_id == 'user_register') { // change submit button $form['submit']['#value'] = t('Complete the registration'); } }
/** * Implements HOOK_form_alter() */ function MYTHEMENAME_form_alter(&$form, &$form_state, $form_id) { //var_dump($form); // submit input if(isset($form['product_id']) && $form_id == 'commerce_cart_add_to_cart_form_' . $form['product_id']['#value']) { $form['submit']['#attributes']['title'] = t('Add to Wishlist'); } // 1. step of checkout if($form_id == 'views_form_commerce_cart_form_default') { $form['actions']['continue_shopping']['#value'] = t('Continue'); $form['actions']['submit']['#value'] = t('Update demand'); $form['actions']['checkout']['#value'] = t('Send demand'); } // 2. step of checkout if($form_id == 'commerce_checkout_form_checkout') { $form['buttons']['continue']['#value'] = t('Send demand'); } }
Příklad úpravy exposed filtru (#process):
/** * Custom process function **/ function MYFUNCTION_process($element, $form_state, $form) { //print('<pre>'.print_r($form,1).'</pre>'); //kpr($element); //kpr($form_state); // First element "CUSTOM_TEXT" $element['CUSTOM_TEXT'] = array( '#markup' => "<div class='my-class'>CUSTOM TEXT</div>", ); // Second element "MY_LINK" $element['MY_LINK'] = array( '#type' => 'link', '#prefix' => '<div class="MYCLASS">', '#title' => '<span>'. t('TITLE') .'</span>', '#suffix' => '</div>', '#href' => 'MYURL', '#id' => 'prev', '#ajax' => array( 'wrapper' => 'level-form', 'method' => 'html', ), '#options' => array( 'html' => true, 'fragment' => 'MY-ANCHOR', 'attributes' => array( 'title' => t('HOVER TITLE'), ), 'query' => array( 'year' => 2013, 'month' => 9, ) ), '#weight' => -10, ); return $element; }
function HOOK_form_alter(&$form, &$form_state, $form_id) { $form['date']['value']['#process'][] = 'MYFUNCTION_process'; //kpr($form); }
...
Odstranění (úprava) popisu "celý den" u pole datum modulu Date:
/** * Theme the way an 'all day' label will look. */ function phptemplate_date_all_day_label() { return ''; }
Místo phptemplate je z hlediska výkonu vhodnější psát název tématu.
Soubor comment.tpl.php obsahuje šablonu komentáře
Příklad:
<div class="comment2<?php print ($comment->new) ? ' comment-new' : ''; print ' '. $status; print ' '. $zebra; ?>"> <div class="clear-block"> <?php if ($submitted): ?> <span class="submitted"><?php print $submitted; ?></span> <?php endif; ?> <?php if ($comment->new) : ?> <span class="new"><?php print drupal_ucfirst($new) ?></span> <?php endif; ?> <?php print $picture ?> <h3><?php print $title ?></h3> <div class="content"> <?php print $content ?> <?php if ($signature): // You can use the following to prevent double-display of signatures on old posts (converting Drupal 5 to Drupal 6) // if ($signature && $comment->cid > 3443): // The highest comment ID before upgrading to Drupal 6 ?> <div class="user-signature clear-block"> <div>—</div> <?php print $signature ?> </div> <?php endif; ?> </div> </div> <?php if ($links): ?> <div class="links"><?php print $links ?></div> <?php endif; ?> </div>
Vlastní vzhled webu v offline režimu.
$conf = array( 'maintenance_theme' => 'my-owns-theme' );
Bližší informace o šablonách naleznete v Template Suggestions.
Příklad upravy úvodní stránky:
page.tpl.php
(základní šablona je vyžadována vždy )page--front.tpl.php
page.tpl.php
(základní šablona je vyžadována vždy )page-front.tpl.php
Příklad změny vzhledu uživatelského profilu:
modules/user/
zkopírujte do svého tématu vzhledu soubor user-profile.tpl.php
.user-profile.tpl.php
dle potřeb.
Odovzený vzhled (sub téma) staví na základním tématu vzhledu, čímž vývojářům a designerům šetří mnoho práce.
Dokumentace: Creating a sub-theme
Příklad:
name = Odvozené téma vzhledu description = Popis odvozeného tématu core = 6.x engine = phptemplate base theme = nazev-zakladniho-tematu stylesheets[screen, projection][] = styles/my-derived-styles.css scripts[] = my-derived-scripts.js
Název odvozeného tématu je uložen v proměnné $theme_key
(hodí se např. při úpravách cest k obrázkům nebo pro třídy CSS):
<?php global $theme_key; print $theme_key; ?>
Dokumentace:
/** * @file * Short description describing the file. * * The first sentence of the long description starts here and continues on this * line for a while finally concluding here at the end of this paragraph. */ /* @group Section comment block ----------------------------------------------------------------------------- */ html, body { min-height: 100% } /* @end Section comment block */ /** * Short description using Doxygen-style comment format. * * The first sentence of the long description starts here and continues on this * line for a while finally concluding here at the end of this paragraph. * * The long description is ideal for more detailed explanations and * documentation. It can include example HTML, URLs, or any other information * that is deemed necessary or useful. */ body { /* This line is indented with 2 spaces, 2 spaces x 1 level of indentation. */ text-align: left; } /* The example's item styling. */ body, div, .selector-3[type="text"] { /* Override the default margins. */ margin: 0; padding: 0; color: #333; background: #fff; background: linear-gradient(#fff, rgba(0, 0, 0, 0.8)); font-family: Times, "Times New Roman", sans-serif; } .selector-1, .selector-2 { padding: 10px; }
\n
nebo LF
)
Kaskádové styly je možné vytvářet v párech. Ve stejném adresáři může být např. soubor example.css s výchozím určením pro tok textu zleva doprava (LTR) a example-rtl.css určený pro tok textu zprava doleva (RTL) např. pro Arabštinu, Hebrejštinu atd.
Soubor example-rtl.css může potlačit určené deklarace souboru example.css. Odlišnosti v toku textu označeny /* LTR */ komentářem v originálním souboru example.css, aby bylo jasné které deklarace je nutné modifikovat v souboru example-rtl.css (pro přehlednost při pozdějších úpravách).
Soubor example-rtl.css je uplatněn pouze v případě použití jazyka (zobrazení stránek) s tokem textu zprava doleva a potlačuje tak určené deklarace souboru example.css.
Left-To-Right (LTR) vlastnosti by měly být označeny níže uvedeným komentářem v souboru example.css:
/** * @file * Left-To-Right (LTR) CSS file example. */ .example-rule { float: left; /* LTR */ margin-right: 1.5em; /* LTR */ padding: 0 0.25em; }
Při použití RTL jazyka bude načten i příslušný soubor example-rtl.css:
/** * @file * Right-To-Left (RTL) CSS file example. */ .example-rule { float: right; margin-left: 1.5em; margin-right: 0; }
.selector { /* Positioning */ position: absolute; z-index: 10; top: 0; left: 0; /* Box Model */ display: inline-block; -moz-box-sizing: border-box; -ms-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; width: 100px; padding: 10px; border: 10px solid #333; /* Other */ background: #000; color: #fff; font-family: sans-serif; font-size: 1.1em; }
Deklarace pište v pořadí od důležitých k méně důležitým:
.selector-1 { width: 10%; } .selector-2 { width: 20%; } .selector-3 { width: 30%; }
Mnoho jednoduchých deklarací je možné psát "jednořádkovým" formátem s mezerou za otevírací a před uzavírací závorkou.
.selector { background-image: linear-gradient(#fff, #ccc), linear-gradient(#f3c, #4ec); box-shadow: 1px 1px 1px #000, 2px 2px 1px 1px #ccc inset; }
Dlouhé hodnoty oddělené čárkou (přechody, stíny atd.) je možné pro zvýšení čitelnosti psát na více řádků.
/** * @file * Example of CSS coding standards for Drupal. */ /* ========================================================================== Grid layout ======================================================================= */ /** * Column layout with horizontal scroll. * * This creates a single row of full-height, non-wrapping columns that can be * browsed horizontally within their parent. * * Example HTML: * * <div class="grid"> * <div class="cell cell-3"></div> * <div class="cell cell-3"></div> * <div class="cell cell-3"></div> * </div> */ /** * Grid container * * Must only contain `.cell` children. */ .grid { height: 100%; /* Remove inter-cell whitespace */ font-size: 0; /* Prevent inline-block cells wrapping */ white-space: nowrap; } /** * Grid cells * * No explicit width by default. Extend with `.cell-n` classes. */ .cell { position: relative; display: inline-block; overflow: hidden; box-sizing: border-box; height: 100%; /* Set the inter-cell spacing */ padding: 0 10px; border: 2px solid #333; vertical-align: top; /* Reset white-space */ white-space: normal; /* Reset font-size */ font-size: 16px; } /* Cell states */ .cell.is-animating { background-color: #fffdec; } /* Cell dimensions */ .cell-1 { width: 10%; } .cell-2 { width: 20%; } .cell-3 { width: 30%; } .cell-4 { width: 40%; } .cell-5 { width: 50%; } /* Cell modifiers */ .cell--detail, .cell--important { border-width: 4px; }
Drupal 8 vychází ze SMACSS kategorizace CSS pravidel.
Každá kategorie sad pravidel by měla být v samostatném CSS souboru.
Drupal 8 může mít jen 2 agregované CSS soubory (dříve jich bylo minimálně 6):
template.php
/** * Preproccess for Page */ function mytheme_process_page(&$variables) { // Node type Article title if (!empty($variables['node']) && $variables['node']->type == 'article') { //kpr($variables['node']); $long_title = $variables['node']->field_long_title[LANGUAGE_NONE][0]['safe_value']; $variables['title'] = $long_title; } } function mytheme_preprocess_node(&$variables, $hook) { // Node type Article if ($variables['node']->type == 'article') { //kpr($variables); // Getting taxonomy term (only one) $tid = $variables['field_categories'][LANGUAGE_NONE][0]['tid']; $term = taxonomy_term_load($tid); // load term object $term_uri = taxonomy_term_uri($term); // get array with path $term_title = taxonomy_term_title($term); $term_path = $term_uri['path']; $article_link = l($term_title,$term_path); // Change date format $article_date = date("F d. Y", $variables['created']); // Block (#1) $block = module_invoke('block','block_view','1'); $block_whole = block_load('block','1'); // not really the whole block until render // Views block ("test") $views_block = module_invoke('views','block_view','test_view-block'); // Creating custom variables for node.tpl.php $variables['article_link'] = $article_link; $variables['article_date'] = $article_date; $variables['block'] = $block; $variables['block_whole'] = $block_whole; $variables['views_block'] = $views_block; } }
node--article.tpl.php
<div><?php print $article_link ." | ". $article_date; ?></div> <?php print render($block['content']); print drupal_render(_block_get_renderable_array(_block_render_blocks(array($block_whole)))); print render($views_block); ?> <?php // Hide the comments and links //hide($content['comments']); //hide($content['links']); // Render comments and links print render($content['links']); print render($content['comments']); ?>
Výhody použití Behaviors v Drupalu:
Příklad obecného jQuery:
$(document).ready(function () { // Do some fancy stuff. });
Příklady použítí jQuery v Drupal 7:
A)
(function ($) { // To understand behaviors, see https://drupal.org/node/756722#behaviors Drupal.behaviors.my_custom_behavior = { attach: function(context, settings) { // Place your code here. } }; })(jQuery);
B)
// JavaScript should be made compatible with libraries other than jQuery by // wrapping it with an "anonymous closure". See: // – https://drupal.org/node/1446420 // – http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth (function($, Drupal, window, document, undefined) { Drupal.behaviors.myModuleBehavior = { attach: function (context, settings) { $('input.myCustomBehavior', context).once('myCustomBehavior', function () { // Apply the myCustomBehaviour effect to the elements only once. }); } }; })(jQuery, Drupal, this, this.document);
Příklad předání proměnné z PHP do JavaSkriptu:
drupal_add_js(array('myTyxModule' => array('tax_rate' => '0.021')), 'setting');
(function($) { Drupal.behaviors.myTyxModule = { attach: function (context, settings) { // You can access the variable by using Drupal.settings.myTyxModule.tax_rate alert(Drupal.settings.myTyxModule.tax_rate); } }; })(jQuery);
Dokumentace:
Příklad použití jQuery – zobrazující se text Text...
ve vyhledávacím poli:
scripts/
obsahující soubory jquery.autofill.js a javascript.js (z přiložených souborů odstraňte příponu .txt).scripts[] = scripts/javascript.js scripts[] = scripts/jquery.autofill.js
Příloha | Velikost |
---|---|
jquery.autofill.js.txt | 1.97 KB |
javascript.js.txt | 157 bajtů |
Příklad použití jQuery – při přejetí myší zůstane blok chvíli zobrazen, při kliku na záhlaví zůstane zobrazen trvale, při opětovném kliku se skryje:
js/
obsahující soubor search_exposed_block.js (z přiloženéo souboru odstraňte příponu .txt).scripts[] = js/javascript.js scripts[] = js/jquery.autofill.js
libraries[search_exposed_block][name] = Toggle search exposed block libraries[search_exposed_block][description] = Toggle search exposed block libraries[search_exposed_block][js][0][file] = search_exposed_block.js libraries[search_exposed_block][js][0][options][weight] = -20
Příloha | Velikost |
---|---|
search_exposed_block.js.txt | 1.59 KB |
Díky aplikačnímu rozhraní API (Application Programming Interface) nemusíte zasahovat do zdrojového kódu Drupalu a tudíž nebudete mít problémy při pozdější aktualizaci. API se hodí zejména při úpravách vzhledu a vývoji vlastních modulů.
Získá odkazy drobečkové navigace pro aktuální stránku.
drupal_get_breadcrumb()
includes/common.inc, line 95
Řetězec obsahující odkazy drobečkové navigace.
Vlastní úprava drobečkové navigace:
<?php // if ($breadcrumb) print $breadcrumb; if ($breadcrumb) { $subtheme_start_page = "<a href=\"/views/news\" title=\"Úvodní stránka novinek\">Novinky</a>"; $crumbs = drupal_get_breadcrumb(); $home_page = array_shift($crumbs); array_unshift($crumbs, $home_page, $subtheme_start_page); print theme_breadcrumb($crumbs); } ?>
Formátuje vnitřní odkaz.
Funkce l správně manipuluje s odkazy, které mohou mít vytvořené aliasy a umožňuje upravovat jejich vlastnosti. Všechny vnitřní odkazy výstupů modulů by měly být generovány touto funkcí.
l($text, $path, $options = array())
includes/common.inc, řádek 1534
Níže jsou uvedena data pro Drupal 5!
$text – text, který bude uzavřen v odkazu
Veškerý text, který může člověk přečíst a má být zobrazen na stránce by měl být zobrazován funkcí t().
$path – cesta odkazu
Může být externí nebo interní:
při zadání úplné cesty bude považována za externí
při zadání pouze cesty např. "admin/content/node" bude považována za interní
v tomto případě musí být systémovou cestou, aby mohl být generován případný alias pomocí funkce url()
$attributes – asociativní pole HTML atributů aplikovaných u elementu odkazu
fragment – vytváří za odkazem "#kotvu" na ID v html zdroji
$query – řetězec přidaný k odkazu za otazníkem (& parametr)
$fragment – identifikátor přidaný k odkazu (# kotva)
$absolute – vynutit absolutní odkaz začínající http:
Užitečné pro odkazy, které budou zobrazovány mimo web, jako například RSS kanály.
$html – podporovat HTML elementy
Hodnota TRUE je např. nutná pro správné zobrazení HTML tagů např. obrázků, jinak se místo obrázku zobrazí v odkazu prostý text (případně HTML entity).
<?php l(t('Home'), '<front>', array('title' => $site_name, 'class' => 'link', 'id' => 'home'), NULL, NULL, FALSE, FALSE); l('<span>' . t('My Node') . '</span>', 'node/1', array('html' => TRUE, 'fragment' => 'my-anchor', 'attributes' => array('title' => t('Hover Desciption')))); ?>
HTML řetězec obsahující odkaz na určenou cestu.
Zjišťuje existenci modulu.
module_exists($module)
$module – název modulu
<?php if(module_exists('themer')) print ' '. themer_body_class(); ?>
Logická hodnota TRUE, pokud je modul nainstalován a povolen.
Překládá řetězce do jazyka stránky nebo určeného jazyka.
Veškerý text, který může člověk přečíst a má být zobrazen na stránce by měl být zobrazován touto funkcí.
t($string, $args = array(), $langcode = NULL)
includes/common.inc, řádek 734
$string – řetězec obsahující anglický text k přeložení.
$args – asociativní pole náhrad vytvořených po překladu. Všechny výskyty každého klíče v tomto poli jsou nahrazeny odpovídající hodnotou.
Klíče se speciálním významem:
$langcode – volitelný kód jazyka překladu odlišný od jazyka stránky
Přeložený řetězec.
Vrací nastylovaný výstup.
<?php print theme('username', $node); ?>
Vrací nastylovanou drobečkovou navigaci.
theme_breadcrumb($breadcrumb)
includes/theme.inc, line 1226
$breadcrumb – pole obsahující odkazy drobečkové navigace
Řetězec obsahující drobečkovou navigaci.
Vlastní úprava drobečkové navigace:
<?php // if ($breadcrumb) print $breadcrumb; if ($breadcrumb) { $subtheme_start_page = "<a href=\"/views/news\" title=\"Úvodní stránka novinek\">Novinky</a>"; $crumbs = drupal_get_breadcrumb(); $home_page = array_shift($crumbs); array_unshift($crumbs, $home_page, $subtheme_start_page); print theme_breadcrumb($crumbs); } ?>
Funkce získá nastavení z aktuálního tématu, která byla zadána v administraci webu.
theme_get_setting($setting_name, $refresh = FALSE))
includes/theme.inc, řádek 900
$setting_name – název nastavení, které má být získáno.
$refresh - zda obnovit nastavení cache.
Hodnota požadovaného nastavení, NULL jestliže nastavení neexistuje.
Zobrazení poslání webu jako meta informace v hlavičce stránky:
<?php $my_description = theme_get_setting('mission', false); if ($my_description) { print '<meta name="description" content="'. $my_description .'" />'; } ?>
Snippet je malý znovupoužitelný kus programového kódu, který může např.:
Příklad zobrazení požadovaných údajů přímo z databáze:
<?php $sql = "SELECT title FROM node ORDER BY node.vid DESC LIMIT 10"; $result = db_query($sql); while ($node = db_fetch_object($result)) { $output .= $node->title ." "; } return $output; ?>
Pro zobrazení je možné využít např. vestavěný PHP filtr obsahu nebo bloku.
Snippety pro Drupal 5:
Doplnění textové navigace do galerie obrázků modulu Image.
Jako základ bylo použito řešení Add a << first < previous next > last >> Pager to Image Nodes Within a Gallery doplněné o lokalizaci.
/** * Image Gallery Pager */ function custom_pager($current_nid, $class = NULL) { $tid = reset(array_keys(taxonomy_node_get_terms($current_nid))); $result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid = %s AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC, n.nid DESC'), $tid); while ($node = db_fetch_object($result)) { $nodes[++$i] = $node; if ($node->nid == $current_nid) $x = $i; } if($x > 1) { $output .= l(t('« first'), 'node/'. $nodes[1]->nid, array('title' => check_plain($nodes[1]->title), 'class' => $class), NULL, NULL, FALSE, TRUE); $output .= l(t('‹ previous'), 'node/'. $nodes[$x-1]->nid, array('title' => check_plain($nodes[$x-1]->title), 'class' => $class), NULL, NULL, FALSE, TRUE); } else { // not required // $output .= '<span class="">' . t(t('« first')) . ' </span>' . '<span class="">' . t('‹ previous') . ' </span>'; } $output .= $x .' ('. $i .')'; if($x < $i) { $output .= l(t('next ›'), 'node/'. $nodes[$x+1]->nid, array('title' => check_plain($nodes[$x+1]->title), 'class' => $class), NULL, NULL, FALSE, TRUE); $output .= l(t('last »'), 'node/'. $nodes[$i]->nid, array('title' => check_plain($nodes[$i]->title), 'class' => $class), NULL, NULL, FALSE, TRUE); } else { // not required // $output .= '<span class="">' . t(t('next ›')) . ' </span>' . '<span class="">' . t(t('last »')) . ' </span>'; } return $output; }
<!-- Image Gallery Pager --> <div class="pager"> <?php if ($page != 0 && $terms) { print custom_pager($node->nid); } ?> </div>
Doplnění navigace s náhledy do galerie obrázků u modulu Image.
Jako základ bylo použito řešení Pager with thumbnails doplněné o lokalizaci, číslování a velikosti náhledů.
/** * Image Gallery Pager with thumbnails */ function custom_pager_thumbnails($current_nid, $class = NULL) { $tid = reset(array_keys(taxonomy_node_get_terms($current_nid))); $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, f.filepath FROM {node} n INNER JOIN {term_node} tn INNER JOIN {files} f ON n.nid = tn.nid AND n.nid = f.nid WHERE tn.tid = %s AND n.status = 1 AND f.filename = \'%s\' ORDER BY n.sticky DESC, n.created DESC, n.nid DESC'), $tid, 'thumbnail'); while ($node = db_fetch_object($result)) { $nodes[++$i] = $node; if ($node->nid == $current_nid) $x = $i; // image size $image_info = image_get_info($nodes[$i]->filepath); $image_width[$i] = $image_info['width']; $image_height[$i] = $image_info['height']; } if ($i < 6) { while (++$j <= $i) { $output .= l('<img src="' . check_url(url('system/files/' . $nodes[$j]->filepath)) . '" alt="'. check_plain($nodes[$j]->title) . '" width="'. $image_width[$j] .'" height="'. $image_height[$j] .'" />', 'node/'. $nodes[$j]->nid, array('title' => check_plain($nodes[$j]->title), 'class' => $class), NULL, NULL, FALSE, TRUE); } } else { switch ($x) { case 1: // first image $y = array($i-1, $i, 1, 2, 3); break; case 2: // second image $y = array($i, 1, 2, 3, 4); break; case $i-1: // penultimate image $y = array($x-2, $x-1, $x, $i, 1); break; case $i: // last image $y = array($x-2, $x-1, $x, 1, 2); break; default: $y = array($x-2, $x-1, $x, $x+1, $x+2); } foreach($y as $index => $z) { if ($index != 2) { $output .= l('<img src="' . check_url(url('system/files/' . $nodes[$z]->filepath)) . '" alt="'. check_plain($nodes[$z]->title) . '" width="'. $image_width[$z] .'" height="'. $image_height[$z] .'" />', 'node/'. $nodes[$z]->nid, array('title' => '('. ($z) .') '. check_plain($nodes[$z]->title), 'class' => $class), NULL, NULL, FALSE, TRUE); } else { $output .= '<span class="active" title="('. ($z) .') '. check_plain($nodes[$z]->title) .'"><img src="' . check_url(url('system/files/' . $nodes[$z]->filepath)) . '" alt="'. check_plain($nodes[$z]->title) . '" width="'. $image_width[$z] .'" height="'. $image_height[$z] .'" /></span>'; } } } return $output; }
<!-- Image Gallery Pager with thumbnails --> <div class="pager"> <?php if ($page != 0 && $terms) { print custom_pager_thumbnails($node->nid); } ?> </div>
/* Theme snippet: Image Gallery Pager with thumbnails */ #content .pager { margin-top: 3px; margin-bottom: 3px; } #content .pager img { margin-bottom: 3px; vertical-align: middle; } #content .pager .active img { border: 5px solid #f93; margin-bottom: 0; }
Výchozí instalace Drupalu obsahuje pouze základní funkčnost, kterou však lze velmi snadno rozšířit pomocí externích modulů dle konkrétních potřeb webu.
Hledání a výběr modulů mohou usnadnit statistiky:
Srovnání možností podobných modulů:
Umístění modulů (knihoven a témat vzhledu):
Moduly:
Vyloučení modulu z aktualizace
Automatické aktualizace viz Drush.
Komerční moduly:
Více viz Comparison of Breadcrumb Customizing modules.
Menu 1 (položka menu) 2 (položka menu) Stránka |
Kategorie A (termín) B (termín) C (termín) |
Kategorie A (termín) B (termín) C (termín) Článek |
|
Drupal 6 | Domů | Domů > A > B | Domů |
Menu Breadcrumb | Domů > 1 > 2 | Domů > A > B | Domů |
Menu Trails (ruční zařazení kategorií ) | Domů > 1 > 2 > Stránka (obsahuje název uzlu ) |
Domů > A > B | Domů > Kategorie > A (x) > B (x) |
Node breadcrumb (málo možností nastavení pravidel ) | Domů > 1 > 2 | Domů > A > B | Domů (nastavená pravidla) |
Taxonomy breadcrumb | Domů | Domů > A > B > C | Domů > A > B > C |
Custom breadcrumb | Domů | Domů > A > B | Domů > Termín s nejvyšší váhou |
Menu Breadcrumb + Taxonomy Breadcrumb | Domů | Domů > A > B > C | Domů > A > B > C |
Menu Trails (bez ručního zařazení kategorií ) + Taxonomy Breadcrumb | Domů > 1 > 2 > Stránka (obsahuje název uzlu ) |
Domů > A > B > C | Domů > A > B > C |
Dokumentace:
Nástroje:
Tipy:
Při vytváření modulů bývá velmi užitečným pomocníkem modul Devel.
Váhy základních fází průběhu zpracovávání v Drupalu (bližší informace viz např. funkce theme):
Minimální adresářová strura:
Uvědomte se rozdíly mezi pojmy:
Hooks (háčky) můžeme chápat např. jako speciálně pojmenované PHP funkce. U vyhledané funkce nahraďte slovo hook_...
za název modulu např. my_module_...
např.:
hook_install() => my_module_install()
hook_enable() => my_module_enable()
hook_disable() => my_module_disable()
Pro vytvořeního vlastního modulu, který má zobrazovat nějaký blok(y) jsou třeba minimálně dva hooky:
hook_block_info() => my_module_info()
hook_block_view() => my_module_view()
Při tvorbě bloku pomocí modulu je vhodné projít si demonstrační kód viz block_example.module.
Pro jednoduché uložení a získání dat je možné využít databázovou tabulku variable a funkce variable_set() a variable_get().
Globálné proměnné např. o uživateli je možné získat zápisem:
global $user;
Textové řetězce je nutné zapisovat do funkce t()
.
stylesheets[all][] = my_module.css stylesheets[screen][] = my_module_screen.css stylesheets[print][] = my_module_print.css
scripts[] = my_module.js
/** * Implementation of hook_init(). */ function my_module_init() { $path = drupal_get_path('module', 'my_module'); drupal_add_css($path . '/my_module.css'); drupal_add_js($path . '/my_module.js'); }
/** * Implementation of hook_init(). */ function my_module_init() { drupal_add_css('body {background: #ccc;}', array('group' => CSS_THEME, 'type' => 'inline')); }
Tipy:
/** * Implements hook_preprocess_block() */ function <your-module-name>_preprocess_block(&$vars) { /* Set shortcut variables. Hooray for less typing! */ $block_id = $vars['block']->module . '-' . $vars['block']->delta; $classes = &$vars['classes_array']; $title_classes = &$vars['title_attributes_array']['class']; $content_classes = &$vars['content_attributes_array']['class']; /* Add global classes to all blocks */ $title_classes[] = 'block-title'; $content_classes[] = 'block-content'; /* Uncomment the line below to see variables you can use to target a field */ #print $block_id . '<br/>'; /* Add classes based on the block delta. */ switch ($block_id) { /* System Navigation block */ case 'system-navigation': $classes[] = 'block-rounded'; $title_classes[] = 'block-fancy-title'; $content_classes[] = 'block-fancy-content'; break; /* Main Content block */ case 'system-main': $classes[] = 'clearfix'; break; // Adding the same classes to more blocks – Grouping cases togheter /* Main Menu block */ case 'system-main-menu': /* User Login block */ case 'user-login': $title_classes[] = 'element-invisible'; break; } }
/** * Implements HOOK_entity_view(). * Limit Teaser to display only the first image of a multiple field. */ function <your-module-name>_entity_view($entity, $type, $view_mode, $langcode) { if($entity->type == 'story' && $view_mode == 'teaser') { //kpr($entity); $entity->content['field_image']['#items'] = array_slice($entity->content['field_image']['#items'], 0, 1); } }
/** * Implements hook_form_FORM_ID_alter(). */ function <your-module-name>_form_node_form_alter(&$form, $form_state) { // Set “Publishing options” vertical tab as default for node edit page. $form['additional_settings']['#default_tab'] = 'edit-options'; // Where 'edit-options' is fieldset ID. }
function <your-module-name>_node_presave($node) { if (user_is_anonymous()) $node->status = FALSE; // means unpublished }
$inline_script = " <!-- My JavaScript --> <script> // JS Content </script> <noscript> // No Script </noscript> <!-- End My JavaScript --> "; $element = array( '#type' => 'markup', '#markup' => $inline_script, ); drupal_add_html_head($element, 'my-javasript');
Udržování instalační "platformy" nebo "profilu" usnadňuje začátek při vytváření nového webu.
Drupal:
Základní nastavení:
Označení modulů:
Instalace:
Administrace (managment):
Lokalizace (jazyky):
Vztahy (relace):
Obsah:
Formulářové prvky:
Komentáře:
Obrázky:
Multimédia:
Efekty a animace:
Navigace:
Uživatelské účty:
Oprávnění:
Knihovny:
Logika:
Přístupnost:
Bezpečnost:
SEO
Strukturovaná data (doporučené formáty):
Zdrojový kód:
Marketing:
Obchodní podmínky:
Povinnosti:
Sociální média (Publishing Drupal 7 Content to Social Media: Part 1):
Import/Export:
Dávkové zpracování:
Automatizace:
Výkon:
Vývoj:
Synchronizace:
Monitoring:
Aplikace:
Administrační témata vzhledu:
Propagace a reklama:
Distribuce:
Terminologie:
Drupal | Wordpress | Joomla/Mambo |
---|---|---|
Page (stránka) | Static Content (statický obsah) | |
Story (článek) | Post (příspěvek) | Dynamic Content Item (dynamický obsah) |
Vocabulary (slovník)
|
Category (kategorie)
|
Section (sekce|rubrika|oddíl)
|
Theme (téma vzhledu) | Template | |
Module (modul) | Plugin (zásuvný modul) | Component |
Block (blok) | Widget | Module |
Input filter | Mambot/Plugin | |
Primary Links | Menu-Horizontal | |
Navigation | Menu-Vertical | |
administrační rozhraní (např. modul Administration Menu) | Back-end (...) | |
Clean URL (čisté URL) | SEF (Search Engine Friendly – ...) | |
Teaser (úvodník – může se lišit od prvního odstavce textu "Body") | Introtext (úvodní text) | |
Body (hlavní obsahová část) | Maintext (hlavní text) | |
Breadcrumb (drobečková navigace) | Pathway (cesta) | |
Forum discussion (diskusní fórum) | ||
Editor (editor|redaktor) | ||
Search (hledání) | ||
Region (oblast) | ||
Comment (komentář|poznámka) | ||
Subject / Title (předmět|téma / název|nadpis) | ||
Preview (náhled) | ||
HTML tag (HTML tag) | ||
View (zobrazit|vidět) | ||
Edit (upravit) | ||
Advertising / Banner (reklama/baner) | ||
Log in / Log out (přihlásit / odhlásit) | ||
Profile (profil) | ||
Avatar (avatar) | ||
Access control (řízení přístupu) | ||
Log (záznam) | ||
Cache (mezipaměť) | ||
Site maintenance (údržba webu) | ||
RSS feed (RSS zdroj) | ||
Parent-Child (nadřízený-podřízený) | ||
Snippet (úryvek|výstřižek|fragment) |
CREATE TABLE image (`nid` INTEGER UNSIGNED NOT NULL, `fid` INTEGER UNSIGNED NOT NULL, `image_size` VARCHAR(32) NOT NULL, PRIMARY KEY (`nid`, `image_size`), INDEX image_fid(`fid`)) /*!40100 DEFAULT CHARACTER SET utf8 */;
INSERT INTO image SELECT DISTINCT f.nid, f.fid, f.filename FROM files f INNER JOIN node n ON f.nid = n.nid WHERE n.type='image' AND f.filename IN ('_original', 'thumbnail', 'preview')
DELETE FROM file_revisions WHERE EXISTS (SELECT * FROM image WHERE image.fid = file_revisions.fid)
Celý postup nejprve vyzkoušejte nejlépe na kopii webu!
$update_free_access = FALSE;
$update_free_access = TRUE;
Pro migraci dat je možné použít i placené služby např.:
Úspěšné převody Drupalu 5 na 6
Prevent file not found errors
After you upgrade your site you should check your site for bad links, to prevent the file not found errors. The http error number for these pages is 404. You can use a simple tool to check the links on your site. You will see errors in you Drupal Administrator logs as well as your web server error logs. Perform the following commands through the administrator menu on your site:
From a command line on a computer connected to the Internet run wget with the following options:
The cookie this command is referring to is the cookie downloaded from your browser when you last logged into your Drupal site as an admin.
wget -r --delete-after --cookies=off --header='Cookie: PHPSESSID=xxx' http://example.com
-r to recursively crawl the site. --delete-after, --cookies=off tells the crawler not to use a cookie. --header=’Cookie: PHPSESSID=XXXX’ tells the Drupal site that session information will be passed in the http header. This should be repeated 2 more times; once for a regular userid, and once for an anonymous userid. After the link check is done check your Drupal admin logs and your webserver error logs. Look in your browser preferences to see what cookies you have for your url.
Postupujte nejlépe dle dokumetace Upgrading from Drupal 6 to 7:
Pro migraci dat je možné použít i placené služby např.:
U webových stránek je vhodné pravidelně provádět alespoň níže uvedené kontroly:
Nastavení:
Vývojové prostředí:
Vývoj:
Vývojová prostředí (editory) podporující TWIG:
{# Comment #}
Proměnné mohou mít atributy nebo prvky:
{{ foo.bar }} {{ foo['bar'] }}
Jestliže atribut obsahuje speciální znaky (např. mínus) použijte funkci attribute():
{# equivalent to the non-working foo.data-foo #} {{ attribute(foo, 'data-foo') }}
Více viz twig.sensiolabs.org/doc/templates.html
Poznámky:
Společnosti a jednotlivci zabývající se Drupalem:
// Remove www if ($_SERVER['HTTP_HOST'] == 'www.example.com') { header('HTTP/1.0 301 Moved Permanently'); header('Location: http://example.com'. $_SERVER['REQUEST_URI']); exit(); }
// Require www if ($_SERVER['HTTP_HOST'] == 'example.com') { header('HTTP/1.0 301 Moved Permanently'); header('Location: http://www.example.com'. $_SERVER['REQUEST_URI']); exit(); }
Online kurzy: