Standardní php funkce jako helpery v šablonách

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
blacksun
Člen | 177
+
0
-

Ahoj,

nevím, jestli jsem na to jen nenarazil, nenašel to nebo to neexistuje, ale nebyla by nějaká možnost, aby se před vyhozením výjimky, že nějaká funkce volaná jako helper není registrovaná jako helper v šabloně, zkusilo zjistit, jestli se nejedná o existující php funkci?

Přijde mi zbytečné volat po vytvoření šablony něco jako:

<?php
  $tpl->registerHelper('ucfirst', 'ucfirst');
?>

Omezila by se tím možnost poslat například pod názvem helperu ucfirst funkci, která se chová jinak než php funkce ucfirst, ale pokud by si někdo chtěl psát vlastní implementaci, tak ji rovnou může pojmenovat jinak.

Případně mít nějaké „přepinátko“, kterým by to šlo nastavit..

Co vy na to?

Panda
Člen | 569
+
0
-

Osobně bych se toho trochu bál, protože vestavěné PHP funkce neumí správně nakládat s UTF-8 a jejich mbstring varianty nejsou tolik známé, takže by to začátečníkům mohlo činit potíže. Některé z těchto základních funkcí jsou zahrnuty v třídách Nette\String a Nette\TemplateHelpers a jejich použití by mělo být preferované.

Pokud tuto možnost chceš v Nette mít již dnes a nezávisle na tom, zda Nette Foundation shledá Tvůj návrh za hodný včlenění do distribuce, můžeš si jednoduše napsat vlastní dodatečný loader helperů:

<?php
abstract class Helpers
{
	public static function functionLoader($helper)
	{
		if (is_callable($helper))
			return $helper;
	}
}
?>

Registraci pak provedeš pomocí

$template->registerHelperLoader('Helpers::functionLoader');
blacksun
Člen | 177
+
0
-

Díky za tvůj návrh úpravy i věcný komentář :-)

Další variantou by mohl být nějaký způsob, jak uvést seznam funkcí, které by se pak dali rovnou volat bez nutnosti registrace každé zvlášť..

blacksun
Člen | 177
+
0
-

Jinak ucfirst byl pouze příklad, na který jsem zrovna narazil, lepším příkladem by bylo třeba něco utf irelevantního..

hurvajs
Člen | 86
+
0
-

Ja si take myslim, ze to neni moc dobry napad. Preci jen, helpery mame nejake standardni, chci-li jine, musim si ho napsat.

Petr Motejlek
Člen | 293
+
0
-

V php.ini se dá nastavit, aby funkce jako strlen byly překryté svojí multibyte alternativou. Jukněte na http://www.php.net/…overload.php (takže začátečníkovi nemusí vadit, že použítá strlen v šabloně jako helper ;)).

Panda
Člen | 569
+
0
-

Ono nejde o to, jestli to jde nastavit nebo ne, ale o to, jestli je to ve výchozím stavu zapnuté a pokud ne, tak jestli to některý hosting zapíná. A čirou náhodou to je ve výchozím stavu vypnuté a zatím jsem neměl tu čest hostovat si web někde, kde by to měli zapnuté. A protože to ovlivňuje chování základních PHP funkcí, tak si nedělám iluze, že by to některý hostér zapnul.

Editoval Panda (5. 12. 2009 9:36)

Petr Motejlek
Člen | 293
+
0
-

Defaultně to zapnuté není, to je pravda. Ale myslím, že to jde měnit přes .htaccess, takže není moc co řešit, nebo ano? ;)

P. S.: Celou dobu se tady snažím hájit myšlenku toho fallbacku, když použiju helper, který nebyl definován, ať se prostě zkusí, jestli neexistuje, na druhou stranu, kolik těch standardních funkcí, které by někdo eventuelně mohl chtít volat jako helper, je? Já osobně jsem zatím snad žádnou nepoužil přímo, já spíš používám něco, čemu říkám konvertory (money|integer|float|string, atd.), který vezmou cosi (ať už je to objekt, nebo primitivní datový typ) a zkusí z toho nějak udělat peněžní částku, celý číslo, atd.

Proto bych spíše navrhoval, aby se dalo do helperů přihazovat nejen po funkcích, aby abych mohl mít třídu (třeba Converters), která by měla statické metody (money, integer, float, …). Tu bych potom předal LatteFilteru a on by si zjistil, jaké má statické metody a udělal by si z nich helpery, abych nemusel pro každou aplikaci, kterou dělám, kopírovat deset řádků kvůli deseti helperům, ale mohl tam mít jen jeden řádek, který by mi tam hodil celou tu třídu, co vy na to?

Panda
Člen | 569
+
0
-

Nastavování konfiguračních hodnot přes .htaccess nemusí být vždy dostupné, přes ini_set tato volba změnit nejde. Myslím, že základní věci v Nette by neměly být závislé na podivných konfiguračních direktivách v PHP. Navíc povolení této volby způsobí, že základní funkce pro práci s řetězci nebudou binárně bezpečné. A to vzhledem k tomu, že i takové PDFko často obsahuje binární data, nemusí být vždy úplně v pořádku.

Jinak to, co popisuješ, umí i současné Nette. Stačí se podívat na můj příspěvek s loaderem a malinko kód modifikovat:

<?php
abstract class Converters
{
	public static function loader($helper)
	{
		// Upozornění: loader nelze kvůli použití __CLASS__ dědit
		// V PHP 5.3 je možné využít funkce get_called_class
		if (is_callable($callback = __CLASS__ . '::' . $helper))
			return $callback;
	}
}
?>

A pak už jen třídu zaregistrovat:

$template->registerHelperLoader('Converters::loader');

Výhodou tohoto postupu je fakt, že se helpery načítají až v momentě, kdy jsou potřeba.

Petr Motejlek
Člen | 293
+
0
-

To je super, díky moc, nechám se inspirovat :). Taky si myslím (viz můj předchozí příspěvek), že pokud půjde zaregistrovat nějakou StandardPHPStringHelpers třídu, do které si člověk jen naháže všechny statické metody jako strlen, ucfirst, že to bude takové hezčí na procházení, než nějaká automatika, u které člověk ještě nemusí úplně vědět, na čem je ;).

P. S.: Taky se mi nelíbí, že doteď ty funkce (strlen, …) nikdo nepředělal, aby fungovaly správně za všech okolností bez nutnosti jakékoliv další konfigurace, ale to už je prostě PHP ;).