Sauber gegliederte, barrierefreie, validierte navigation

mikk
Beiträge: 32
Registriert: Do 17. Nov 2005, 19:49
Wohnort: Stuttgart
Kontaktdaten:

Beitrag von mikk » Sa 10. Jun 2006, 19:22

conradius hat geschrieben:hm, also liebe Leute, die neu dazukommen; wartet noch schnell einen Moment, wir sind daran die Sache zu überarbeiten.
Wie lange müssen wir noch warten :twisted: ??

Ich brauch ebenfalls ein geschachteltes ul/li Menü --- werde mich heute Abend auch dran setzen ;)

Chopper
Beiträge: 108
Registriert: Mi 9. Feb 2005, 17:09
Wohnort: Berlin
Kontaktdaten:

Beitrag von Chopper » Fr 23. Jun 2006, 01:06

Hi,
gibs was neues ? ;) ...

habs auch mal eingebunden ...

Mit einer Ebene klappt noch alles Problemlos, komischerweise stellt er bei der ersten unterebene nur das erste Element da bis zum ende </li>, bricht dann ab ohne den <ul> tag zu schließen und macht mit der restlichen ersten Ebene weiter ...

naja n8 ...

MfG
Chopper

conradius
Beiträge: 168
Registriert: Di 19. Jul 2005, 11:52
Wohnort: Wabern (Bern/CH)
Kontaktdaten:

Beitrag von conradius » Fr 23. Jun 2006, 15:29

hallo Leute,
sorry, bin zur Zeit sehr beschäftigt - und hab dazu auch noch keine Boardbenachrichtigung erhalten... :?

Bei mir klappt die verschachtelte Liste einwandfrei - aber noch ohne ModRewrite.
Ich habe aber auch noch einen peinlichen bug beheben müssen - den Ihr aber auch nicht bemerkt habt. :wink:

Die return Anweisung in der Funktion navigation_level_x() beendet diese natürlich und verunmöglicht somit die Rekursivität. Die aktualiserte Version liegt nach wie vor unter http://www.mereo.ch/_support/con_ul_mainnavigation.zip

Ein Beispiel seht Ihr hier am laufen: http://www.minggmbh.ch/index.php?idcat=26

@mvf ich melde mich bald wieder!

Gruss
Conradius

Chopper
Beiträge: 108
Registriert: Mi 9. Feb 2005, 17:09
Wohnort: Berlin
Kontaktdaten:

Beitrag von Chopper » Fr 23. Jun 2006, 21:48

Ich hatte die Version von Rezeptionist.
Aber jo danke nun funktioniert es :)

n0Fear
Beiträge: 12
Registriert: Fr 29. Apr 2005, 13:42
Kontaktdaten:

Beitrag von n0Fear » Mi 9. Aug 2006, 14:53

Hab noch nen bug gefunden, die 3. ebene wurde zu früh geschlossen wenn es der unterpunkt des letzten punktes der 2. ebene war

gefixte version:

Code: Alles auswählen

<?php
/***********************************************
* CONTENIDO MODUL - OUTPUT
*
* Modulname  :      Hauptnavigation
* Author(s)   :     Jan Lengowski, Andreas Lindner, 4fb
* Copyright   :     Contenido - four for business, Andreas Lindner
* Created     :     12.08.2005
* Modified on :		22-05-2006
* Modified by :		Mereo, Conrad Leu
************************************************/

#System properties in use:
#Type: navigation, Name: idcat_homepage
#Contains idcat of tree to be displayed in main navigation

#Includes
cInclude("frontend", "includes/functions.navigation.php");

#If no tree is selected, use client setting
$start_cat = "CMS_VALUE[0]";
if ($start_cat=='') {
	$cApiClient = new cApiClient($client);
	$start_cat = $cApiClient->getProperty('navigation','idcat_homepage');
}

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, $start_cat) ) {
	$sel_idcat = $idcat;
} else {
	$sel_idcat = $start_cat;
}

