Pagina 1 van 1

variatie in parsen template-blocks

Geplaatst: 11 mar 2007, 14:01
door markgh
Hallo,

ik zag dat het volgende een optie is die in phpBB3 beschikbaar wordt, maar zou graag al van dit principe gebruik maken in mijn huidige site.

Het betreft een modificatie van het template systeem, waarbij je verschillen kunt aangeven voor bijvoorbeeld het eerste item in rij die via template->assign_block_vars wordt doorgestuurd anders wordt weergegeven dat de rest.

voorbeeld:

Code: Selecteer alles

$i=0;
while($i < 4)
{
$template->assign_block_vars('loop',array('GETAL' => $i, 'TEKST' => 'lala'));
}

Code: Selecteer alles

<!-- BEGIN loop[0] -->
[b]{loop.GETAL}<br>
{loop.TEKST}[/b]<br>
<!-- END loop[0] -->
<!-- BEGIN loop[1-3] -->
{loop.GETAL}<br>
<!-- END loop[1-3] -->
en dat geeft dus:
0
lala


1
2
3
Enig idee of dit al bestaat voor phpBB2.0.*, en of dit überhaupt te doen is met het huidige template systeem/extreme styles systeem?

dank

Geplaatst: 11 mar 2007, 14:23
door Bee
Met eXtreme Styles kan je in de buurt komen, maar loopen gaat daar alleen met echte PHP-code.

Geplaatst: 11 mar 2007, 17:45
door markgh
het is gelukt, met wat wijzigingen aan template.php

voor het resultaat zie:
http://dev.msrvsaurus.nl/nieuw/test.php

(let niet op de rest van de site, nog zwaar work-in-progress)

als er interesse is wil ik de template.php best plaatsen

Geplaatst: 11 mar 2007, 19:12
door Salomon
Misschien handig als je alleen het aangepaste deel laat zien...

Geplaatst: 11 mar 2007, 19:14
door Bertie
Salomon schreef:Misschien handig als je alleen het aangepaste deel laat zien...
Waarom zou dat handig zijn

Geplaatst: 11 mar 2007, 19:21
door markgh
Template.php

Code: Selecteer alles

		// This will handle the remaining root-level varrefs
		$code = preg_replace('#\{([a-z0-9%\-_]*?)\}#is', '\' . ( ( isset($this->_tpldata[\'.\'][0][\'\1\']) ) ? $this->_tpldata[\'.\'][0][\'\1\'] : \'\' ) . \'', $code);

