[PHP] sitemap op basis van een multidimensionale array

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik ben, zoals zovelen, een eigen light-weight CMS aan het schrijven.
Eén van de dingen die ik wil bereiken is een automatische sitemap.
Ik ben er al in gelukt om automatisch een multidimensionale array op te bouwen.
Hieronder staat een voorbeeld array: een klein beetje uitleg.

Op het eerste niveau staan 1_startpagina, 2_diensten, 3_pc-onderhoud, h_foo.php
Onder 2_diensten staat een extra navigatieniveau: 1_test.php, 1_website, 2_blah.php, 2_netwerk.
Onder 2_diensten/2_netwerk staat nog een extra niveau: 1_nieuwe-map, 2_nieuwere-map, 3_nieuwste-map.

Op basis van deze mulitdimenisonale array zou ik dus een sitemap willen maken met ul - li

code:
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
Array
(
    [0] => 1_startpagina
    [1] => 2_diensten
    [2] => Array
        (
            [0] => 1_test.php
            [1] => 1_website
            [2] => 2_blah.php
            [3] => 2_netwerk
            [4] => Array
                (
                    [0] => 1_nieuwe-map
                    [1] => 2_nieuwere-map
                    [2] => 3_nieuwste-map
                )

            [5] => 3_pc-onderhoud
            [6] => Array
                (
                    [0] => 1_nieuwe-map
                    [1] => 2_nieuwere-map
                    [2] => 3_nieuwste-map
                )

            [7] => h_foo.php
        )


Mijn php-code ziet er als volgt uit:
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
$this->Sitemap($array);

   function Sitemap($input, $count = 0) {

      if($count == 0)
         {
            print "<ul>\n";
         }

      foreach($input as $value)
         {
            if(is_array($value))
               {
                  print "\n<ul>\n";

                  $count++;

                  $this->sSitemap($value, $count);
               }
            else
               {
                  print "\t<li>$value</li>\n";
               }
         }
      print "</ul>\n";

      if($count == 1)
         {
            print "\t</li>\n";
         }
   }


Deze code zorgt ervoor dat mijn sitemap bijna volledig afgedrukt wordt:

code:
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
<ul>
    <li>1_startpagina</li>
    <li>2_diensten</li>

<ul>
    <li>1_test.php</li>
    <li>1_website</li>
    <li>2_blah.php</li>
    <li>2_netwerk</li>

<ul>
    <li>1_nieuwe-map</li>
    <li>2_nieuwere-map</li>

    <li>3_nieuwste-map</li>
</ul>
    <li>3_pc-onderhoud</li>

<ul>
    <li>1_nieuwe-map</li>
    <li>2_nieuwere-map</li>
    <li>3_nieuwste-map</li>

</ul>
    <li>h_foo.php</li>
</ul>
    <li>3_producten</li>

<ul>
    <li>1_nieuwe-map</li>
    <li>2_nieuwere-map</li>
    <li>3_nieuwste-map</li>

</ul>
    <li>4_contactgegevens</li>
    <li>5_sitemap</li>
</ul>


Het probleem is echter dat ik er maar niet in slaag om een subniveau van de juiste html code te voorzien. Er staat:
code:
1
2
3
4
5
6
7
8
9
<ul>
    <li>1_startpagina</li>
    <li>2_diensten</li>

        <ul>
            <li>1_test.php</li>
            <li>1_website</li>
            <li>2_blah.php</li>
            <li>2_netwerk</li>

maar dat zou dus het onderstaande moeten zijn:
code:
1
2
3
4
5
6
7
8
9
10
11
12
<ul>
    <li>1_startpagina</li>
    <li>2_diensten

        <ul>
            <li>1_test.php</li>
            <li>1_website</li>
            <li>2_blah.php</li>
            <li>2_netwerk</li>
        </ul>
    </li>
...


Na verschillende dagen van debuggen en vloeken, had ik graag gebruik gemaakt van jullie enorme kennis.

[ Voor 1% gewijzigd door Verwijderd op 21-07-2007 11:25 . Reden: Te snel op versturen geduwd :) ]


Acties:
  • 0 Henk 'm!

Verwijderd

   </ul>
</li>


dit zal wel

   </ul>
</ul>


moeten zijn?

