[PHP] Webshop menu probleem.

Pagina: 1
Acties:
  • 439 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Beste Tweakers,

Ik moet voor het bedrijf waar ik nu werk een webshop ontwikkelen. Tot nu toe werkt alles prima, totdat ik het menu wilde maken (links). Het probleem is dat ik niet weet hoe ik het menu moet onderverdelen qua code. Het moet er bijvoorbeeld zo uit komen te zien:

Gereedschappen
---Sleutels
------Dopsleutels

etc.

Ik heb daarom in mijn MySQL database een table genaamd categorien. Die ziet er als volgt uit:

ID | NAAM | PARENT

Je hebt dan dus bijv.:

1 | gereedschappen | 0
2 | sleutels | 1
3 | dopsleutels | 2

Mijn vraag is dus nu, hoe maak ik, dat als ik op bijv. sleutels klik, dat hij het menu herlaad (geen probleem) dat hij die categorie weergeeft in het menu?

Ik zit al een paar dagen met dit probleem, maar ik kom er echt niet uit. Jullie zijn mijn laatste hoop! _/-\o_

Groetjes,

T-Xorcist

Acties:
  • 0 Henk 'm!

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
Met een query haal je de gegevens van menuitem sleutels en in die query zeg je meteen dat hij een veld toevoegt waarin de parentname in komt te staan.

even snel uit hoofd en lekker ranzig:
code:
1
2
SELECT tabel.id, tabel.naam, tabel.parent, t2.naam FROM tabel, tabel as t2 WHERE
tabel.id = 2 AND tabel.id = t2.parent

zo iets ik zeg niet dat die werkt, sterker nog ik denk eerder dat die niet werkt :+ maar dan heb je vast een begin

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik weet wel hoe ik een query moet maken, het probleem zit meer in dat de diepte van een bepaalde categorie. Die is namelijk dynamisch. Je zult dus denk ik met een array() moeten gaan werken? Ik weet niet precies hoe dit werkt O+

Acties:
  • 0 Henk 'm!

Verwijderd

Je bedoelt zeker categorieën en oneindige subcategorieën?

Dan moet zou ik functies gaan zoeken, die zgn. "Breadcrumbs" kunnen genereren en daarvan kun je dan de treeview maken.
Bovendien zullen er toch ook wel standaard treeview (boomstructuur) scripts te vinden zijn?

Kunnen die dopsleutels ook nog in meerdere categorieën voorkomen?
Of alleen maar in de categorie "Sleutels"?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verwijderd schreef op donderdag 09 november 2006 @ 09:04:
Je bedoelt zeker categorieën en oneindige subcategorieën?
Yep! subcategorie van subcategorie zeg maar, en dat zo oneindig door (bij wijze van spreken).
Dan moet zou ik functies gaan zoeken, die zgn. "Breadcrumbs" kunnen genereren en daarvan kun je dan de treeview maken.
Bovendien zullen er toch ook wel standaard treeview (boomstructuur) scripts te vinden zijn?
Hm, nooit van gehoord. Heb je daar een voorbeeld URL voor, of een URL waar ik meer informatie daarover kan vinden?
Kunnen die dopsleutels ook nog in meerdere categorieën voorkomen?
Of alleen maar in de categorie "Sleutels"?
Die kan alleen maar in de categorie "Sleutels" voorkomen! ;)

Acties:
  • 0 Henk 'm!

  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 04-09 08:16

OkkE

CSS influencer :+

Pseudo-code, niet getest dus. :)

[edit: foutje, was de </li> vergeten]


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function printNavigation($parent, $level)
{
    $sql = "select * from `database` where `parent` = ".$parent;
    $rs = mysql_query($sql);

    print '<ul>';
    while ($row = mysql_fetch_object($rs))
    {
        print '<li>';
        print '<a href="index.php?id='.$row->id.'">'.str_repeat('&nbsp;',$level).$row->menuitem.'</a>';
        printNavigation($row->id, $level+1);
        print '</li>';
    }
    print '</ul>';
}

[ Voor 9% gewijzigd door OkkE op 09-11-2006 09:14 ]

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Okke, ziet er goed uit!! Alleen een vraagje:

