Jak na zašifrované footer.php (a jiné části) šablony

Poslední dobou se rozmáhá šifrování nejrůznějších částí WordPress šablon. V některých případech jde o primitivní ochranu před mazáním copyrightu, v jiných je tento způsob využíván ke vkládání škodlivého kódu do stránky.

Zašifrovat lze totiž jak pouhé html tagy, tak také php funkce, které se ovšem vykonají. A pakliže tato funkce dělá něco nekalého a nemá žádný výstup, nikdy se to nemusíme dozvědět. Dbejte tedy zvýšené opatrnosti u takovýchto šablon. Spouštění cizího kódu na vašem serveru může být velmi nebezpečné.

Šifrovaný kód může vypadat třeba takto:

eval(base64_decode('Pz4gICAgICAgICAgICAgDQogICAgICAgIDwvZGl2Pg0KICAgIDwvZGl2Pg0KDQoJPGRpdiBpZD0iYm9keV9yaWdodCI+PGEgaHJlZj0iaHR0cDovL2VtYWlsbWFya2V0aW5ncHJvLm9yZy8iIHRpdGxlPSJFbWFpbCBtYXJrZXRpbmcgc29mdHdhcmUiPkVtYWlsIG1hcmtldGluZyBzb2Z0d2FyZTwvYT48P3BocCBlbmRpZjsgPz4NCjwvYj4NCgkJPC9wPg0KICAgIDwvZGl2Pg0KICAgICAgIA0KPC9kaXY+DQogPD8='));

Pokud si tedy šifrovanou část šablony chcete prohlédnout v plné její kráse, a případně poté nakopírovat do souboru footer.php nešifrovaně, existuje velmi snadná úprava šifrovaného kódu, která vám to umožní.

  1. V libovolném editoru (klidně i v tom zabudovaném ve WordPressu) si otevřete soubor, jehož obsah je šifrovaný (může to být footer.php, případně sidebar.php, ale i jiné).
  2. Vyhledejte řádek, kde je šifrovaný obsah.
  3. Doplňte před a za tento řádek html komentáře označující začátek a konec šifrovaného výpisu pro lepší pozdější orientaci.
  4. Nahraďte php funkci eval funkcí echo

Úpravy ilustruje následující kód:

<!-- začátek šifrovaného výpisu -->
<?php echo(base64_decode('Pz4gICAgICAgICAgICAgDQogICAgICAgIDwvZGl2Pg0KICAgIDwvZGl2Pg0KDQoJPGRpdiBpZD0iYm9keV9yaWdodCI+PGEgaHJlZj0iaHR0cDovL2VtYWlsbWFya2V0aW5ncHJvLm9yZy8iIHRpdGxlPSJFbWFpbCBtYXJrZXRpbmcgc29mdHdhcmUiPkVtYWlsIG1hcmtldGluZyBzb2Z0d2FyZTwvYT48P3BocCBlbmRpZjsgPz4NCjwvYj4NCgkJPC9wPg0KICAgIDwvZGl2Pg0KICAgICAgIA0KPC9kaXY+DQogPD8='));
?>
<!-- konec šifrovaného výpisu -->

Pakliže si takto soubor upravíte a znovu načtete v prohlížeči vaší stránku, můžete si nyní prohlédnout zdrojový kód, kde budete mít mezi výše uvedenými komentáři dekódovaný výpis toho, co se odehrávalo šifrovaně. PHP funkce se po této úpravě již nevykonávají, proto nemusíte mít o své bezpečí strach.

Obsah si můžete, jak jsem již zmínil, nakopírovat zpět do svého souboru s tím, že funkci echo (bývalou eval) smažete, nebo aspoň zakomentujete.

Obecně je ale lepší se poohlédnout po šabloně, která před vámi nic neskrývá. Jestliže jste dokázali odhalit jedno šifrované místo (protože jste chtěli něco upravit a ono to nešlo), může se někde jinde ukrývat další. A je dobré tedy, pokud se této šablony nehodláte vzdát, pečlivě prohlédnout všechny soubory šablony a případná šifrovaná místa odstranit a analyzovat spouštěný kód, jestli neskrývá něco nekalého.

Vůbec nejlepší je nestahovat WordPress šablony z nějakých pochybných diskusních fór. A to ani za předpokladu, že vám zdarma nabízejí šablonu, kterou jiný server prodává. Slušnou sbírku šablon zdarma pro vás má i oficiální server wordpress.org.

Reference:

http://cz.php.net/manual/en/function.eval.php

http://wordpress.org/extend/themes/

Bezpečné vytváření vlastních funkcí ve functions.php

aneb

**Fatal error: Cannot redeclare function() in /somefile.php on line 1**

Při vytváření vlastních funkcí pro vaši šablonu, zvláště pak, pokud se snažíte vytvořit odvozenou šablonu, anglicky child theme, můžete na výše zmíněnou chybu narazit.
Znamená to jediné, funkce, kterou jste pro svou šablonu vytvořili, již existuje. Takže buď se snažíte vytvořit funkci s názvem, který nějaká nativní PHP či WordPress funkce již využívá, nebo je vytvořena uživatelem právě v souboru functions.php vaší šablony, nebo šablony, kterou využíváte pro svou odvozenou šablonu.

Jak vytvořit vlastní (odvozenou) šablonu (child theme)

Snad každý, kdo si nainstaluje WordPress se dřív nebo později pokusí udělat do šablony nějaký zásah. Ovšem nikdy nezasahujte do defaultní šablony (u WordPressu 3.0 a vyšším jde o šablony Twenty Ten v adresáři twentyten). V případě problémů tak budete mít jistotu, že máte šablonu, na kterou můžete přepnou a mít aspoň základní funkční web.

