Pro svůj již běžící zajímavý projekt Vyluštit.cz jsem chtěl uživatelům nabídnout co nejjednodušší front-end. Vlastně vůbec nerozlišovat front-end a back-end. Důvod? Tím je cílová skupina, luštitelů křížovek, osmisměrek, sudoku, kvizů a všech možných soutěží. Takže nejlépe úpravy správcům na kliknutí, hlasování hvězdičkami, prostě rychle a jednoduše. To všechno se bez javascriptu neobejde.

Přiznám se, že jsem celkem donedávna nepatřil k příznivcům javascriptových knihoven a o jQuery jsem jen věděl, že existuje. Potřeba používání AJAXu a všech možných kontrol mě donutila jQuery vyzkoušet. Nelituju! Samotné jQuery mi ušetřilo spoustu času a nervů, protože práce s AJAXem i DOMem je maličkostí. Dalším plusem je možnost rozšíření (pluginů):

Skvělý plugin RateIt – hvězdičkové hodnocení

Pro potřebu hodnocení soutěží a to nejlépe graficky bez nutného opětovného načítání stránky po hlasování. Tento plugin to splňuje dokonale a nastavení je velmi jednoduché. Podle obrázku řádek hodnocení vypadá v kódu takto:

<div id="topic-polls">Hodnocení: <div class="rateit"></div> • Hlasů: <span id="popularity-counter">0</span>

Jak se to spustí a jak nabinduju AJAX po hodnocení:

$jQuery('.rateit').rateit({ step: 1, ispreset: true, value: 0 });
$jQuery('.rateit').bind('rated', function (e){
 $jQuery.ajax({
  url: 'url se skriptem',
  data: {
	 value: $jQuery('.rateit').rateit('value')
	 // dalsi podle potreby....
  },
  type: 'POST',
  success: function(){
         // v pripade uspechu jsem si pripocetl 1 u hlasu puvodniho hodnoceni a dopocetl celkove hodnoceni
	 popularity_counter++;
	 $jQuery('#popularity-counter').html(popularity_counter);
	 popularity += $jQuery('.rateit').rateit('value');
         $jQuery('.rateit').attr('title', 'Hodnotil si');
	 $jQuery('.rateit').rateit('value', popularity / popularity_counter);
         $jQuery('.rateit').rateit('readonly', true);
  }
 });
});

Abych to uživatelům usnadnil a nemusel nikdo přemýšlet jestli více hvězdiček znamená dobře nebo špatně. Doplnil jsem navíc ToolTipy:

var tooltipvalues = ['velmi špatná', 'špatná', 'průměrná', 'dobrá', 'výborná'];
$jQuery('.rateit').bind('over', function (event, value){ $jQuery(this).attr('title', tooltipvalues[value-1]); });

Stránky pluginu RateIt zde. Příklady použití pluginu najdete zde. No není to skvělé? Určitě je a teď přejdu k božímu… 🙂

Boží plugin Jeditable – in place editace

Velice příjemná věcička, která umožní upravovat obsah, bez nutnosti přecházet na jinou stránku. Jen poklepu na daném textu a on se změní do možnosti úprav. Pro představu:

Jak je z obrázku vidět, text je v trošku jiném kódu než původní. Proto považuji tento plugin za boží ;-). Text formátuji do HTML pomocí Texy, ale když jej chci nabídnou k úpravě, měl by být neformátovaný. Jeditable mi umožňuje AJAXové načtení obsahu před úpravou a po úpravě opět za pomoci AJAXu jej uložit :-). A to za pomoci několika řádků kódu:

$jQuery('.edit-content div').editable('url kam ulozit',{
 event: 'dblclick',
 loadurl: 'url odkud vzit obsah, je-li jiny od stavajiciho',
 type: 'textarea',
 getDataType: 'json',
 width: 450,
 height: 300,
 placeholder: 'pokud je obsah prazdny, zobrazi se tento text',
 // Asi netreba vysvetlovat indikator prace
 indicator: 'pracuji...',
 tooltip: 'Klikni (dvojklik) pro změnu...',
 onblur: 'submit',
 submitdata:{
  token: 'treba token proti CSRF'
 },
 callback: function(response, settings){
 	// callback po provedeni ... zde obycejne ruzne skryvam nebo zobrazuji informaci o uspechu
 }
});

Díky tomuto pluginu se úprava obsahu opravdu stává příjemnou a o to mi přece ve Vyluštit.cz šlo.

Stránky pluginu Jeditable zde. Příklady použití pluginu najdete zde.

Mnoho webových prezentací má v hlavičce rotující fotografie, u RS WordPress lze pro tento efekt krásně využít NextGen Gallery plugin a možnost zkráceného zápisu pomocí shortcodů. Pak se do šablony zapíše něco takového

<?php echo do_shortcode('[slideshow id=X]'); ?>

, kde X je číslo Vaší fotogalerie s upravenými fotkami na tu správnou velikost.

Svůj efekt to splní, ale fotky budou v přesně daném pořadí, ale co když máte spoustu fotek a vy by jste chtěl náhodné řazení. Ihned doplním, že u jQuery slideshow přidání random určitě nefunguje.

Zbývá poslední možnost a tou je úprava přímo v kódu pluginu NextGen Gallery.

Jak upravit plugin pro náhodný výběr obrázků u slideshow

  1. Najít soubor, který generuje JSON pro jQuery slideshow. Tím je prozaicky pojmenovaný json.php v adresáři xml pluginu NextGen Gallery;
  2. Editovat jej a najít řádek 93 (momentálně), jinak je obsahem function start_process() a v case je to metoda s řetězcem gallery;
  3. Tento upravit na použití funkce pro výběr náhodných obrázků
    nggdb::get_random_images(100, $this->id)

    , kde číslo 100 určuje počet fotografií do LIMIT;

  4. Výsledný řádek by mohl vypadat například takto:
    $this->result['images'] = ($this->id == 0) ? nggdb::find_last_images( 0 , 100 ) : nggdb::get_random_images(100, $this->id);

