PHPTAL Atributivnyj YAzyk SHablonov dlya PHP Laurent Bedubourg Kornel Lesinski Dan Sheppard Anton Valerievich Andrievskij Istoriya pereizdaniya ---------------------------------------------------------------------- Soderzhanie 1. Vstuplenie 2. Pochemu PHPTAL? 3. Ustanovka 4. Primer 5. Atributivnyj YAzyk SHablonov TAL 1. Prioritet atributov 2. Prostranstvo imen TAL 1. tal:define 2. tal:condition 3. tal:repeat 4. tal:omit-tag 5. tal:replace 6. tal:content 7. tal:attributes 1. Opcional'nye atributy 8. tal:on-error 3. Prostranstvo imen METAL 1. metal:define-macro 2. metal:use-macro 3. metal:define-slot 4. metal:fill-slot 4. Prostranstvo imen I18N 1. i18n:translate 2. i18n:attributes 3. i18n:name 4. XHTML v perevodah 5. Prostranstvo imen PHPTAL 1. phptal:debug 2. phptal:cache 1. Prinuditel'noe obnovlenie 2. Ogranicheniya: 3. phptal:tales 6. tal:block 7. PHPTALES 1. path: 2. Alternative PHP operator syntax 3. string: 4. php: 5. not: 6. exists: 7. default 8. structure 9. Expression chains 6. PHP Integration 1. Constants 2. Configuration methods 3. class PHPTAL 4. interface PHPTAL_Filter 5. interface PHPTAL_Trigger 6. interface PHPTAL_TranslationService 1. method setLanguage(...) 2. method useDomain($domain) 3. method setVar($key,$value) 4. method translate($key) 5. method setEncoding($encoding) 7. Working with gettext 1. Creating the translation directory structure 2. Portable Object files 3. Translation Domain 4. Using Translator in PHP 5. Variable interpolation 8. Creating custom expression modifiers 7. Note for system administrators 8. Useful links 9. Greetings Vstuplenie ---------------------------------------------------------------------- PHPTAL yavlyaetsya PHP realizaciej sistemy shablonov Zope Page Template (ZPT). PHPTAL podderzhivaet prostranstva imen TAL, METAL i I18N. PHPTALES yavlyaetsya e'kvivalentom TALES, Template Attribute Language Expression Syntax (sintaksis atributivnogo yazyka shablonov). On opredelyaet, kak obrabatyvayutsya znacheniya atributov XML. Tak kak PHPTALES podoben TALES, TAL shablony python i PHP mogut odinakovo ispol'zovat'sya i transportirovat'sya iz odnogo yazyka v drugoj. CHtoby byt' sovmestimym s TAL, PHPTAL realizuet XPath-podobnyj dostup k dannym. PHPTAL razrabotan Laurent Bedubourg i svobodno rasprostranyaetsya pod licenziej LGPL(i v dannyj moment podderzhivaetsya Kornel Lesinski). Pochemu PHPTAL? ---------------------------------------------------------------------- XML/HTML shablony otdelyayut logiku skripta (obrabotku dannyh) ot predstavleniya (otobrazheniya e'tih dannyh) v veb. Takoe otdelenie imeet ryad preimushchestv. o bolee udobnoe proektirovanie programmy/skripta o prostota razdeleniya zadach mezhdu programmistom i dazijnerom o uproshchenie podderzhki posle razrabotki o prostota sozdaniya veb skinov (vidov) Bol'shinstvo shablonnyh yazykov ispol'zuyut tegi , <% %> ili chtoby opredelit', gde i kakoe znachenie podstavit' v shablon. E'to uproshchaet razrabotku sajta, no nikak ne pomogaet razrabotchikam shablonov. TAL dlya opisaniya logiki ispol'zuet XML atributy, ne zatragivaya sintaks i strukturu XHTML. E'to daet nam vozmozhnost' predosmotra TAL shablona v brauzere (ili v WYSIWYG redaktore) i ne narushaet podsvetku HTML sintaksisa v redaktore programmista. Esli Vy uzhe ispol'zovali kakie-libo sistemy shablonov, to navernyaka stalkivalis' s chem-to vrode e'togo: <%loop myarray as myitem %> <%/loop%>
<% myitem %>
V PHPTAL mozhno opisat' tozhe samoe proshche i krasivee:
Tekst, kotoryj budet zamenen znacheniem myitem Primer 1 Primer 2 Primer 3
Takoj shablon budet korrektno otobrazhen v brauzere s primerami "Primer 1", "Primer 2" i "Primer 3", poe'tomu mozhno prodemonstrirovat' ego klientu dazhe na toj stadii, kogda kod, neobhodimyj dlya polucheniya znachenij 'myarray', eshche ne sushchestvuet. Drugoe vazhnoe preimushchestvo PHPTAL sostoit v tom, chto Vy poluchaete dostup k pomoshchi i bolee chem trehletnim opytu, dokumentacii i primeram soobshchestva Zope. Pol'zovateli PHPTAL yavlyayutsya chast'yu e'togo soobshchestva i avtomaticheski poluchayut ot nego ischerpyvayushchuyu i poleznuyu informaciyu Glavnaya sila PHPTAL v tom, chto dlya "prodvinutyh" programmistov i resursoemkih sistem on nastraivaemyj nastol'ko, naskol'ko tol'ko e'to vozmozhno, i v to zhe vremya ochen' prost i komfortnen dlya lyubygo novichka Ustanovka ---------------------------------------------------------------------- PHPTALrealizovan v vide PEAR biblioteki (sm. http://pear.php.net). Biblioteku PHPTAL mozhno skachat' na sajte PHPTAL (http://phptal.org). Estanovku mozhno vypolnit' s pomoshch'yu utilit pear: pear install http://phptal.org/latest.tar.gz Posle ustanovki, tak zhe prosto mozhno obnovlyat' PHPTAL, ispol'zuya PEAR: pear upgrade http://phptal.org/latest.tar.gz Mozhno obojtis' i bez PEAR, poprostu razarhivirovav arhiv. tar zxvf PHPTAL-X.X.X.tar.gz cp -r PHPTAL-X.X.X/PHPTAL* /path/to/your/lib/folder E'ti instrukcii ustanovyat fajl PHPTAL.php i sootvetstvuyushchuyu papku PHPTAL v direktoriyu /path/to/your/lib/folder. Primer ---------------------------------------------------------------------- Prostoj primer namnogo interesnee i poznavatel'nee, chem mnogie slova Vash shablon vsegda budet sintaksicheski pravil'nym xml/html dokumentom (s prisutstvuyushchim kornevym e'lementom)! Vot primer fajla pod nazvaniem 'my_template_file.xhtml'. Mesto dlya zagolovka stranicy

Primer zagolovka

Imya Telefon
CH'e-to imya CHej-to telefon
Oleg Radchenko 5226611
Oleg Radchenko 5226611
Vse, chto Vam ponadobit'sya sdelat' v php - e'to vklyuchit' (include) biblioteku PHPTAL i, vozmozhno, ustanovit' neskol'ko peremennyh, chtoby nastroit' shablonnuyu sistemu. name = $name; $this->phone = $phone; } } // Sozdaem massiv ob~ektov dlya testirovaniya $people = array(); $people[] = new Person("foo", "01-344-121-021"); $people[] = new Person("bar", "05-999-165-541"); $people[] = new Person("baz", "01-389-321-024"); $people[] = new Person("quz", "05-321-378-654"); // Peredaem massiv dannyh obrabotchiku shablonov $template->title = 'YA Zagolovok'; $template->people = $people; // Vypolnyaem obrabotku shablona try { echo $template->execute(); } catch (Exception $e){ echo $e; } ?> Vypolniv takoj PHP skript, Vy poluchite chto-to vrode e'togo: YA Zagolovok

YA Zagolovok

Imya Telefon
foo 01-344-121-021
bar 05-999-165-541
baz 01-389-321-024
quz 05-321-378-654
PHPTAL ne zabotitsya o perenosah stroki i otstupah ni v chitaemyh, ni v generiruemyh fajlah. CHtoby poluchit' krasivyj HTML (s perenosami i pravil'nymi otstupami), mozhno ispol'zovat' HTML Tidy na e'tape postprocessinga. Atributivnyj YAzyk SHablonov TAL ---------------------------------------------------------------------- Soderzhanie 1. Prioritet atributov 2. Prostranstvo imen TAL 1. tal:define 2. tal:condition 3. tal:repeat 4. tal:omit-tag 5. tal:replace 6. tal:content 7. tal:attributes 1. Opcional'nye atributy 8. tal:on-error 3. Prostranstvo imen METAL 1. metal:define-macro 2. metal:use-macro 3. metal:define-slot 4. metal:fill-slot 4. Prostranstvo imen I18N 1. i18n:translate 2. i18n:attributes 3. i18n:name 4. XHTML v perevodah 5. Prostranstvo imen PHPTAL 1. phptal:debug 2. phptal:cache 1. Prinuditel'noe obnovlenie 2. Ogranicheniya: 3. phptal:tales 6. tal:block 7. PHPTALES 1. path: 2. Alternative PHP operator syntax 3. string: 4. php: 5. not: 6. exists: 7. default 8. structure 9. Expression chains E'ta sekciya opisyvaet TAL i ego rasshireniya. E'ta sekciya prednaznachena, glavnym obrazom, dlya razrabotchikov shablonov. No okazhetsya poleznoj i dlya teh, komu predstoit integratorovat' shablony s PHP. Prioritet atributov Pervym delom zapomnite: poryadok zapisi atributov ne imeet nikakogo vliyaniya na poryadok ih obrabotki. Rassmotrim primer: ... absolyutno identichna takoj: ... Prioritet obrabotki atributov, naprimer, tal:define i tal:condition, ne budet zaviset' ot togo, v kakom poryadke oni zapisany vnutri tega SPAN. Poryadok obrabotki opredelyaetsya specifikaciej TAL: 1. define 2. condition 3. repeat 4. content ili replace 5. attributes 6. omit-tag Prostranstvo imen TAL 1. tal:define 2. tal:condition 3. tal:repeat 4. tal:omit-tag 5. tal:replace 6. tal:content 7. tal:attributes 1. Opcional'nye atributy 8. tal:on-error tal:define E'tot atribut ob~yavlyaet odnu ili bolee peremennyh, kotorye zatem mogut byt' ispol'zovany v shablone. Ob~yavlenie peremennoj, soderzhashchej dlinnyj put': Ob~yavlenie stroki vnutri shablona: Ob~yavlenie neskol'kih peremennyh odnovremenno: Ob~yavlenie peremennoj s ispol'zovaniem drugoj peremennoj: I malen'kij tryuk s ispol'zovaniem bufera vyvoda: hello ${fname} welcome on this page tal:define mozhno i udobno ispol'zovat' vmeste s drugimi atributami, no on vsegda budet obrabotan pervym. V predposlednem primere (ob~yavlenie peremennoj s ispol'zovaniem drugoj peremennoj) teg span ne budet otobrazhen, t.k. on i sam pustoj, i ne soderzhit tal atributov, kotorye by naznacheli ego soderzhanie. Dazhe v poslednem primere tekst iz span ne budet pokazan, t.k. peremennaya 'hello' ego "s~edaet" (podmenyaet svoim pustym znacheniem) No vot drugoj primer: Zdes' peremennaya 'hello' budet ustanovlena, a ee soderzhimoe popadet v teg span odnako, sleduyushchij primer nevernyj (tochnee, ne otobrazit nikakogo soderzhaniya vnutri span), t.k. tal:define opredelit soderzhanie peremennoj 'hello' pered tem, kak tal:content ispol'zuet ee dlya opredeleniya togo, chto dolzhno byt' vnutri e'lementa span. CHtoby ne bylo ukazano vnutri span v shablone, e'to budet proignorirovanno (zameneno znacheniem peremennoj 'hello'). No v nashem sluchae hello ne budet opredeleno, i poe'tomu vozniknet isklyuchenie (exception). hello ${fname} welcome on this page Kstati, v e'tom primere my ne ispol'zovali slovo 'global' pered opredeleniem peremennoj. V PHPTAL peremennye byvayut global'nymi i lokal'nymi. Global'naya peremennaya budet dostupna vo vsem shablone i v vyzyvaemyh iz nego makrosov.

Lokal'naya zhe peremennaya vidna tol'ko vnutri tega, v kotorom ona opredelena:

tal:condition Teg i ego soderzhimoe budet otobrazheno tol'ko togda, kogda uslovie vypolnyaetsya. Privetstvuem, nash lyubimyj posetitel'! Pozhalujsta, avtorizujtes', chtoby poluchit' dostup k e'toj stranice Esli programmisty PHP skripta ne predostavili Vam (razrabotchiku shablonov) nuzhnye metody i peremennye v peredavaemyh shablonu dannyh, Vy mozhete sami vypolnit' neobhodimyj PHP kod: ... CHastoe ispol'zovanie instrukcij PHP v shablonah privelo by k tomu, chto logika skripta byla by razbrosana mezhdu PHP fajlami i shablonami, chto uvodit nas ot iznachal'noj idei razdeleniya koda i vida. Poe'tomu zhelatel'no obespechit' razrabotchikov shablonov vsemi nuzhnymi bulevymi znacheniyami i metodami, naprimer: ... ... tal:repeat E'tot atribut sluzhit dlya ciklov nad perechislyaemymi dannymi: massivami, associativnymi massivami i perechislyaemymi ob~ektami v PHP5 Atribut repeat poocheredno probegaet po vsem znachenieyam ukazannogo resursa (naprimer, massiva). tekst, kotoryj zamenitsya znacheniem iz item Vnutri cikla mozhno ispol'zovat' special'nye klyuchevye slova repeat/*, chtoby poluchit' dostup k informacii ob sostoyanii cikle (i vseh vneshnih ciklov). Vot spisok dopustimyh klyuchevyh slov: o repeat/item/key : vozvrashchaet klyuch e'lementa item v associativnom massive some/result (esli associativnosti netu, to prosto vozvrashchaet indeks e'togo e'lementa) o repeat/item/index : vozvrashchaet indeks e'lementa item (ot 0 do count-1) o repeat/item/number : vozvrashchaet poryadkovyj nomer e'lementa item (ot 1 do count) o repeat/item/even : vozvrashchaet true, esli indeks chetnyj o repeat/item/odd : vozvrashchaet true, esli indeks nechetnyj o repeat/item/start : vozvrashchaet true, esli e'lement yavlyaetsya pervym o repeat/item/end : vozvrashchaet true, esli e'lement yavlyaetsya poslednim o repeat/item/length : vozvrashchaet kolichestvo e'lementov v some/result v e'tih primerah, vmesto nazvaniya "item" nuzhno ispol'zovat' to zhe nazvanie, chto i v vyrazhenii tal:repeat (tal:repeat="item some/result"). Odno iz samyh rasprostrannennyh primenenij atributa tal:repeat - otobrazhenie razul'tatov zaprosa k baze dannyh. Sleduyushchij primer srabotaet tol'ko v tom sluchae, esli playersRanking yavlyaetsya ob~ektom, realizuyushchim interfejs PHP Iterator:
Poziciya Igrok Ochki
tal:omit-tag E'tot atribut zastavit parser PHPTAL proignorirovat' otkryvayushchij i zakryvayushchij tegi e'lementa i vyvesti tol'ko ego soderzhimoe. esli uslovie condition verno, to tol'ko E'TOT tekst budet pokazan (otkryvayushchij i zakryvayushchij tegi span budut upushcheny) V rezul'tate poluchim: esli uslovie condition verno, to tol'ko E'TOT tekst budet pokazan (otkryvayushchij i zakryvayushchij tegi span budut upushcheny) E'tot atribut polezen, chtoby sozdat' "opcional'nyj" e'lement. Naprimer, spryatat' ssylku, esli kakoe-to uslovie ne vypolnyaetsya. Esli Vam nuzhen e'lement, tegi kotorogo nikogda ne budut vyvedeny, ispol'zujte tal:block tol'ko e'tot tekst budet vyveden; 10 raz tal:replace Ispol'zuya e'tot atribut, mozhno zamenit' ves' e'lement celikom (vklyuchaya otkryvayushchij i zakryvayushchij teg) na zadannuyu stroku, ili na pustuyu, esli znachenie ne zadano. a ya stroka plohaya! V rezul'tate poluchim: ya - prekrasnaya stroka tal:replace udobno ispol'zovat' dlya sozdaniya primerov v shablone, kotorye dolzhny byt' ignorirovany pri ego obrabotke pered otobrazheniem.
znachenie item
Primer 1
Primer 2
tal:content Znachenie e'togo atributa stanet tekstom vnutri tega. e'tot tekst budet zamenen V rezul'tate poluchim: moya stroka tal:attributes S pomoshch'yu tal:attributes mozhno ustanavlivat' na letu znacheniya atributov tega. kakaya-nibud' ssylka Dlya primera, pust' znachenie 'somelink' budet takovym: $somelink->href = "http://www.google.com"; $somelink->title = "google search engine"; $somelink->text = "the google search engine"; V rezul'tate poluchim: the google search engine Tochka s zapyatoj (;) razdelyaet neskol'ko atributov. CHtoby zapisat' tochku s zapyatoj kak chast' znacheniya, neobhodimo ee produblirovat' (;;). Vot primer, gde tal:attributes ispol'zuetsya sovmestno s tal:repeat: ... Modifikator php: budet opisan nizhe. Itak, rassmotrim nash primer. Esli ryadok nechetnyj, togda dlya tr budet ispol'zovan atribut class="odd". Dlya chetnyh zhe ryadkov atribut class voobshche ne budet ustanovlen. "condition ? then : else" yavlyaetsya special'nym vyrazheniem PHP; hotya ego pol'za imeet mesto byt' vo mnogih sluchayah, luchshe popytat'sya izbezhat' ego ispol'zuvaniya. Pravil'nee bylo by poprosit' PHP programmista obespechit' dizajnera shablonov special'nymi modifikatorami (sm. PHP integraciya / pol'zovatel'skie modifikatory), kotorye mogli by ispol'zovat'sya primerno tak: ... Modifikator vozvratit "odd", esli repeat/ranking/odd raven true, a inache false. Opcional'nye atributy Zadavaya znachenie, mozhno ispol'zovat' tak nazyvaemye al'ternativnye znacheniya, razdelyaya ih znakom |. Esli pervoe znachenie ne opredeleno, parser popytaetsya podstavit' sleduyushchee v cepochke, esli ono tozhe ne opredeleno - sleduyushche, i t.d. Pri ispol'zovanii al'ternativnyh znachenij, v tal:attributes mozhno ispol'zovat' znachenie nothing (ili NULL v vyrazhenii php) kak poslednee al'ternativnoe znachenie. Togda atribut ne budet dobavlen tegu, esli znachenie dlya atributa ne opredeleno. E'to pozvolit izbezhat' "pustyh" atributov: ... tal:attributes="title object/tooltip | nothing"> XHTML atributy selected, checked i drugie podobnye budut takzhe obrabotany pravil'no. Ne zabyvajte, chto XHTML registro-zavisim, poe'tomu zapis' SELECTED oshibochna v XHTML. Pravil'naya zapis' - selected. tal:on-error Znachenie e'togo atributa podstavitsya v teg, esli teg soderzhit vnutri sebya oshibku (naprimer, neverno zadannyj put', ili isklyuchenie, vyzvannoe PHP vo vremya generacii tega). e'tot tekst zamenitsya na imya pol'zovatelya Esli dostup k 'name' ili 'user' vyzovet oshibku, to na meste tega budet pokazano soobshchenie ob oshibke. E'tot mehanim rabotaet dlya lyuboj vlozhennosti tegov: Prostranstvo imen METAL 1. metal:define-macro 2. metal:use-macro 3. metal:define-slot 4. metal:fill-slot METAL oboznachaet 'Macro Extension for TAL' (rasshirenie TAL dlya makrosov). E'to prostranstvo imen realizovano v PHPTAL i daet vozmozhnost' razrabotchikam sozdavat' i vyzyvat' XML/XHTML makrosy v svoih shablonah. metal:define-macro E'tot atribut ob~yavlyaet makros. Po svoej suti makrosy e'to obychnye shablony, kotorye mogut byt' mnogokratno vstavleny v drugie shablony.

Poslednee obnovlenie: data poslednego obnovleniya
Makros nasleduet dostupnye peremennye iz vyzyvayushchego shablona. V nashem primere znachenie peremennoj 'mdate' nuzhno ob~yavit' v shablone, v kotorom ispol'zuyut e'tot makros. metal:use-macro E'tot atribut vyzyvaet makros i vklyuchaet rezul'tat ego vypolneniya v tekushchij shablon v to mesto, otkuda on vyzvan Mozhno dazhe vyzvat' makros iz drugogo fajla, prosto dopisav put' k nemu: Pri e'tom mozhno ispol'zovat' vsyu gibkost' podstanovok peremennyh: Makros mozhet vyzyvat' samogo sebya. Takim obrazom, mozhno ispol'zovat' rekursiyu dlya vyvoda massivov:
metal:define-slot E'tot atribut dolzhen byt' ob~yavlen vnutri tega, ob~yavlyayushchego makros (metal:define-macro). Sloty mogut zamenyat'sya vyzyvayushchim shablonom na dinamicheski generiruemyj XML/XHTML. Cloty pomogayut raznoobrazit' stranicy. Esli makros predstavit' kak celuyu stranicu, to sloty mozhno predstvit' kak sekcii, var'iruyushchiesya v zavisimosti ot, naprimer, URL. K primeru, na toj zhe glavnoj stranice sajta slot vyvodit svezhie novosti ili perechen' dejstvij, dostupnyh pol'zovatelyu posle ego avtorizacii.
news description
V e'tom primere my opredelyaem sekciyu pod nazvaniem 'news_place', soderzhimoe kotoroj mozhet byt' podmeneno vyzyvayushchim shablonom. Nizhe my rassmotrim, kak ispol'zovat' sloty, ssylayas' na e'tot primer. metal:fill-slot E'tot atribut mozhet byt' ispol'zovan tol'ko vnutri e'lementa s metal:use-macro. On zastavit PHPTAL podmenit' soderzhimoe ob~yavlennogo ran'she slota.

Menyu pol'zovatelya

Takim obrazom, sloty pozvolyayut s legkost'yu raznoobrazit' i uslozhnit' shablony s pomoshch'yu prostoj tehnologii push. Prostranstvo imen I18N 1. i18n:translate 2. i18n:attributes 3. i18n:name 4. XHTML v perevodah K svedeniyu: 'i18n' yavlyaetsya akronimom (sokrashcheniem) ot slova 'internationalization' (internacionalizaciya). E'to prostranstvo imen sluzhit dlya sozdaniya mnogoyazykovyh shablonov. S pomoshch'yu special'nyh atributov mozhno ukazyvat' tekst, kotoryj dolzhen byt' pereveden v processe obrabotki shablona. i18n:translate E'tot atribut opredelyaet tekst, kotoryj dolzhen byt' pereveden s pomoshch'yu sistemy perevoda, vstroennoj v PHPTAL.
Dobro pozhalovat'!
V vysheprivedennom primere PHPTAL budet iskat' perevod s klyuchem 'welcome_message' i zamenit soderzhimoe tega e'kvivalentnym perevodom.
Dobro pozhalovat'!
A e'to drugoj sluchaj: klyuch dlya perevoda ne ukazan, poe'tomu PHPTAL vospol'zuetsya soderzhimym 'Dobro pozhalovat'!' kak klyuchem dlya perevoda. Takim obrazom, budet podstavlen e'kvivalentnyj perevod dlya klyucha 'Dobro pozhalovat'!'. Esli zhe perevoda s takim klyuchem ne najdeno, to v kachestve perevoda budet ispol'zovan sam klyuch. Imenno poe'tomu luchshe ispol'zovat' chitabel'nye soobshcheniya v kachestve klyuchej vmesto neponyatnyh sokrashchenij. Malo togo, klyuch mozhet zadavat'sya peremennoj:
...
i18n:attributes Zadaet, kakie atributy dolzhny byt' perevedeny. Pary znachenij Atribut-Klyuch dolzhny byt' perechisleny cherez tochku s zapyatoj: Picture i18n:name V sam perevod mozhno dinamicheski posdtavlyat' znacheniya peremennyh. Dlya e'togo nuzhno naznachit' tak nazyvaemye "peremennye perevoda", to est', neobhodimo opredelit', kakuyu peremennuyu v perevode na kakuyu real'nuyu peremennuyu (dostupnuyu v shablone) neobhodimo zamenit'. Dlya togo, chtoby zadat' takoe sootvetstvie, ispol'zujte i18n:name V stroke perevoda mozhno ispol'zovat' zapis' ${xxx}, gde "xxx" - nazvanie "peremennoj perevoda", kotoraya dolzhna zamenyat'sya dinamicheski na real'nuyu peremennuyu shablona. Sootvetstvuyushchee znachenie budet podstavleno v teg i ego soderzhimoe. Esli zhe Vy ne hotite, chtoby znachenie bylo pomeshcheno v tegi, ispol'zujte tal:replace vmesto tal:content. Atribut tal:omit-tag prigoditsya, esli znachenie predstavlyaet soboj konkatenaciyu strok. foo foo Primer ispol'zovaniya i18n:
Dobro pozhalovat', , u Vas neprochitannyh pisem.
Klyuch perevoda v e'tom primere budet sleduyushchij: "Dobro pozhalovat', ${user}, u Vas ${mails} neprochitannyh pisem." V podstavlyaemom perevode, PHPTAL zamenit ${user} na ${user/name}, a ${mails} na ${user/nbrMails}. Bolee podrobno o svyazke I18N s PHPTAL mozhno prochitat' v razdele PHP e'toj spravki. XHTML v perevodah Po umolchaniyu predpolagaetsya, chto perevody soderzhat tol'ko tekst i ne soderzhat tegi, poe'tomu PHPTAL e'kraniruet vse simvoly "<". Nachinaya s versii 1.1.14, v i18n:translate dopuskaetsya ispol'zovaniya klyuchevogo slova structure, chtoby otmenit' e'kranirovanie i vyvodit' perevedennyj tekst "kak est'":
Dast:
bold text
Odnako, TAL atributy vnutri perevedennyh strok budut ignorirovany. Konechno, sleduet pomnit', chto ploho formatirovannyj XHTML v perevodah isportit horosho formatirovannyj shablon. Prostranstvo imen PHPTAL 1. phptal:debug 2. phptal:cache 1. Prinuditel'noe obnovlenie 2. Ogranicheniya: 3. phptal:tales E'ti atributy ne opredeleny v specifikaciyah TAL, no bessomnenno mogut prigodit'sya pri rabote s PHPTAL. phptal:debug E'tot atribut aktiviruet otladku PHPTAL dlya tega s e'tim atributom. Primechanie To debug errors in macros called across templates you need to add phptal:debug in template which defines the macro, not the one which uses it. The debug mode stores information like filename and source line number in the template, so exceptions thrown by incorrect path access will contain more information about where they where thrown. ...
...
phptal:cache E'tot atribut pozvolyaet keshirovat' na diske rezul'tat obrabotki e'lementa (vklyuchaya ego teg). Gotovoe keshirovannoe znachenie budet ispol'zovano do teh por, poka srok dejstviya kesha ne istechet. Primechanie Ispol'zovanie kesha rekomenduetsya tol'ko dlya e'lementov so slozhnymi vyrazheniyami, vychisleniyami, makrosami iz vneshnih fajlov ili PHP dostupa k BD. Vo vseh drugih sluchayah, nekeshirovannye shablony budut nastol'ko zhe bystro obrabatyvat'sya, kak i keshirovannye. V atribute neobhodimo ukazat', kak dolgo dolzhen sohranit'sya kesh. Dlya e'togo nuzhno zapisat' chislo s suffiksom 'd', 'h', 'm' ili 's'.
budet zanovo obrabotan kak minimum raz v 3 chasa. Mozhno ogranichit' "vidimost'" kesha, dopisav "per". Po umolchaniyu, kesh vidim vsem stranicam, ispol'zuyushchim e'tot shablon. Ispol'zujte "per url", chtoby zadannyj e'lement keshirovalsya otdel'no dlya raznyh URL.
    budet keshirovan na odin den', otdel'no dlya kazhdoj stranicy. Mozhno ukazat' "per expression", gde expression - nekoe vyrazhenie. Togda otdel'nye znacheniya v keshe budut generirovat'sya dlya kazhdogo raznogo znacheniya e'togo vyrazheniya (vyrazhenie DOLZHNO v rezul'tate davat' stroku). Vyrazhenie ne mozhet ispol'zovat' peremennye, opredelennye v tom zhe e'lemente s pomoshch'yu tal:define.
      ...
      budet keshirovat'sya kazhdye 25 minut, otdel'no dlya kazhdogo ID ob~ekta. Prinuditel'noe obnovlenie Vmesto togo, chtoby ochishchat' kesh, razumno ispol'zovat' versiyu ili vremya poslednih izmenenij vmeste s per. E'to povlechet za soboj regeneraciyu kesha kazhdyj raz, kogda versiya ili vremya pravki budut izmeneny. V e'tom sluchae, mozhno obojtis' bez ochistki kesha.
      ...
      Ogranicheniya: o Bloki phptal:cache mogut byt' vlozhennymi, no samyj vneshnij blok budet keshirovat' vse vlozhennye bloki, nesmotrya na sostoyanie ih aktual'nosti. o Nel'zya ispol'zovat' metal:fill-slot vnutri e'lementov s phptal:cache. o phptal:tales E'tot atribut pozvolyaet izmenyat' "povedenie" PHPTALES. Po umolchaniyu, vyrazheniya atributov interpretiruyutsya v maksimal'nom sootvetstvii s ZPT (Zope Page Templates). Odnako, najdutsya sluchai, kogda Vy by hoteli ispol'zovat' PHP povsyudu, to est' Vy by vezde primenyali modifikator php:. Drugaya problema otnositel'no PHPTALES sostoit v sposobe, koim PHPTAL interpretiruet puti. Naprimer, myobject/mymethod/property/10/othermethod/hashkey zajmet otnositel'no mnogo vremeni na interpretaciyu (NO ne koncentrirujte na e'tom slishkom mnogo vnimaniya; ne nuzhno optimizirovat', poka vy ne zametite real'noe snizhenie proizvoditel'nosti!) PHPTAL dolzhen (runtime) proverit', chto myobject - e'to ob~ekt; proverit', chto 'mymethod' - metod e'togo ob~ekta (ili, byt' mozhet, peremennaya), i zatem vyzvat' ego; ubedit'sya, chto rezul'tat yavlyaetsya ob~ektom so svojstvo; opredelit', chto znachenie svojstva - massiv; najti desyatyj e'lement e'togo massiva i opredelit', chto e'to ob~ekt; opredelit', chto othermethod - metod e'togo ob~ekta (a ne peremennaya), i poluchit' rezul'tat ego vyzova; opredelit', chto rezul'tat - snova ob~ekt, i zatem poluchit' znachenie dlya klyucha 'hashkey'. Konechno, my peregibaem palku v e'tom primere, i, na samom dele, chashche vsego nas takie problemy ne budut volnovat', ta kak e'tot process ochen' bystr. No chto, esli e'tot ochen' dlinnyj put' vyzyvaetsya v bol'shom cikle tal:repeat? Amin'!.. Imenno tut phptal:tales prihodit na pomoshch':
      Please note that the above example does the same as:
      O modifikatore 'php:' chitajte podrobnee v sootvetstvuyushchej glave . tal:block tal:block budet ochen' polezen, kogda nuzhno spryatat' mnogo e'lementov s obil'nym kolichestvom TAL atributov. Drugimi slovami, teg tal:block - bolee korotkij sposob sozdat' obychnyj HTML teg s atributom tal:omit-tag to zhe samoe, chto i: Drugoj primer:
      to zhe samoe, chto i:
      PHPTALES 1. path: 2. Alternative PHP operator syntax 3. string: 4. php: 5. not: 6. exists: 7. default 8. structure 9. Expression chains PHPTALES is the expression syntax used inside tal, metal, PHPTAL attributes. From above examples, you should have seen some PHPTALES examples (string:, php:, not:, ...). This chapter describes the usage of PHPTALES in templates. The value of a TAL attribute may contain more than one expression (ex: tal:define), in which case each expression must be separated from the next one with a ';' character. path: This is the default modifier used in TAL expression when no other modifier is specified. The following lines will give the same result: ${data/user/name} Inside the template or inside expression strings, you can refer to a context variable using its path in the form ${path/to/my/variable}

      ${document/title}

      Preduprezhdenie If you try to read variable that does not exist, PHPTAL will throw an exception. Use exists: to check if variable can be read Alternative PHP operator syntax Because '<', '>' and '&' characters are cumbersome to use in XML, PHPTAL provides alternative syntax for PHP operators using these characters, and a few more for consistency. These operators can be used only in php: expressions. o < : LT (less than) o > : GT (greater than) o <= : LE (less or equal) o >= : GE (greater or equal) o == : EQ (equal) o != : NE (not equal) o && : AND o || : OR string: Because expressions are separated by a ';' character, and because '$' marks the start of a path, you must use: o ';;' when you want to insert a real ';' character in a string, o '$$' when you want to insert a real '$' character in a string. string:foo $bar baz string:foo $$bar baz string:foo ; php:doFoo() string:foo ;; php:doFoo() php: This expression evaluates what follows as a regular PHP expression except that '->' are replaced by dots '.' and variable names does not need to be prefixed with a dollar '$' sign. A dot '.' separated from the rest of expression by spaces is assumed to be a concatenation sign. php:htmlentities(foo) php:'string ${varReplaced}' php:'string ${some.path().to[0].var}' php:NOT foo OR (bar GT baz) php:a + b php:array('a', 'b', 'c') php:range(0, 90) php:foo . a.b.c(e) . htmlentities(SomeClass::staticMethod()) php:SomeClass::ConstOfClass php:SomeClass::$staticVar php: should be used with care and won't be needed in 80% of your templates but sometimes you will need to invoke some special PHP method to be certain whether a user is logged in, or to retrieve specific complex data depending on some conditions, dynamically inside the template. not: This expression is a boolean one, useful in tal:condition statements. not logged exists: This expression returns true if the path specified after it exists, and false otherwise. It is analogous to PHP's isset(). Normally using a path which doesn't exist throws an error like "Cannot find variable 'foo' in current scope". Thus, uncertain paths must be checked first: Use user/preferences here if defined Podskazka In PHPTALES use isset() instead. default This is not an expression but a keyword, allowing template designers to keep the content of a tag as an alternative value if an error occurs, or if something is not defined. default my var value no some/var and no other/path found here Unknown page Above examples introduce the '|' character that allows the definition of alternatives for defines or prints. structure This is not an expression modifier but a keyword. While printing variables inside PHPTAL templates, you will have noticed that PHPTAL encodes each variable to ensure the validity of the output document. Sometimes, you may use HTML/XML variables which must be echoed as is.

      In above examples, we assume that $document->title and $document->content are variables containing preformated HTML which must be echoed as is. Expression chains An expression chain is a list of expressions separated by '|' characters. While evaluating expressions separated by '|', PHPTAL will stop its evaluation when an expression value is not null and no error was raised while evaluating the expression. As a string: expression is always true, string: always terminates an expression chain whatever expression may follow. You can use php: expressions inside expression chains, like any other expression.

      PHP Integration ---------------------------------------------------------------------- Soderzhanie 1. Constants 2. Configuration methods 3. class PHPTAL 4. interface PHPTAL_Filter 5. interface PHPTAL_Trigger 6. interface PHPTAL_TranslationService 1. method setLanguage(...) 2. method useDomain($domain) 3. method setVar($key,$value) 4. method translate($key) 5. method setEncoding($encoding) 7. Working with gettext 1. Creating the translation directory structure 2. Portable Object files 3. Translation Domain 4. Using Translator in PHP 5. Variable interpolation 8. Creating custom expression modifiers This section is aimed at PHP developers and explains how to use and customize PHPTAL behaviors for simple and advanced usage. o PHPTAL: the main PHPTAL class. It is used to load and execute templates. o PHPTAL_Filter: filtering template sources and PHPTAL output. o PHPTAL_Trigger: handles output of elements with phptal:id. o PHPTAL_TranslationService: for replacing the built-in gettext support with your own internationalization system. Constants The only constant defined in PHPTAL.php is PHPTAL_VERSION. It contains version of PHPTAL library installed on your system (in format: X.X.X). In older versions of there were constants for configuration. They have been removed in favor of methods. Configuration methods PHPTAL tries to use best defaults possible and you shouldn't need to change any of the settings. All of these are methods of the PHPTAL class. set* methods return instance of their class, so you can chain them: setPhpCodeDestination('/tmp/phptal')->setOutputMode(PHPTAL::XML)->setTemplate('tpl.zpt')->execute(); ?> to zhe samoe, chto i: setPhpCodeDestination('/tmp/phptal'); $phptal->setOutputMode(PHPTAL::XML); $phptal->setTemplate('tpl.zpt'); echo $phptal->execute(); ?> o setEncoding(encoding): Specify what encoding your templates use. The default is UTF-8. o setOutputMode(mode): If given PHPTAL::XHTML (the default), will output elements like , , and attribtes like checked, selected according to XHTML specification, including HTML compatibility guidelines. Use PHPTAL::XML if you want to output other XML formats, like Atom or RSS. o setTemplateRepository(string_or_array): Specifies where to look for templates. If given a string, it adds it to the list of paths searched. If given array, it replaces the list. This doesn't mean all your files need to be in the root directory, you can use sub folders to organize your template designer's work. It's just a shortcut which will allow you to reference templates without specifying the real path, but instead their relative path within the repository. o setPhpCodeDestination(path): To tell PHPTAL where to store its intermediate (temporary) PHP files. By default it uses directory given by PHP's sys_get_tmp_dir(), which usually is '/tmp/' directory. o setPhpCodeExtension(string): What filename extension should be used for intermediate PHP files. The default is php and frankly, there's no reason to change it. o setCacheLifetime(num_days): Maximum number of days intermediate files and fragments cached with phptal:cache should be kept. o setForceReparse(boolean): forces reparsing of all templates all the time. This slows down PHPTAL very much, it should be used only for testing and debugging. Never enable this on production servers. There are other set* methods for filters, internationalization, etc. They have been described in other sections of this manual. class PHPTAL This is the main library class for you to use. The most common method of use: title = 'my title'; $tpl->values = array(1,2,3,4); $tpl->user = new User('Joe'); // execute the template and echo the result in a 'secure' way try { echo $tpl->execute(); } catch (Exception $e){ echo "Exception thrown while processing template\n"; echo $e; } ?> You can perfectly well choose to specify the template source after setting context variables. set('title', 'my title'); $tpl->set('values', array(1,2,3,4)); $tpl->set('user', new User('Joe')); $tpl->setTemplate('mytemplate.xhtml'); ... ?> You can also decide to use a generated string as the template source instead of using an existing template file: my title

      my title

      EOS; require_once 'PHPTAL.php'; $tpl = new PHPTAL(); $tpl->setSource($src); $tpl->title = 'this is my title'; try { echo $tpl->execute(); } catch (Exception $e){ echo $e; } ?> In the above example, because PHPTAL requires a template source identifier (usually the template file realpath), PHPTAL will use the md5 of the $src parameter as a unique identifier. You may decide to force the identifier using a second setSource() argument: my title

      my title

      EOS; require_once 'PHPTAL.php'; $tpl = new PHPTAL(); // If you specify where the source comes from (second argument to setSource), // PHPTAL will be able to generate more helpful error messages. $tpl->setSource($src, __FILE__); $tpl->title = 'this is my title'; try { echo $tpl->execute(); } catch (Exception $e){ echo $e; } ?> interface PHPTAL_Filter This interface allows you to automatically filter templates sources (pre-filters) or PHPTAL result (post-filters). Pre filters are invoked before the template parsing and won't be invoked until the source template file is modified. Post filters are invoked after each template execution. setPreFilter(new MyPreFilter()); $tpl->setPostFilter(new MyPostFilter()); echo $tpl->execute(); ?> You can set only one pre-Filter and one post-Filter using set*Filter. If you have more than one filter to chain, you can wrap them into a single class, implementing the PHPTAL_Filter interface, which would invoke the filter's chain. _filters[] = $filter; } public function filter($source){ foreach($this->_filters as $filter){ $source = $filter->filter($source); } return $source; } } $myfilter = new FilterChain(); $myfilter->add(new CommentFilter()); // imaginary filter $myfilter->add(new TidyFilter()); // imaginary filter $tpl = new PHPTAL('mytemplate.xhtml'); $tpl->setPostFilter($myFilter); echo $tpl->execute(); ?> interface PHPTAL_Trigger The phptal:id attribute was added into the PHPTAL for the PHP5 version to replace the old PHPTAL_Cache interface and to abstract it a little more. When a phptal:id is reached, PHPTAL will look in its triggers list for a matching id and will invoke the trigger start() and end() methods before entering the element, and just after it. If the PHPTAL_Trigger::start() methods returns PHPTAL_Trigger::SKIPTAG, PHPTAL will ignore the element and its content (start() may echo something to replace it). If your trigger wants the element and its content to be executed, you'll have to return PHPTAL_Trigger::PROCEED. The PHPTAL_Trigger::end() will be called after the element (whether it has been executed or not). This allows you to build cache systems using ob_start() in start() and ob_get_contents(), ob_end_clean() in end(). ...
      ... foo bar baz foo bar baz ...
      ... For some reason we decide the
      block requires to be cached. We introduce a phptal:id into the template: ...
      ... foo bar baz foo bar baz ...
      ... Then we write our trigger which will cache the
      content: _cachePath = 'cache.' . $tpl->getContext()->id; // if already cached, read the cache and tell PHPTAL to // ignore the tag content if (file_exists($this->_cachePath)){ $this->_usedCache = true; readfile($this->_cachePath); return self::SKIPTAG; } // no cache found, we start an output buffer and tell // PHPTAL to proceed (ie: execute the tag content) $this->_usedCache = false; ob_start(); return self::PROCEED; } // Invoked after tag execution public function end($phptalid, $tpl) { // end of tag, if cached file used, do nothing if ($this->_usedCache){ return; } // otherwise, get the content of the output buffer // and write it into the cache file for later usage $content = ob_get_contents(); ob_end_clean(); echo $content; $f = fopen($this->_cachePath, 'w'); fwrite($f, $content); fclose($f); } private $_cachePath; private $_usedCache; } ?> The key here is to return from start() with either SKIPTAG or PROCEED. When SKIPTAG is returned, PHPTAL will just ignore the tag and call end(). This usually means that the trigger takes the hand in deciding what to show there. When PROCEED is returned, PHPTAL will execute the tag and its content as usual, then call end(). This allows our cache class to play with output buffers to execute the tag once and to store the result in a file which will be used in later calls. To install our trigger we use: addTrigger('somePossiblyUniqueKeyword', $trigger); $tpl->id = 1; echo $tpl->execute(); ?> You can add as many triggers as you like to your templates. A generic cache trigger may also handle more than one phptal:id... etc... interface PHPTAL_TranslationService 1. method setLanguage(...) 2. method useDomain($domain) 3. method setVar($key,$value) 4. method translate($key) 5. method setEncoding($encoding) PHPTAL comes with a default gettext translation service, as shown in another section. For some reason you may prefer to implement your own service of translation. The PHPTAL_TranslationService interface is here to serve your needs. The usage of your service will be the same as the PHPTAL_GetTextTranslator. $tpl->setTranslator($yourOwnTranslatorInstance); Your implementation must define the following methods: method setLanguage(...) This method may be called by the template to change the current output language. Its arguments are a list of possible languages (use func_get_args() to get the argument array). The first known language should be used by your service. _currentLang = $lang; return; } } ... private $_currentLang; } ?> method useDomain($domain) If you decided to store your translations into separate files, one for each application, for example, this method allows you to select the translation domain from your templates (i18n:domain). _domains)){ $file = "domains/$this->_currentLang/$domain.php"; $this->_domains[$domain] = include($file); } $this->_currentDomain = $this->_domains[$domain]; } ... private $_currentDomain; private $_domains = array(); } ?> The above example is a possible translation solution where keys are stored in PHP files which return an associative array of key => translation. method setVar($key,$value) This method matches i18n:name calls. It builds an interpolation context for later translate calls. _context[$key] = $value; } ... private $_context = array(); } ?> method translate($key) The last and most important method to implement, it asks your service to translate the specified key for the currently selected language. _currentDomain[$key]; // interpolate ${myvar} using context associative array while (preg_match('/\${(.*?)\}/sm', $value, $m)){ list($src,$var) = $m; if (!array_key_exists($var, $this->_context)){ $err = sprintf('Interpolation error, var "%s" not set', $var); throw new Exception($err); } $value = str_replace($src, $this->_context[$var], $value); } return $value; } ... } ?> method setEncoding($encoding) PHPTAL class calls this method to inform your translation service what encoding is used by the template. translate() method should return strings in that encoding. If you always use the same encoding for templates and translation files (i.e. UTF-8), you can leave this method empty. Working with gettext 1. Creating the translation directory structure 2. Portable Object files 3. Translation Domain 4. Using Translator in PHP 5. Variable interpolation gettext is a standard GNU internationalization / translation system which can be used with PHP and which is supported by PHPTAL. The usage of gettext is simple but you will have to perform some tests to be sure everything works fine on your system. First, PHP must be compiled with the --with-gettext flag. See PHP documentation for how to do this. You can test your installation using following peace of code: // // test if gettext extension is installed with php // if (!function_exists("gettext")) { echo "gettext is not installed\n"; } else { echo "gettext is supported\n"; } Creating the translation directory structure The PHP gettext extension requires a specific structure which will contain your translation files. /path/to/your/translation_root/en_US/LC_MESSAGES/ /path/to/your/translation_root/en_GB/LC_MESSAGES/ /path/to/your/translation_root/fr_FR/LC_MESSAGES/ /path/to/your/translation_root/es_ES/LC_MESSAGES/ ... and so on ... The language code is composed of two characters defining the language itself (en, fr, es, ...) and two characters defining the country (US, GB, FR, ES, ...). The directory pattern is: //LC_MESSAGES/ Portable Object files PO files are plain text files that contain your translation. You can safely edit them by hand. po minimalistic example (en_US/LC_MESSAGES/mydomain.po): msgid "" msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Simple test" msgstr "A small sentence in english" Once edited, each PO file must be indexed using: msgfmt mydomain.po -o mydomain.mo This command won't work if you don't have gettext tools installed on your system. This will produce a MO file (machine object) indexing your translation for quick access. Then you have to translate this file in other languages. po minimalistic example (fr_FR/LC_MESSAGES/mydomain.po): msgid "" msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Simple test" msgstr "Une petite phrase en franc,ais" The translation file must also be indexed: msgfmt mydomain.po -o mydomain.mo Translation Domain The domain is matched against your translation file names. In above examples we used 'mydomain' as domain name. You can have more than one domain for the same application, it can enhance gettext's performance to split your application translations in more than one file. Using Translator in PHP setLanguage('en_GB.utf8', 'en_GB'); // register gettext domain to use $tr->addDomain('mydomain', '/path/to/your/translation_root'); // specify current domain $tr->useDomain('mydomain'); $tpl = new PHPTAL('mytemplate.xhtml'); // tell PHPTAL to use our translator $tpl->setTranslator($tr); // output translated template echo $tpl->execute(); } catch (Exception $e){ echo $e; } If you need to translate some other text, that is not in the template (e.g. plaintext e-mail message), you can reuse PHPTAL's translator: $tr = $tpl->getTranslator(); $subject = $tr->translate("Registration information"); $tr->setVar("user",$username); $message = $tr->translate("Dear ${user}, thanks for registering!"); mail($email, $subject, $message); If you're using PHPTAL's standard gettext translator, you can use gettext() too. Variable interpolation The I18N namespace allows some variable interpolation in your translations. # english msgid "welcome" msgstr "Welcome ${name} you have ${n} mails!" # french msgid "welcome" msgstr "Bienvenue ${name} vous avez recu ${n} messages!" A template can use this interpolation as follows: Welcome you currently have unread messages! Because i18n:translate contains a value 'welcome', the template data will be ignored and the message given by gettext will be used instead. Creating custom expression modifiers PHPTAL comes with some basic expression modifiers (not:, exists:, string:, php:, path:). These modifiers are defined by ZPT specifications but PHPTALES can be extended with your own modifiers to manipulate strings, date, money numbers, objects, whatever... The aim of a modifier is to return some PHP code that will be included in the template PHP source. Modifiers are used at parse time. If you change the behavior of a modifier, you'll have to delete generated PHP files and reparse all templates using it. Please note that modifiers produce code, and mustn't echo data! Any PHP function starting with "phptal_tales_" is usuable as a modifier. Modifiers takes two arguments: o $src: the source string after the "modifier:" keyword o $nothrow: a boolean which determines whether exceptions may be thrown or not by phptal_path() resolution. This boolean must be propagated whenever you call another phptal_tales_* modifier from within your own modifier. For example, in the following TAL template, The src argument will be "my/path/value", and the $nothrow boolean will be false, because tal:replace requires the path to be fully resolvable. An expression like: Will use 2 modifiers: o some-modifier: with "my/path/value" as $src argument and $nothrow set to true because an alternative exists o path: with "other/path" as $src, and $nothrow set to false because in case the alternative is not found, tal:replace will be in trouble. Remember, path: is the implicit modifier used when no other modifier is specified. Modifiers can use other modifiers to generate simpler PHP code. The example below shows this. // // This modifier will return a money formated string (XXX.XX) // // usage: // // money: path/to/my/amount // // this modifier uses phptal_tales() function to generate the // PHP code that will return the value of the modifier argument. // // in the example: // // money: path/to/my/amount // // the produced code will be something looking like: // // sprintf("%01.2f", phptal_path($ctx->path, "to/my/amount")) // // This code will be included right into the template where needed. // // @param string $src // The expression string // @param string $nothrow // A boolean indicating if exceptions may be throw by phptal_path if // the path does not exists. // @return string // PHP code to include in the template // function phptal_tales_money( $src, $nothrow ) { // remove spaces we do not require here $src = trim($src); return 'sprintf("%01.2f", '.phptal_tales($src, $nothrow).')'; } Note for system administrators ---------------------------------------------------------------------- PHPTAL functions by generating PHP files from the template's logic, this means that it needs a directory to store those generated files so they can be parsed by the PHP interpreter. By default PHPTAL will use the system's temp directory (via PHP's sys_get_temp_dir() function if available) or will try to guess where it should be, /tmp on Unix like systems and c:\windows\temp on Microsoft ones, to store the compiled templates. The default destination can be changed to your liking by calling setPhpCodeDestination() method with the appropriate path. Be it the system's temp directory or a custom one, it needs to have its permissions setup as to allow the PHP running process (the Apache user if using mod_php or the cgi/fastcgi user otherwise) to create and update files in that directory. PHPTAL creates one file for each different template file and one file for each tag if using phptal:cache. It doesn't create separate files for macros (which are simply compiled as PHP functions inside the compiled template file). These files are automatically cleaned up once in a while, more specifically, each time a template is compiled there is random probability, controlled by setCachePurgeFrequency() method, which will just delete files older than set by setCacheLifetime() method. Alternatively you can also schedule the deletion of old/unused files by running this from an Unix-like shell (e.g. in a cron job): find /tmp/ -name tpl_\* \( -atime +1 -o -mtime +14 \) -delete Useful links ---------------------------------------------------------------------- o ZPT Zope Page Template front page, o TAL the Template Attribute Language page, o METAL is the Macro Expansion of TAL, o TALES the TAL Expression Syntax. Greetings ---------------------------------------------------------------------- Big thanks goes to: o ZPT team, who made these useful specifications, o The PHPTAL community for their support, help and reports, o Jean-Michel Hiver, who 'forced' me to look at them, o Olivier Parisy, the first enthusiastic PHPTAL user and bug finder,