Pro jednodušší úpravy si vytvořte odvozenou šablonu ( Child theme)

V adresáři /wp-content/themes se při defaultní instalaci bez dodatečných šablon nachází jen adresář twentyten s defaultní šablonou. Na této úrovni si vytvořte nový adresář (složku) s názvem vlatní šablony. Třeba “sablona” (vyvarujte se háčkům a čárkám, pro jistotu).

style.css je základ, víc nic nepotřebujete

K vytvoření vlastní odvozené šablony vám stačí jeden jediný soubor v této složce. A sice soubor s názvem “style.css” (malým písmem).

Do tohoto souboru vložíte následující kód:

/*
Theme Name: Šablona
Theme URI: http: //priklad.cz/
Description: Vlastní šablona odvozená od Twenty Ten
Author: Vaše jméno
Author URI: http: //vase-homepage.cz
Template: twentyten
Version:  0.1.0
*/

Theme name je název vaší šablony, ten si zvolte libovolný (pakliže ste si vytvářeli vlastní šablonu z dříve modifikované šablony, přjemenujte si ji tak, aby název byl odlišný od “Twenty Ten”)
Theme URI je adresa vašeho tématu, pokud byste jej třeba někde propagovali a udělali pro něj vlastní webovou stránku, tak zde by byla adresa této propagační stránky. Někdy se také uvádí stránka pro kterou je šablona dělána
Description je popis tématu. Čím bylo inspirováno a podobně
Author: vaše jméno, vašich 15 vteřin slávy ;)
Author URI: pakliže máte nějakou vlastní webovou stránku, šup sem s ní :)
Template: jediný povinný řádek, který nelze vynechat. Musí obsahovat adresář ve kterém je šablona od které je ta vaše odvozena. Pozor, tato položka je case-sensitive (čili je rozdíl mei malými a velkými písmeny)
Version: verze vaší šablony. Buď rovnout 1.0 nebo raději opatrně začněte s 0.1 :)

Opravdu si dejte pozor na položku Template. Ověřte, jestli máte správný název adresáže původní šablony a jestli tato šablona v daném adresáři skutečně je. Pakliže třeba s šablonou nějak manipulujete, může se stát, že šablonu nakopírujete o úroveň níže ( wp-content/themes/twentyten/twentyten ) a pak vám odvozená šablona nebude fungovat.

Dále do souboru style.css patří ještě jeden řádek. A sice tento:

@import url("../twentyten/style.css");

Kde namísto twentyten uvedete stejnou hodnotu, jako u parametru Template. Proč vkládáme tento řádek? Inu proto, že soubor style.css odvozené šablony úplně nahrazuje ten ze šablony původní.Čili, pakliže byste tento řádek nevložili, z původní šablony by se nenahrály vůbec žádné css styly. A to dost pravděpodobně nechcete.

Po tomto řádku již můžete vesele vkládat vlastní styly. Pro orientaci je ještě dobré připomenout, že css má tu vlastnost, že později definované styly přepisují ty dříve uvedené. Tedy, pokud změníte barvu nadpisů h2 v tomto souboru, nepoužije se hodnota nadefinovaná v css původní šablony, i když je celý jeho obsah, díky výše uvedenému řádku, namportován.

functions.php na rozšíření funkcionality

Vedle souboru style.css, který je základním kamenem každé šablony, má spefické vlastnosti ještě soubor functions.php. Jde o soubor, ve kterém uživatel může rozšiřovat funkcionalitu šablony o vlasní funkce. Může si vytvořit vlastní funkce prakticky na cokoli. Mnohé tipy na to co a jak udělat spoléhají právě na tento soubor.

To, co byste měli vědět je to, že tento soubor nepřepisuje soubor functions.php původní šablony, ale načítá se spolu s ním. Přesněji řečeno těsně před ním. Lze tedy nelze takto redeklarovat funkce uvedené v původní šabloně, ale je možné je ve vaší odvozené šabloně bez dalšího užít.

Další soubory odvozené šablony

Tyto dva soubory vám již bohatě stačí k proměně vzhledu a funkcionality šablony. Ovšem můžete chtít také změnit způsob výpisu zobrazení článku, nebo stránky, kategorie či rovnou úvodní stránky. I toto odvozená šablona zvládne. Pakliže adresář odvozené šablony obsahuje nějaký soubor (vyjma style.css a functions.css), který je také v původní šabloně, použije se namísto původního ten, který je obsažený v odvozené šabloně. A pakliže soubor, který by se normálně použil v odvozené šabloně naopak není, použije se ten, který je v šabloně původní. A to je přeci geniální, nemusíte myslet na všechny soubory a jen si měnit to, co přesně potřebujete.

Takže když budete chtít upravit výpis článku, jednoduše si do adresáře své odvozené šablony nakopírujete soubor single.php z původní šablony a začnete editovat. Nic víc, nic míň.

Ještě zde pro vás uvedu jeden velmi důležitý diagram. Ten ukazuje jak WordPress vybírá soubory pro zobrazení konkrétní stránky (příspěvku, rubriky, stránky, stránky s výsledkama hledání a podobně). Všimněte si, že vše má fallback na index.php. Čili, pokud vaše původní šablona některý ze souborů, který byste chtěli editovat nemá, vezměte druhý či třetí, a tak dále, v pořadí, pokud existuje, a pakliže ne, vždy můžete sáhnout po index.php a ten přejmenovat na vámi požadovaný soubor (single.php, page.php, category.php, search.php a tak dále a tak dále).

Zdroj: http://www.wp-tricks.co.il/