/* 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, $start_cat;

		$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 != $start_cat ){

				$navitems = array();

				$sql = "SELECT
							A.idcat,
							C.name,
							C.public,
							C.idcatlang
						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  = '".$start_cat."'
						ORDER
							BY A.idtree";

					  $db->query($sql);

					  while ($db->next_record()) {

							/* Check for external redirects... */
							$sql = "SELECT
										a.external_redirect AS ext,
										a.idartlang AS idartlang
									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
										c.idclient  = '".$client."' AND
										c.idcat     = b.idcat AND
										a.idart     = b.idart AND
										a.idlang    = '".$lang."'";

							$db2->query($sql);
							$flag = false;
							while ($db2->next_record()&&!$flag) {
								if (isStartArticle($db2->f("idartlang"), $db->f("idcat"), $lang))
								{
									$flag = true;
									$target = ( $db2->f("ext") == 0 ) ? '_self' : '_blank';

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

		   }

		   return true;
		}

		$sql = "SELECT
					A.idcat,
					C.name,
					C.public,
					C.idcatlang
				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,
							a.idartlang AS idartlang
						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
							c.idclient  = '".$client."' AND
							c.idcat     = b.idcat AND
							a.idart     = b.idart AND
							a.idlang    = '".$lang."'";

				$db2->query($sql);
				$flag = false;
				while ($db2->next_record() && !$flag) {
					if (isStartArticle($db2->f("idartlang"), $db->f("idcat"), $lang))
					{
						$flag = true;
						$target = ( $db2->f("ext") == 0 ) ? '_self' : '_blank';

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

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

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

}  // end function

$sql = "SELECT
			A.idcat,
			C.name,
			C.public,
			C.idcatlang
		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,
					a.idartlang AS idartlang
				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
					c.idclient  = '".$client."' AND
					c.idcat     = b.idcat AND
					a.idart     = b.idart AND
					a.idlang    = '".$lang."'";

		$db2->query($sql);
		#$db2->next_record();
		$flag = false;
		while ($db2->next_record()&&!$flag) {
			if (isStartArticle($db2->f("idartlang"), $db->f("idcat"), $lang))
			{
				$flag = true;
				$target = ( $db2->f("ext") == 0 ) ? '_self' : '_blank';

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

/* Create Navigation Array */
if(($sel_idcat=='')||($sel_idcat=='0')){
	$cApiClient = new cApiClient($client);
	$sel_idcat = $cApiClient->getProperty('navigation', 'idcat_homepage');
}

nav($sel_idcat);

/* Start Output buffer */
ob_start();

/**
 * navigation_level_x is the recursive function to build
 * a navigation/an unordered list with an undefined depth
 * @param Int $idcat Category id, Array $data Items of the current category, Array $subdata Subitems of the current category
 */
function navigation_level_x( $idcat, $data, $subdata ) {
	global $tpl, $sess;
	if (is_array($data['sub'])) {
		foreach ($data['sub'] as $key => $data2) {
			if (checkCatPermission($data2['idcatlang'],$data2['public'])) {
				$tpl->reset();
				$tpl->set('d', 'NAME',  $data2['name']);
				$tpl->set('d', 'TARGET', $data2['target']);
				$tpl->set('d', 'HREF',  $sess->url('index.php?idcat='.$data2['idcat']));
				$tpl->next();

				if ($idcat == $data2['idcat'] && empty($data2['sub'])) {
					$tpl->generate('templates/nav_selected.html', 0, 0);
				} elseif($idcat == $data2['idcat'] && !empty($data2['sub'])) {
					$tpl->generate('templates/nav_open.html', 0, 0);
				} elseif($idcat != $data2['idcat'] && is_array($data2['sub']) && catIsChildOf($idcat, $data2['idcat'])) {
					$tpl->generate('templates/nav_open.html', 0, 0);
				} else {
					$tpl->generate('templates/nav_default.html', 0, 0);
				} // end if


				$nextdata = $data2['sub'];
				if ( empty( $data2['sub'] ) ) {
					$return = false;
				} else {
					if ( is_array( $data2['sub'] ) ) {
						navigation_level_x( $idcat, $data2, $nextdata );
						$return = true;
					} else {
						$return = false;
						} // end if
					} // end if
				} // end if

				if ( is_array( $subdata ) ) {
					$last_cat = end( $subdata );
					if ( $data2['idcat'] == $last_cat['idcat'] ) {
						$tpl->reset();
						$tpl->next();
						$tpl->generate('templates/nav_close.html', 0, 0);
						} // end if
					} // end if
				
			} // end foreach
		} // end if
	return $return;
	} // end function

$tpl->reset();
$tpl->next();
// start the nav-surrounding ul
$tpl->generate('templates/nav_start.html', 0, 0);

foreach ($navitems as $key => $data) {
	/* 1. Navigation level */
	if (checkCatPermission($data['idcatlang'],$data['public'])) {
		$tpl->reset();
		$tpl->set('d', 'NAME',  $data['name']);
		$tpl->set('d', 'TARGET', $data['target']);
		$tpl->set('d', 'HREF',  $sess->url('index.php?idcat='.$data['idcat']));

		$tpl->next();
		if ($idcat == $data['idcat'] && empty($data['sub'])) {
			$tpl->generate('templates/nav_selected.html', 0, 0);
		} elseif($idcat == $data['idcat'] && !empty($data['sub'])) {
			$tpl->generate('templates/nav_open.html', 0, 0);
		} elseif($idcat != $data['idcat'] && is_array($data['sub']) && catIsChildOf($sel_idcat, $data['idcat'])) {
			$tpl->generate('templates/nav_open.html', 0, 0);
		} else {
			$tpl->generate('templates/nav_default.html', 0, 0);
		} // end if

		$subdata = $data['sub'];
		
		navigation_level_x( $idcat, $data, $subdata );
		} // end if
	} // end foreach

// close the nav-surrounding ul
$tpl->generate('templates/nav_end.html', 0, 0);

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

/* Clean buffer */
ob_end_clean();

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

conradius
Beiträge: 168
Registriert: Di 19. Jul 2005, 11:52
Wohnort: Wabern (Bern/CH)
Kontaktdaten:

Beitrag von conradius » Do 10. Aug 2006, 10:53

hey n0Fear,
danke fürs Mithelfen.
Ich versteh' aber erstens Deine Aussage nicht ganz, wann die Ebene zu früh geschlossen wurde und zweitens sehe ich keinen Unterschied zwischen meiner und Deiner geposteten Version... Bin ich blind oder was genau hast Du gefixt?

Gruss
Conradius

n0Fear
Beiträge: 12
Registriert: Fr 29. Apr 2005, 13:42
Kontaktdaten:

Beitrag von n0Fear » Mo 14. Aug 2006, 12:55

moin, ich habe diesen block (ab zeile 335)

Code: Alles auswählen

            if ( is_array( $subdata ) ) { 
               $last_cat = end( $subdata ); 
               if ( $data2['idcat'] == $last_cat['idcat'] ) { 
                  $tpl->reset(); 
                  $tpl->next(); 
                  $tpl->generate('templates/nav_close.html', 0, 0); 
                  } // end if 
               } // end if 
hinter diesen geschoben

Code: Alles auswählen

            $nextdata = $data2['sub']; 
            if ( empty( $data2['sub'] ) ) { 
               $return = false; 
            } else { 
               if ( is_array( $data2['sub'] ) ) { 
                  navigation_level_x( $idcat, $data2, $nextdata ); 
                  $return = true; 
               } else { 
                  $return = false; 
                  } // end if 
               } // end if 
            } // end if 
damit die unterebene erst generiert wird, bevor er prüft ob die liste geschlossen werden muss.

conradius
Beiträge: 168
Registriert: Di 19. Jul 2005, 11:52
Wohnort: Wabern (Bern/CH)
Kontaktdaten:

Beitrag von conradius » Mi 10. Jan 2007, 23:58

die Verbesserung von n0Fear ist übrigens angepasst und im ZIP aktualisiert: http://www.mereo.ch/_support/con_ul_mainnavigation.zip

späten Dank noch für den Tipp n0Fear!

Gruss,
Conradius

silicone
Beiträge: 299
Registriert: Di 15. Mär 2005, 10:33
Kontaktdaten:

Beitrag von silicone » Fr 2. Mär 2007, 09:18

Super Modul!

Leider für mich mit einem kleinen Haken:
Wenn ich mit dieser Navigation ein Dropdown-Menu gestalten möchte, habe ich das Problem, das immer nur die Unterpunkte des gerade aktiven Menüpunktes gelistet werden. Ich brauch aber die komplette Navigation...

Lässt sich das leicht ändern?

Gruß,
Thomas

conradius
Beiträge: 168
Registriert: Di 19. Jul 2005, 11:52
Wohnort: Wabern (Bern/CH)
Kontaktdaten:

Beitrag von conradius » Fr 9. Mär 2007, 15:46

@silicone: konntest Du schon was mit den per pm gesendeten Infos anfangen?

Gruss,
Conrad

silicone
Beiträge: 299
Registriert: Di 15. Mär 2005, 10:33
Kontaktdaten:

Beitrag von silicone » Fr 9. Mär 2007, 15:58

Sorry, bin nicht dazu gekommen, mich da weiter reinzuknien. Hatte sich mittlerweile (ohne mein Zutun) erledigt...

Wenn ich Zeit finde, schau ich nochmal rein.

Gruß,
Thomas

kashban
Beiträge: 44
Registriert: Fr 7. Mai 2004, 10:29
Kontaktdaten:

Beitrag von kashban » Di 8. Mai 2007, 20:38

Hallo!

Ich möchte ebenfalls die komplette Navi anzeigen. Was muss ich ändern?

Viele Grüße,
Kashban

conradius
Beiträge: 168
Registriert: Di 19. Jul 2005, 11:52
Wohnort: Wabern (Bern/CH)
Kontaktdaten:

kompletter Navigationsbaum - dropdown à la suckerfish

Beitrag von conradius » Mo 14. Mai 2007, 09:40

@kashban: hier doch noch veröffentlicht, was ich mit silicone schon "gepmt" habe:

ich habe das Modul aus diesem Thread auch grad vor kurzem umgebaut. Als Vorbild hatte ich eine Navigationsliste à la suckerfish (http://alistapart.com/articles/dropdowns), bei der alle Ebenen bereits offen sind und per CSS angesteuert werden.
Mein Modul ist aber noch nicht ganz reif zur Veröffentlichung, deshalb wurde es bis jetzt im Thread auch noch nicht erwähnt.
Es funktioniert zwar, listet aber nur 2 Ebenen auf, also "Baum/Kategorie/Unterkategorie". Mein Ziel wäre aber, dass es genauso flexibel n-Ebenen auflistet, wie sein Vorfahre aus diesem Thread.

Das Modul, ich nenne es fulltreenavigation, kapiert geschützte Kategorien, listet Kategorien ohne online Startartikel nicht auf, auch wenn sie online sind und verwendet HTML-Templates.

Du findest die benötigten Dateien unter http://www.mereo.ch/_support/m_fulltreenavigation.zip
Wenn Du noch ein bisschen damit herumpröbelst und herausfindest, weshalb nur zwei Ebenen gelistet werden, bin ich Dir dankbar für ein Feedback zur Verbesserung. Mir fehlt nämlich jetzt grad die Zeit dazu.
Das Navigations-Array wird bei diesem Modul in der Klasse class.m_fulltreenavigation.php erstellt. Für die Installation/Verwendung hat's ein kleines readme in der ZIP-Datei.

Gruss und bei Fragen/Problemen bitte melden,
Conradius

conradius
Beiträge: 168
Registriert: Di 19. Jul 2005, 11:52
Wohnort: Wabern (Bern/CH)
Kontaktdaten:

Navigation mit mod_rewrite

Beitrag von conradius » Mo 14. Mai 2007, 09:59

übrigens noch zum Status der Navigation mit mod_rw:

1. installiert die mod_rewrite-Version von stese: http://www.polycoder.de/contenido-wcms/ ... d-rewrite/
2. nehmt irgendeine Navigation, z.B. eine der oben genannten, splittet die fulltreenav mittels CSS, falls gewünscht - et voilà! So könnt ihr eine sauber gegliederte, nötigenfalls gesplittete Navigation mit schönen seoptimized urls machen. ;-) (mit domain.tld/category oder domain.tld/article.html oder beidem kombiniert)

PS: fürs Navi-splitten lest mal das hier durch. Ich denke, das sollte helfen: http://alistapart.com/articles/dropdowns

herzliche Grüsse,
Conradius

casi1969
Beiträge: 71
Registriert: Mi 4. Aug 2004, 16:30
Wohnort: Köln
Kontaktdaten:

Beitrag von casi1969 » Di 15. Mai 2007, 16:48

Wirklich barrierefrei sind die Suckerfish Dropdowns nicht. Es ist keine Tastaturbedienung möglich und die Flyout-Menus sind für Menschen mit motorischen Einschränkungen kaum zu nutzen.

Eine Alternative:
http://pfirsichmelba.de/artikel-scripts ... sible.html

Gesperrt