WordPress – konec problémů s psaním hranaté závorky

Jestli používáte aktuální verze WordPressu a nejste úplní začátečníci, tak jste nejspíš chtěli někdy napsat nějaký shortcode (jestli neznáte, to je něco jako „makro“ připravené nějakým vývojářem tématu či šablony použitelné v rámci textů příspěvků, uvozené nějakým magickým slovem v [hranatých závorkách], více viz Shortcode API).

Jenže WordPress někdy od verze 4.něco používá pro wysiwyg editor aktualizovanou verzi TinyMCE, která obsahuje i fullscreen plugin – vychytávku, která když v editoru zmáčknete Ctrl+Alt+F (nebo pravý alt + F), tak vám jej zvětší na plné okno, aby vás nic nerušilo.

A to je právě ten problém, protože stejná klávesová zkratka je na české, slovenské, polské a bůhvíjakých dalších klávesnicích vyhrazená pro napsání levé hranaté závorky, bez které se ten shortcode nedá moc napsat (vynechám hacky jako přepínání klávesnic či napsání jinde a zkopírování).

Reportoval jsem to jako bug WordPressu, tam mě s tím poslali k … TinyMCE, tak jsem to reportoval i tam, uvidíme, jestli to upraví.

Nicméně neplačte, řešení existuje a je primitivní, stačí jedna pidiaakcička do vašeho functions.php souboru, případně pro ty, pro které je i to příliš složité, jsem z toho připravil i plugin. Tak si vyberte:

Úprava – přidání do functions.php:

// This is all the magic. Simply called on TinyMCE Init and removing CTRL+ALT+F shortcut defined in default TinyMCE package
add_action( 'wp_tiny_mce_init', function () {
?>
<script>
 jQuery( document ).on( 'tinymce-editor-init', function( event, editor ) {
 editor.shortcuts.remove( 'meta+alt+f' );
 }
 );
</script>
<?php
});

Plugin

Plugin je zatím ke stažení zde. Dal jsem jej ke zveřejnění v oficiálním seznamu pluginů, pak to tu aktualizuji.

Licence

Jestli máte neodbytnou potřebu mi poděkovat, ocením, když o této stránce dáte vědět na svém Facebooku, Twitteru, Google plus, blogu či třeba domovní nástěnce. Jo a jestli to tu neznáte – možná se vám bude hodit pár dalších podobně užitečných tipů.

Disclaimer

A samozřejmě – jestli vám můj kód sežere kočku či zapálí dům, tak mi nevolejte.

WordPress: vytvářejte snadno podstránky aktuální stránky

Pakliže používáte WordPress jako CMS pro firemní web, pak nejspíše používáte Stránky, které mají na rozdíl od Příspěvků hierarchii. Běžně tak potřebujete vytvořit podstránku k nějaké stránce. Je to triviální, prostě při vytváření stránky vyberete v pravém menu Nadřazenou stránku a hotovo.

Jenže když těch stránek máte hodně, musíte tu nadřazenou hledat, navíc mnoho lidí má jiný pracovní a myšlenkový postup – jsou na webu na té nadřazené stránce a řeknou „ha, k téhle stránce by se hodila nějaká podstránka“, nebo prostě vytváří nový web a pracují prostě stylem „Teď vytvořím Úvodní stránku. Publikuju jí. Zkontroluji. A teď k ní potřebuju podstránku“.

Proto jsem pro vás připravil drobný kód pro vaše functions.php, které přidá do záložky Akce ve vaší Navigační liště (Admin Bar) volbu „Přidat podstránku“. Po kliknutí na tento odkaz se vám otevře okno pro založení nové stránky a automaticky předvyplní Nadřazenou stránku tou, ze které jste přišli.

