Novy string parser pre Html::el

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

Sic to asi nie je nikde zdokumentovane, ale Html::el umoznuje vkladanie atributov priamo v prvom atribute:

<?php
	$my_element = Html::el( 'td width=16' );
?>

Kazdopadne, ak potrebujete vlozit nieco komplikovanejsie ako zoznam tried, jednoduchy parser nezafunguje:

<?php
	$my_element = Html::el( 'td class="w-16px align-right"' );
?>

Metoda el samozrejme ma k dispozicii aj druhy parameter $attrs na vlozenie atributov. Ak ale ma byt dana fncia k dispozicii, tak by mohla fungovat trosku lepsie:

<?php
	// ...
	// Nette/Web/Html.php
	// ...
	public static function el($name = NULL, $attrs = NULL)
	{
		$el = new self ;
		// $parts = explode(' ', $name);
		// $el->setName(array_shift($parts));

		$parts = array();
		if( $name )
		{
			// tag attr1 attr2="value1 value2 value3" attr3=value4
			preg_match_all('/\s*([a-z]+)\s*(=\s*("[^"]*"|[^\s]+))?\s*/', $name, $parts, PREG_SET_ORDER);
			$el->setName($parts[0][0]);
		}

		if (is_array($attrs)) {
			$el->attrs = $attrs;

		} elseif ($attrs !== NULL) {
			$el->setText($attrs);
		}

		foreach ($parts as $pair) {
			// $pair = explode('=', $pair, 2);
			// $el->attrs[$pair[0]] = isset($pair[1]) ? trim($pair[1], '"') : TRUE;
			$el->attrs[$pair[1]] = isset($pair[3]) ? trim($pair[3], '"') : TRUE;
		}
		return $el;
	}
	// ...
?>
Honza Marek
Člen | 1664
+
0
-

Dobré, to se bude hodit v rendererech. Teď už je potřeba to jen nacpat do nette.

jasir
Člen | 746
+
0
-

Jojo, už jsem na to také narazil. Také bych to přidal.

martincohen
Člen | 14
+
0
-

Tak este drobna uprava: je potrebne pridat array_shift( $parts ) (riadok 14) aby sa samotne meno elementu nedostalo do atributov:

<?php
	public static function el($name = NULL, $attrs = NULL)
	{
		$el = new self ;
		// $parts = explode(' ', $name);
		// $el->setName(array_shift($parts));

		$parts = array();
		if( $name )
		{
			// tag attr1 attr2="value1 value2 value3" attr3=value4
			preg_match_all('/\s*([a-z]+)\s*(=\s*("[^"]*"|[^\s]+))?\s*/', $name, $parts, PREG_SET_ORDER);
			$el->setName($parts[0][0]);
			array_shift( $parts );
		}

		if (is_array($attrs)) {
			$el->attrs = $attrs;

		} elseif ($attrs !== NULL) {
			$el->setText($attrs);
		}

		foreach ($parts as $pair) {
			// $pair = explode('=', $pair, 2);
			$el->attrs[$pair[1]] = isset($pair[3]) ? trim($pair[3], '"') : TRUE;
		}
		return $el;
	}
?>
martincohen
Člen | 14
+
0
-

Honza M. napsal(a):

Dobré, to se bude hodit v rendererech. Teď už je potřeba to jen nacpat do nette.

Povodne som to potreboval pre ConventionalRenderer samozrejme letmy pohlad na metodu getWrapper() odhali ze pre nastavenie wrapperu je mozne pouzit nie len string ale i hotovy element: (coz som samozrejme zistil az potom)

<?php
	// Pouzitie stringu
	$form->getRenderer()->wrappers['label']['container'] = 'th class="w-min a-r"';
	// Pouzitie elementu
	$form->getRenderer()->wrappers['label']['container'] = Html::el( 'th', array( 'class' => 'w-min a-r' ) );
?>

Editoval martincohen (3. 6. 2009 10:31)

Honza Marek
Člen | 1664
+
0
-

Jj, to vím. Potřeboval jsem to, když jsem se pokoušel o renderer pro komponentu DataGrid od Romana Sklenáře. Systém je podobný jako u ConventionalRendereru. Chtěl jsem, aby byl DataGrid skinovatelný pomocí jQuery UI a na to je potřeba změnit těch tříd opravdu hodně. Takže nejjednodušší bylo vytvořit v poděděné třídě úplně nové statické pole. A tam se Html objekt dát nedá.

romansklenar
Člen | 655
+
0
-

Tu podporu pro to jsem ti tam dopsal, nevím ale jestli je to třeba dávat přímo do továrničky třídy Html, mělo by být co nejjednoduchší (v těch vykreslovačí je volána dost často, když si vyprofilujete formulář, nebo ten DataGrid) a navíc když stejné věci jde dosáhnout jinými způsoby…

Neříkám, že bych to nevyužil, jen podotýkám, že to může mít i druhou stranu mince (složitější kód na zparsování vstupu, další regulár(y) → zpomalení).

David Grudl
Nette Core | 8228
+
0
-

Je to tam.

U třídy konstruktoru HTML je rychlost skutečně klíčová, takže jsem to naimplementoval krapet jinak, ale funkčnost by měla být stejná.