Sortering på tabeller
Hvis der er en ting jeg hader, så er det at lave trivielle tabeller med sortering. Jeg har dog efterhånden fundet den løsning jeg bedst kan li’.
Typisk vil man ha’ noget html som dette:
1 2 3 4 5 | <table> <tr> <th><a href="list.php?sort=name&type=asc">Navn</a></th> <th><a href="list.php?sort=age&type=asc">Alder</a></th> [...] |
Men det er pænt irriterende at generere linket, samt holde styr på om man sorterer stigende eller faldende, og der kommer sikkert også andre parametre med ind i URL’en. Så det har man ikke lyst til. Jeg ved godt at der findes Javascripts der kan sortere tabeller, men det virker kun hvis man ser hele tabellen, og ikke hvis der er flere sider.
Min løsning er at lave en form med nogle skjulte felter, og med manipulere den med jQuery når man klikker på th’erne.
Min tabel vil så se sådan ud:
1 2 3 4 5 | <table> <tr> <th x:name="name" class="sortable">Navn</th> <th x:name="age" class="sortable">Alder</th> [...] |
I mit stylesheet har jeg selvfølgelig en
1 2 3 | table th.sortable { cursor:pointer; } |
Og måske en text-decoration:underline så man kan se at man kan trykke på feltet.
Så laver jeg en form med to skjulte felter jeg bruger til at sortere med:
1 2 3 4 | <form action="list.php" method="get" id="form"> <input type="hidden" id="order_by" name="order_by" value="<{$smarty.get.order_by|escape|default:"name"}>"/> <input type="hidden" id="order_type" name="order_type" value="<{$smarty.get.order_type|escape|default:"asc"}>"/> </form> |
Derefter noget jQuery:
1 2 3 4 5 6 7 8 9 | <script type="text/javascript"> $(document).ready(function() { $("th.sortable").click(function() { $("#order_by").val($(this).attr("x:name")); $("#order_type").val($("#order_type").val() == "desc" ? "asc" : "desc"); $("#form").submit(); }); }); </script> |
Sprog i Smarty
I forlængelse at mit forrige indlæg vil jeg komme med nogle idéer til hvordan man kan tilføje sprogsupport i Smarty.
Det jeg gerne vil ende med er en løsning hvor jeg i mine templates kan skrive noget lignende:
1 | <h1>{translate}Welcome to my site{/translate}</h1> |
Men også
1 | <title>{$title|translate}</title> |
Jeg vil også kunne angive sproget direkte, fx:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <html> <head> <title>{$title|translate:"fr"}</title> </head> <body> <h1>{translate lang="fr"}Welcome to my site{/translate}</h1> </body> </html> |
Jeg vil aldrig kalde Smarty direkte, men altid via min egen klasse som extend’er Smarty. Det gør det bl.a. nemmere at sætte diverse indstillinger op. I min egen klasse vil jeg, for at understøtte sprog, tilføje en block og en modifier. Det gør jeg på følgende måde:
1 2 3 4 5 6 7 8 | class mbnSmarty extends Smarty { public function __construct() { $this->register_modifier('translate', 'smarty_m_translate'); $this->register_block('translate', 'smarty_b_translate'); } } |
Bagefter skal jeg skrive de to funktioner hhv. smarty_b_translate og smarty_m_translate.
1 2 3 4 5 6 7 8 9 10 11 12 13 | function smarty_b_translate($args, $str, &$smarty, &$repeat) { if (!$repeat) { $text = new Text(); $text->setText($content); return $text->translate($args['lang'] ? $args['lang'] : LANG); } } function smarty_m_translate($str, $lang = LANG) { $text = new Text(); $text->setText($str); return $text->translate($lang); } |
Jeg har i mine eksempler gået ud fra, at der er defineret en LANG-konstant på følgende måde:
1 | define("LANG", "da"); |
Jeg bruger også en Text-klasse, som I selv må lave :)
Idé til caching i Smarty
På BedsteVen.dk viser jeg de seneste aktiviteter på forsiden. Det samme gør jeg på aktivitetssiden. Hver aktivitet indeholder en del databaseopslag. Eftersom min database-klasse som nævnt før automatisk gi’r mig en getFoo() og setFoo() hvis tabellen indeholder feltet foo. Valgte jeg at implementere noget simpelt caching på følgende måde:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | {* Jeg har tilføjet et 'cache' felt i min aktivitetstabel *} {assign var="cache" value=$activity->getCache()} {if $cache} {$cache} {else} {capture name=act} {* Her hentes og vises den enkelte aktivitet *} {/capture} {* Jeg viser det fangede indhold *} {$smarty.capture.act} {* Måske lidt grimt, men templaten kan også gemme indhold. Derfor gemmer jeg det genererede indhold her *} {$activity->setCache($smarty.capture.act)} {/if} |
Videresende sin smartlog-blog
Hermed et lille tip til hvordan man viderestiller sin smartlog-blog til an anden. Man kan ikke gøre det på den “rigtige” måde, men jeg løste det ved at lave følgende i min template:
1 2 3 4 5 6 7 8 9 10 | <{if $single}> <{assign var="s" value=$posts.0->getHeadline()}> <{elseif $tag}> <{assign var="s" value=$tag->getTag()}> <{elseif $page}> <{assign var="s" value=$page->getHeadline()}> <{/if}> <meta http-equiv="Refresh" content="0; url=http://mbn.dk/?s=<{$s|escape}>"> |
Det er meget simpelt, og det virker de fleste gange. Eftersom smartlog.dk ikke kender den nye adresse videresender jeg til søgesiden i min blog.

Jeg hedder Morten, og jeg har udviklet webapplikationer siden slutningen af 90'erne.