[PHP/MYSQL] Menu building

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • JefSnare
  • Registratie: Augustus 2007
  • Laatst online: 09-11-2020
Geachte tweakers,

Al een tijdje ben ik van plan in mijn huidige cms een menu building optie te maken waardoor het menu makkelijker aan te passen wordt via de database en via het adminpaneel. Het cms bestaat al in de vorm van PHP <-> MySQL. Verschillende dingen zoals artikelen worden uit de database gehaald en nu wil ik het menu ook volledig in de database hebben en deze kunnen aanpassen.

Ik ben nog in de stap van het ontwerp, vandaar de keuze dit topic in SEA te plaatsen. Er is wel code maar ik wil het vanaf de grond af doen zodat vrienden/collega's ook makkelijk kunnen inzien hoe dit werkt.

Het ontwerp
Ik wil een menu die uit de database de volgorde en eventuele subitem. Dit heb ik vertaald naar de volgende structuur (tabel)

code:
1
2
3
4
5
menu_id
item_naam
item_link
item_sub_from
item_rang


In combinatie met volgend PSD'tje worden de items opgehaald en neergezet.

code:
1
2
3
4
connectie met DB -> haal array van items
ophalen van gegevens per menu item
neerzetten hoofditems en eventuele subitems bij het hoofditem
connectie sluiten


Nu is mijn vraag of deze manier van denken een goede manier is en deze manier eigenlijk wel gaat werken? Misschien dat er feedback is of iets dergelijks zodat ik nog even dat stapje verder kan gaan, denk aan normalisatie, ERD of UML maken, PSD specifieker uitwerken? Ik ga het zelf scripten, ikzelf heb dus wel een idee hoe het moet maar wil het proces meer vastleggen van hoe of wat er gebeurt.

alvast bedankt _/-\o_

Twitter Flickr


Acties:
  • 0 Henk 'm!

  • jbdeiman
  • Registratie: September 2008
  • Laatst online: 16-09 07:11
@JefSnare
Op zich is je database opbouw helemaal niet zo verkeerd. Je kan op deze manier prima je menu opbouwen. Echter zoals je het nu schetst haal je de hoofdmenu items op en daarbij de submenu-items. => Wat nu als je menu structuur dieper wordt dan 2 lagen (dus je kan ook weer een subitem onder het submenu hangen)

Toon je die dan gewoon niet in het menu? Op zich zie ik er verder geen rare dingen in, behalve dat je na het ophalen van je menu de verbinding wil sluiten. Als je na het menu nog meer op moet halen is het gemakkelijker om steeds gebruik te maken van dezelfde verbinding en deze pas aan het einde van de pagina (nadat alles uit de database is gehaald) weer te sluiten.

offtopic:
Ik moest eerst even kijken wat een PSD was, kende het zelf alleen als PhotoShop Doc. Voor andere tweakerts die ditzelfde hebben, het is een ProgrammaStructuur-Diagram.

Acties:
  • 0 Henk 'm!

  • japaveh
  • Registratie: Maart 2003
  • Laatst online: 15-09 17:43

japaveh

Jield BV

Wellicht kun je hier nog relevante info uit halen.
Crisp's blog: Formatting a multi-level menu using only one query

Solo Database: Online electronic logbook and database system for research applications


Acties:
  • 0 Henk 'm!

  • JefSnare
  • Registratie: Augustus 2007
  • Laatst online: 09-11-2020
jbdeiman schreef op dinsdag 08 december 2009 @ 09:46:

offtopic:
Ik moest eerst even kijken wat een PSD was, kende het zelf alleen als PhotoShop Doc. Voor andere tweakerts die ditzelfde hebben, het is een ProgrammaStructuur-Diagram.
offtopic:
Ik had het wel even moeten vermelden inderdaad


Maar de gedachte over het "dubbele" submenu;

code:
1
2
3
4
5
home   informatie
           algemeen
           televisie
                       sub-sub-item
                       sub-sub-item