* Hoe kan ik dynamisch het $level bepalen? want het level staat nl nergens in de database.
* Hij laat nu ook de subcategorien al zien, maar dat moet eigenlijk pas als ik op de categorie erboven heb geklikt (dus bijv. id=4). Heb je enig idee hoe ik dat kan fixen?

Dank alvast!! :D

Acties:
  • 0 Henk 'm!

Verwijderd

wil je nu met 1 klik op het menu alle subcategorien uitklappen of enkel de onderliggende?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verwijderd schreef op donderdag 09 november 2006 @ 10:02:
wil je nu met 1 klik op het menu alle subcategorien uitklappen of enkel de onderliggende?
Enkel de onderliggende subcategorie. Als men dan weer op die klikt, dan word gekeken of er weer een submenu onder moet, zo niet, moet hij de artikelen laten zien (in een ander scherm) :)

Acties:
  • 0 Henk 'm!

Verwijderd

dan kan je toch voor elke klik een sql query uitvoeren???

gewoon kijken waar hij op klikt en kijken of ergens de parent gelijk is aan de id van de categorie waarop geklikt is :)

Acties:
  • 0 Henk 'm!

  • cavey
  • Registratie: Augustus 2000
  • Laatst online: 29-05 01:29
met ajax kan je de boel dynamisch laten genereren zonder een pagina refresh ;)

paar handige queries maken, je datamodel uitbreiden om je nieuwe functionaliteit te kunnen ondersteunen..... en dan is het toch gewoon een papier-oefening/structuur omzetten naar php code?

nofi, maar dit is toch gewoon "use your own brains to figure out concepts" of use google om het wiel niet opnieuw uit te vinden? Alle mooie pseudo code hier ten spijt, dit klinkt gewoon als een analyse probleem en dan omzetten naar een functionele specificatie.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verwijderd schreef op donderdag 09 november 2006 @ 10:06:
dan kan je toch voor elke klik een sql query uitvoeren???

gewoon kijken waar hij op klikt en kijken of ergens de parent gelijk is aan de id van de categorie waarop geklikt is :)
Dat kan best mogelijk zijn, maar ik zie door de bomen het bos niet meer ;) Weet je waar ik dat dan precies moet zetten? Ik heb nu dit:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php 
function printNavigation($parent, $level) 
{ 
  $sql = mysql_query("SELECT * FROM `categorien` WHERE `parent` = ". $parent) or die(); 

  print ("<ul>\n");
    while ($row = mysql_fetch_object($sql)) 
    { 
      print ("<li><a href=\"index.php?c=". $row->id ."\">". str_repeat('&nbsp;',$level) . strtoupper($row->naam_nl) ."</a></li>\n"); 
      printNavigation($row->id, $level+1); 
    } 
  print ("</ul>\n"); 
} 
    
printNavigation(0,0);
?>

Enig idee waar ik welke query moet zetten?

Acties:
  • 0 Henk 'm!

Verwijderd

Een oplossing die ik hier ooit voor heb gebruikt is het hele menu (inclusief alle siblings) uitlezen uit de database, dan elk niveau in DIV's zetten, en alle 2de level items hiden... wanneer een gebruiker op een knop klikt, wordt of het artikel geopend (geen siblings) of de siblings ge-unhide. Ik neem aan dat het niet te belastend is voor de database om alles in een keer uit te lezen! Waarschijnlijk hoef je het hele menu dan slechts een keer op te bouwen, omdat er in een sessie toch niets zal veranderen (denk ik?)

Indien je interesse hebt in het menuutje moet je maar even PM'en...

Acties:
  • 0 Henk 'm!

Verwijderd

en deze functie roep je elke keer aan dat er op een menu item geklikt wordt? En deze geef je dan de id mee van het item waarop geklikt is, dan ben je er toch lijkt me? Die nieuwe aanroep hoeft volgens mij ook niet, als je maar 1 niveau eronder wilt tekenen dan lijkt me die overbodig...

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

