Řešení více skinů (šablon)

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

Přemýšlím, jak v Nette nejlépe vyřešit tzv. skiny. Resp. mám nějaké podmínky, za kterých chci nabídnout (tj. nastavit v bootstrapu) jeden konkrétní skin a podmínky, za kterých druhý skin. Jde třeba o datum – letní a zimní skiny.

Protože chci jít ale cestou DRY, rád bych, kdyby byl jeden skin výchozí – tj. obsahoval by všechny šablony a ten druhý by z něj čerpal, případně by něco přepisoval. Řekněme že zimní skin by třeba měl jen jiné CSSko, popř. jinou jednu ze všech možných šablon.

Všechny Presentery bych rád zachoval pro oba skiny samozřejmě.

Díval jsem se v examples na modules-usage, ale moudrý z toho moc nejsem…
Bohužel ani wiki o použití modulů neříká více, než odkaz na neexistující stranu.. :(

Ondřej Mirtes
Člen | 1536
+
0
-

Já si myslím, že většina skinovatelnosti se dá vyřešit čistě v CSS (viz http://www.csszengarden.com/) – a pro ten zbytek můžeš po šablonách rozstrkat nějaké if blocky pracující s proměnnou $skin.

redhead
Člen | 1313
+
0
-

Pokud by mělo jít pouze o změnu css, tak v BasePresenteru šabloně předávat název css která se má použít, podle nějakého rozhodnutí a v šabloně to pak vykreslit do hlavičky.. Nehledej v tom žádné přehnané hrátky s moduly..

Majkl578
Moderator | 1364
+
0
-

Takováhle věc by šla řešit přepsáním Presenter::formatLayoutTemplateFiles() a Presenter::formatTemplateFiles() a nastavováním templatů dynamicky v těchto metodách. Nebo se mýlím?

maarlin
Člen | 207
+
0
-

Napsali byste to jinak? Není to zbytečně složité?

BasePresenter:

public function formatLayoutTemplateFiles($presenter, $layout)
	{
		$list = parent::formatLayoutTemplateFiles($presenter, $layout);

		$skinName = 'summer-skin';

		foreach ($list as $intList => $eachList) {
			$exploded = explode ('/', $eachList);
			$oldListContent = $list[$intList];
			$list[$intList] = '';

			foreach ($exploded as $int => $part) {
				if ($int == 0) {
					$startingSlash = '';
				} else {
					$startingSlash = '/';
				}
				if ($part == 'templates') {
					$list[$intList] .= $startingSlash.$part.'/'.$skinName;
				} else {
					$list[$intList] .= $startingSlash.$part;
				}
			}
			if (!file_exists($list[$intList])) {
				$list[$intList] = '';
				foreach ($exploded as $int => $part) {
					if ($int == 0) {
						$startingSlash = '';
					} else {
						$startingSlash = '/';
					}
					if ($part == 'templates') {
						$list[$intList] .= $startingSlash.$part.'/default';
					} else {
						$list[$intList] .= $startingSlash.$part;
					}
				}
			}
		}

		return $list;
	}

	public function formatTemplateFiles($presenter, $view)
	{
		$list = parent::formatLayoutTemplateFiles($presenter, $view);

		$skinName = 'summer-skin';

		$list = str_replace('@', '', $list);
		foreach ($list as $intList => $eachList) {
			$exploded = explode ('/', $eachList);
			$oldListContent = $list[$intList];
			$list[$intList] = '';

			foreach ($exploded as $int => $part) {
				if ($int == 0) {
					$startingSlash = '';
				} else {
					$startingSlash = '/';
				}
				if ($part == 'templates') {
					$list[$intList] .= $startingSlash.$part.'/'.$skinName;
				} else {
					$list[$intList] .= $startingSlash.$part;
				}
			}
			if (!file_exists($list[$intList])) {
				$list[$intList] = '';
				foreach ($exploded as $int => $part) {
					if ($int == 0) {
						$startingSlash = '';
					} else {
						$startingSlash = '/';
					}
					if ($part == 'templates') {
						$list[$intList] .= $startingSlash.$part.'/default';
					} else {
						$list[$intList] .= $startingSlash.$part;
					}
				}
			}
		}

		return $list;
	}
Majkl578
Moderator | 1364
+
0
-

Není zbytečné pracovat s výsledkem překrývané metody? Nebylo by jednodušší prostě ji překrýt a napsat si ji celou sám?

iguana007
Člen | 970
+
0
-

chtěl bych se zeptat, jak se to nakonec vyřešilo? Funguje to řešení v pohodě nebo se to dá udělat ještě jinak? Příští týden budu totéž řešit taky, tak proto se ptám.
Díky za info.