had ik nog even niet aan gedacht. In eerste instantie dacht ik aan een menu met enkele sub-menu's. Goeie tip want die ondersteuning zou er wel moeten zijn, dus dan zou er bijvoorbeeld in item_sub_from 1, 3 staan. Waarmee ik doen op 1ste item en 3e subitem, zodat de sub-sub regel hierna komt.

@japaveh:
Hier heb ik zeker wat aan, kan ik zeker even kijken hoe crisp de opbouw heeft uitgevoert.

Edit: Even een testcase opgezet met de code van Crisp, zoals altijd werkt het zoals het moet bij Crisp. Ik ga deze opbouw bestuderen en bekijken hoe Crisp dit heeft gecodeerd zodat ik de PSD kan uitbreiden.

[ Voor 9% gewijzigd door JefSnare op 08-12-2009 11:01 ]

Twitter Flickr


Acties:
  • 0 Henk 'm!

  • jbdeiman
  • Registratie: September 2008
  • Laatst online: 16-09 07:11
Waarom met komma gescheiden waarden opslaan voor sub-subs?

Je kunt een recursieve functie gebruiken, en in jouw voorbeeld kan je "sub-sub-item" gewoon instellen als sub_item_from. , dus daar alleen 4 instellen (als dat het id is van "televisie"). Immers van "televisie" is al bekend dat 2 ('informatie') de parent is van "televisie".

Acties:
  • 0 Henk 'm!

  • frankivo
  • Registratie: Januari 2002
  • Laatst online: 02-06 13:53
voor de vorm zou ik item_sub_from hernoemen naar item_parent
iets meer gangbare term voor hetzelfde :p

iRacing Profiel


Acties:
  • 0 Henk 'm!

  • JefSnare
  • Registratie: Augustus 2007
  • Laatst online: 09-11-2020
frankivo schreef op dinsdag 08 december 2009 @ 12:22:
voor de vorm zou ik item_sub_from hernoemen naar item_parent
iets meer gangbare term voor hetzelfde :p
Zeker een punt om over na te denken, ik kan dan ingewikkelde functies in PHP gaan schrijven maar op het oog van uitbreiding en leesbaarheid is sub_item_from een beter punt. Hieronder nog even de bijgewerkte structuur.

code:
1
2
3
4
5
6
menu_id
item_naam
item_link
item_sub_from
sub_item_from
item_rang


@FrankTM:
Jij bedoeld het normaliseren van de titels of namen van de velden zodat je niet sub_item_from benamingen gaat verwarren met sub_item_from.

Dan is dit misschien wel een betere uitwerking;

code:
1
2
3
4
5
6
7
menu_id
item_naam
item_link
item_parent
item_child_from_parent
item_child_from_child
item_rang

Waarbij dus het item_child_form_parent terug naar een parent id koppelt en het item_child_from_child terug koppelt naar een child...Alleen denk ik misschien nu te lastig.

Alleen wat ik terug lees uit je reactie noemde je alleen het hernoemen van item_sub_from naar item_parent. Is de uitwerking hierboven dan niet beter?

EDIT;
PSD technisch gezien is het handiger om een oplossing te hebben waarin weinig speciaals moet gebeuren. Het koppelen van id's en terug zoeken is op te lossen met verschillende soorten query (paralized oid) maar hiermee doel ik meer op de structurering van de code.

[ Voor 10% gewijzigd door JefSnare op 08-12-2009 14:05 ]

Twitter Flickr


Acties:
  • 0 Henk 'm!

  • BM
  • Registratie: September 2001
  • Laatst online: 16-09 15:23

BM

Moderator Spielerij
Misschien is dit ook wel een interessant topic?
Binaire boom in een database. Beste aanpak?
Moet wel wat gerelateerds uit te halen zijn denk ik :? En zo niet, is het alsnog best interessant :+

Xbox
Even the dark has a silver lining | I'm all you can imagine times infinity, times three