[ Voor 33% gewijzigd door Verwijderd op 21-07-2007 11:23 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Was verkeerde indent van mij.
Er moeten nog lijsten achterkomen.
Ik heb de laatste lijst beter ge-indent-ed (bestaat dit woord wel?) om het voorbeeld duidelijker te maken.

Acties:
  • 0 Henk 'm!

  • aOk
  • Registratie: September 2000
  • Niet online

aOk

Zoiets misschien?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
$this->Sitemap($array);

   function Sitemap($input) {
        print "<ul>\n";

      foreach($input as $value)
     {
        if(is_array($value))
       {
          Sitemap($value);
       }
        else
       {
          print "<li>$value</li>\n";
       }
     }
      print "</ul>\n";
   }
?>


Ik zou overigens .. Son of suckerfish willen aanraden:
http://www.htmldog.com/articles/suckerfish/dropdowns/

en dan is de code ietsje anders bij .. sitemap($value); in de buurt.

Verder zou ik je willen aanraden om de multidimensionele array aan te passen en per niveau een omschrijving en een subniveau te gebruiken.

Dus dat er een omschrijving direct bij een subniveau hoort.

[ Voor 38% gewijzigd door een moderator op 21-07-2007 12:34 . Reden: Code-tags ]


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Ik vind je multidimensionale array wat onhandig ogen, waarom maak je er niet zoiets van:

code:
1
2
3
4
5
6
7
array(
  0 => array('page' => 'startpagina'
           'subpages' => array(
                  0 => array('page' => 'a_subpage', 'subpages' => null),
                  1 => array('page' => 'another_subpage', 'subpages' => array(...))
            )
  );


Dat kan je vrij eenvoudig recursief uitlezen en aangezien de html die je moet genereren toch ook recursief is moet dat niet te moeilijk zijn.

[ Voor 4% gewijzigd door ACM op 21-07-2007 11:41 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@ aOK

Dit had ik ook al bedacht.
Het probleem is echter dat deze code niet valideert.

code:
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
<ul>
    <li>1_startpagina</li>
    <li>2_diensten</li>
        <ul>
            <li>1_test.php</li>
            <li>1_website</li>
            <li>2_blah.php</li>
            <li>2_netwerk</li>
                <ul>
                    <li>1_nieuwe-map</li>
                    <li>2_nieuwere-map</li>
                    <li>3_nieuwste-map</li>
                </ul>
            <li>3_pc-onderhoud</li>
                <ul>
                    <li>1_nieuwe-map</li>
                    <li>2_nieuwere-map</li>
                    <li>3_nieuwste-map</li>
                </ul>
            <li>h_foo.php</li>
        </ul>
    <li>3_producten</li>
        <ul>
            <li>1_nieuwe-map</li>
            <li>2_nieuwere-map</li>
            <li>3_nieuwste-map</li>
        </ul>
    <li>4_contactgegevens</li>
    <li>5_sitemap</li>
</ul>


Volgens de voorschriften is de enige juiste manier om een tweede niveau in een ul te brengen.
Je mag je <li> niet afsluiten als je een niveau lager gaat. Je tweede <ul> begint binnen de <li>
code:
1
2
3
4
5
6
7
8
<ul>
    <li>tekst</li>
    <li>tekst
        <ul>
            <li>tekst</li>
        </u>
    </li>
</ul>


En laat ik nu net te lomp zijn om daar in te slagen :)

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Met zo'n recursieve structuur kan je eerst de naam van de huidige pagina + een li printen en dan kijken of er subpages zijn.
Zoja, dan print je eerst recursief de subpages en sluit je dan pas de li af... Ik zie het probleem niet?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik ben nog maar een kleine vis hoor, maar wat win ik ermeer om mijn array op die manier op te bouwen?

<< echte newbie vraag :)

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Verwijderd schreef op zaterdag 21 juli 2007 @ 11:43:
Ik ben nog maar een kleine vis hoor, maar wat win ik ermeer om mijn array op die manier op te bouwen?
Nou... de arraystructuur op zich boeit niet zo, zolang je maar kan checken of er subpages zijn voor je je li-element afsluit... En met mijn structuur is dat aanzienlijk makkelijker dan met de jouwe.

Acties:
  • 0 Henk 'm!

  • aOk
  • Registratie: September 2000
  • Niet online

aOk

Als je de array zo aanpast als ACM en ik adviseren dan kun je het alsvolgt wel goed doen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
function Sitemap($arrInput) {
    strOutput = "<ul>\n";
    foreach($input as $value)
    {
        strOutput .= "<li>".$value['page'];
        if(is_array($value['subpages']))
        {       
            strOutput .= "\n".Sitemap($value['subpages']);
        }
        strOutput .= "</li>\n";
    }
    strOutput .= "</ul>\n";
    return strOuput;
}
echo Sitemap($array);
?>

[ Voor 29% gewijzigd door aOk op 21-07-2007 11:58 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
ik ga dan even mijn hoofd breken om die nieuwe array op te bouwen :)

Alvast bedankt...

[ Voor 5% gewijzigd door Verwijderd op 21-07-2007 11:51 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bedankt voor de uitstekende hulp.
Ik wil jullie de code niet onthouden. Je weet nooit dat iemand anders er iets mee kan.

PHP:
1
2
3
4
5
   function sitemap() {
      $array = $this->directoryToArray(FILES);
      $sitemap =  $this->sSitemap($array);
      echo $sitemap;
  }

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
   function directoryToArray($directory, $filter=FALSE) {
      if(substr($directory,-1) == '/')
         {
            $directory = substr($directory,0,-1);
         }

      if(!file_exists($directory) || !is_dir($directory))
         {
            return(FALSE);
         }
      elseif(is_readable($directory))
         {
            $directory_list = opendir($directory);
            while($file = readdir($directory_list))
               {
                  if(!ereg("^\.{1,2}", $file) && $file != INDEX)
                     {
                        $path = $directory.'/'.$file;
                        if(is_readable($path))
                           {
                              $subdirectories = explode('/',$path);
                              if(is_dir($path))
                                 {
                                    $directory_tree[] = array(
                                       'name'      => end($subdirectories),
                                        'content'   => $this->directoryToArray($path, $filter));
                                 }
                              elseif(is_file($path))
                                 {
                                    $extension = end(explode('.',end($subdirectories)));
                                    if($filter === FALSE || $filter == $extension)
                                       {
                                          $directory_tree[] = array('name'      => end($subdirectories));
                                       }
                                 }
                           }
                     }
               }
            closedir($directory_list); 
            return($directory_tree);
         }
      else
         {
            return(FALSE);  
         }
   }

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
   function sSitemap($input) {
      $return = "<ul>\n";
      foreach($input as $value)
         {
            $return  = $return."\t<li>".$value['name'];
            if(is_array($value['content']))
               {
                  $return  =  $return.$this->sSitemap($value['content']);
               }
            $return  =  $return."</li>\n";
         }
    $return = $return."</ul>\n";
    return($return);
   }
Pagina: 1