Nette odkaz v DB popř. jako static text mimo šablonu

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

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
+
0
-

Nějak nechápu i čem mluvíš. Data z databáze předáš do šablony a tam už si voláš {link …}

PetrP
Člen | 587
+
0
-

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.

jasir
Člen | 746
+
0
-

Myslím, že tohle by mohlo pomoct… Snad…

PetrP
Člen | 587
+
0
-

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&param2=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
+
0
-

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
+
0
-

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
+
0
-

A co v případě, když ještě routování nemám hotové a všude používám {plink …}?

Ola
Člen | 385
+
0
-

Ty nesmíš v DB používat {link} a {plink} ale {linkFilter} ;), teď sem si toho všimnul

Bernard Williams
Člen | 207
+
0
-

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
+
0
-

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)

Bernard Williams
Člen | 207
+
0
-

Paráda! Vše šlape jak má. Mockrát děkuju!