// přidá odkazy do admin baru
function kapler_admin_bar_menu($wp_admin_bar) {
global $post;
 // jen když jsem na Stránce a aktuální uživatel má právo editovat stránky a má právo k té nadřazené stránce
 if (is_page() && current_user_can( 'edit_page', $post->ID )) {
 $args = array(
 'id' => 'add_subpage',
 'title' => _('Vytvořit podstránku'), 
 'href' => admin_url( 'post-new.php?post_type=page&parent='.$post->ID ),
 'parent' => 'new-content'
 );
 $wp_admin_bar->add_node($args);
 }
}
add_action('admin_bar_menu', 'kapler_admin_bar_menu');

// když je editační stránka page s předvyplněným parent, nastaví jej
function kapler_admin_head() 
{
 // vkládat jen u Stránek a jen když je vyplněný parametr parent
 if( !empty($_GET['post_type']) && $_GET['post_type']=='page' && !empty( $_GET['parent'] ) ) {
 ?>
 <script type="text/javascript">
 jQuery(document).ready( function($) 
 {
 $('#parent_id').val(<?php echo $_GET['parent']; ?>);
 });
 </script>
 <?php
 }
}
add_action( 'admin_head-post-new.php', 'kapler_admin_head' );

WordPress tip: snadné pojmenování akcí a filtrů

Když se pořádně naučíte programovat ve WordPressu, zamilujete si nepochybně akce a filtry stejně jako já a budete jich aplikovat ve vašem kódu desítky či stovky.

To má ale několik nevýhod

  1. furt musíte vymýšlet, jak je pojmenovávat, a to tak, abyste je pak zas nějak našli
  2. přitom se ale nesmí funkce se stejným názvem opakovat, jinak dojde ke konfliktu
  3. mám pak někdy tunu funkcí, které se aplikují na stejnou akci/filtr a různě se kříží či dělají to samé
  4. nesmí se tyto funkce jmenovat stejně, jako funkce, které definovali autoři WP či pluginů.
  5. optimálně by měly být funkce a filtry snadno přenosné i na další weby

Za těch 10 let co s WP dělám jsem si vymyslel systém, který všechny tyto problémy řeší – pojmenovávám své akce a filtry vždy přesně podle názvu dané akce či filtru a před to používám jednotný prefix.

Např. si řeknu, že budu jako prefix vždy používat své jmého, tedy „kapler_“. Takže když chci vytvořit funkci k filtru sanitize_tile, prostě ji pojmenuji kapler_sanitize_title. Tedy funkce z minulého příspěvku by vypadala takto

function kapler_sanitize_title($title) {
    return str_replace('+', '-', $title); // sanitize plus with dash
}
add_filter('sanitize_title', 'kapler_sanitize_title');

Pointa je, že:

  1. nemusím přemýšlet ani vteřinu nad názvem a přitom se nikdy nebude jmenovat jako funkce někoho jiného (mé jméno je celkem unikátní)
  2. každý filtr či akce má vždy jednu mou funkci, tedy nemůže dojít ke konfliktu, resp. když dojde, tak vím, že už jsem tuto funkci aplikoval jinde a můžu je tak sloučit
  3. Tím že mám všechny filtry vztahující se k jedné proměnné u sebe, nehrozí, mnohem snadněji zkontroluji, jestli se nějak nekříží
  4. Takové funkce snadno přenesu i na jiné weby, protože mají prostě vždy stejnou strukturu

Teoretickou nevýhodou je snad jen ztráta té informace o tom, co daná funkce dělá z názvu funkce. Ale to jen na první pohled. Ve skutečnosti ta funkce už svým názvem prostě jasně říká, že se něco provádí s filtrem sanitize_title. A co konkrétně se provádí, to je pak definováno komentáři u těch jednotlivých úprav.

Klíčové je, že pakliže změním/rozšířím funkcionalitu, nemusím měnit název funkce, aby přesně vyjadřoval její funkčnost. Tedy když budu chtít nahrazovat nejen + ale i = za pomlčku, tak nemusím funkci přejmenovávat z „plus_to_dash“ na „plus_and_equals_to_dash“, ani nemusím vytvářet druhou funkci „equals_to_dash“ aplikovanou na stejný filtr, ani nemusím mít neodpovídající chování funkce „plus_to_dash“, kdyby dělala něco jiného, než jen „plus to dash“.