Protože se jedná o část pro JSON, tak touto úpravou neovlivníte běžné fotogalerie. Má to však malý háček a tím jsou aktualizace pluginů. Musíte si to pohlídat a v případě aktualizace tohoto pluginu změnu provést znovu, v opačném případu se vše bude chovat jako před úpravou :-(. Co by člověk pro tuto drobnost neudělal.

Netroufáte si na takovou změnu?

Pak nejlépe oslovit někoho, kdo Vám ji udělá. Třeba přímo mne a já Vám ji za velmi příjemnou cenu provedu, případně poradím, co vše by šlo ještě upravit.

Internet je jich plný, ale když je nějaká potřeba, tak ji ne a ne najít. Potřeboval jsem průhlednou, protože pozadí nebylo bílé. Co čert nechtěl, nemohl jsem si vzpomenout na Preloader. A proto pro příště (to jsou výrazy pro vyhledávač):

  • obrázek při nahrávání,
  • pohybující se obrázek v případě nahrávání přes Ajax,
  • ajax loading graphics

Máte-li pozadí bílé, dají se pěkné najít třeba zde. Jinak, a to jsem využil já, nechat si vygenerovat nový preloader pomocí služby Preloaders. Tato služba nabízí vygenerování několika druhů preloaderů s barevným i transparentním pozadí (GIF i APNG).

U jednoho webu zákazníka jsem potřeboval řešit mapu webu, ale bez nutnosti vytvářet speciální stránku šablony. WordPress má pěknou funkci pro výpis všech stránek wp_list_pages(), ale to je přímo php funkce a ne Shortcode. Povolovat skriptování uvnitř obsahu stránek nebo příspěvků to opravdu nechci. Shortcode by to chtělo ;-). Whoala … pěkný plugin s názvem List Pages Shortcode toto řeší.

Krátce o List Pages Shortcode

Úžasné je zachování stejných parametrů jako u originální funkce, takže především exclude na nechtěné stránky a nastavení hloubky pomůže zobrazit mapu webu během okamžiku.

A příklad? Zobrazení seznamu stránek setříděného podle názvu se dá udělat takto:

[list-pages sort_column="post_title"]

Při psaní přihlašování, kde jsem chtěl používat hmac, aby se neposílalo heslo v plain textu, jsem si náhodou všiml, že mi nesedí výsledný hash_hmac, když se v hesle vyskytne znak specifický pro českou abecedu. Prekérní situace… 😎

Drobný příklad, mějme řetězec a klíč.

řetězec:
ščřžýáá je to na nic 123456
klíč:
TLr8zA75tI1q3Jo

php (běžně používané funkce):

hash(sha256) = 8af726e3c15be3687de0b13102667701994323832bb252503f841bf3d3722e34
hash_hmac(sha256) = d39a1c610d009f1f1f569800fc4d74ac8d27a8b8e2011b526bf886f7a066fec1

jquery plugin pro sha256 (jquery.sha256.min.js):

hash(sha256) = 723f6dd8d04fe3ac3f268f1d6b9a938a778ad71d6f699de968206ad4c5909bdf
hash_hmac(sha256) = 83a2bdbd3ba93279fa94c76d31ed506d132f167fc46e4dd203b84ea7e861cf1a

Problém je na světě, ono to nesedí. Hledal jsem i jinou implementaci a přes Wikipedii našel…

javascript (implementace například z http://jssha.sourceforge.net/):

hash(sha256) = 723f6dd8d04fe3ac3f268f1d6b9a938a778ad71d6f699de968206ad4c5909bdf
hash_hmac(sha256) = 83a2bdbd3ba93279fa94c76d31ed506d132f167fc46e4dd203b84ea7e861cf1a

Opět jsou výsledky různé. Stejně jsem kvůli „českým znakům“ potřeboval pracovat s řetězci v Unicodu a ne ASCII, jak nabízí php u funkcí hash a hash_hmac. A hlavně jsem potřeboval v javascriptové i phpčkové části dostávat stejné výsledky.

Implementace sha256 pro php, která umí pracovat s Unicode, se dala najít na internetu celkem snadno – zde, takže stačilo jen ověřit chování. Nastavit pro práci s Unicode ($chrsz = 16;) a doplnit o hmac:

function muj_sha256_hmac($key, $data)
{
  $blocksize = 64;
  if (strlen($key) > $blocksize)
  {
    $key = muj_sha256($key);
  }
  else if (strlen($key) < $blocksize)
  {
    $key = str_pad($key, $blocksize, chr(0x00));
  }
  $ipad = $key ^ str_repeat(chr(0x36), $blocksize);
  $opad = $key ^ str_repeat(chr(0x5C), $blocksize);
  return muj_sha256($opad . pack('H*', muj_sha256($ipad . $data)));
}

U javascriptu se muselo udělat trochu více, ale analogicky podle phpčkového skriptu. Poznámka jen pro budoucnost, až budu trojčit, že mi nesedí hashe :-).

Doplnění 1:

Všechno fungovalo krásně, dokud nedošlo na 64bitový server, protože pak jsem obdržel opět různé údaje. Přitom již minule stačilo php část vyřešit za pomoci mb_convert_encoding() a převést text na UTF-16LE.

hash('sha256', mb_convert_encoding('text v SHA256', 'UTF-16LE'));