Code: Selecteer alles

		$line_count = sizeof($code_lines);
		for ($i = 0; $i < $line_count; $i++)
		{
			$code_lines[$i] = chop($code_lines[$i]);
			if (preg_match('#<!-- BEGIN (.*?) -->#', $code_lines[$i], $m))
			{
				$n[0] = $m[0];
				$n[1] = $m[1];
				unset($extra_var);
				if(preg_match('#%[0-9]%#',$m[1])) // NIEUW
				{
					$p1 = strpos($m[1],'%');
					$p2 = strpos($m[1],'%');
					$aantal = 1;
					$extra_var = substr($m[1],(1+$p1),($p2-$p1-1));
					$m[1] = preg_replace('#%[0-9]%#','',$m[1]);
				}
				elseif(preg_match('#%*[-]*%#',$m[1]))
				{
					$p1 = strpos($m[1],'%');
					$p2 = strpos($m[1],'%');
					$extra_var = substr($m[1],(1+$p1),($p2-$p1-1));
					$extra_var = explode("-",$extra_var);
					$extra_var[1] = $extra_var[1]+1;
					$aantal = $extra_var[1]-$extra_var[0];
					$m[1] = substr($m[1],0,$p1);
				}
				
				// Added: dougk_ff7-Keeps templates from bombing if begin is on the same line as end.. I think. :)
				if ( preg_match('#<!-- END (.*?) -->#', $code_lines[$i], $n) )
				{
					$block_nesting_level++;
					$block_names[$block_nesting_level] = $m[1];
					if ($block_nesting_level < 2)
					{
						// Block is not nested.
						$code_lines[$i] = '$_' . $n[1] . '_count = ( isset($this->_tpldata[\'' . $n[1] . '.\']) ) ?  sizeof($this->_tpldata[\'' . $n[1] . '.\']) : 0;';
						$code_lines[$i] .= "\n" . 'for ($_' . $n[1] . '_i = 0; $_' . $n[1] . '_i < $_' . $n[1] . '_count; $_' . $n[1] . '_i++)';
						$code_lines[$i] .= "\n" . '{';
					}
					else
					{
						// This block is nested.

						// Generate a namespace string for this block.
						$namespace = implode('.', $block_names);
						// strip leading period from root level..
						$namespace = substr($namespace, 2);
						// Get a reference to the data array for this block that depends on the
						// current indices of all parent blocks.
						$varref = $this->generate_block_data_ref($namespace, false);
						// Create the for loop code to iterate over this block.
						$code_lines[$i] = '$_' . $n[1] . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
						$code_lines[$i] .= "\n" . 'for ($_' . $n[1] . '_i = 0; $_' . $n[1] . '_i < $_' . $n[1] . '_count; $_' . $n[1] . '_i++)';
						$code_lines[$i] .= "\n" . '{';
					}

					// We have the end of a block.
					unset($block_names[$block_nesting_level]);
					$block_nesting_level--;
					$code_lines[$i] .= '} // END ' . $n[1];
					$m[0] = $n[0];
					$m[1] = $n[1];
				}
				else
				{
					// We have the start of a block.
					$block_nesting_level++;
					$block_names[$block_nesting_level] = $m[1];
					if ($block_nesting_level < 2)
					{
						// Block is not nested.
						$code_lines[$i] = '$_' . $m[1] . '_count = ( isset($this->_tpldata[\'' . $m[1] . '.\']) ) ? sizeof($this->_tpldata[\'' . $m[1] . '.\']) : 0;';
						if(!isset($extra_var))
						{
							$code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = 0; $_' . $m[1] . '_i < $_' . $m[1] . '_count; $_' . $m[1] . '_i++)';
						}
						elseif($aantal == 1) // NIEUW
						{
							$code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = '.$extra_var.'; $_' . $m[1] . '_i == '.$extra_var.'; $_' . $m[1] . '_i++)';
						}
						elseif($aantal > 1) // NIEUW
						{
							$code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = '.$extra_var[0].'; $_' . $m[1] . '_i < '.$extra_var[1].'; $_' . $m[1] . '_i++)';
						}
						$code_lines[$i] .= "\n" . '{';
					}
					else
					{
						// This block is nested.

						// Generate a namespace string for this block.
						$namespace = implode('.', $block_names);
						// strip leading period from root level..
						$namespace = substr($namespace, 2);
						// Get a reference to the data array for this block that depends on the
						// current indices of all parent blocks.
						$varref = $this->generate_block_data_ref($namespace, false);
						// Create the for loop code to iterate over this block.
						$code_lines[$i] = '$_' . $m[1] . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
						if(!isset($extra_var))
						{
							$code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = 0; $_' . $m[1] . '_i < $_' . $m[1] . '_count; $_' . $m[1] . '_i++)';
						}
						elseif($aantal == 1) // NIEUW
						{
							$code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = '.$extra_var.'; $_' . $m[1] . '_i == '.$extra_var.'; $_' . $m[1] . '_i++)';
						}
						elseif($aantal > 1) // NIEUW
						{
							$code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = '.$extra_var[0].'; $_' . $m[1] . '_i < '.$extra_var[1].'; $_' . $m[1] . '_i++)';
						}
						$code_lines[$i] .= "\n" . '{';
					}
				}
			}
*.tpl

Code: Selecteer alles

Normaal:<br />
<!-- BEGIN loop -->
{loop.GETAL}<br />
<!-- END loop -->
<br />
Alleen de eerste:<br />
<!-- BEGIN loop%1% -->
{loop.GETAL}<br />
<!-- END loop -->
<br />
De rest<br />
<!-- BEGIN loop%2-4% -->
{loop.GETAL}<br />
<!-- END loop -->
eind
Omdat de array maar 4 entries heeft en je er hier om 5 vraagt komt er een 'lege' rij onder, ben er nog niet achter hoe dit te omzeilen valt.

Misschien is het niet helemaal netjes maar het werkt wel ;)

//edit:
bovenste preg_replace toegevoegd

Geplaatst: 11 mar 2007, 19:23
door Bee
Bertie schreef:
Salomon schreef:Misschien handig als je alleen het aangepaste deel laat zien...
Waarom zou dat handig zijn
Als je niet weet waar het staat, is het nogal nutteloos ja.