Acties:
  • 0 Henk 'm!

  • sjorsjuhmaniac
  • Registratie: Februari 2009
  • Laatst online: 23:32
JefSnare schreef op dinsdag 08 december 2009 @ 14:02:
[...]


code:
1
2
3
4
5
6
7
menu_id
item_naam
item_link
item_parent
item_child_from_parent
item_child_from_child
item_rang

Waarbij dus het item_child_form_parent terug naar een parent id koppelt en het item_child_from_child terug koppelt naar een child...Alleen denk ik misschien nu te lastig.

Alleen wat ik terug lees uit je reactie noemde je alleen het hernoemen van item_sub_from naar item_parent. Is de uitwerking hierboven dan niet beter?
Ik zou persoonlijk geen directe link met child(s) opslaan, enkel de parent. Wanneer je meerdere childs per item gaat krijgen dan zal je meerdere child-id's erin kwijt moeten.
Doordat je item_rang gebruikt is het ook niet nodig om eventueel de rang af te leiden en dus mijn inziens overbodig of heb je er een directe reden voor?

Misschien is het ook handig een veld toe te voegen waarmee je de volgordes van de (sub)menu's kan beïnvloeden.

Voor uniformiteit zou ik ook alle benamingen in het Nederlands of het Engels zetten, vooral omdat je er dadelijk met meerdere mensen aan gaat werken zo ver ik begrijp uit je startpost

Acties:
  • 0 Henk 'm!

  • JefSnare
  • Registratie: Augustus 2007
  • Laatst online: 09-11-2020
sjorsjuhmaniac schreef op dinsdag 08 december 2009 @ 15:31:
[...]
Ik zou persoonlijk geen directe link met child(s) opslaan, enkel de parent. Wanneer je meerdere childs per item gaat krijgen dan zal je meerdere child-id's erin kwijt moeten.
Doordat je item_rang gebruikt is het ook niet nodig om eventueel de rang af te leiden en dus mijn inziens overbodig of heb je er een directe reden voor?

Misschien is het ook handig een veld toe te voegen waarmee je de volgordes van de (sub)menu's kan beïnvloeden.

Voor uniformiteit zou ik ook alle benamingen in het Nederlands of het Engels zetten, vooral omdat je er dadelijk met meerdere mensen aan gaat werken zo ver ik begrijp uit je startpost
Dat bedoelde ik dus met het opslaan met spaties of komma's in een veld, eigenlijk wil ik dat niet en dit id de maximale structuur.
Bijv.
code:
1
2
3
4
5
(1)home  (1)informatie
            (2)registratie
            (2)TV-Gids
                         (3)informatie
                         (3)registratie

Legenda: 1 = hoofditem, 2 = child_from_parent, 3 = child_from_child

Nederlandse veld-benamingen vindt ik zeker een goed idee, alleen wil ik dit hier in niet gebruiken dan worden sommige definities gewoon te lang en dit moet iedere programmeur / ingenieur wel snappen met als bijlage een PSD.

code:
1
2
3
4
5
6
7
menu_id
item_naam
item_link
item_parent
item_child_from_parent
item_child_from_child
item_rang(*)

* = De rang staat voor de volgorde van de menu items, ieder item krijgt een rangorde mee. Nu schiet mij ineens te binnen dat een andere benaming beter gaat werken, order is een betere definitie van dat veld ;)

code:
1
2
3
4
5
6
7
menu_id
item_naam
item_link
item_parent
item_child_from_parent
item_child_from_child
item_order

Twitter Flickr


Acties:
  • 0 Henk 'm!

  • JefSnare
  • Registratie: Augustus 2007
  • Laatst online: 09-11-2020
BM schreef op dinsdag 08 december 2009 @ 14:41:
Misschien is dit ook wel een interessant topic?
Binaire boom in een database. Beste aanpak?
Moet wel wat gerelateerds uit te halen zijn denk ik :? En zo niet, is het alsnog best interessant :+
Zeker een interessant topic alleen is dat net even een onbepaalde nesting van items, hier is dat gelimiteerd tot 2. Ik ga het zeker even bookmarken ;)