Prostě bych jen změnil nahrazování za

str_replace(array('+','='), '-', $title)

WordPress – filtry a akce pro začátečníky

Na všechny weby své a svých klientů už asi 10 let používám nejpoužívanější CMS na světě – WordPress. Miluji na něm jeho snadnou modifikaci, díky které můžete snadno ze základního systému pro správu blogů udělat pokročilý systém na správu téměř jakéhokoliv obsahu, a přitom geniální zachování aktualizovatelnosti.

Základem této snadné modifikace jsou dva skvělé prvky – akce a filtry. Prakticky na každou zabudovanou funkci WP jsou aplikované nějaké akce a/nebo filtry.

Řekněme, že potřebujete upravit chování WP při tvorbě slugů – hezkých URL – z titulku příspěvku – např. chcete, aby se + symbol převáděl na pomlčku. Zjistíte (nejsnadněji vhodným dotazem na Google), že toto provádí interně funkce sanitize_title.

A teď – mohli byste jí upravit, ale pak by jste o tuto úpravu přišli při příští aktualizaci WP. Nebo kdyby WP byl plně objektový systém, byste mohli tuto funkci přepsat vlastní funkcí, ale to by často znamenalo, že byste museli zkopírovat celou větší funkci, jen kvůli malé změně, a když by se tato funkce ve wordpressu měnila, museli byste si dávat pozor, aby ta vaše držela krok.

Místo toho má WP právě filtry a akce:

  • filtry mají na vstupu nějakou hodnotu (typicky text) a vy navázáním vaší funkce na tento filtr můžete tuto hodnotu změnit.
  • akce mají jen své místo a prioritu a vy navázáním své funkce na danou akci můžete na daném místě provést vlastní akci – typicky něco vypsat.

Takže zpět k našemu příkladu. Funkce sanitize_title má před výstupem na sebe nevázán filter, který se jmenuje také sanitize_title (není vždy pravidlem, že se shodují, záleží s čím pracují).

Vy tak můžete do svého tématu (např. do svého souboru s funkcemi functions.php) napsat následující volání tohoto filtru:

function plush_to_dash($title) {
    return str_replace('+', '-', $title);
}
add_filter('sanitize_title', 'plus_to_dash');

Řádek add_filter aplikuje váš filtr definovaní funkcí „plus_to_dash“ na filtr, který se jmenuje sanitize_title a který je aplikovaný v kódu u funkce sanitize_title na proměnou $title. Vaše funkce plus_to_dash tak bere na vstupu tuto jednu proměnou a nahradí v ní plus za pomlčku a výsledek vrátí.

Podobně fungují akce, které však nepracují s hodnotou, ale jen s místem, kde jsou umístěné. Tedy např. akce wp_head:https://codex.wordpress.org/Plugin_API/Action_Reference/wp_head je zodpovědná za vypsání veškerého obsahu do hlavičky vašeho webu. Když tedy budete chtít do hlavičky třeba vlastní styl, uděláte to nějak takto:

add_action('wp_head','hook_css');

function hook_css()
{

$output="<style> .wp_head_example { background-color : #f1f1f1; } </style>";

echo $output;

}

A pointa je, že akce i filtry je možné nejen přidávat, ale i odstraňovat a tím můžete snadno změnit i výchozí chování WordPressu. Toho docílíte snadno funkcemi remove_action resp. remove_filter.

Např. řekněme, že se vám nelíbí, že WordPress na výstupu automaticky převádí pevné odřádkování v obsahu příspěvku na odstavce. Dělá to tak, že aplikuje funkci wpautop na filter the_content.  Tedy není nic snazšího, než tento filtr odstranit:

remove_filter( 'the_content', 'wpautop' );