Co dělat, když už jste do defaultní šablony zasáhli? Jak z takové šablony udělat odvozenou?

To se stává často. Ale i toto má své řešení. Stáhněte si znovu vaší instalaci WordPressu (anglicky: http://wordpress.org/, nebo česky: http://cs.wordpress.org/), rozbalte archív a v adresáři wp-content/themes uvidítě původní šablonu. Adresář s šablonou přejmenujte na twentyten2 a nakopírujte jej do vaší instalace na serveru do složky wp-content/themes. V administraci aktivujte tuto staronovou šablonu. Bude mít stejný název, ale v šedivém obdélníčku následujícím za větou: “Všechny soubory této šablony jsou uloženy v” uvidíte “themes/twentyten2″.

Poté můžete již přejmenovat adresář vaší šablony (z twentyten) na vlastní název a změnit název šablony v souboru style.css (řádek Theme name). Nyní musíte v administraci opět aktivovat tuto vaší šablonu (již se bude zobrazovat  pod vaším jménem). Po její úspěšné aktivaci přejmenujte adresář “twentyten2″ na “twentyten”. Tím umožníte budoucí aktualizaci této šablony v novějších verzích WordPressu.

No a nyní již zpět k vaší odvozené šabloně. Do souboru style.css přidejte řádek “Template: twentyten”. Samozřejmě můžete veškerý další obsah souboru style.css smazat a nahradit jej importovacím řádkem. Dalším důležitým krokem je smazání všech funkcí v souboru functions.php (pakliže neobsahuje nějaké vámi definované, ty můžete zachovat). No a poté už můžete mazat všechny soubory, které jste doposud neupravili. Pakliže ste neupravovali soubor 404.php a víte, že jej upravovat ani nebudete, klidně jej smažte. Obdobně pro všechny soubory, které jste neupravovali, ani upravat chtít nebudete.

A kde je nějaká výhoda odvozených šablon?

Možná se ptáte, proč podstupovat toto martýrium a proč si rovnou nenakopírovat celý adresář twentyten do vlastního názvu a nepřepsat název šablony ve style.css a mít tak již kompletní šablonu a neupravovat ji komplet?

Odvozené šablony vám umožní bezpečný upgrade vaší původní šablony. Pakliže budoucí verze WordPressu upgraduje šablonu Twenty Ten, bude vaše odvozená šablona čerpat upgradovaný soubor functions.php, upgradovaný index.php (pakliže nemáte vlastní) a také upgradovaný style.css. Totéž platí o šabloně, kterou si někde koupíte a její autor vydá další, třeba opravnou, verzi. Můžete si poté upgradovat původní šablonu bez toho, anižbyste přišli o své úpravy. Jde tedy především o bezpečnou úpravu šablon.

Reference:

http://codex.wordpress.org/Child_Themes

http://codex.wordpress.org/Template_Hierarchy

Vlastní Walker pro vaše šablony

WordPress Funkce na procházení více položek, wp_nav_menu, wp_list_categories, wp_list_pages, wp_list_comments a další, mají mezi svými parametry také jeden, který je, a často i zůstává, pro uživatele tak trochu zahalen tajemstvím. Jde o parametr “walker”.

Jako modelovou, pro tento článek, jsem si vybral funkci wp_list_categories(), která prochází kategorie a ty posléze, dle v parametrech předaných pravidel, vypisuje, ale také třeba jen vrací (pomocí parametru echo). Skrce parametry této funkce můžeme změnit kde co. Můžeme nechat vypsat i prázdné kategorie, můžeme ovlivnit pořadí výpisu, to, jestli se kategorie vypíší jako seznam nebo ne, jestli zobrazíme počet příspěvků v kategorii a tak dále a tak dále.

Tvůrci WordPressu se nám snažili případnou editaci co možná nejvíc zpříjemnit. Ovšem někdy ani tato široká škála možností nestačí a tvůrce si s parametry nevystačí. V tom případě přichází na řadu vytváření vlastního Walkeru.

Jaké Walkery jsou ve WordPressu dostupné

Walker je třída, jenž zajišťuje procházení více položek a jejich výpis či vracení do proměnné. Všechny WordPress Walkery (Walker_Comment, Walker_CategoryDropdown, Walker_PageDropdown, Walker_Page, Walker_Category, Walker_nav_menu) jsou odvozené od původní třídy Walker, kterou rozšiřují (extends) o nové funkce.
Walkery Walker_Category, Walker_Page, Walker_PageDropdown a Walker_CategoryDropdown jsou umístěny v souboru wp-includes/classes.php. Walker_Comment je v souboru wp-includes/comment-template.php a Walker_nav_menu je v souboru wp-includes/nav-menu-template.php.

Poznámka: Pro potřeby administrace existují ještě další Walkery a jsou definované v souborech wp-admin/includes/template.php (Walker_Category_Checklist) a wp-admin/includes/nav-menu.php (Walker_Nav_Menu_Edit, Walker_Nav_Menu_Checklist). Z nich můžete čerpat inspiraci pro vaše úpravy walkerů.

Vytváříme vlastní Walker

Pakliže chceme takový Walker modifikovat, musíme si vytvořit nový, který bude rozšiřovat (extend) již nějaký existující. A to buď původní Walker, nebo již nějaký, který jej rozšiřuje (extends). Jak na to.

V souboru functions.php naší šablony (pakliže jej vaše šablona ještě nemá, klidně jej vytvořte) vytvoříme novou třídu (class), která bude rozšiřovat (extends) nějaký Walker. Jak jsem psal, budeme se zde modelově zabývat rošiřováním Walkeru funkce wp_list_categories(). Tento Walker je definován v souboru wp-includes/classes.php na řádku 1283

Tato třída definuje 4 funkce, a sice: start_lvl, end_lvl, start_el a end_el. Funkce start_lvl se volá, když některá kategorie má subkategorie a tyto se mají vypsat hierarchicky, end_lvl se zas vykoná když se dojde za poslední položku hierarchicky vypsané subkategorie, start_el se volá vždy, když se zpracovává nová položka, a end_el, když se ukončilo zpracování každé položky.

Když budeme chtít například upravit způsob výpisu jednotlivých položek bude nám stačit, když námi nově vytvořená třída bude definovat jen funkci start_el. Nic víc není třeba. Samozřejmě je možné, upravovat více, nebo dokonce všechny funkce.

Čili v souboru functions.php si nadefinujeme novou třídu rozšiřující Walker_Category.

class Vlastni_Walker extends Walker_Category {
...
}

A do této třídy si můžeme nakopírovat funkce, které chceme upravit.

class Vlastni_Walker extends Walker_Category {
function start_el(&amp;$output, $page, $depth, $args, $current_page) {
		if ( $depth )
			$indent = str_repeat("\t", $depth);
		else
			$indent = '';
 
		extract($args, EXTR_SKIP);
		$css_class = array('page_item', 'page-item-'.$page-&gt;ID);
		if ( !empty($current_page) ) {
			$_current_page = get_page( $current_page );
			if ( isset($_current_page-&gt;ancestors) &amp;&amp; in_array($page-&gt;ID, (array) $_current_page-&gt;ancestors) )
				$css_class[] = 'current_page_ancestor';
			if ( $page-&gt;ID == $current_page )
				$css_class[] = 'current_page_item';
			elseif ( $_current_page &amp;&amp; $page-&gt;ID == $_current_page-&gt;post_parent )
				$css_class[] = 'current_page_parent';
		} elseif ( $page-&gt;ID == get_option('page_for_posts') ) {
			$css_class[] = 'current_page_parent';
		}
 
		$css_class = implode(' ', apply_filters('page_css_class', $css_class, $page));
 
		$output .= $indent . '
 
	<li class="' . $css_class . '"><a title="' . esc_attr( wp_strip_all_tags( apply_filters( 'the_title', $page-&gt;post_title, $page-&gt;ID ) ) ) . '" href="' . get_page_link($page-&gt;ID) . '">' . $link_before . apply_filters( 'the_title', $page-&gt;post_title, $page-&gt;ID ) . $link_after . '</a>';
 
		if ( !empty($show_date) ) {
			if ( 'modified' == $show_date )
				$time = $page-&gt;post_modified;
			else
				$time = $page-&gt;post_date;
 
			$output .= " " . mysql2date($date_format, $time);
		}
	}
}</li>

A můžeme se pustit do upravování. Provádět si můžeme prakticky cokoli. Když budeme s úpravami hotovi a spokojeni, stačí již jen zavolat funkci wp_list_categories() s patřičným parametrem.

1
wp_list_categories( array( 'walker' => new Vlastni_Walker() ) );

Samozřejmě můžeme redefinovat také všechny funkce, která třída Walker_Category dědí od původní třídy Walker. Tato třída je definována opět v souboru wp-include/classes.php, tentokráte na řádku 742. Jde o funkce, kromě těch čtyrech již zmíněných, display_element(), walk(), paged_walk(), get_number_of_root_elements() a unset_children().

Jak upravit výstup funkce wp_head()

funkce wp_head() slouží ke spouštění akcí (actions), které musí být vykonány v hlavičce. Jde například o generování odkazů na styly pluginů. Bez této funkce by pluginy neměly šanci do hlavičky svůj kód procpat a nutily by, při instalaci, uživatele k úpravě hlavičky.

Samozřejmě je tato funkce také využívána wordpressem samotným ke generování kódu, který využívá. Někdy je tento kód užitečný a žádoucí, jindy ne. Když shledáte, že kód žádnoucí není, což je možné říci například o meta tagu “generator”, který komukoli bez skupulí oznámí verzi wodpressu. Toho pak může například využít potencionální útočník.

Pakliže chcete některé informace, které hlavička generuje odstranit, máte v zásadě dvě možnosti. Buď použít plugin, nebo přidat pár řádků kódu do functions.php.

Plugin Clean up wp_head

Řešením tohoto problému se zabývá plugin Clean up wp_head. Ke stažení zde: http://wordpress.org/extend/plugins/clean-up-wp-head/

Po nainstalování vám v sekci “Nastavení” přibude položka “Clean up wp_head”, kde si již jednoduchým zaškrtáváním navolíte co zobrazit a co ne.

Řešení skrze functions.php

Pakliže nejste fanouškem pluginů, máte omezené zdroje (php memory limit), chcete nastavení mít zakomponované přímo v šabloně pro snadný přenost na jiné servery a nebo k tomu máte jakýkoli jiný důvod, můžete využít úpravy souboru functions.php v adresáři vaší wordpress šablony. Pakliže vaše šablona tento soubor nemá, jednoduše jej vytvořte.

Příprava

K odstraňování zobrazených souborů využijeme funkci remove_action(). Seznam akcí, přiřazených funkci wp_head() je k nahlédnutí v souboru wp-includes/default-filters.php. Zde uvádím upravený výpis části tohoto souboru (odstranil jsem z posloupnosti řádky, které pro další výklad nejsou důležité):

add_action( 'wp_head',             'wp_enqueue_scripts',            1     );
add_action( 'wp_head',             'feed_links',                    2     );
add_action( 'wp_head',             'feed_links_extra',              3     );
add_action( 'wp_head',             'rsd_link'                             );
add_action( 'wp_head',             'wlwmanifest_link'                     );
add_action( 'wp_head',             'index_rel_link'                       );
add_action( 'wp_head',             'parent_post_rel_link',          10, 0 );
add_action( 'wp_head',             'start_post_rel_link',           10, 0 );
add_action( 'wp_head',             'adjacent_posts_rel_link_wp_head', 10, 0 );
add_action( 'wp_head',             'locale_stylesheet'                    );
add_action( 'wp_head',             'noindex',                       1     );
add_action( 'wp_head',             'wp_print_styles',               8     );
add_action( 'wp_head',             'wp_print_head_scripts',         9     );
add_action( 'wp_head',             'wp_generator'                         );
add_action( 'wp_head',             'rel_canonical'                        );
add_action( 'wp_head',             'wp_shortlink_wp_head',          10, 0 );

Snad jen pro úplnost dodám, že add_action má jako první parametr funkci, na kterou se má nová funkce pověsit (hook) (viz seznam takových funkcí ), poté název funkce, která se má pověsit (hook), poté prioritu nově přidávané funkce a počet parametrů funkce. To abyste se dokázali v kódu vyznat.

Samotné odstraňování

Když už víme, co všechno je na funkci wp_head pověšené (hooked), můžeme začít s odstraňováním toho, co nechceme zobrazovat.

K tomu nám, jak již bylo řečeno, slouží funkce remove_action(). Ta má stejné parametry jako funkce add_action(). A to je důležité. K odstranění již pověšené (hooked) funkce  musíme zadat identické parametry priority a počtu argumentů funkce, jako byly zadány při přidávání této funkce pomocí add_action().

Takže co a jak odstranit. Zde je ukázka typického výstupu funkce wp_head() ze stránek david.binda.cz :

<link rel=”alternate” type=”application/rss+xml” title=”david.binda &raquo; Feed” href=”http://david.binda.cz/feed” />
<link rel=”alternate” type=”application/rss+xml” title=”david.binda &raquo; Comments Feed” href=”http://david.binda.cz/comments/feed” />
<link rel=”alternate” type=”application/rss+xml” title=”david.binda &raquo; Úvod Comments Feed” href=”http://david.binda.cz/uvod/feed” />
<link rel=”EditURI” type=”application/rsd+xml” title=”RSD” href=”http://david.binda.cz/xmlrpc.php?rsd” />
<link rel=”wlwmanifest” type=”application/wlwmanifest+xml” href=”http://david.binda.cz/wp-includes/wlwmanifest.xml” />
<link rel=’index’ title=’david.binda’ href=’http://david.binda.cz’ />
<link rel=’prev’ title=’Nabídka’ href=’http://david.binda.cz/nabidka’ />
<meta name=”generator” content=”WordPress 3.0.1″ />

No a zde je seznam remove_action funkcí odstraňující jednotlivé řádky tohoto výpisu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//odstraní odkaz (link) s parametrem rel = alternate odkazujícím na feed nejnovějších článků a komentářů
remove_action( 'wp_head', 'feed_links', 2 );
//odstraní odkaz (link) s parametrem rel = alternte odkazujícím na speciální feeds (komentáře stránky v tomto případě, ale jde i o feed rubrik, štítků a podobně)
remove_action( 'wp_head', 'feed_links_extra', 3 );
//odstraní odkaz (link) s parametrem rel = EditURI
remove_action( 'wp_head', 'rsd_link' );
//odstraní odkaz (link) na wlwmanifest (Windows Live Writer)
remove_action( 'wp_head', 'wlwmanifest_link' );
//odstraní odkaz (link) s parametrem rel = index
remove_action( 'wp_head', 'index_rel_link' );
//odstraní odkaz (link) s parametrem rel = prev a rel = next (next není ve výpisu nahoře)
remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
//odstraní poslední řádek, meta tag generator
remove_action( 'wp_head', 'wp_generator' );
//odstraní odkaz (link) s parametrem rel = up (není ve výše uvedeném výpise)
remove_action( 'wp_head', 'parent_post_rel_link', 10, 0 );
//odstraní odkaz (link) s parametrem rel = start (není ve výše uvedeném výpisu)
remove_action( 'wp_head', 'start_post_rel_link', 10, 0 );

Takže již víte, jak odstranit odkazy (link) generované funkcí wp_head(). Já osobně, kdybych měl něco odstraňovat, bych odstranil meta tag generator, odkaz na wlwmanifest a odkaz na Really simple discovery (EditURI). Zvláště pak, pokud pravidelně neaktualizujete a chcete si vaší instalaci WordPressu udržet v bezpečí.

Reference a další užitečné odkazy:

http://codex.wordpress.org/Function_Reference/remove_action

http://codex.wordpress.org/Function_Reference/add_action

http://codex.wordpress.org/Plugin_API/Action_Reference

http://core.trac.wordpress.org/browser/tags/3.0.3/wp-includes/default-filters.php

http://adambrown.info/p/wp_hooks – sezman všech wordpress hooks

Jak rozdělit dlouhý příspěvek na několik stránek? WordPress Quicktags!

Pokud řešíte problém, jak rozdělit dlouhý příspěvek ve WordPressu na několik stránek a hledáte nějaký šikovný pluign pro tuto činnost, nehledejte. To WordPress umí již v základu, jen málo kdo čte dokumentaci.

Snad každý uživatel ví, že WordPress umožňuje rozdělit text na perex a hlavní část textu. Tak se děje pomocí quicktagu <!- -more- -> Jeho použitím docílíte toto, že na výpisu článku se zobrazí jen vámi vybraná úvodní pasáž příspěvku, aniž byste museli v šabloně něco přenastavovat.

Poznámka: Jinou možností je použití Stručného výpisu příspěvku v kombinaci s funkcí the_excerpt() namíto funkce the_content(). Viz http://codex.wordpress.org/Function_Reference/the_excerpt

Neexistuje ale pouze <!- -more- ->, ale také <!- -nextpage- ->

O dalším dostupném quicktagu ví jen málokdo. A přitom se jedná o velmi užitečnou značku. Tuto značku můžete v příspěvku, na rozdíl od <!- -more- -> užít kolikrát chcete. Na místě, kde ji použijete se příspěvek rozdělí a při správném použití funkce wp_link_pages() : http://codex.wordpress.org/Template_Tags/wp_link_pages, se také zobrazí odkazy na další stránky příspěvku. Můžete tak příspěvek rozdělit na několik stránek a usnadnit tak čtenářovi čtení (dlouhý text většinou odrazuje).

Použití funkce wp_link_pages() není nijak obtížné. Profesionální šabona by měla tuto funkci mít již v základu připravenou k použití a není tedy třeba nic upravovat. Pokud jste si třeba šablonu ale dělali sami, nebo vaše šablona z nějakého jiného důvodu tuto fci neobsahuje, není nic jednoduššího, než ji do šablony vložit. A to klidně rovnou pod funkci the_content() v souboru single.php, popřípadě také page.php

Tato funkce, bez změny parametrů, Vypíše Tento kód:

1
<p>Stránky: ODKAZY NA JEDNOTLIVÉ STRÁNKY</p>

Čili je obsah umístěn uvnitř odstavce a nebude se tedy s obsahem nějak přímo mísit. Použití je tedy následující:

<?php
...
the_content();
wp_link_pages();
...
?>

Pokud používáte k výpisu článku vlastní query_posts funkci, zkontrolujte, jestli jste pamatovali na možnost stránkování (parametr paged). Více o této problematice zde: http://david.binda.cz/wordpress-nefunkcni-strankovani-v-dusledku-query_posts

Reference:

http://codex.wordpress.org/Write_Post_SubPanel#Quicktags
http://codex.wordpress.org/Template_Tags/wp_link_pages
http://codex.wordpress.org/Function_Reference/the_excerpt
http://codex.wordpress.org/Function_Reference/the_content

Více výpisů článků najednou (Multiple loops)

Proč někdo potřebuje více výpisů článků (dále již jen multiple loops)? WordPress codex odpovídá v tomto duchu:

Odpověď na tuto otázku je, v zásadě taková, že chceme udělat s jednou skupinou článků něco jiného, než s druhou skupinou článk, ale přitom chceme obě skupiny vypsat na jedné stránce zároveň. „Něco jiného“ může znamenat prakticky cokoli. Limitovaní jste pouze vašemi znalostmi PHP a vaší představivostí.

Stručný popis základního cyklu pro výpis příspěvků

Než se pustíme do multiple loops, je dobré vědět něco o základní cyklu pro výspis článků. Tento vypadá takto:

/—code php





\—

Nejprve se ujistíme, že je co vypisovat (první řádek). Na stránce archivu či kategorie (soubory archive.php či category.php) jde o to, jestli jsou v daném archivu (dle měsíce, data, roku, autora, štítku) či kategorii nějaké články. Určení okruhu článků (výběr kategorie či archivu) je provedeno z url adresy. Pakliže máme články, které splňují kritéria, vezme kód každý jednotlivý článek a provede s ním to, co mu řekneme.

Zpracování stejného souboru článku dvakrát

No a nyní se již můžeme pustit do více výpisů takových článků. Nejdříve si předvedeme jak zpracovat stejný okruh článků znovu. Čili ještě jednou provést výpis stejných článků, ovšem třeba s jiným formátováním výstupu.

Jde o celkem jednoduchou operaci. Stačí použít funkci rewind_posts(). Ta přetočí pomyslné počítadlo vypsaných článků zpět na začátek a další výpis začně znovu, pěkně od začátku.

/—code php






\—

Dva různé soubory článků

Pokud ovšem chceme mít na stránce dva různé soubory článků, bude již operace trochu složitější, ovšem stále jde celkem o banalitu, kterou se lze snadno naučit.

Poumůže nám funkce query_posts(), která vytvoří nový objekt s články a přetočí jej na začátek, přičemž stávající smaže a nelze jej dále znovu použít. Na stránce popisu funkce query_posts() se dočtete možnosti, jak specifikovat jaké články chcete vybrat.

Použití je poté následující:

/—code php
// nejprve proběhne výpis tradičních článků



// a poté vybereme posledních 5 článků z kategorie nezařazené
// parametr category_name využívá název url tzv. slug, nikoli název




\—

Dva různé soubory článků se zachováním původního souboru

Výše uvedené řešení, jak bylo napsáno, nezachovává původní soubor článků. To může být někdy na škodu, jelikož s ním třeba chceme také ještě pracovat. Původní soubor lze ovšem zachovat. Řešení je následující:

/—code php



have_posts()) : $muj_soubor->the_post(); ?>