offtopic:
Oeps, een nieuwe post gemaakt, niet de bedoeling :X

[ Voor 6% gewijzigd door JefSnare op 08-12-2009 16:14 ]

Twitter Flickr


Acties:
  • 0 Henk 'm!

  • sjorsjuhmaniac
  • Registratie: Februari 2009
  • Laatst online: 23:32
JefSnare schreef op dinsdag 08 december 2009 @ 16:12:
[...]


Nederlandse veld-benamingen vindt ik zeker een goed idee, alleen wil ik dit hier in niet gebruiken dan worden sommige definities gewoon te lang en dit moet iedere programmeur / ingenieur wel snappen met als bijlage een PSD.
Ik bedoelde uniformiteit; doe het of in het NL of in het EN, nu worden er Nederlandse en Engelse termen door elkaar gebruikt

In je laatste structuur is het overigens alleen item_naam die afwijkt.

Ik zou een dergelijke indeling gebruiken:
code:
1
2
3
4
5
6
menu_id
item_name
item_link
item_parent
item_weight
item_sublevel


item_weight is daarbij een gewichtsfactor waarmee je de volgorde van de menu-items kan bepalen door in je query hierop te sorteren. Meerdere items met dezelfde gewichtsfactor worden dan verder op naam gesorteerd.

item_sublevel is een andere naam voor de item_order. deze lijkt me gepaster omdat met item_order vaak een volgorde in een lijst (op hetzelfde (sub)level) wordt aangeduid.

Acties:
  • 0 Henk 'm!

  • JefSnare
  • Registratie: Augustus 2007
  • Laatst online: 09-11-2020
Ik moest even de twee "ontwerpen" naast elkaar zetten om goed te kijken wat het grote verschil was. Ik zie dat je bedoeld dat ik met een UNION (oid) de resultaten kan sorteren en deze op volgorde kan weergeven.
code:
1
2
3
4
5
6
7
menu_id
item_name
item_link
item_parent
item_child_from_parent
item_child_from_child
item_order

Was inderdaad even vergeten om naam om te vormen naar name...hierboven huidig "ontwerp".

Alleen, als ik een sub-sub-menu heb, hoe ga ik dit vormen met onderstaande structuur? Ik snap je principe met parent, weight (goeie tip trouwens ;)) en het sublevel, maar als ik dus een sub-sub-menu heb hoe ga ik dat wegschrijven?

code:
1
2
3
4
5
6
menu_id
item_name
item_link
item_parent
item_weight
item_sublevel


Om verder te denken, als ik ga programmeren wil ik zover mogelijk de database nuttig maken om de parent, child en child from child relaties te beheren. Zie hieronder een "vernieuwd" ontwerp van het PSD.
code:
1
2
3
4
connectie met DB -> sorteren op parent en sublevel
sorteren van weight op volgorde
neerzetten hoofditems,eventuele subitems en sub-sub-items als parent het hoofditem
connectie sluiten wanneer pagina einde bereikt.


Nu kan stap 2 en 3 samen, bijvoorbeeld door twee query's of door een UNION en AND te gebruiken. Is het in dit geval dan handig om een dubbele/UNION AND query uit te voeren of gewoon in PHP de weight (volgorde) te sorteren. Het is wel fijn om alle gegevens aangeleverd te krijgen van de DB als die al in volgorde zijn, dan wordt de functie op zich overzichtelijker (qua PHP code, die query wordt wel ingewikkeld :P ).

Twitter Flickr


Acties:
  • 0 Henk 'm!

  • Jory
  • Registratie: Mei 2006
  • Laatst online: 16-09 13:37
Hoezo heb je twee queries nodig om de items op volgorde te krijgen? Als je gewoon "ORDER BY `item_weight`" achteraan je query plakt, is alles al gesorteerd. Een UNION is hiervoor echt niet nodig hoor.