cavey schreef op donderdag 09 november 2006 @ 10:09:
met ajax kan je de boel dynamisch laten genereren zonder een pagina refresh ;)
Vergeet dan alleen niet dat search engines dit lastig tot niet kunnen indexeren!
"AJAX" is handig op sommige punten, maar absoluut geen must ;)

Acties:
  • 0 Henk 'm!

  • Pin0
  • Registratie: November 2002
  • Niet online
Volgens mij wil de TS dus een dynamische tree maken in MySQL en in één tabel.
Wellicht is het volgende artikel wel wat voor je, daar heb ik veel aan gehad, zeker als je het aantal querys aan de bezoekers kant wilt beperken. (Geen queries in een loop/recursieve functie ed)

http://www.sitepoint.com/article/hierarchical-data-database

Vooral de Modified Preorder Tree Traversal vind ik een mooie oplossing...

Mijn Lego Mocs - LEGO idea: The Motorcycle Garage


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Pin0 schreef op donderdag 09 november 2006 @ 10:35:
Volgens mij wil de TS dus een dynamische tree maken in MySQL en in één tabel.
Wellicht is het volgende artikel wel wat voor je, daar heb ik veel aan gehad, zeker als je het aantal querys aan de bezoekers kant wilt beperken. (Geen queries in een loop/recursieve functie ed)

http://www.sitepoint.com/article/hierarchical-data-database

Vooral de Modified Preorder Tree Traversal vind ik een mooie oplossing...
Ziet er inderdaad erg goed uit! Ik ben er mee aan het kloten om het zo maar te zeggen, maar het wil niet echt lukken. Ik ga nog een aantal dingen proberen.. *zucht*

Als ik nu op een subcategorie klikt, verdwijnen de hoofdcategoriën ...

Wat een gedoe is het toch ook weer ;)

[ Voor 4% gewijzigd door Verwijderd op 09-11-2006 11:25 ]


Acties:
  • 0 Henk 'm!

  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 04-09 08:16

OkkE

CSS influencer :+

Verwijderd schreef op donderdag 09 november 2006 @ 09:31:
Okke, ziet er goed uit!! Alleen een vraagje:

* Hoe kan ik dynamisch het $level bepalen? want het level staat nl nergens in de database.
* Hij laat nu ook de subcategorien al zien, maar dat moet eigenlijk pas als ik op de categorie erboven heb geklikt (dus bijv. id=4). Heb je enig idee hoe ik dat kan fixen?

Dank alvast!! :D
$level is alleen om een inspringing te kunnen doen, zodat duidelijk is wat submenu's zijn en wat niet. Je moet de functie, voor het hele menu, aanroepen met printNavigation(0,0);

In mijn ogen is de beste manier om het hele menu uit te lezen, en alle submenu's die je niet wilt laten zien een CSS class mee geven, waarmee je ze verbergt.

Volledige script wat ik hier nog had liggen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
function PrintNavigation($active=0, $lang='nl', $parent=0, $level=0)
{
    $sql = sprintf("SELECT w.ID, w.Hidden, t.Navigation FROM `Website` AS w, `Translations` AS t WHERE w.Parent = %d AND w.ID = t.Page AND t.Language = '%s' ORDER BY w.Order ASC", $parent, $lang);
    $rs = mysql_query($sql) or die(mysql_error());

    if (mysql_num_rows($rs) > 0)
    {
        if ($level == 0) { print '<ul id="nav">'; }
        else 
        {
            $sqlnum = sprintf("SELECT `Parent` FROM `Website` WHERE `ID` = %d", $active);
            $rsnum = mysql_query($sqlnum) or die(mysql_error());
            $rownum = mysql_fetch_object($rsnum);

            if ($active > 0 && ($parent == $active || $parent == $rownum->Parent)) { print '<ul class="selected">'; }
            else { print '<ul>'; }
        }

        while ($row = mysql_fetch_object($rs))
        {
            if (!empty($row->Navigation) && $row->Hidden==0)
            {
                $num_rows = mysql_num_rows(mysql_query("SELECT `ID` FROM `Website` WHERE `Parent` = $row->ID AND `Hidden` = 0"));

                print '<li>';

                if ($row->ID == $active)
                {
                    printf('<strong id="navitem%d">%s</strong>', $row->ID, ($row->Navigation));
                }
                elseif (0==$parent && $num_rows>0)
                {
                    printf('<span id="navitem%d">%s</span>', $row->ID, ($row->Navigation));
                }
                else
                {
                    printf('<a id="navitem%d" href="index.php?lang=%s&amp;id=%d">%s</a>', $row->ID, $lang, $row->ID, ($row->Navigation));
                }
                
                // For multi-level navigation, uncomment this line:
                if ($num_rows>0) { PrintNavigation($active, $lang, $row->ID, $level+1); }

                print '</li>';
            }
        }
        print '</ul>';
    }
}