// pro pochopení toho,že původní soubor byl zachován přidávám jeho přetočení a nový výpis původního souboru







\—

Jak vidíte v kódu, nemáte přístup, v novém souboru, k funkcím have_posts či the_post přímo. Ale skrze název vámi vytvořeného objektu muj_soubor. Na to je nutné pamatovat. A zároveň platí, že uvnitř cyklu while již máte přístup ke všem funkcím (the_content, the_title, the_permalink a podobně) přímo, bez reference na objekt.

Objekt typu WP_Query() přijímá stejné parametry jako funkce query_posts().

Vnořené soubory článků (nested loops)

Také se může stát, že potřebujete ještě před dokončením jednoho výpisu článků vypsat další soubor. I toto je řešitelné, ovšem má to svá specifika, na která je nutné myslet. Je zde opět nutnost vytvořit nový objekt a na konci výpisu je nutné zavolat funkci wp_reset_postdata()

/—code php
// vybereme články z kategorie s ID 3
$muj_soubor = new WP_Query( „cat=3“ );
if ( $muj_soubor->have_posts() ) {
while ( $muj_soubor->have_posts() ) {
$muj_soubor->the_post();
the_content(); //výpis obsahu již probíhá bez reference na objekt muj_soubor
}
}
wp_reset_postdata(); // tento řádek je nesmírně důležitý a u vnořených výpisů nesmí chybět!
\—