Je kunt ook Crisp zijn code pakken. In de ORDER BY clause vervang je dan `name` door `item_weight`. (Crisp sorteerd op alfabed, wat jij dus niet wil.)

Acties:
  • 0 Henk 'm!

  • JefSnare
  • Registratie: Augustus 2007
  • Laatst online: 09-11-2020
Ik zag het inderdaad in Crisps voorbeeld, alleen dacht ik het met deze uitwerking simpeler kunnen doen. Ik bedenk me opeens dat de manier van sorteren zoals Crisp doet eigenlijk overzichtelijker is ;). Nu alleen het "probleem" nog met de sub-sub-menu items, hoe moet ik dat gaan aanpakken? Gewoon een AND erachter hangen?

Niet dat ik het nu nog ga coderen ik wil het namelijk eerst helemaal uitwerken en dan coderen ;)

Twitter Flickr


Acties:
  • 0 Henk 'm!

  • Asator
  • Registratie: December 2009
  • Laatst online: 12-02-2024
Hier heb je nog een link met wat informatie, er staat ook pure SQL oplossing in
http://dev.mysql.com/tech...es/hierarchical-data.html

Waar je nu mee bezig bent is het "The Adjacency List Model", je kan ook kijken naar de "The Nested Set Model" maar die is wel lastiger uit te werken.

  • JefSnare
  • Registratie: Augustus 2007
  • Laatst online: 09-11-2020
@Asartor:
Interessante leesstof, is (gelukkig) veel meer te vinden over "The Adjacency List Model" op het WWW en in diverse boeken hier in de boekenkast. Die SQL oplossing interesseert mij wel, vooral de uitleg op die pagina en de onderbouwing met voorbeelden ;). Thnx ;)

[ Voor 11% gewijzigd door JefSnare op 10-12-2009 08:45 ]

Twitter Flickr


  • jbdeiman
  • Registratie: September 2008
  • Laatst online: 16-09 07:11
@JefSnare
Nog wel even een zeer algemene opmerking over jou aanpak. Je bleef maar vasthouden aan de "child_from_child", omdat je zoals je zelf aangeeft niet dieper te willen dan 2 lagen. Maar wat brengt de toekomst? Ga je dan ook niet dieper dan 2 lagen?

Ik heb zelf ook een scriptje (alleen niet helemaal 100% uitgewerkt, maar hij doet het) waarbij de menu-structuur zoals die zelf op de pagina wordt weergegeven niet dieper kan dan 2 lagen (buiten de hoofdlaag), maar: Ik kan wel pagina's onder een "sub-sub-item" hangen. Deze zijn uit het CMS wel gewoon bereikbaar en er zijn wel links naar toe te maken. De menustructuur moet overzichtelijk blijven voor eenbezoeker. Maar de links moeten ook logische namen hebben en de URL moet logisch zijn opgebouwd. Hiervoor dus de keuze om (zoals je uiteindelijk ook lijkt te gaan doen) met de parent te gaan werken.

Overigens:
De combinatie Weight en ORDER (sublevel), waarom 2 wegingen eraan hangen? 1 zou toch genoeg moeten zijn om de volgorde te bepalen?

  • sjorsjuhmaniac
  • Registratie: Februari 2009
  • Laatst online: 23:32
JefSnare schreef op woensdag 09 december 2009 @ 15:41:
Alleen, als ik een sub-sub-menu heb, hoe ga ik dit vormen met onderstaande structuur? Ik snap je principe met parent, weight (goeie tip trouwens ;)) en het sublevel, maar als ik dus een sub-sub-menu heb hoe ga ik dat wegschrijven?

code:
1
2
3
4
5
6
menu_id
item_name
item_link
item_parent
item_weight
item_sublevel
Even je eigen vb erbij pakken:
code:
1
2
3
4
5
home   informatie
           algemeen
           televisie
                       sub-sub-item (zenders)
                       sub-sub-item (aanbieders)


