Curlebrackets, vlastný filter a podivné @php:

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

Ahojte,

Spravil som si vlastný filter, ktorý prechádza v šablóne všetky odkazy, a keď nájde niečo ako nette:Presenter:action?… tak to nahradí normálnym odkazom. Navyše zistí, či má užívateľ právo takúto stránku navštíviť, a ak nie, tak ho jednoducho nezobrazí.

Funguje to výborne, ale narazil som na jeden problém. Ak mám nasledovný kód:

<a href="!nette:Film:edit?id={$film->id}">Edit film</a>

tak sa {$film->id} nahradí vo vygenerovanom template konštrukciou

<a href="<?php echo $template->escape($component->link('Film:edit', array (
  'id' => '_@php:p11@_',
)))?>">Edit film</a>

Takže id-čko tam nie je, iba _@php:p11@_. Podarilo sa mi zistiť, že toto používa filter removePhp ale nedopátral som sa kde sa toto nahrádzanie odohráva. Mohli by ste ma niekto usmerniť na čo sa mám pozrieť, aby som si svoj filter mohol dobre upraviť?

Vďaka.

redhead
Člen | 1313
+
0
-

Na přesně to samé jsem narazil také. Už ani nevím u čeho, ale taky jsem si pohrával s novým filtrem za použití LatteFilteru. Nenašel jsem řešení..

pozn.: CurlyBracketsFilter byl přejmenován na LatteFilter.

David Grudl
Nette Core | 8229
+
0
-

Tam zřejmě dochází ke konfliktu dvou filtrů, tvého a LatteFilter. Ono záleží i na pořadí registrování filtrů.

Že tam je to _@php:p11@_, to je jen kvůli maskování PHP kódu v textu šablony před filtrem.

fiso
Člen | 32
+
0
-

Prehodenie poradia problém nevyrieši:

<a href="<?php echo $template->escape($component->link('Film:edit', array (
  'id' => '{$film->id}',
)))?>">Edit film</a>

Ako by sa to dalo vyriešiť? Je to pre mňa dosť nepríjemná vec.

David Grudl
Nette Core | 8229
+
0
-

Zkus sem poslat kod tveho filtru.

fiso
Člen | 32
+
0
-
// links regarding on authorization
$this->template->registerFilter(function($s)  {
	return preg_replace_callback(
		'#(?P<before>\<(h1|h2|h3|h4|h5|h6|li).*\>.*)?(?P<tagStart>\<(?P<tag>[^>]+)\s.*(?P<attr>src|href|action|on[a-z]+)\s*=\s*)"(?P<alwaysShow>\!)?(?P<uri>nette:.*?)(?P<tagEnd>[\#"].*\>(?(?=.*\<\/\\4\>).*\<\/\\4\>|.*\<\/\\4\>))(?P<after>.*\<\/\\2\>)?#',
	    function($m) {
			// html definitions before link
			$before = isset($m['before']) ? $m['before'] : '';
			// tag (such as a, img, etc) that contains interesting attribute
			$tagStart = $m['tagStart'];
			// tag contents
			$tag = $m['tag'];
			// attribute name
			$attr = $m['attr'];
			// value of the attribute
			$uri = $m['uri'];
			// end of the containing tag
			$tagEnd = $m['tagEnd'];
			// html definitions after link
			$after = isset($m['after']) ? $m['after'] : '';

			// determines whether the link has to be always shown (it is ignoring authorization rules)
			$alwaysShow = !empty($m['alwaysShow']);

			// it is some other scheme
			$parts = parse_url($uri);
			if (!isset($parts['scheme']) || $parts['scheme'] !== 'nette') return $m[0];

			// parse query parameters into array
			if (isset($parts['query'])) {
				parse_str($parts['query'], $params);
				foreach ($params as $k => $v) {
					if ($v === '') $params[$k] = NULL;
				}
			} else {
				$params = array();
			}


			$path = isset($parts['path']) ? $parts['path'] : 'this!';

			$return = "";
			if(!$alwaysShow && $path != 'this!') {
				// presenter represents resource, action represents privilege
				$arr = explode(":", $path);
				$actionName = end($arr);
				$presenterName = prev($arr);
				$return .= '<?php if(Environment::getUser()->isAllowed(\''.$presenterName.'\', \''.$actionName.'\')): ?>';
			}

			$return .= $before
				. $tagStart
				. '"<?php echo $template->escape($component->'
				. (strncmp($attr, 'on', 2) ? 'link' : 'ajaxLink')
				. '(\''
				. $path
				. '\', '
				. var_export($params, TRUE)
				. '))?>'
				. $tagEnd
				. $after;

			if(!$alwaysShow && $path != 'this!') {
				$return .= '<?php endif ?>';
			}

			return $return;
		},
		$s
	);
});
fiso
Člen | 32
+
0
-

Ak niekoho napadne ako ten kód vylepšiť, tak nech sa tiež kľudne ozve :)

fiso
Člen | 32
+
0
-

Zaujímavá vec, takéto kusy kódu

<a href="!nette:Film:view?id={$film->id}">View film</a> | <a href="!nette:Film:edit?id={$film->id}">Edit film</a>

<a href="!nette:Film:view?id={$film->id}">View film</a>
| <a href="!nette:Film:edit?id={$film->id}">Edit film</a>

generujú toto:

<a href="!nette:Film:view?id=<?php echo TemplateHelpers::escapeHtml($film->id) ?>">View film</a> | <a href="<?php echo $template->escape($component->link('Film:edit', array (
  'id' => '{$film->id}',
)))?>">Edit film</a>

<a href="<?php echo $template->escape($component->link('Film:view', array (
  'id' => '{$film->id}',
)))?>">View film</a>
| <a href="<?php echo $template->escape($component->link('Film:edit', array (
  'id' => '{$film->id}',
)))?>">Edit film</a>

Rozdiel v šablóne je v pridanom riadku.

fiso
Člen | 32
+
0
-

Prišiel som na to, čo treba spraviť, nie je to ale nič príjemné a jednoduché.

Môj filter používa funkciu var_export, ktorá nejako pokazí UTF-8 znaky \x02 a \x01 a nahradí ich znakom _, a preto fcia strtr toto správne nespracuje. To je dôvod všetkých _@php čo boli vyššie. Takže zmenou týchto znakov na _ vo fcii extractPhp som docielil že var_export mi vyhodí niečo takéto:

<a href="<?php echo $template->escape($component->link('Film:view', array("id" => "<?php echo TemplateHelpers::escapeHtml($film->id) ?>")))?>">Viewa film</a>

Takže prvý nápad čo som dostal, je spraviť si vlastný „var_export“ s tým, že tie <?php oseká. No to sa ale nedá, lebo tam vlastne vtedy vôbec nie sú :-D je tam iba _@php takže s tým sa pohnúť nedá. Iné riešenie je použiť LatteFilter neskoršie ako ten môj, a potom vo vlastnom var_exporte parsovať jednotlivé argumenty (prehnať to cez nejaký BaseTemplate::parseTag alebo čo…)

Najlepšie čo ma zatiaľ napadlo, je použitie eval:

<a href="<?php echo $template->escape($component->link('Film:view', array("id" => eval("<?php echo TemplateHelpers::escapeHtml($film->id) ?>"))))?>">Viewa film</a>

Edit: No ani ten poriadne nefunguje. Musí sa znovupoužiť deklarácia use Nette … a problém je v tom že je v tom kóde echo takže sa číslo id vypíše na nesprávnom mieste

Je to dobre hnusné, že?

Editoval fiso (25. 9. 2009 21:46)