PrintNavigation($PageID, $Lang);

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
OkkE, geweldig script moet ik zeggen, maar ik heb nergens in de database staan of ze hidden moeten zijn o.i.d. Heb je enig idee hoe ik dat kan implenmenteren in mijn site?

Ik weet het, /me is lastig O+

Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 08:58

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op donderdag 09 november 2006 @ 11:45:
OkkE, geweldig script moet ik zeggen, maar ik heb nergens in de database staan of ze hidden moeten zijn o.i.d. Heb je enig idee hoe ik dat kan implenmenteren in mijn site?

Ik weet het, /me is lastig O+
Eeh.. no offence maar je wil nu dat we je wel erg aan het handje gaan houden.

Hier in PRG draait het nog steeds om het *zelf* ontwikkelen en we verwachten dan ook dat je er zelf in eerste instantie zelf mee aan de slag gaat. Je hebt nu al een kant en klaar script gekregen waarmee je zelf uit de voeten zou moeten kunnen. Als je dat niet lukt is dat niet erg maar probeer in elk geval eerst een aantal zaken voordat je een vraagt stelt. Het komt nu nogal over op "dit lukt me niet, wie fixt het even voor me". PRG is een discussieforum en geen helpdesk.

Dus: wat heb je nu zelf al geprobeerd hiermee? Wat lukte daar niet mee? Kreeg je foutmeldingen? Etc. Zie ook Programming Beleid - De Quickstart

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 04-09 08:16

OkkE

CSS influencer :+

Op regel 3 wordt het veld Hidden van de Website-tabel opgehaald, op regel 21 wordt gekeken of deze waarde 0 is. Als deze 0 is (dus _niet_ verborgen) dan wordt 'ie geprint.

De rest mag je echt zelf doen. Vind dat ik voor vandaag wel genoeg gehoplen heb. ;)

Edit: Zie Creepy dus. :P

[ Voor 5% gewijzigd door OkkE op 09-11-2006 11:56 ]

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Het gaat zo zowiezo niet werken :(

Ik moet namelijk bijvoorbeeld dit hebben: Gereedschap --> sleutels --> dopsleutels --> 1/2 --> groot.

Het probleem is dus, dat 1/2 dus meer voorkomt in de database bij een product.
Nu moet ik dus gaan werken met 2,6,3,8 en dat exploden waarschijnlijk..

't Gaat allemaal niet van een lije dakje :/

Acties:
  • 0 Henk 'm!

Verwijderd

Schrijf eens voor jezelf uit, wat je precies wilt bereiken.
Zomaar scripts verbouwen en "on the fly" nog even bedenken
dat het toch net iets anders moet, dat gaat niet werken
(heb ik zelf ook ervaring mee ;) )

Ik vermoed, dat, zodra je het hebt uitgeschreven je wellicht
mijn vraag
Kunnen die dopsleutels ook nog in meerdere categorieën voorkomen?
Of alleen maar in de categorie "Sleutels"?
anders gaat beantwoorden.

Nog één ander ding:
dopsleutels --> 1/2

Kan dat niet één categorie worden?
Maar dat is wellicht te ver doorgedacht

Acties:
  • 0 Henk 'm!

Verwijderd

Hey, zelf had ik ook dit probleem. Op wikipedia staat er een mooi stukje over Pre-order Tree Traversal (zoals Pin0 zei). Er staat pseudo-code, en die zou je in ieder geval moeten helpen om je menu te maken. (klikkie)

