Erweiterung der Templateklasse

swelpot
Beiträge: 101
Registriert: Mo 26. Jul 2004, 20:42
Wohnort: Rhein-Main
Kontaktdaten:

Erweiterung der Templateklasse

Beitrag von swelpot » Mi 6. Okt 2004, 15:04

Hi,

nachdem ich die mitgelieferte Templateklasse gefunden und schätzen gelernt habe hatte ich irgendwann den Wunsch mal eine Navigation der Form:

Code: Alles auswählen

Punkt 1 | Punkt 2 | Punkt 3 | Punkt 4
damit zu realisieren.
Das Problem dabei war aber, dass ich keine If-Konstrukte oder sonstwelche Funktionen innerhalb des Templates verwenden konnte, um beispielsweise den letzten bzw. ersten | zu unterdrücken.
Hier also eine Erweiterung der Templateklasse um:
- die erwähnten If-Konstruktionen
- eine Möglichkeit Zähler im Template zu verwenden
- die API-String-Funktionen im Template einsetzen zu können

Alle weiteren Infos findet Ihr in den Kommentaren zu den jeweiligen Klassen.

Um die Klassen fest zu implementieren muss die Datei eingebunden werden. Allerdings ist mir noch nicht so 100%-ig klar, wo das überall erfolgen muss. Eigentlich sollte doch ein Eintrag in der functions.api.php der Form

Code: Alles auswählen

cInclude('classes',  'class.extendedTemplate.php');
reichen. Oder?


Ein Beispiel noch... Das folgende Template:

Code: Alles auswählen