home:
code:
1
2
3
4
5
6
"1"
"home"
"www.mijnhomepage.nl/leukelink.php"
"0"  //geen parent
"1" //zo hoog mogelijk, eventueel kan je in je code inbakken dat items met negatieve weight 'sticky' zijn
"0"


info:
code:
1
2
3
4
5
6
"2" //id
"info"
"www.mijnhomepage.nl/info.php"
"0"  //geen parent
"2" //net niet als eerste zetten
"0"


tv:
code:
1
2
3
4
5
6
"3" //id
"televisie"
"www.mijnhomepage.nl/tv.php"
"2"  //info is parent 
"9" //als 9e zetten, dus dat is hier gewoon als laatste als je er maar 2 hebt
"1"  //sublevel


zenders:
code:
1
2
3
4
5
6
"4" //id
"zenders"
"www.mijnhomepage.nl/tv.php?zender=f"
"3"  //tv is parent 
"-1" //als 1e zetten; voor altijd
"2"  //sublevel


aanbieders:
code:
1
2
3
4
5
6
"5" //id
"aanbierders"
"www.mijnhomepage.nl/tv.php?aanbieder=k"
"3"  //tv is parent 
"1" //als 1e zetten; maar dit gaat 'zenders'  winnen door de -1
"2"  //sublevel


en dit alles in een query opvragen + sorteren
SQL:
1
2
3
4
SELECT m.*
  FROM menu AS m
  WHERE m.published = 1
  ORDER BY m.sublevel, m.parent, m.weight


en daarna, net als Crisp doet, in een functie met enkele arrays en loops gebruiken om je hiërarchie te bouwen. Je hebt dus inderdaad geen union nodig, hoogstens een join als je wat gebruikerspecifieke data op wil slaan oid.
jbdeiman schreef op donderdag 10 december 2009 @ 09:13:

Overigens:
De combinatie Weight en ORDER (sublevel), waarom 2 wegingen eraan hangen? 1 zou toch genoeg moeten zijn om de volgorde te bepalen?
weight en sublevel zijn twee verschillende dingen.

weight: een zogenoemde gewichtsfactor waarmee je volgordes in je menu kunt maken (buiten die op alfabet, die met een standard sort query kan maken). zo kan je in dat specifieke level het menu een plaats toekennen bv de 1e link die een user ziet, of de 8e of als laatste in het lijstje; maar dit kan dus de hoofdmenu-lijst zijn of die van een submenu.

sublevel: geeft enkel aan in welke sublaag van het menu zich bevind. in de sublaag kan het dus de eerste maar ook de 8e of de laatste link zijn die zichtbaar is.

Acties:
  • 0 Henk 'm!

  • JefSnare
  • Registratie: Augustus 2007
  • Laatst online: 09-11-2020
@^^ Bedankt voor je toelichting, ik begin het helemaal te snappen. Ik ga mij nog even verdiepen in de link die Asartor gaf ;)

Verder moet ik mij even verder gaan verdiepen in het bouwen en produceren van een tree in MySQL. Het programmeren is van later zorg, zodra het namelijk op papier staat en goed op papier dan weet elke programmeur ermee op te gaan en kan ik het gaan ontwikkelen ;)

Twitter Flickr


Acties:
  • 0 Henk 'm!

Verwijderd

In je sql roep je steeds recursief de children aan van degene die je gevonden hebt. Het recursielevel is je level, dus dat hoef je niet in je record op te nemen. Je eerste aanroep is het eerste child van "parent" 0.

  • Taenadar
  • Registratie: Januari 2004
  • Laatst online: 21:25
Waarom geef je eigenlijk item_sublevel aan? Als je een pagina aanroept obv van ID kan je daarna toch gewoon het parent vinden? En vervolgens controleren of deze een parentID heeft, als deze een parent heeft ga opnieuw en anders heb je het bovenste niveau gevonden.
Pagina: 1