Informace o této problematice na WordPress codex (anglicky):

http://codex.wordpress.org/The_Loop#Multiple_Loops

Vnořené výpisy článků: http://codex.wordpress.org/The_Loop#Nested_Loops

Reference funkce query_posts: http://codex.wordpress.org/Function_Reference/query_posts

Popis objektu WP_Query: http://codex.wordpress.org/Function_Reference/WP_Query

Vlastní řazení výpisu rubrik ve widgetech i funkcích

Použití rubrik, respektive jejich výpisu častou používáme k vytvoření navigace. Funkce wp_list_categories() je snad každému tvůrci WordPress šablon známá. Tato funkce nám ovšem, stejně jako její „front-end“ ve widgetech, dává na výběr řazení dle následujících kritérií:

  • ID
  • name – Defaultní nastavení
  • slug
  • count
  • term_group

**Vlastní řazení výpisu rubrik**

Často by se nám ale hodilo vlastní řazení, ideálně takové, které si můžeme přizpůsobit. Od verze 3.0 máme ve WordPressu možnost vytvářet uživatelská menu, čímž lze toto vlastní řazení nahradit (O WordPress menu bude některý další příspěvek). Ovšem existuje také jednoduchý plugin – My Category Order -, který nám do navigačního menu v administraci do sekce „Příspěvky“ přidá položku „Pořadí rubrik“, kde si pořadí můžeme namixovat dle svých představ jednoduchým „drag & drop“ (tažením, jak se hezky česky překládá)