{counter name=test start=1 step=5}
{if(\"ab\" == \"ac\")}
	{counter name=test2}
	abc
{else if({counter name=test} == 6)}
	{counter name=test print=false}<br>
	ghi<br>
	{if(true)}abc{/if}<br>
	{counter name=test}<br>
	jkl
{else if(false)}
	lkde
{else}
	gekh
{/if}
sollte diese Ausgabe erzeugen:

Code: Alles auswählen

1

	<br>
	ghi<br>
	abc<br>
	16<br>
	jkl

Hier der Code:
class.extendedTemplate.php:

Code: Alles auswählen

<?
cInclude("classes", "class.template.php", false);


/**
 * class ExtendedTemplate
 * 
 * Erweiterte Version der Contenido-Templateklasse
 * 
 * Die Funktion der Superklasse ist uneingeschränkt verfügbar.
 * Der erweiterten Klasse können Instanzen von Parserklassen, die von AbstractTemplateParser erben müssen,
 * oder deren Klassennamen übergeben werden, die dann nacheinander das Template auswerten.
 * 
 * Fest Implementiert sind zur Zeit die Klassen:
 * - StrAPIFunctionsParser
 * - CounterFunctionParser
 * - IfFunctionParser
 *
 *
 * @author Stefan Welpot
 * @version 1.0
 */
class ExtendedTemplate
	extends Template
{
	var $array_registeredParsers;
	
	/**
	 * Konstruktor
	 *
	 * @param $tags Array Tags Anfang und Ende des dynamischen Blocks, sowie für statische Bereiche
	 * @param $parser Array Objektinstanzen von Kindklassen von AbstractTemplateParser oder deren Klassennamen
	 */
	function ExtendedTemplate($tags = false, $parser = false) {
		$this->Template($tags);
		
		
		$this->array_registeredParsers = array(
											new StrAPIFunctionsParser(),
											new CounterFunctionParser(),
											new IfFunctionParser()
										);
										
				
		if(is_array($parser)) {
			$this->array_registeredParsers = $parser;
		}
		
	}
	
    /**
     * Generiert das Template und gibt es aus/zurück.
	 *
     * @param $template string/file Template
     * @param $return bool Return or print template
     * @param $note bool Echo "Generated by ... " Comment
     *
     * @return string complete Template string
     */
    function generate($template, $return = 0, $note = 1) {
		$template = parent::generate($template, true, $note);

		foreach($this->array_registeredParsers as $class) {
			if(is_string($class)) {
				$classInstance = new $class;
			}
			else if(is_object($class)) {
				$classInstance = $class;
			}
			
			if(is_object($classInstance)) {
				if(is_subclass_of($classInstance, "AbstractTemplateParser")) {
					$template = $classInstance->parse($template);
				}
				else {
					$template = "TemplateParserKlasse " . get_class($classInstance) . " ist nicht von AbstractTemplateParser abgeleitet!";
					break;
				}
			}
		}


        if ($return) {
            return $template;
        }
        
        echo $template;
	}
}



/**
 * class AbstractTemplateParser
 * 
 * Abstrakte Superklasse für alle Templateparser
 *
 * @author Stefan Welpot
 * @version 1.0
 */
class AbstractTemplateParser {

	/**
	 * Konstruktor
	 */
	function AbstractTemplateParser() {}
	
	/**
	 * Parst das übergeben Template
	 *
	 * @param $template string das zu parsende Template
	 *
	 * @return string das geparste Template
	 */
	function parse($template) {
		return $template;
	}
}


/**
 * class IfFunctionParser
 * 
 * Implemenation des AbstractTemplateParser zum Auswerten von 
 * If-Konstrukten im Template
 * Als Tags im Template sind vorgesehen:
 *   - {if(Bedigung)}
 *   - {else if(Bedingung)}
 *   - {else}
 *   - {/if}
 *
 * Ein If-Konstrukt besteht dabei mindestens aus {if(Bedingung)} und einem abschließenden {/if}.
 * Das {else if(Bedingung)} kann beliebig oft hintereinander verwendet werden.
 * Die Konstrukte an sich können beliebig tief geschachtelt werden.
 * Die Bedinungen der {if()}- und {else if()}-Teile werden durch eval ausgewertet
 * und können somit auch PHP-Funktionen interpretieren.
 *
 *
 * @author Stefan Welpot
 * @version 1.0
 */
class IfFunctionParser
	extends AbstractTemplateParser
{

    /**
     * Regexp-Pattern für {if(Bedingung)}
     * @var pattern_if
     */
	var $pattern_if = 		"\{if\040*\((.*?)\)\}";

    /**
     * Regexp-Pattern für {else if(Bedingung)}
     * @var pattern_elseif
     */
	var $pattern_elseif = 	"\{else if\040*\((.*?)\)\}";

    /**
     * Regexp-Pattern für {else}
     * @var pattern_else
     */
	var $pattern_else = 	"\{else\}";

    /**
     * Regexp-Pattern für {/if}
     * @var pattern_endif
     */
	var $pattern_endif = 	"\{\/if\}";
	
    /**
     * Länge des {if(Bedinung)}-Tags ohne Bedingung
     * @var patternlength_if
     */
	var $patternlength_if =			6;

    /**
     * Länge des {else if(Bedinung)}-Tags ohne Bedingung
     * @var patternlength_elseif
     */
	var $patternlength_elseif = 	11;

    /**
     * Länge des {else}-Tags
     * @var patternlength_else
     */
	var $patternlength_else = 		6;

    /**
     * Länge des {/if}-Tags
     * @var patternlength_endif
     */
	var $patternlength_endif = 		5;



	/**
	 * Konstruktor
	 */
	function IfFunctionParser() {
		$this->AbstractTemplateParser();
	}

	
	/**
	 * @see AbstractTemplateParser#parse(string)
	 */
	function parse($template) {
		$array2_uncompletedConstructs = array(); //geöffnete, aber noch nicht geschlossene funktionen

		//hilfsvariablen
		$array_match_all = array();
		$array_match_part = array();
		$uncompletedConstructsIndex = 0;
		$elseifIndex = 0;
		$currentOffset = 0;
		$oldOffset = -1;
		
		$array_construct = array();
		
		$pattern_all = "/(?is)(" . $this->pattern_if . "|" . $this->pattern_elseif . "|" . $this->pattern_else . "|" . $this->pattern_endif . ")/";

        //das template solange nach konstruktteilen durchsuchen bis keine mehr gefunden werden
		while($currentOffset != $oldOffset) {
			$oldOffset = $currentOffset;
			
			//wenn irgendein teil einer if-konstruktion gefunden wird
			if(preg_match($pattern_all, $template, $array_match_all, PREG_OFFSET_CAPTURE, $currentOffset) > 0) {
				//herausfinden, welcher teil gefunden wurde
				//if-teil
				if(preg_match("/(?is)" . $this->pattern_if . "/", $array_match_all[0][0], $array_match_part) > 0) {
					$uncompletedConstructsIndex++; //inkrement openFunctionIndex

					$array2_uncompletedConstructs[$uncompletedConstructsIndex]['if']['condition'] = $array_match_part[1];
					$array2_uncompletedConstructs[$uncompletedConstructsIndex]['if']['pos_start'] = $array_match_all[0][1];
					$array2_uncompletedConstructs[$uncompletedConstructsIndex]['if']['pos_end'] = $array2_uncompletedConstructs[$uncompletedConstructsIndex]['if']['pos_start'] + $this->patternlength_if + strlen($array_match_part[1]);
					$currentOffset = $array2_uncompletedConstructs[$uncompletedConstructsIndex]['if']['pos_end'];	
				}
				//elseif-teil
				else if(preg_match("/(?is)" . $this->pattern_elseif . "/", $array_match_all[0][0], $array_match_part) > 0) {
					$elseifIndex = count($array2_uncompletedConstructs[$uncompletedConstructsIndex]['elseif']);

					$array2_uncompletedConstructs[$uncompletedConstructsIndex]['elseif'][$elseifIndex]['condition'] = $array_match_part[1];
					$array2_uncompletedConstructs[$uncompletedConstructsIndex]['elseif'][$elseifIndex]['pos_start'] = $array_match_all[0][1];
					$array2_uncompletedConstructs[$uncompletedConstructsIndex]['elseif'][$elseifIndex]['pos_end'] = $array2_uncompletedConstructs[$uncompletedConstructsIndex]['elseif'][$elseifIndex]['pos_start'] + $this->patternlength_elseif + strlen($array_match_part[1]);
					$currentOffset = $array2_uncompletedConstructs[$uncompletedConstructsIndex]['elseif'][$elseifIndex]['pos_end'];	
				}
				//else-teil
				else if(preg_match("/(?is)" . $this->pattern_else . "/", $array_match_all[0][0], $array_match_part) > 0) {
					$array2_uncompletedConstructs[$uncompletedConstructsIndex]['else']['pos_start'] = $array_match_all[0][1];
					$array2_uncompletedConstructs[$uncompletedConstructsIndex]['else']['pos_end'] = $array2_uncompletedConstructs[$uncompletedConstructsIndex]['else']['pos_start'] + $this->patternlength_else;
					$currentOffset = $array2_uncompletedConstructs[$uncompletedConstructsIndex]['else']['pos_end'];	
				}
				//endif
				else if(preg_match("/(?is)" . $this->pattern_endif . "/", $array_match_all[0][0], $array_match_part) > 0) {
					$array2_uncompletedConstructs[$uncompletedConstructsIndex]['endif']['pos_start'] = $array_match_all[0][1];
					$array2_uncompletedConstructs[$uncompletedConstructsIndex]['endif']['pos_end'] = $array2_uncompletedConstructs[$uncompletedConstructsIndex]['endif']['pos_start'] + $this->patternlength_endif;
					$currentOffset = $array2_uncompletedConstructs[$uncompletedConstructsIndex]['endif']['pos_end'];	
					
					
					//gefundene komplette funktion sofort ersetzen
					$array_construct = array_pop($array2_uncompletedConstructs);
					$uncompletedConstructsIndex--;
					$template = $this->replaceConstruct($array_construct, $template);
					//offset korrigieren = anfang der ersetzten funktion
					$currentOffset = $array_construct['if']['pos_start'];
				}				
			}
		} // end while
		
		if($uncompletedConstructsIndex > 0) { // wenn noch offene Funktionen vorhanden sind => Fehler im Template
			$template = "Fehler in IF-Konstruktionen. Folgende If-Statements sind nicht abgeschlossen:<br>\n";
			foreach($array2_uncompletedConstructs as $array_construct) {
				$template .= "- {if(" . $array_construct['if']['condition'] . ")}<br>\n";
			}
		}
		
		return $template;
	} // end function
	
	
	/**
	 * Ersetzt die als Array übergebene Funktion durch 
	 * den ersten Teil mit einer wahren Bedingung
	 *
	 * @param $array_construct Array das komplette If-Konstrukt das ausgewertet werden soll
	 * @param $template string das Template in dem das Konstrukt ersetzt werden soll
	 *
	 * @return string das Template mit dem ersetzten Konstrukt
	 */
	function replaceConstruct($array_construct, $template) {
		$array_elseif = array();		
		$key = 0;
		$replace_text = "";
		$boolConditionTrue = false;

		//prüfen ob der if-teil wahr ist und $replace_text finden
		if(eval("return " . $array_construct['if']['condition'] . ";")) {
			if(array_key_exists('elseif', $array_construct)) { //wenn ein elseif-teil existiert
				$replace_text = substr($template, $array_construct['if']['pos_end'], $array_construct['elseif'][0]['pos_start'] - $array_construct['if']['pos_end']);
			}
			else if(array_key_exists('else', $array_construct)) { //wenn nur ein else-teil existiert
				$replace_text = substr($template, $array_construct['if']['pos_end'], $array_construct['else']['pos_start'] - $array_construct['if']['pos_end']);
			}
			else {//wenn der nächste teil schon endif ist
				$replace_text = substr($template, $array_construct['if']['pos_end'], $array_construct['endif']['pos_start'] - $array_construct['if']['pos_end']);
			}
		}
		else {
			//alle elseif-teile prüfen
			if(is_array($array_construct['elseif'])) {
				foreach($array_construct['elseif'] as $key => $array_elseif) {
					if(eval("return " . $array_elseif['condition'] . ";")) {
						$boolConditionTrue = true;
						
						if(array_key_exists(($key + 1), $array_construct['elseif'])) { //wenn ein weiterer elseif-teil existiert
							$replace_text = substr($template, $array_elseif['pos_end'], $array_construct['elseif'][$key+1]['pos_start'] - $array_elseif['pos_end']);
						}
						else if(array_key_exists('else', $array_construct)) { //wenn nächster teil nur ein else-teil ist
							$replace_text = substr($template, $array_elseif['pos_end'], $array_construct['else']['pos_start'] - $array_elseif['pos_end']);
						}
						else {//wenn der nächste teil schon endif ist
							$replace_text = substr($template, $array_elseif['pos_end'], $array_construct['endif']['pos_start'] - $array_elseif['pos_end']);
						}
						
						break;
					}
				}
			}
			
			//wenn bisher noch keine wahre Bedingung gefunden wurde
			if(!$boolConditionTrue) {
				if(array_key_exists('else', $array_construct)) { // wenn ein else-teil existiert
					$replace_text = substr($template, $array_construct['else']['pos_end'], $array_construct['endif']['pos_start'] - $array_construct['else']['pos_end']);
				}
				else { // sonst wird das gesamte kontrukt durch einen leeren string ersetzt
					$replace_text = "";
				}
			}
		} // end else
					
		//if-konstruktion durch wahren teil ersetzen
		$template = substr_replace($template, $replace_text, $array_construct['if']['pos_start'], $array_construct['endif']['pos_end'] - $array_construct['if']['pos_start']);
		
		return $template;
	}
}


/**
 * class CounterFunctionParser
 * 
 * Implemenation des AbstractTemplateParser zur Verwendung von 
 * Zählern im Template
 * Als Tag im Template ist vorgesehen:
 *   - {counter PARAMETER}
 * Die PARAMETER sind:
 *   - name=ZÄHLERNAME
 *   - start=STARTWERT (default: 0)
 *   - step=SCHRITTWEITE (default: 1)
 *   - print=(true|false) (default: true)
 * Alle Parameter sind optional.
 *
 * Über die Name-Eigenschaft können mehrere unschiedliche Zähler verwendet werden.
 * Bei jedem Vorkommen des {counter}-Tags wird der gleichnamige Zähler um STEP erhöht.
 * Wird die Eigenschaft print auf true oder gar nicht gesetzt erfolgt eine Ausgabe des 
 * Zählerwerts an der Stelle des {counter}-Tags
 *
 *
 * @author Stefan Welpot
 * @version 1.0
 */
class CounterFunctionParser
	extends AbstractTemplateParser
{

    /**
     * Regexp-Pattern für {counter PARAMETER}
     * @var pattern_countertag
     */
	var $pattern_countertag =	"/(?si)\{counter(.*?\})/";

    /**
     * Regexp-Pattern für Parameter name=NAME
     * @var pattern_countername
     */
	var $pattern_countername =	"/(?i)name\040?\=(.+?)(\040|\})/";

    /**
     * Regexp-Pattern für Parameter start=STARTWERT
     * @var pattern_counterstart
     */
	var $pattern_counterstart =	"/(?i)start\040?\=(\d+?)(\040|\})/";

    /**
     * Regexp-Pattern für Parameter step=SCHRITTWEITE
     * @var pattern_counterstep
     */
	var $pattern_counterstep =	"/(?i)step\040?\=(\d+?)(\040|\})/";

    /**
     * Regexp-Pattern für Parameter print=(true|false)
     * @var pattern_counterprint
     */
	var $pattern_counterprint =	"/(?i)print\040?\=(true|false)(\040|\})/";
	
    /**
     * Defaultwert für Parameter name
     * @var default_countername
     */
	var $default_countername = "unnamed";

    /**
     * Defaultwert für Parameter start
     * @var default_counterstart
     */
	var $default_counterstart = 0;

    /**
     * Defaultwert für Parameter step
     * @var default_counterstep
     */
	var $default_counterstep = 1;

    /**
     * Defaultwert für Parameter print
     * @var default_counterprint
     */
	var $default_counterprint = true;
	
	
	/**
	 * Konstruktor
	 */
	function CounterFunctionParser() {
		$this->AbstractTemplateParser();
	}

	
	/**
	 * @see AbstractTemplateParser#parse(string)
	 */
	function parse($template) {
		$counterParameters = "";
		$counterKey = "";
		$array_matches = array();
		$array_countermatches = array();
		$array_initCounters = array();
		$boolPrint = $this->default_counterprint;
		$boolDoNotInkr = false;
		
		preg_match_all($this->pattern_countertag, $template, $array_countermatches, PREG_SET_ORDER);

		for($i = 0; $i < count($array_countermatches); $i++) {
			$counterKey = "";
			
			$counterParameters = $array_countermatches[$i][1];

			//Attribut Countername auslesen, falls vorhanden
			preg_match($this->pattern_countername, $counterParameters, $array_matches);
			if(count($array_matches) > 0) {
				$counterKey = $array_matches[1];
			}
			else { // sonst defaultname
				$counterKey = $this->default_countername;
			}

							
			if(!array_key_exists($counterKey, $array_initCounters)) { // neuen Counter initialisieren
				$array_initCounters[$counterKey]['value'] = $this->default_counterstart;
				$array_initCounters[$counterKey]['step'] = $this->default_counterstep;
				$boolDoNotInkr = true;
			}
			

			//Attribut step
			preg_match($this->pattern_counterstep, $counterParameters, $array_matches);
			if(count($array_matches) > 0) {
				$array_initCounters[$counterKey]['step'] = $array_matches[1];
			}
	

			//Attribut start
			preg_match($this->pattern_counterstart, $counterParameters, $array_matches);
			if(count($array_matches) > 0) {
				$array_initCounters[$counterKey]['value'] = $array_matches[1];
				$boolDoNotInkr = true;
			}
			
			
			// value regulär erhöhen
			if(!$boolDoNotInkr) {
				$array_initCounters[$counterKey]['value'] = $array_initCounters[$counterKey]['value'] + $array_initCounters[$counterKey]['step'];
			}
			else {
				$boolDoNotInkr = false;
			}
			
			
			//Attribut print
			preg_match($this->pattern_counterprint, $counterParameters, $array_matches);
			if(count($array_matches) > 0) {
				$boolPrint = (strcasecmp("true", $array_matches[1]) == 0) ? true : false;
			}
			else {
				$boolPrint = $this->default_counterprint;
			}


			if($boolPrint) {
				$template = preg_replace($this->pattern_countertag, $array_initCounters[$counterKey]['value'], $template, 1);
			}
			else {
				$template = preg_replace($this->pattern_countertag, '', $template, 1);
			}
		}
		
		return $template;
	}
}



/**
 * class StrAPIFunctionsParser
 * 
 * Implemenation des AbstractTemplateParser zum Auswerten von 
 * ContenidoStrAPIFunktionen.
 * Als erlaubte Funktionen sind vorgesehen:
 *   - {capiStrTrimHard(STRING, LÄNGE)}
 *   - {capiStrTrimAfterWord(STRING, LÄNGE)}
 *   - {capiStrTrimSentence(STRING, LÄNGE)}
 *
 * Die die Funktionen werden ertrahiert, ausgewertet und anschließend durch das Ergebnis ersetzt.
 *
 *
 * @author Stefan Welpot
 * @version 1.0
 */
class StrAPIFunctionsParser 
	extends AbstractTemplateParser
{

    /**
     * zu ersetzende Funktionen
     * @var array_strAPIFunctions
     */
	var $array_strAPIFunctions = array(
									"capiStrTrimHard",
									"capiStrTrimAfterWord",
									"capiStrTrimSentence"
								);
								

    /**
     * Konstruktor
     */
	function StrAPIFunctionParser() {
		$this->AbstractTemplateParser();
	}
	
    /**
     * @see AbstractTemplateParser#parse(string)
     */
	function parse($template) {
		$anzahlMatches = 0;
		$array2_matches = array();
		$evaledCode = "";
		
		foreach($this->array_strAPIFunctions as $functionname) {
			$anzahlMatches = preg_match_all("/(?si)\{" . preg_quote($functionname, "/") . "\(\"?(.*?)\"?,\040?(\d+?)\)\}/", $template, $array2_matches);

			for($i = ($anzahlMatches - 1); $i >= 0; $i--) {
				$evaledCode = eval("return " . $functionname . "(\"" . $array2_matches[1][$i] . "\", " . $array2_matches[2][$i] . ");");
				
				$template = preg_replace(
								"/(?si)\{" . preg_quote($functionname, "/") . "\(\"?" . preg_quote($array2_matches[1][$i], "/") . "\"?,\040?" . preg_quote($array2_matches[2][$i], "/") . "\)\}/",
								$evaledCode,
								$template
				);
				
			} //end for(i)
		} // end foreach

		return $template;
	}
}
?>
Vielleicht hat ja jmd. Verwendung dafür

Grüße

Stefan


Nachtrag: Downloadmöglichkeit http://www.swelpot.de/temp/class.ExtendedTemplate.zip
Zuletzt geändert von swelpot am Di 9. Nov 2004, 12:26, insgesamt 1-mal geändert.

emergence
Beiträge: 10645
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Re: Erweiterung der Templateklasse

Beitrag von emergence » Mi 6. Okt 2004, 16:33

swelpot hat geschrieben:Eigentlich sollte doch ein Eintrag in der functions.api.php der Form

Code: Alles auswählen

cInclude('classes',  'class.extendedTemplate.php');
reichen. Oder?
sollte reichen...
*** make your own tools (wishlist :: thx)

emergence
Beiträge: 10645
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Beitrag von emergence » Di 9. Nov 2004, 12:00

hatte endlich mal zeit mich ein wenig damit herumzuspielen...

funktioniert ganz gut

um es leichter für die anderen nachvollziehbar zu machen hab ich dein erstes beispiel mit den menüpunkten umgesetzt...

Code: Alles auswählen

<?php
cInclude('classes',  'class.extendedTemplate.php');

$template = "{FIRST}<br>
{counter name=seperator start=0 step=1 print=false} 
<!-- BEGIN:BLOCK -->
{if({counter name=seperator} != 1)} | {/if}
<b>{COUNTME}</b>
<!-- END:BLOCK -->
<br>{SECOND}
";

$tpl = new ExtendedTemplate();

$tpl->reset();
$tpl->set('s', 'FIRST',  "header");
$tpl->set('s', 'SECOND',  "footer");

for ($i=0; $i<10; $i++) {
    $tpl->set('d', 'COUNTME',  "this->".$i);
    $tpl->next();
}

echo $tpl->generate($template,1);

?>
der obrige code führt zu folgendem ergebniss

header
this->0 | this->1 | this->2 | this->3 | this->4 | this->5 | this->6 | this->7 | this->8 | this->9
footer

tja wie gesagt funktioniert das ganz gut... nur gibt es einen fehler

Code: Alles auswählen

[09-Nov-2004 12:10:41] PHP Warning:  Invalid argument supplied for foreach() in e:\contenido_4.4.x\contenido\classes\class.extendedTemplate.php on line 310
es wird nicht überprüft ob überhaupt ein elseif vorhanden ist...
*** make your own tools (wishlist :: thx)

swelpot
Beiträge: 101
Registriert: Mo 26. Jul 2004, 20:42
Wohnort: Rhein-Main
Kontaktdaten:

Beitrag von swelpot » Di 9. Nov 2004, 12:13

schön, dass es gefällt ;-)

aber da du gerade den thread wiederbelebt hast, ist mir aufgefallen, dass es da noch einen bugfix gab, der noch nicht hier gepostet ist...
trat auf, falls die if-bedingung falsch ist und es keine elseif-teile gibt (glaube ich mich zu erinnern :? )
ist aber nur eine zusätzliche arrayüberprüfung:

ab zeile 308:
statt

Code: Alles auswählen

		else {
			//alle elseif-teile prüfen
			foreach($array_construct['elseif'] as $key => $array_elseif) {
				if(eval("return " . $array_elseif['condition'] . ";")) {
jetzt diesen

Code: Alles auswählen

		else {
			//alle elseif-teile prüfen
			if(is_array($array_construct['elseif'])) {
				foreach($array_construct['elseif'] as $key => $array_elseif) {
					if(eval("return " . $array_elseif['condition'] . ";")) {

und natürlich noch den block abschließen:
ab zeile 325:
statt

Code: Alles auswählen

					break;
				}
			}
			
			//wenn bisher noch keine wahre Bedingung gefunden wurde
			if(!$boolConditionTrue) {
diesen

Code: Alles auswählen

						break;
					}
				}
			}
			
			//wenn bisher noch keine wahre Bedingung gefunden wurde
			if(!$boolConditionTrue) {

hoffe, dass war jetzt halbwegs verständlich....

grüße

stefan

emergence
Beiträge: 10645
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Beitrag von emergence » Di 9. Nov 2004, 12:16

siehe obriges posting...
bugfix sollte beim ersten posting von dir noch rein...
*** make your own tools (wishlist :: thx)

swelpot
Beiträge: 101
Registriert: Mo 26. Jul 2004, 20:42
Wohnort: Rhein-Main
Kontaktdaten:

Beitrag von swelpot » Di 9. Nov 2004, 12:19

hmm,
sollte mal die posts aufmerksam bis zum ende lesen...
sorry...
baue den fix gleich oben ein.


grüße

stefan

emergence
Beiträge: 10645
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Beitrag von emergence » Di 9. Nov 2004, 12:45

tja zusammenfassend muss ich sagen
kompliment ;-) wirklich ne feine erweiterung...
man braucht zwar ein wenig bis man die möglichkeiten erahnen kann, was man nun alles machen kann, aber sobald man das mal verstanden hat, ist es wirklich ne geile sache...

das mit den capiStr funktionen ist ebenso ne sehr nützliche erweiterung...

ich werd mir das noch ein wenig weiter ansehen...
mal sehen wie kompliziert es ist etwas wie
{htmlspecialchars("{capiStrTrimHard("{STRING}", 10)}")}
umzusetzen...
*** make your own tools (wishlist :: thx)

swelpot
Beiträge: 101
Registriert: Mo 26. Jul 2004, 20:42
Wohnort: Rhein-Main
Kontaktdaten:

Beitrag von swelpot » Di 9. Nov 2004, 13:49

müsste eigentlich ganz einfach funktionieren...
eine neue templateparser-klasse von AbstractTemplateParser ableiten.
und die Methode parse implementieren.
dabei könntestdu ja ähnlich dem ersetzen der capistr-funktionen vorgehen.
meine idee für eine umsetzung wäre alle tags der form {funktionsname(.*?)} versuchen durch eval() zu jagen.
sollte natürlich erst gemacht werden, wenn die anderen umwandlungen schon gemacht sind...
ansonsten einfach nach den gewünschten funktionen ausschau halten...

und natürlich nicht vergessen den neuen templateparser bei der basisklasse zu registrieren...


grüße

stefan

coarsy
Beiträge: 19
Registriert: Di 21. Dez 2004, 11:18
Wohnort: Frankfurt
Kontaktdaten:

Frage hierzu!

Beitrag von coarsy » Di 21. Dez 2004, 12:03

Hallo zusammen!

Habe versucht, diese Klassen (Logik erinnert übrigens sehr start an smarty) zu inkludieren... Leider funktioniert das nicht, wie ich mir das vorgestellt habe... Habe erstmal die ExtendedTemplate Klasse in das Verzeichnis mit den Klassen abgespeichert und natürlich diese auch in der functions.api mit eingebunden... Muß hierfür sonst noch irgendwas verändert werden?

Mein Problem ist, dass ich mein horizontales Menu wie folgt gestalten möchte:

punkt_1 | punkt_2 | punkt_3 | punkt_4 | punkt_5 (inaktiver Zustand)

Im Aktiven Zustand habe ich dann folgendes Problem, wenn man davon ausgeht, dass punkt_3 nun aktiv ist:

punkt_1 | punkt_2 PUNKT_3 punkt_4 | punkt_5

Der Trenner links und rechts von PUNKT_3 soll verschwinden, da dieser nun farbig hinterlegt ist! Hat jemand das schon mal in dieser Art und Weise realisiert? Wäre Euch wirklich sehr dankbar, wenn mir jemand nen Lösungsansatz dazu zeigen könnte!

Viele Grüße und vielen Dank!

Chris

swelpot
Beiträge: 101
Registriert: Mo 26. Jul 2004, 20:42
Wohnort: Rhein-Main
Kontaktdaten:

Beitrag von swelpot » Di 21. Dez 2004, 12:24

hi,

denke, dass das nachfolgende Template eine mögliche Lösung wäre:

Code: Alles auswählen

<!--BEGINN:BLOCK-->
{if(({counter name=cnt1} > 1) && ({CURRENT} != {counter name=cnt2}) && ({CURRENT} != ({counter name=cnt3} + 1)))} | {/if}
{NAVITEM}
<!--END:BLOCK-->
in deinem Navimodulcode musst du dann eben {NAVITEM} mit dem jeweiligen Navitext füllen und {CURRENT} mit der fortlaufenden Nummer des gerade aktiven Navitems.

Grüße

Stefan

coarsy
Beiträge: 19
Registriert: Di 21. Dez 2004, 11:18
Wohnort: Frankfurt
Kontaktdaten:

Vielen Dank schon mal dafür, aber

Beitrag von coarsy » Di 21. Dez 2004, 12:40

{if(({counter name=cnt1} > 1) && ({CURRENT} != {counter name=cnt2}) && ({CURRENT} != ({counter name=cnt3} + 1)))} | {/if}

wird bei mir im Klartext ausgegeben! Was muß hier noch eingestellt werden, damit das von der Template Klasse geparsed wird?

Mein Template sieht im Moment so aus:

Code: Alles auswählen

<!-- BEGIN:BLOCK -->
<td align="center" bgcolor="#BB655D" style="border-top: 1px solid #FFFFFF; border-bottom: 1px solid #FFFFFF; height: 20px;"><a style="font-family: verdana, arial, helvetica, sans-serif; 
font-weight: normal;
font-size: 11px;
text-decoration: none;
color: #FFFFFF;" target="{TARGET}" href="{HREF}">{NAME}</a></td>
{if(({counter name=cnt1} > 1) && ({CURRENT} != {counter name=cnt2}) && ({CURRENT} != ({counter name=cnt3} + 1)))}
<td width="1" align="center"><img src="img/1_back.gif" border="0"></td>
{/if} 
<!-- END:BLOCK -->
Fette Greetz 2 U!

Chris

swelpot
Beiträge: 101
Registriert: Mo 26. Jul 2004, 20:42
Wohnort: Rhein-Main
Kontaktdaten:

Beitrag von swelpot » Di 21. Dez 2004, 12:46

wie schaut denn dein modulcode aus?

coarsy
Beiträge: 19
Registriert: Di 21. Dez 2004, 11:18
Wohnort: Frankfurt
Kontaktdaten:

Der sieht so aus:

Beitrag von coarsy » Di 21. Dez 2004, 12:50

OUTPUT:

Code: Alles auswählen

<?php
// Hauptnav
/***********************************************
* CONTENIDO MODUL - OUTPUT
*
* Modulname : Navigation 1.1
* Author : Jan Lengowski
* Copyright : Contenido - four for business
* Created : 15-05-2003
* Modified : 26-05-2003
************************************************/

if ( !is_object($db2) ) {
$db2 = new DB_Contenido;
}

/**
* Check if a category is child
* of another category
*
* @return boolean true/false
* @author Jan Lengowski <Jan.Lengowski@4fb.de>
* @copyright four for business AG 2003
*/
function catIsChildOf($id, $idparent) {

global $cfg, $client, $lang;

$db = new DB_Contenido;

$parent = $id;

while ( $parent != 0 ) {

$sql = "SELECT
a.parentid
FROM
".$cfg["tab"]["cat"]." AS a,
".$cfg["tab"]["cat_lang"]." AS b
WHERE
a.idclient = '".$client."' AND
b.idlang = '".$lang."' AND
a.idcat = b.idcat AND
a.idcat = '".$parent."'";

$db->query($sql);
$db->next_record();

$parent = $db->f("parentid");

if ($parent == $idparent) {
return true;
}

}

return false;

}

if ( catIsChildOf($idcat, CMS_VALUE[0]) ) {
$sel_idcat = $idcat;
} else {
$sel_idcat = CMS_VALUE[0];
}

/* Include Template Class */
include_once($cfg["path"]["contenido"] . 'classes/class.template.php');

/**
* Array storing alle the
* navigation data
*/
$navitems = array();


/* Template Instance */
$tpl = new Template;

/**
* Recursive function for creating
* the navigation array
* @param Int $idcat Category id
*/
function nav($idcat) {

global $navitems, $client, $lang, $cfg;

$db = new DB_Contenido;
$db2 = new DB_Contenido;

$sql = "SELECT parentid FROM ".$cfg["tab"]["cat"]." WHERE idcat = '$idcat'";

$db->query($sql);
$db->next_record();

$parentid = $db->f("parentid");

if ( $parentid == 0 ) {

if ( $idcat != CMS_VALUE[0] ){

$navitems = array();

$sql = "SELECT
A.idcat,
C.name
FROM
".$cfg["tab"]["cat_tree"]." AS A,
".$cfg["tab"]["cat"]." AS B,
".$cfg["tab"]["cat_lang"]." AS C
WHERE
A.idcat = B.idcat AND
B.idcat = C.idcat AND
B.idclient = '$client' AND
C.idlang = '$lang' AND
C.visible = '1' AND
B.parentid = 'CMS_VALUE[0]'
ORDER
BY A.idtree";

$db->query($sql);

while ($db->next_record()) {

/* Check for external redirects... */
$sql = "SELECT
a.external_redirect AS ext
FROM
".$cfg["tab"]["art_lang"]." AS a,
".$cfg["tab"]["cat_art"]." AS b,
".$cfg["tab"]["cat"]." AS c
WHERE
b.idcat = '".$db->f("idcat")."' AND
b.is_start = '1' AND
c.idclient = '".$client."' AND
c.idcat = b.idcat AND
a.idart = b.idart AND
a.idlang = '".$lang."'";

$db2->query($sql);
$db2->next_record();

$target = ( $db2->f("ext") == 0 ) ? '_self' : '_blank';

$navitems[$db->f("idcat")] = array("idcat" => $db->f("idcat"),
"name" => $db->f("name"),
"target" => $target);
}

}

return true;
}

$sql = "SELECT
A.idcat,
C.name
FROM
".$cfg["tab"]["cat_tree"]." AS A,
".$cfg["tab"]["cat"]." AS B,
".$cfg["tab"]["cat_lang"]." AS C
WHERE
A.idcat = B.idcat AND
B.idcat = C.idcat AND
B.idclient = '$client' AND
C.idlang = '$lang' AND
C.visible = '1' AND
B.parentid = '$parentid'
ORDER BY
A.idtree";

$db->query($sql);

while ($db->next_record()) {

/* Check for external redirects... */
$sql = "SELECT
a.external_redirect AS ext
FROM
".$cfg["tab"]["art_lang"]." AS a,
".$cfg["tab"]["cat_art"]." AS b,
".$cfg["tab"]["cat"]." AS c
WHERE
b.idcat = '".$db->f("idcat")."' AND
b.is_start = '1' AND
c.idclient = '".$client."' AND
c.idcat = b.idcat AND
a.idart = b.idart AND
a.idlang = '".$lang."'";

$db2->query($sql);
$db2->next_record();

$target = ( $db2->f("ext") == 0 ) ? '_self' : '_blank';

$tmp_nav[$db->f("idcat")] = array("idcat" => $db->f("idcat"),
"name" => $db->f("name"),
"target" => $target);
}

$tmp_nav[$idcat]["sub"] = $navitems;
$navitems = $tmp_nav;

/* Function call */
nav($parentid);

} // end function

$sql = "SELECT
A.idcat,
C.name
FROM
".$cfg["tab"]["cat_tree"]." AS A,
".$cfg["tab"]["cat"]." AS B,
".$cfg["tab"]["cat_lang"]." AS C
WHERE
A.idcat = B.idcat AND
B.idcat = C.idcat AND
B.idclient = '$client' AND
C.idlang = '$lang' AND
C.visible = '1' AND
B.parentid = '$sel_idcat'
ORDER BY
A.idtree";

$db->query($sql);

while ( $db->next_record() ) {

/* Check for external redirects... */
$sql = "SELECT
a.external_redirect AS ext
FROM
".$cfg["tab"]["art_lang"]." AS a,
".$cfg["tab"]["cat_art"]." AS b,
".$cfg["tab"]["cat"]." AS c
WHERE
b.idcat = '".$db->f("idcat")."' AND
b.is_start = '1' AND
c.idclient = '".$client."' AND
c.idcat = b.idcat AND
a.idart = b.idart AND
a.idlang = '".$lang."'";

$db2->query($sql);
$db2->next_record();

$target = ( $db2->f("ext") == 0 ) ? '_self' : '_blank';

$navitems[$db->f("idcat")] = array("idcat" => $db->f("idcat"),
"name" => $db->f("name"),
"target" => $target);
}

/* Create Navigation Array */
nav($sel_idcat);

/* Start Output buffer */
ob_start();

echo '<table cellspacing="0" cellpadding="0" width="100%" border="0"><tr>';

$i = 0;

foreach ($navitems as $key => $data) {
/* 1. Navigations Ebene */
$tpl->reset();
$tpl->set('d', 'NAME', $data['name']);
$tpl->set('d', 'TARGET', $data['target']);
$tpl->set('d', 'HREF', $sess->url('front_content.php?idcat='.$data['idcat']));
$tpl->set('d','INDEX','$i');
$tpl->next();


if ($idcat == $data['idcat'] || is_array($data['sub'])) {
$tpl->generate('templates/navfirst_h_on.html');
} else {
$tpl->generate('templates/navfirst_h_off.html');
}
if (is_array($data['sub'])) {
$tmp_data = array();
$tmp_data = $data;

} // end if

$i++;

} // end foreach
echo '</tr></table>';

/* Read out buffer */
$html = ob_get_contents();

/* Clean buffer */
ob_end_clean();

/* Output buffer-contents */
echo $html;

?>

swelpot
Beiträge: 101
Registriert: Mo 26. Jul 2004, 20:42
Wohnort: Rhein-Main
Kontaktdaten:

Beitrag von swelpot » Di 21. Dez 2004, 12:59

du musst, wenn du die erweiterten templatefunktionen benutzt, auch eine solche instanz benutzen:
statt:

Code: Alles auswählen

/* Template Instance */
$tpl = new Template;
diesen hier:

Code: Alles auswählen

/* Template Instance */
$tpl = new ExtendedTemplate;
und CURRENT sollte auch irgendwo ersetzt werden...

grüße

coarsy
Beiträge: 19
Registriert: Di 21. Dez 2004, 11:18
Wohnort: Frankfurt
Kontaktdaten:

Axo! Jetzt verstehe ich die Zusammenhänge allmählich...

Beitrag von coarsy » Di 21. Dez 2004, 13:38

Bin nämlich erst seit gestern bei Contenido dabei ;-)

Was sollte denn in Current stehen? Der inkrementierte Wert des aktuellen
Durchlaufs der Schleife? Also:

Code: Alles auswählen

echo '<table cellspacing="0" cellpadding="0" width="100%" border="0"><tr>';

$i = 1;

foreach ($navitems as $key => $data) {
/* 1. Navigations Ebene */
$tpl->reset();
$tpl->set('d', 'NAME', $data['name']);
$tpl->set('d', 'TARGET', $data['target']);
$tpl->set('d', 'HREF', $sess->url('front_content.php?idcat='.$data['idcat']));
$tpl->set('d','CURRENT',$i);
$tpl->next();


if ($idcat == $data['idcat'] || is_array($data['sub'])) {
$tpl->generate('templates/navfirst_h_on.html');
} else {
$tpl->generate('templates/navfirst_h_off.html');
}
if (is_array($data['sub'])) {
$tmp_data = array();
$tmp_data = $data;

} // end if

$i++;

} // end foreach
echo '</tr></table>';
Vielen Dank erstma für Deine prompte Hilfe!

Chris

Gesperrt