Hier is mijn stukje PHP code om een array op te vullen met alle menu-items in de juiste volgorde:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    Function Pre_order_traversal($root,$lang,$pin)
    {
        // info: http://en.wikipedia.org/wiki/Pre-order_traversal
        $root = new Node($root);
        $arrNodes = Array();
        array_push($arrNodes,$root);
        if ($root->HasChildren())
        {
            array_push($arrNodes,"-");
            $children = $root->ChildNodes($root->getId(),$lang,$pin);
            foreach ($children as $child)
            {
                $arrNodes = array_merge($arrNodes,Pre_order_traversal($child->getId(),$lang,$pin));
            }
            array_push($arrNodes,"+");
        }
        return $arrNodes;
    }


Had zelf enkele klasses geschreven in PHP voor andere pagina's, en heb daar dan functionaliteit aan toegevoegd zoals de "HasChildren()" functie en "ChildNodes()" functie om snel te controleren of een bepaalde categorie nog subcategoriën heeft. Zo werkt alles dynamisch. Normaal zou die Pre_order_traversal functie snel om te bouwen moeten zijn naar iets wat werkt voor jou.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

offtopic:
Onze forumsoftware is prima in staat te bepalen waar regels behoren te eindigen, dus laat die enters in je post in het vervolg maar weg hoor. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 04-09 08:16

OkkE

CSS influencer :+

Verwijderd schreef op donderdag 09 november 2006 @ 15:09:
Het gaat zo zowiezo niet werken :(

Ik moet namelijk bijvoorbeeld dit hebben: Gereedschap --> sleutels --> dopsleutels --> 1/2 --> groot.

Het probleem is dus, dat 1/2 dus meer voorkomt in de database bij een product.
Nu moet ik dus gaan werken met 2,6,3,8 en dat exploden waarschijnlijk..

't Gaat allemaal niet van een lije dakje :/
Maakt toch niet uit dat "1/2" een aantal keer voor komt? Het lijkt mij, dat als iemand in het menu wat jij hier boven post, op "1/2" klikt, dat dat alleen de items van "Sleutels > Dopsleutels > 1/2" in beeld komen. En niet de 1/2 van Hamers.

Er hoeft dus niets ge-explodeerd te worden. Anders misschien eens verder zoeken naar Breadcrumb's, want dat is zoals zo'n lijstje/menu-tje heet. :)

-- edit --

@cavey: Als ik kijk naar TS zijn laatste reactie, dan geeft hij het volgende voorbeeld:
T-Xorcist schreef op donderdag 09 november 2006 @ 15:09:
Ik moet namelijk bijvoorbeeld dit hebben:
Gereedschap --> sleutels --> dopsleutels --> 1/2 --> groot.
Dat lijkt mij meer op breadcrumb's als op een normaal menu. :)

[ Voor 14% gewijzigd door OkkE op 09-11-2006 16:27 ]

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


Acties:
  • 0 Henk 'm!

  • cavey
  • Registratie: Augustus 2000
  • Laatst online: 29-05 01:29
breadcrumbs is toch meer om bij te houden waar je op "dit" moment zit in je website... ?

Nuja kan me vergissen.

@Erkens: hmmmmmmmm, daar heb je wel een punt ja, van search engine friendliness die dan ver te zoeken is :)

Nogmaals @T-Xorcist: schrijf eens uit op papier hoe je menu structuur moet werken, nesting, dieptes, openklappen etc. Leg je databasemodel er naast, bedenk eens wat je allemaal nodig hebt aan functionaliteit, en bedenk dan ook eens hoe hard je je databasemodel moet ombouwen (kolom erbij, extra (koppel)tabellen etc) om de gewenste functionaliteit te kunnen faciliteren.

Neem vervolgens de hier genoemde algoritmes/patterns (bread crumbs, pre_order tree traversal) en nog een zooi datastructuren ter hand en harte...... en formuleer dan een plan hoe je alles aan elkaar knoopt. Het is een hoop papierwerk en nadenkwerk in het begin, je zal het vast niet waarderen "wtf, papierwerk, nadenken, ik wil meteen programmeren! Hup snel resultaat, tralalala", en ik kom nu vast belerend over, maar eh, een goede voorbereiding is het halve werk ;)