Geplaatst: 12 mar 2007, 11:23
door markgh
Ook dat laatste probleem opgelost.

Totale function compile

Code: Selecteer alles

	/**
	 * Compiles the given string of code, and returns
	 * the result in a string.
	 * If "do_not_echo" is true, the returned code will not be directly
	 * executable, but can be used as part of a variable assignment
	 * for use in assign_code_from_handle().
	 */
	function compile($code, $do_not_echo = false, $retvar = '')
	{
		// replace \ with \\ and then ' with \'.
		$code = str_replace('\\', '\\\\', $code);
		$code = str_replace('\'', '\\\'', $code);

		// change template varrefs into PHP varrefs

		// This one will handle varrefs WITH namespaces
		$varrefs = array();
		preg_match_all('#\{(([a-z0-9\-_]+?\.)+?)([a-z0-9\-_]+?)\}#is', $code, $varrefs);
		$varcount = sizeof($varrefs[1]);
		for ($i = 0; $i < $varcount; $i++)
		{
			$namespace = $varrefs[1][$i];
			$varname = $varrefs[3][$i];
			$new = $this->generate_block_varref($namespace, $varname);

			$code = str_replace($varrefs[0][$i], $new, $code);
		}

		// This will handle the remaining root-level varrefs
		$code = preg_replace('#\{([a-z0-9%\-_]*?)\}#is', '\' . ( ( isset($this->_tpldata[\'.\'][0][\'\1\']) ) ? $this->_tpldata[\'.\'][0][\'\1\'] : \'\' ) . \'', $code); // TOEGEVOEGD: '%'

		// Break it up into lines.
		$code_lines = explode("\n", $code);

		$block_nesting_level = 0;
		$block_names = array();
		$block_names[0] = ".";
		
		// Second: prepend echo ', append ' . "\n"; to each line.
		$line_count = sizeof($code_lines);
		for ($i = 0; $i < $line_count; $i++)
		{
			$code_lines[$i] = chop($code_lines[$i]);
			if (preg_match('#<!-- BEGIN (.*?) -->#', $code_lines[$i], $m))
			{
				$n[0] = $m[0];
				$n[1] = $m[1];
				// BEGIN MOD_variabele_parser
				unset($extra_var); 
				if(preg_match('#%[0-9]%#',$m[1]))
				{
					$p1 = strpos($m[1],'%');
					$p2 = strpos($m[1],'%');
					$aantal = 1;
					$extra_var = substr($m[1],(1+$p1),($p2-$p1-1));
					$m[1] = preg_replace('#%[0-9]%#','',$m[1]);
				}
				elseif(preg_match('#%*[-]*%#',$m[1]))
				{
					$p1 = strpos($m[1],'%');
					$p2 = strpos($m[1],'%');
					$extra_var = substr($m[1],(1+$p1),($p2-$p1-1));
					$extra_var = explode("-",$extra_var);
					$extra_var[1] = $extra_var[1]+1;
					$aantal = $extra_var[1]-$extra_var[0];
					$m[1] = substr($m[1],0,$p1);
				}
				// EIND MOD_variabele_parser
				
				// Added: dougk_ff7-Keeps templates from bombing if begin is on the same line as end.. I think. :)
				if ( preg_match('#<!-- END (.*?) -->#', $code_lines[$i], $n) )
				{
					$block_nesting_level++;
					$block_names[$block_nesting_level] = $m[1];
					if ($block_nesting_level < 2)
					{
						// Block is not nested.
						$code_lines[$i] = '$_' . $n[1] . '_count = ( isset($this->_tpldata[\'' . $n[1] . '.\']) ) ?  sizeof($this->_tpldata[\'' . $n[1] . '.\']) : 0;';
						$code_lines[$i] .= "\n" . 'for ($_' . $n[1] . '_i = 0; $_' . $n[1] . '_i < $_' . $n[1] . '_count; $_' . $n[1] . '_i++)';
						$code_lines[$i] .= "\n" . '{';
					}
					else
					{
						// This block is nested.

						// Generate a namespace string for this block.
						$namespace = implode('.', $block_names);
						// strip leading period from root level..
						$namespace = substr($namespace, 2);
						// Get a reference to the data array for this block that depends on the
						// current indices of all parent blocks.
						$varref = $this->generate_block_data_ref($namespace, false);
						// Create the for loop code to iterate over this block.
						$code_lines[$i] = '$_' . $n[1] . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
						$code_lines[$i] .= "\n" . 'for ($_' . $n[1] . '_i = 0; $_' . $n[1] . '_i < $_' . $n[1] . '_count; $_' . $n[1] . '_i++)';
						$code_lines[$i] .= "\n" . '{';
					}

					// We have the end of a block.
					unset($block_names[$block_nesting_level]);
					$block_nesting_level--;
					$code_lines[$i] .= '} // END ' . $n[1];
					$m[0] = $n[0];
					$m[1] = $n[1];
				}
				else
				{
					// We have the start of a block.
					$block_nesting_level++;
					$block_names[$block_nesting_level] = $m[1];
					if ($block_nesting_level < 2)
					{
						// Block is not nested.
						$code_lines[$i] = '$_' . $m[1] . '_count = ( isset($this->_tpldata[\'' . $m[1] . '.\']) ) ? sizeof($this->_tpldata[\'' . $m[1] . '.\']) : 0;';
						if(!isset($extra_var)) // IF statement toegevoegd
						{
							$code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = 0; $_' . $m[1] . '_i < $_' . $m[1] . '_count; $_' . $m[1] . '_i++)';
						}
						// BEGIN MOD_variabele_parser
						elseif($aantal == 1)
						{
							$code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = '.$extra_var.'; $_' . $m[1] . '_i == '.$extra_var.'; $_' . $m[1] . '_i++)';
						}
						elseif($aantal > 1)
						{
							if($aantal > '$_'.$m[1].'_count')
							{ $max = '$_'.$m[1].'_count';	}
							else { $max = $aantal; }
							$code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = '.$extra_var[0].'; $_' . $m[1] . '_i < '.$max.'; $_' . $m[1] . '_i++)';
						}
						// EIND MOD_variabele_parser
						$code_lines[$i] .= "\n" . '{';
					}
					else
					{
						// This block is nested.

						// Generate a namespace string for this block.
						$namespace = implode('.', $block_names);
						// strip leading period from root level..
						$namespace = substr($namespace, 2);
						// Get a reference to the data array for this block that depends on the
						// current indices of all parent blocks.
						$varref = $this->generate_block_data_ref($namespace, false);
						// Create the for loop code to iterate over this block.
						$code_lines[$i] = '$_' . $m[1] . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
						if(!isset($extra_var)) // IF statement toegevoegd
						{
							$code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = 0; $_' . $m[1] . '_i < $_' . $m[1] . '_count; $_' . $m[1] . '_i++)';
						}
						// BEGIN MOD_variabele_parser
						elseif($aantal == 1)
						{
							$code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = '.$extra_var.'; $_' . $m[1] . '_i == '.$extra_var.'; $_' . $m[1] . '_i++)';
						}
						elseif($aantal > 1)
						{
							if($aantal > '$_'.$m[1].'_count')
							{ $max = '$_'.$m[1].'_count';	}
							else { $max = $aantal; }
							$code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = '.$extra_var[0].'; $_' . $m[1] . '_i < '.$max.'; $_' . $m[1] . '_i++)';						}
						// EIND MOD_variabele_parser
						$code_lines[$i] .= "\n" . '{';
					}
				}
			}
			else if (preg_match('#<!-- END (.*?) -->#', $code_lines[$i], $m))
			{
				// We have the end of a block.
				unset($block_names[$block_nesting_level]);
				$block_nesting_level--;
				$code_lines[$i] = '} // END ' . $m[1];
			}
			else
			{
				// We have an ordinary line of code.
				if (!$do_not_echo)
				{
						$code_lines[$i] = 'echo \'' . $code_lines[$i] . '\' . "\\n";';
				}
				else
				{
					$code_lines[$i] = '$' . $retvar . '.= \'' . $code_lines[$i] . '\' . "\\n";'; 
				}
			}
		}
		// Bring it back into a single string of lines of code.
		$code = implode("\n", $code_lines);
		return $code;

	}
Mijn wijzigingen staan tussen // BEGIN MOD_variabele_parser en // EIND...

ook een paar kleine toevoegingen, gemarkeerd door 'TOEGEVOEGD'