Nette odkaz v DB popř. jako static text mimo šablonu
- Bernard Williams
- Člen | 207
Nazdárek,
už nějakou chvilku si nevím rady s odkazem, který mám umístěný v DB nebo pouze ve statické třídě. Když je text přímo v šabloně, tak použiju {link …} nebo „nette:…“, ale když data čtu z DB a poté je vypisuji do šablony, tak ani jeden z těchto způsobů nefunguje. Jak mám tedy odkaz v DB řešit?
S poděkováním
Bernard
- Honza Kuchař
- Člen | 1662
Nějak nechápu i čem mluvíš. Data z databáze předáš do šablony a tam už si voláš {link …}
- PetrP
- Člen | 587
Mluví o tomto:
$this->template->text = '
Nejaky nadpis
=============
A textik..... "odkaz":{link Default:}
';
A nette nenabízí žadnou moznost jak to řešit.
Jedině si na to napsat nějakou vlastní rutinu nebo to nechat project
CurlyBrackedFiltrem:
$this->template->text = CurlyBracketsFilter::invoke($this->template->text);
Už se o tom na fóru kdysi mluvilo, ale nevím jestli nějak dopadlo.
- PetrP
- Člen | 587
jasir napsal(a):
Myslím, že tohle by mohlo pomoct… Snad…
Nj, ale neni to pod volnou licenci ;/
Přikládám teda moje řešení pod new BSD
/**
* Copyright (c) Petr Procházka
* @license new BSD
*/
Class LinkFilter {
/**
* @param string
* @return string
*/
public static function encode($s)
{
return preg_replace_callback('#(?<!{linkFilter )'.preg_quote(Environment::getHttpRequest()->getUri()->getBaseUri(),'#').'[^\s]*#',array(__CLASS__,'encodeCallback'),$s);
}
private static function encodeCallback($match)
{
$router = Environment::getApplication()->getRouter();
$httpRequest = new HttpRequest;
$httpRequest->setUri(new UriScript($match[0]));
$request = $router->match($httpRequest);
if (!($request instanceof PresenterRequest))
{
return $match[0];
}
$params = $request->getParams();
$destination = ':'.$request->getPresenterName().':'.$params['action'];
unset($params['action']);
$params = http_build_query($params);
$destination = $destination.(!empty($params)?'?':'').$params;
return '{linkFilter '.$match[0]." $destination}";
}
/**
* @param string
* @return string
*/
public static function decode($s)
{
return preg_replace_callback('#\{linkFilter (http[^\s]+)? ?([^\}]*) ?\}#',array(__CLASS__,'decodeCallback'),$s);
}
private static function decodeCallback($match)
{
$presenter = Environment::getApplication()->getPresenter();
if ($presenter === NULL) return $match[1];
$link = $presenter->link((strpos(trim($match[2]),'//')===0?'':'//').trim($match[2]));
if ($link == '#' OR preg_match('#^error:#',$link)) return $match[1];
return $link;
}
}
Asi to ještě není ideální v případě nějakeho zájmu to dorozšířím.
Použití:
$data = '
Text text <a href="http://moje.domena/nekam">Odkaz</a>
Nebo "Odkaz":http://moje.domena/nekam
';
// Při ukládání do db
$model->save( LinkFilter::encode($data) );
// Při zobrazovaní
$presenter->template->text = LinkFilter::decode($data);
Je možný i zápis přes macro {linkFilter url destination}
url = adresa ktera se použije v případě že destination neodpovídá
žádná routa
Nemusí se uvádět
destination = zápis podobný tomuto
(mimo jiné je podporovanej i v
$presenter->link()) Presenter:action?param1=value¶m2=value
Tedy například:
{linkFilter http://neco.cz/ Homepage:}
{linkFilter http://neco.cz/produkt/123 Products:view?id=123}
{linkFilter :Auth:login}
Editoval PetrP (5. 8. 2009 17:52)
- Bernard Williams
- Člen | 207
Tohle bohužel nejde použít, i když by to bylo asi nejjednodušší. Zkoušel jsi to sám?
$this->template->text = CurlyBracketsFilter::invoke($this->template->text);
Co se týče té třídy LinkFilter, dá se v textu použít konstrukce {link …} nebo pouze <a href=… popř. Texy. Pokud ne, tak to neřeší můj problém. Musel bych do DB ukládat odkazy již v konečné podobě a kdybych se rozhodl udělat nějakou změny v routování, tak bych to v DB musel vše ručně upravit.
- Ola
- Člen | 385
Já spíš myslím, že to co posílal PetrP funguje tak, že v textu
normálně odkazuješ přes
<a href="http://example.com/category/nette">Nette</a>
např., ale před uložením do databáze se vybere vhodná routa a podle ní se
to opraví na
<a href="{linkFilter Category: 5}">Nette</a>
(kde 5 je
id nette kategorie) a potom se to vždycky při zobrazení zase zpracuje dle
rout v aplikaci.
Na to finální zobrazení by ale asi bylo vhodný udělat si helper kterej zavolá LinkFilter::decode takhle: $this->template->registerHelper(‚links‘, ‚LinkFilter::decode‘);
A pak v šabloně:
{!$content|links}
Editoval Ola (5. 8. 2009 12:31)
- Bernard Williams
- Člen | 207
A co v případě, když ještě routování nemám hotové a všude používám {plink …}?
- Bernard Williams
- Člen | 207
Takže do té DB mohu psát odkazy jak je libo jen s tím rozdílem, že místo {plink …} napíšu {linkFilter …} ?
- PetrP
- Člen | 587
Bernard Williams napsal(a):
Takže do té DB mohu psát odkazy jak je libo jen s tím rozdílem, že místo {plink …} napíšu {linkFilter …} ?
Tak to původně nebylo zamýšleno, ale už to jde.
Myšlenka je takové že to použije bfu které plní data do aplikace, např
přes nějaký wysiwyg a všechny adresy si pěkně píše ručně / kopíruje
z adresního řádku. Při ukládání to proženeš
LinkFilter::encode($data)
a všechny adresy na tvůj server se
převedou na adekvátní zapis dle rout. A při zobrazování se zase dle
aktuálních rout převedou na aktualní url, tedy teď můžeš psát adresy
tak jak je más (třeba http://example.com/index.php?…) a až zmeníš libovolně
routy tak se adresa změní.
Je taky možné zápis přes
{linkFilter http://example.com/ :Defaul:defaul?param=value}
kdy ta adresa se použije v případě že se nenajde adektávtní routa,
třeba byla smazána (nemusi se uvadet)
a ten zápis za ?
je podporovaný přímo v nette (klasický to
pro zjednodušení neumožnuje)
// EDIT
Šlo by i přidat podporu pro p?link, ale otázka je jestli to je potřeba,
protože tohle je prostě určené pro plnění dat někým kdo ani nemusí
věďet že existuje nette, natož néjaké {link…
A taky bych se pak pravdepodobně nevyhnul evalu (eval od slova evil) ;]
Editoval PetrP (5. 8. 2009 17:41)