Als je weet wat je hebt, waar je heen wilt, wat je kan gebruiken en wat je ook zelf kan, dan is het ontwikkelen van je menu vele malen makkelijker dan zoals iemand anders ook al riep "halfbakken scripts ombouwen en bijschaven net zo lang tot het een beetje werkt om tot de conclusie te komen dat het toch niet helemaal doet wat je wilt en je zit met een $ding in je maag. Net de IKEA waarbij je niet weet wat je met het laatste schroefje moet doen...... die nou net zo belangerijk is omdat zonder dat schroefje je hele applicatie zo wankel is als ik weet niet wat" ;)

Acties:
  • 0 Henk 'm!

  • Wim-Bart
  • Registratie: Mei 2004
  • Laatst online: 10-01-2021

Wim-Bart

Zie signature voor een baan.

Een hoop oplossingen allemaal maar is het niet gewoon simpeler om met een tabel, div's en id's te werken, des noods met ul/li?

Zelf heb ik altijd gewoon een simpele tabel:
code:
1
2
3
veld 1: menu_id, integer, not null, uniqe
veld 2: menu_parent, integer, not null
veld 3: menu_text, varchar(128), not null


menu_id = Uniek nummer en bepaald de volgorde, 1= eerste, 2= 2e, 3= 3e etc
menu_parent = Verwijzing naar de parent, bij hoofdmenu items is dit altijd 0
menu_text = De tekst van het menu

Een voorbeeld van een menu is bijvoorbeeld:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
menu_id menu_parent menu_text
======= =========== ================================
1       0           Het bedrijf
2       0           Producten
3       0           Diensten
11      1           Ons bedrijf
12      1           Onze visie
21      2           Logistiek
22      2           Kantoor
31      3           Onderhoud
32      3           Leasing en financiering
211     21          Klein vervoer
212     21          Groot vervoer
221     22          Meubelen
222     22          Verbruiksartikelen
2111    211         Vrachtwagens <= 10 ton
2112    211         Vrachtwagens > 10 ton
etc.
etc.


Selectie uit de tabel gebeurd altijd heel simpel:
SQL:
1
SELECT * FROM `menu` ORDER BY `menu_id`, `menu_parent`;


Vanuit PHP lees ik de de tabel altijd in één keer uit en dump hem op het scherm met de juiste code erom heen.

[ Voor 27% gewijzigd door Wim-Bart op 09-11-2006 16:50 ]

Beheerders, Consultants, Servicedesk medewerkers. We zoeken het allemaal. Stuur mij een PM voor meer info of kijk hier De mooiste ICT'er van Nederland.


Acties:
  • 0 Henk 'm!

  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 04-09 08:16

OkkE

CSS influencer :+

Wim-Bart schreef op donderdag 09 november 2006 @ 16:42:
menu_id = Uniek nummer en bepaald de volgorde, 1= eerste, 2= 2e, 3= 3e etc
menu_parent = Verwijzing naar de parent, bij hoofdmenu items is dit altijd 0
menu_text = De tekst van het menu

Een voorbeeld van een menu is bijvoorbeeld:
code:
1
2
3
4
5
6
7
8
9
10
menu_id menu_parent menu_text
======= =========== ================================
1       0           Het bedrijf
2       0           Producten
3       0           Diensten
11      1           Ons bedrijf
12      1           Onze visie
21      2           Logistiek
22      2           Kantoor
[...]
Ik zou echt nooit mijn ID gebruiken voor iets anders als alléén interne identificatie.

Wat gebeurd er als je "Onze visie" nu boven "Ons bedrijf" wilt hebben? Juist, dan moet je je menu_id aanpassen. En als je iets niet wil, is het wel je unieke veld aanpassen. :)

Gewoon auto_nummering op je PrimaryKey (menu_id) zetten, en daarnaast een veld met de Volgorde (menu_order).

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


Acties:
  • 0 Henk 'm!