Tohoto pluginu můžeme poté využít ve widgetech. Sem již česká lokalizace nedorazila a tak máme k dispozici widget „My Category Order“ s volbou Order by: „My order“ zohledňující naše pořadí.

Ovšem jak již titulek napovídá, lze naše pořadí zohlednit i při použití funkce wp_list_categories() a to přidáním parametru ‘orderby=order’ (namísto například orderby=slug či orderby=name).

**Nevýhody užití pluginu oproti řešení dle WordPress Menu**

Jistou, i když drobnou a odstranitelnou, nevýhodou u tohoto postupu, oproti wordpress menu, je nemožnost tažením při sestavování pořadí, nějakou tu rubriku vyjmout (to při použití wordpress menu lze). Ovšem i rozhraní widgetu nabízí možnosti „Vyjmout“ (sem čeština dorazila) a „Exclude Tree“ (sem nedorazila :) ). Samozřejmě při použití funkce wp_list_categories() používáme analogicky ‘exclude=1,2′ a ‘exclude_tree=1′. Jak jsem již psal, při použití wordpress menu máme posléze možnost skrze administraci bez zásah do šablony jednoduše kategorie vyjmout. A není nutné to navíc, při použití jak ve widgetu tak v šabloně, nastavovat na dvou místech.

Poznámka: Rozdíl mezi ‘exclude’ a ‘exclude_tree’ – Při užití exclude se z výpisu vyjme jen a pouze kategorie s korespondujícím ID. Při použití exclude_tree se vyjme kategorie s korespondujícím číslem, ale také všechny její podkategorie (subcategories).

**Ošetření pro případ nezapnutného pluginu**

Použití tohoto pluginu v šabloně není navíc nutné ošetřovat pomocí function_exists() či is_plugin_active() funkcí. Pakliže plugin nebude aktivní, funkce wp_list_categories() v šabloně s nastaveným ‘orderby=order’ bude tento parametr ignorovat a výpis provede dle defaultní hodnoty parametru orderby ‘orderby=name’ (čili vypíše kategorie seřazené dle názvu).

Správné ošetření použití pluginů a vlastních funkcí ve WordPress šabloně

Aneb

**Fatal error: Call to undefined function …**

Ačkoli WordPress nabízí v základu velmi slušnou škálu funkcí, jeho popularitu zvyšuje snad ještě větší množství pluginů, které práci se základním wordpressem buď „pouze“ zjednodušují či zpříjemňují, nebo dokonce rozšiřují.

Poznámka: asi nejlepším zdrojem pluginů je přímo na oficiálních stránkách wordpressu: http://wordpress.org/extend/plugins/

Mnoho tvůrců šablon či administrátorů webových stránek založených na WordPressu proto rádo sáhne po nějakém tom pluginu. Stáhnou jej, nahrají přes FTP do příslušného adresáře (pakliže nevyužijí možnost vyhledávání a instalace pluginu přímo z administrace wordpressu) a vloží nově přidanou funkci do šablony. Vše funguje tak jak má. Až do doby, kdy plugin deaktivují nebo upgradují na vyšší verzi, ve které plugin nefunguje. Poté se jejich stránka nezobrazí vůbec, nebo se zobrazí jen její část a poté chyba: „Fatal error: Call to undefined function ….“