Verwijderd

Pin0 schreef op donderdag 09 november 2006 @ 10:35:
http://www.sitepoint.com/article/hierarchical-data-database

Vooral de Modified Preorder Tree Traversal vind ik een mooie oplossing...
Ik ben het met je eens dat dit een mooie oplossing is. Ik heb nog enkele vragen/stellingen m.b.t. deze oplossing die misschien een beetje off-topic zijn maar toch ook wel interessant zijn voor de TS.


Stel je maakt gebruik van een Modified Preorder Tree Traversal algoritme dan kan je op een eenvoudige manier de onderliggende deelboom vanuit een willekeurig node selecteren. Bij een dergelijke selectie heb je echter altijd de gehele deelboom te pakken. Het lijkt me echter ook makkelijk om maar een deel van de onderliggende deelboom te selecteren (met een bepaalde diepte). Je wilt bijvoorbeeld in je menu maar twee niveau's laten zien om het geheel overzichtelijk te houden.

Valt er in dat geval iets voor te zeggen om je tabel uit te breiden met een extra kolom welke de diepte van een node representeert.


En verder...

Het invoegen van nieuwe nodes is verre van efficient aangezien de mogelijkheid bestaat dat de halve boom (of meer) moet worden geupdate. Mocht een boom met enige regelmaat wijzigen dan is het algoritme wellicht een stuk minder interessant om te gebruiken.
Zijn er oplossingen voor dit probleem waarbij de voordelen (weinig queries) van dit algoritme behouden blijven?

Acties:
  • 0 Henk 'm!

  • B-Man
  • Registratie: Februari 2000
  • Niet online
djinglez: de plaatsen waar ik MPTT toepas, daar werk ik altijd met een extra kolom die de depth bijhoud. Aangezien het sowieso geen algoritme is voor write-intensive omgevinging is die extra kolom niet zo'n issue.

Verder heb ik net even gezocht, want ik heb al een aantal maal tijd besteed aan zoeken naar efficiente algoritmen voor het opslaan van boomstructuren.
Je hebt natuurlijk het materialized path (pas ik ook wel eens toe), al is dat 'ranzig' wat betreft normalisatie. Verder is dat wel een redelijk efficiente methode als je enkel nodes toevoegt, en niet gaat schuiven met nodes binnen de boom, dan moet namelijk voor alle onderliggende nodes het materialized path opnieuw 'berekend' worden.

Verder heb ik eerder eens twee andere manieren beschreven gezien, maar die waren behoorlijk complex. Een ervan staat hier

Acties:
  • 0 Henk 'm!

Verwijderd

B-Man schreef op vrijdag 10 november 2006 @ 16:09:
djinglez: de plaatsen waar ik MPTT toepas, daar werk ik altijd met een extra kolom die de depth bijhoud. Aangezien het sowieso geen algoritme is voor write-intensive omgevinging is die extra kolom niet zo'n issue.

Verder heb ik net even gezocht, want ik heb al een aantal maal tijd besteed aan zoeken naar efficiente algoritmen voor het opslaan van boomstructuren.
Je hebt natuurlijk het materialized path (pas ik ook wel eens toe), al is dat 'ranzig' wat betreft normalisatie. Verder is dat wel een redelijk efficiente methode als je enkel nodes toevoegt, en niet gaat schuiven met nodes binnen de boom, dan moet namelijk voor alle onderliggende nodes het materialized path opnieuw 'berekend' worden.

Verder heb ik eerder eens twee andere manieren beschreven gezien, maar die waren behoorlijk complex. Een ervan staat hier
Dank je B-Man, de laatste link is inderdaad erg interessant en ik ga dit artikel morgen eens rustig doorlezen. Ik heb zojuist het eerte stuk gelezen en volgens mij lijkt het op hetgeen ik zelf ook in gedachte had, dus morgen eens doorlezen :) Dank u _/-\o_

Verder ben ik het met je eens dat de 'materialized path'-oplossing wat ranzig is :) In het geval zoals hierboven beschreven misschien goed bruikbaar maar het zou voor mij niet de eerste keus zijn.
Pagina: 1