To svědčí o tom, že tvůrce šablony řádně neošetřil užití pluginu. Jak na to? Hned si to vysvětlíme.

Ošetření pluginu pomocí function_exists()

Vezměme si pro demonstraci plugin Limit Post Add-on. Tento plugin nám rozšiřuje možnosti WordPressu o limit počtu slov při výpisu článku na hlavní stránce, archívech a rubrikách (samozřejmě jej lze užít i jinde). A dělá to jednoduše. Dle instalačních pokynů stačí nahradit funkci the_content(); funkcí the_content_limit(200, „continue…“); ( „5) Replace the_content(); with the_content_limit(200, „continue…“);“ )

To ale samozřejmě nestačí. Když šablonu vezmete a přenesete ji poté třeba na jinou instalaci wordpressu bez tohoto pluginu, nebo jej deaktivujete či jinak znemožníte jeho fungování, dostane se vám již zmíněného upozornění: „Fatal error: Call to undefined function the_content_limit„.

K ošetření tohot možného stavu použijeme nativní PHP funkci function_exists(). A sice takto:

<?php if ( function_exists(‘the_content_limit’) : ?>
<p><?php the_content_limit(200, ‘Continue…’);  ?></p>
<?php else : ?>
<p><?php the_content(); ?></p>
<?php endif; ?>

Všimněte si, že v kódu nejdříve otestuji existenci funkce the_content_limit a pakliže existuje, tak ji zavolám. Pokud ne, mám připravený tzv. fall-back (funkci, která se vykoná při selhání podmínky) na klasický the_content().

Poznámka: Fall-back je v tomto případě nepostradatelný. Pokud by došlo k deaktivaci pluginu, na stránce by se nevypsal žádný obsah! A to nechceme.

Ošetření pomocí plugin_is_active()

Na rozdíl od prvního řešení nyní využijeme „wordpressí“ funkci (funkce function_exists() je PHP nativní). Použití této funkce je vhodné v případě, kdy nevíme přesně, jaké funkce plugin vytváří a zpřístupňuje. Co ovšem musíme znát, je adresář ve kterém je plugin nainstalovaný a název php souboru pluginu (většinou jsou tyto názvy totožné).

<?php if ( is_plugin_active(‘adresar-pluginu/soubor-pluginu.php’) ) : ?>
//vykonáme požadované operace pro případ, že plugin aktivní je
<?php endif; ?>

Namísto adresar-pluginu přijde název adresáře (složky) ve které je plugin nainstalovaný. Nejedná se o složku „wp-content/pluigns“ ale o složku obsaženou právě v této složce. Cestu nezadáváme absolutní, ale relativní ke složce „/wp-content/plugins/“ a namísto „soubor-pluginu.php“ přijde název souboru pluginu (jak jsem psal, je většinou totožný s názvem pluginu s pomlčkami namísto mezer a také bývá totožný s názvem složky pluginu).

Takže do budoucna již žádné nepříjemné

Fatal error: Call to undefined function…

Speciální šablona pro konkrétní rubriku, stránku či příspěvek

Někdy se stane, že potřebujete v redakčním systému WordPress pro nějakou konkrétní kategorii, stránku či příspěvek zvláštní zobrazení – šablonu. Chcete třeba pro určitou rubriku odstranit nadpis, nebo nechat vypsat nějaký text navíc. K docílení tohoto efektu můžete použít složitý systém podmínek v php, nebo jednoduše vytvořit nový soubor (od WordPress 2.9). Jak tedy na to?

Řešení 1: WordPress template slug

Máte-li již existující šablonu, na které chcete provést změny (dejme tomu category.php  pro zobrazení výpisu rubrik), vezmete tento soubor a nakopírujete jeho aktuální obsah do nového souboru se speciálním názvem. Název souboru bude podle jednoho z následujících schémat:

(pokud ve vaší šabloně neexistuje soubor category.php, užijte soubor archive.php a pokud ani ten neexistuje, použijte index.php – déle uvedené názvy souborů se ale nemění v závislosti na názvu souboru s původním obsahem)

category-1.php (pro kategorii s ID 1)

category-nazev-kategorie.php (pro kategorii s názvem „Název kategorie“)

Obsah tohoto nově vytvořeného souboru si poté upravíte dle potřeby.

Obdobně lze vytvořit takto speciální šablony pro jednotlivé příspěvky (post-5.php či post-nazev-prispevku.php) i stránky (page-1.php či page-nazev-stranky.php).

Řešení 2: Custom templates for wordpress page

Přiřazení speciální šablony ke konkrétní kategorii, přípěvku či článku si už WordPress dále zařídí sám.

Pro stránky navíc můžete vytvořit speciální šablonu, která bude přístupná skrze administrační rozhraní při tvorbě či editaci stránky a můžete ji tedy užít pro více stránek na vašem webu. Opět vyjdeme ze základního souboru page.php, jehož obsah si nakopírujeme do nového souboru, nyní již s libovolným názvem. Na úvod (na úplně první řádek) tohoto .php souboru vložíte následující kód:

<?php
/*
Template Name: Nazev sablony
*/
?>

Upravíte si samozřejmě název šablony, který je zapsán za dvojtečkou. V našem případě jde o Nazev sablony (je rozumné nepoužívat při volbě názvu diakritiku, co kdy to někdy přeci jen zlobilo ;) )

Poznámka: Pro úpravu souborů můžete využít například Bluefish editor s nainstalovaným neoficiálním rozšířením pro podporu WordPress syntaxe a možností vložit již hotovou část kódu (mezi již hotovými kódy je i kód pro vytvoření nové šablony pro stránku): http://david.binda.cz/turn-bluefish-editor-into-powerful-wordpress-ide