Ideal data structure for nested list format?

T

Tuxedo

In trying to construct a nested html list with perl I have some questions
what the ideal data structure may be for the specific purpose.

The menu is generated on the fly for each page request. The script lives in
a perl file named menu.pl and the current page that is accessed is known to
the script via a server environment variable accessible in a $current_page
perl variable. The html parts are imported onto individual html pages
through SSI (includes) and all pages are placed at a root level, so there
are no sub-directories or chances of any pages having a same name.

This is a simplified html output of the menu in an unordered list format:

<ul>
<li><a href=1.1.html>Level 1.1</a>
<ul>
<li><a href=2.1.html>Level 2.1</a></li>
<li><a href=2.2.html>Level 2.2</a>
<ul>
<li><a href=3.1.html>Level 3.1</a></li>
<li><a href=3.2.html>Level 3.2</a></li>
</ul>
</li>
<li><a href=2.3.html>Level 2.3</a></li>
</ul>
</li>
</ul>

So there are three levels and the first two levels have nested lists
within. If for example page 3.2.html is accessed, the script should write
out that <li> entry *without* the enclosing <a href=3.2.html>..</a> parts,
as well as add a css-class to that one list item: <li class=current_page>.

The script should know its nearest parent <li> item, so in case of
accessing page 3.2.html, that would be the <li> with the 2.2.html link.
This entry should then have have the css-class: <li class=parent_level_2>.

Additionally, the second nearest parent should be given another css-class,
such as <li class=parent_level_1> (so it may be styled differently).

If the current page is one that does not exist in the menu, although the
menu has been imported on such a page, then no special classes or non-link
formatting is needed for any of the array entries. The html output would
just appear exactly as the above example.

Without the actual link names, I guess the list may be constructed with a
LoL or an AoA, such as:

my @AoA = ('1.1.html',
['2.1.html',
'2.2.html',
['3.1.html',
'3.2.html'],
'2.3.html']);

If so, a parallel AoA's would be needed for the link names to be combined
in a final loop. Or is some other data structure better suited for the
purpose? I.e.: sticking all items together in a nested html list in order
of entry in the perl code, as well as figure out the opening parent <li>
points (if any) in order to apply custom css-classes to relevant <li>'s.

Looking at perldsc, in addition to AoA, alternatives such as HoA, AoH, HoH
as well as some more elaborate data structures exist. I'm not sure what's
best? The maintenance of the link list will involve changing or updating
entries only very occasionally, so it can be done in separate arrays in
case that's better. Anyway, it's not important how, as long as it works...

What is the ideal data structure for the particular hierarchial list
functionality and where the described level specific output can easily be
incorporated?

Many thanks for any advise or general pointers.

Tuxedo
 
T

Tuxedo

Ben Morrow wrote:

[...]

Many thanks for the detailed concept in how to build the particular menu
and list format. I understand it's not entirely ready-to-run code, and so
I'd like to know how your example can generate the final html code. Perhaps
you or someone here can help fill in the missing parts?:

#!/usr/bin/perl -w

use warnings;
use strict;

my @pages = (
{ page => "1.1.html", title => "Level 1.1", children => [
{ page => "2.1.html", title => "Level 2.1" },
{ page => "2.2.html", title => "Level 2.2", children => [
{ page => "3.1.html", title => "Level 3.1" },
{ page => "3.2.html", title => "Level 3.2" },
] },
{ page => "2.3.html", title => "Level 2.3" },
] },
);

# and then build a hash of 'parents', like so

sub populate_parents;
sub populate_parents {
my ($parents, $pages, $parent) = @_;

for (@$pages) {
my $page = $_->{page};
push @{$parents->{$page}}, $parent;
my $kids = $_->{children};
$kids and populate_parents $parents, @$kids, $page;
}
}

my %parents;
populate_parents \%parents, \@pages, undef;

# This will give you a data structure like

%parents = (
"1.1.html" => [undef],
"2.1.html" => [undef, "1.1.html"],
"3.1.html" => [undef, "1.1.html", "2.2.html"],
# ...
);

# Then, given a page name, you can build another hash

my $page = "3.1.html";
my $parents = $parents{$page};
my %class =
map +($parents->[$_] => "parent_level_$_"),
grep defined $parents->[$_],
0..$#$parents;

The above code 'as is' returns the error "Not an ARRAY reference at
../menu.pl line 23", which is on the line beginning with "for (@$pages) ".

If only the arrays and hashes could be generated without error, I can then
try to access and print the entries through some kind of loop construct.
Any additional ideas and code bits would be greatly appreciated!

Thanks again,
Tuxedo
 
U

Uri Guttman

T> Ben Morrow wrote:
T> [...]

T> Many thanks for the detailed concept in how to build the particular menu
T> and list format. I understand it's not entirely ready-to-run code, and so
T> I'd like to know how your example can generate the final html code. Perhaps
T> you or someone here can help fill in the missing parts?:

T> #!/usr/bin/perl -w

T> use warnings;
T> use strict;

T> my @pages = (
T> { page => "1.1.html", title => "Level 1.1", children => [
T> { page => "2.1.html", title => "Level 2.1" },
T> { page => "2.2.html", title => "Level 2.2", children => [
T> { page => "3.1.html", title => "Level 3.1" },
T> { page => "3.2.html", title => "Level 3.2" },
T> ] },
T> { page => "2.3.html", title => "Level 2.3" },
T> ] },
T> );

gack!! use a templater. many to choose from. check out mine called
Template::Simple. you pass it a data structure and template and you get
rendered text. nothing more to it. you can nest structures, templates
and template chunks all you want. lists are automatic too with no extra
markup (a list of elements renders a list of template chunks). all you
need to do is create your html templates (again, they can be included
and nested) and render with one call.

uri
 
T

Tuxedo

Uri Guttman wrote:

[...]
gack!! use a templater. many to choose from. check out mine called
Template::Simple. you pass it a data structure and template and you get
rendered text. nothing more to it. you can nest structures, templates
and template chunks all you want. lists are automatic too with no extra
markup (a list of elements renders a list of template chunks). all you
need to do is create your html templates (again, they can be included
and nested) and render with one call.

uri

Thanks for the tip, I've not tried Template::Simple before so I'm not sure
how it works yet. I need to install and test it as well as delve into the
manual, which looks a little less than simple at first sight...

Can anyone advise me how to generate the following type of nested list by
Template::Simple?

<ul>
<li><a href=1.1.html>Level 1.1</a>
<ul>
<li><a href=2.1.html>Level 2.1</a></li>
<li><a href=2.2.html>Level 2.2</a>
<ul>
<li><a href=3.1.html>Level 3.1</a></li>
<li><a href=3.2.html>Level 3.2</a></li>
</ul>
</li>
<li><a href=2.3.html>Level 2.3</a></li>
</ul>
</li>
</ul>

And is it actually possible to apply the advanced formatting relating to
the $current_page URL along with any parent <li class=bits> if and where
parent entry <li>'s are present? (as detailed in my first post in this
thread). Can all of this be done with the help of Template::Simple?

Many thanks,
Tuxedo
 
U

Uri Guttman

T> Thanks for the tip, I've not tried Template::Simple before so I'm
T> not sure how it works yet. I need to install and test it as well as
T> delve into the manual, which looks a little less than simple at
T> first sight...

it has 4 markups. 150 lines of total code. simple is as simple codes!

the docs are fairly clear (as clear as i can write them!). can you ask
specific questions?

T> Can anyone advise me how to generate the following type of nested list by
T> Template::Simple?

T> <ul>
T> <li><a href=1.1.html>Level 1.1</a>
T> <ul>
T> <li><a href=2.1.html>Level 2.1</a></li>
T> <li><a href=2.2.html>Level 2.2</a>
T> <ul>
T> <li><a href=3.1.html>Level 3.1</a></li>
T> <li><a href=3.2.html>Level 3.2</a></li>
T> </ul>
T> </li>
T> <li><a href=2.3.html>Level 2.3</a></li>
T> </ul>
T> </li>
T> </ul>

not much different than with any other templater. first break it up into
'chunks' as i call them. each ul/li level and possibly each data row
would be a chunk. a template chunk maps to a perl hash. lists are just
generated by passing an array of hashes instead of a single hash. note
that you can skip a chunk by not stuffing it or passing an empty hash to
it. that is how you do conditionals

so the inner levels would be something like this (VERY untested as i am
typing on the fly):

[% START unordered %]
<ul>
[% START link_line %]
<li><a href=[%level%].html>Level [%level%]</a></li>
[% END link_line %]
</ul>
[% END unordered %]

that is the basic template. recursion to make any depth is not directly
supported but you can fake it easily with a code ref in the data or
doing subtemplates yourself.

save that in a file and you can apply data to it and render it. if you
break up your data with code refs at different levels, each code ref can
render its level using the same template. a little more complex but
doable. the code refs are best if they are closures. they get passed the
template and they should have their data as closure args. i am not going
to teach that now.

so the basic data would look like this for the inner levels:

{
unordered => {
link_line => [
{ level => '3.1' },
{ level => '3.2' },
]
}
}


as you can see the data matches the tree shape of the template. when i
get some time i may show how to do deeper recursion with closures. just
not tonight.

T> And is it actually possible to apply the advanced formatting relating to
T> the $current_page URL along with any parent <li class=bits> if and where
T> parent entry <li>'s are present? (as detailed in my first post in this
T> thread). Can all of this be done with the help of Template::Simple?

didn't follow that so i can't help.

uri
 
P

Peter J. Holzer

T> Ben Morrow wrote:
T> [...]

T> Many thanks for the detailed concept in how to build the particular menu
T> and list format. I understand it's not entirely ready-to-run code, and so
T> I'd like to know how your example can generate the final html code. Perhaps
T> you or someone here can help fill in the missing parts?:

T> #!/usr/bin/perl -w

T> use warnings;
T> use strict;

T> my @pages = (
T> { page => "1.1.html", title => "Level 1.1", children => [
T> { page => "2.1.html", title => "Level 2.1" },
T> { page => "2.2.html", title => "Level 2.2", children => [
T> { page => "3.1.html", title => "Level 3.1" },
T> { page => "3.2.html", title => "Level 3.2" },
T> ] },
T> { page => "2.3.html", title => "Level 2.3" },
T> ] },
T> );

gack!! use a templater.

With a templater you still need to represent the data you want to render
with the templater. I don't see how you could represent a tree, where
each node contains a link to a page and a title, much differently in
perl than Ben showed above (I am assuming that "page" and "title" aren't
as redundant as the seem to be in the example. Instead of "Level 1.1"
the title would probably be something like "1.1 - Introduction" in the
real world).
many to choose from. check out mine called Template::Simple. you pass
it a data structure

Yup. But you have to have the data structure first. That's what you
quoted above.

hp
 
T

Tuxedo

Ben Morrow wrote:

[...]
That would be because I'm an idiot, and was typing in the code without
testing it, and made an elementary mistake. However, I'm going to leave
it to you to find it, because you need to understand the code at least
that well before you use it. (I'll give you a hint: $pages isn't an
array reference, and it ought to be.)

Ben

Thank for the hint. Anyway, why should you test the code? After all, you've
already offered some most helpful advise along with even purpose written
code. Nobody expects it to work without errors, although it would be nice
if it did. That said, I'm the better runner-up for the idiot title in not
seeing through your code properly. However, once I know it may produce the
relevant list order and particular variable output, I would surely study it
character-by-character until I do know its intricate functionality.

On the line where the error is returned it says @$pages. As far as I
understand an array reference is written \@pages

So I changed @$pages to \@pages as I guess it should be. The same error no
longer occurs but instead there are some other errors:

tuxedo:~$ ./menu.pl
Pseudo-hashes are deprecated at ./menu.pl line 24.
Argument "1.1.html" isn't numeric in hash element at ./menu.pl line 24.
Use of uninitialized value in hash element at ./menu.pl line 25.
Pseudo-hashes are deprecated at ./menu.pl line 26.

These are lines 24/25/26 of code :

my $page = $_->{page};
push @{$parents->{$page}}, $parent;
my $kids = $_->{children};

Again, I do not see through these particular errors and so any further
hints from anyone here would be greatly appreciated :)

Tuxedo
 
T

Tuxedo

Uri said:
T> Thanks for the tip, I've not tried Template::Simple before so I'm
T> not sure how it works yet. I need to install and test it as well as
T> delve into the manual, which looks a little less than simple at
T> first sight...

it has 4 markups. 150 lines of total code. simple is as simple codes!

I installed Template::Simple as stand-alone module, after installing
File::Slurp and setting a use lib 'external_modules/lib/perl5/site_perl'
call in the Makefile.PL script within the Template-Simple-0.02 directory.

The 'make test' stage of the installation failed with many errors (too many
to list here). Some were 'Can't locate File/Slurp.pm'. Perhaps this was the
cause of all consecutive errors, because of the external module location
and so File::Slurp could not be found by this installation step. Maybe this
is not important? Aftrer all, the other steps: perl Makefile.PL
PREFIX=/mypath/external_modules/, make and make install worked fine, so I
think the module should now be fully functional. When being in the
directory where I ran the installation, I can do 'perldoc Template::Simple'.

PS: I install modules in external directories because I usually run into
insufficient system privilidges on various web hosts.
the docs are fairly clear (as clear as i can write them!). can you ask
specific questions?

Can someone here place the list example in an working working script? Are
separate parts meant to exist in separate files? Alternatively, I think I
need an 'hello, I'm a template' equivalent 'hello world'... Anyone?

[...]
so the inner levels would be something like this (VERY untested as i am
typing on the fly):

[% START unordered %]
<ul>
[% START link_line %]
<li><a href=[%level%].html>Level [%level%]</a></li>
[% END link_line %]
</ul>
[% END unordered %]
[...]

so the basic data would look like this for the inner levels:

{
unordered => {
link_line => [
{ level => '3.1' },
{ level => '3.2' },
]
}
}
[...]

T> And is it actually possible to apply the advanced formatting relating
T> to the $current_page URL along with any parent <li class=bits> if and
T> where parent entry <li>'s are present? (as detailed in my first post
T> in this thread). Can all of this be done with the help of
T> Template::Simple?

didn't follow that so i can't help.

The $current_page is a variable output when a page access matches one that
exists in an array field, being the filename portion of the current URL.
The $current_page is known to any perl process while run through a CGI
process, which is importing the link list onto otherwise static HTML pages.
To clarify by an example, if you are at a page (one you happen to know)
such as http://bestfriendscocoa.com/recipes.html then 'Tasty Recipes' in
the header would not show as what may appear to some people as a link to a
different page, but would instead be printed in plain text.

Any other formatting I refer to is applicable in a nested navigation system
of the unordered list I posted previously, typically used by many CSS
navbars. For example, if users are on page 3.2.html, the parent <li> which
contains the link 2.2.html, would be formatted with a style class <li
class=parent_level_2>, while the parent of that, being the <li> containing
the link 1.1.html would be formatted with an <li class=parent_level_1>.
This allows for building a clear navigation system. I guess
Template::Simple can do all this, but maybe not all as any kind of standard
function. After all, the idea of the list output is actually very simple.

Tuxedo
 
U

Uri Guttman

BM> Using T::S you would need to go through and insert class => "..."
BM> entries in your main data structure. There isn't any way to use a
BM> subsidiary hash the way I was suggesting. (This is one of the things I
BM> find slightly irritating about T::S, though I've yet to find a better
BM> alternative for basic (i.e., 'don't want TT2') stuff.)

how would you modify T::S to accomodate your idea? remember, my goal was
a very simple and fast templater. you can do very fancy stuff with code refs
in the data tree. the first public version was 37 lines of code. that
morphed into 150 lines when i made it OO and a proper module. that is
the definition of simple! :)

uri
 
T

Tuxedo

Ben said:
[...]
I installed Template::Simple as stand-alone module, after installing
File::Slurp and setting a use lib 'external_modules/lib/perl5/site_perl'
call in the Makefile.PL script within the Template-Simple-0.02
directory.

Why did you do that? You shouldn't be editing the Makefile.PL at all.
Put external_module/.../site_perl in PERL5LIB in the environment,
instead.

Is PERL5LIB meant to be a temporary Unix environment variable at time of
installation, pointing to /some/external_module/.../site_perl? Eg.:
PERL5LIB=/path/to/module_dir/
Does Makefile.PL probe for that during module installation, to find any
relevant dependency modules that may not otherwise exist in Perl's standard
library locations? Or do you mean something else regarding PERL5LIB?

[...]
If you haven't run the tests you have no reason for thinking that.

I'm not sure what you mean, I ran 'make test' and there were many errors.

[...]
my $T = Template::Simple->new;
my $ref = $T->render(<<T, { world => "I'm a template" });
Hello, [% world %]!
T
print $$ref;

Thanks for this bit of code, I'm sure it works :)

[...]
Using T::S you would need to go through and insert class => "..."
entries in your main data structure. There isn't any way to use a
subsidiary hash the way I was suggesting. (This is one of the things I
find slightly irritating about T::S, though I've yet to find a better
alternative for basic (i.e., 'don't want TT2') stuff.)

Thanks for this advise as well. It sounds highly complex to make T::S do
what I'd like for this particular, yet simple, nested list structure.

Tuxedo
 
T

Tuxedo

Peter said:
T> Ben Morrow wrote:
[...]
T> #!/usr/bin/perl -w

T> use warnings;
T> use strict;

T> my @pages = (
T> { page => "1.1.html", title => "Level 1.1", children => [
T> { page => "2.1.html", title => "Level 2.1" },
T> { page => "2.2.html", title => "Level 2.2", children =>
[
T> { page => "3.1.html", title => "Level 3.1" },
T> { page => "3.2.html", title => "Level 3.2" },
T> ] },
T> { page => "2.3.html", title => "Level 2.3" },
T> ] },
T> );

gack!! use a templater.

With a templater you still need to represent the data you want to render
with the templater. I don't see how you could represent a tree, where
each node contains a link to a page and a title, much differently in
perl than Ben showed above (I am assuming that "page" and "title" aren't
as redundant as the seem to be in the example. Instead of "Level 1.1"
the title would probably be something like "1.1 - Introduction" in the
real world).

I think you understand well. The actual content on 1.1.html may indeed be
an introduction to sub-branches that grow directly off the main information
trunk so to speak, i.e. 2.1, 2.2 and 2.3, while 2.2.html is an introduction
node to what exists on the next level, i.e. 3.1 and 3.2. In a real
situation, an <li> node is just an overview of what exists directly one
level deeper within it's own <li></li> scope. Yet, nodes are actual html
pages, like any other pages, only the content is different. As you say, the
intermediate or the first <li> may appear redundant in my example. The
structure may be a bit better described as:

+ Overall topic (node)
* Some topic
+ Sub-topic (node)
* Some topic ZZz
* Some topic Xxx
* Some other topic

As long as the actual information contained in the various pages is well
arranged by topics and sub-topics, this structure can work just fine for
whatever purpose it serves. For example, some people may click on a node
for an intro, overview or table-of-contents or whatever happens to be
suitably kept in such a place, while others may go directly to a sub-topic
page. I guess this is not an entirely unusual format used in navigation
systems with typical HTML/CSS menus. These can be styled in different ways,
such as clicking on a topic to reveal sub-topics, or by tree-expansion
on-mouseover or other special effects. This is all done with help of CSS
and that requires the right list structure to begin with. Almost all such
navigation systems on the web are built on simple unordered html list.
Yup. But you have to have the data structure first. That's what you
quoted above.

I had also thought an LoL could be combined with another LoL holding the
titles, but maybe this is somewhat limiting in design:

my @lol = ('1.1.html',
['2.1.html',
'2.2.html',
['3.1.html',
'3.2,html'],
'2.3']);

Template driven or not, in case someone has written a template or module
that can output the exact type of listing format needed, it will surely do
fine too. The code may however best be written from scratch. After all, the
actual final tree format is not an irregular structure of some kind.

How Ben wrote it looks fine to me and is certainly easy to maintain
whenever changes are needed. I just couldn't run his code without errors
and I can't see through the entire perl syntax unfortunately... But if you
say it can't be done differently in perl, then that must also be the right
way to go! What type of Perl data structure is it btw.? An AoH?

Tuxedo
 
T

Tuxedo

Ben Morrow wrote:

[...]
Yes. This will only apply while the envvar is set, though: you will
still need

use lib "...";

Yes I presumed I should 'use lib' for the required T:S File:Slurp
dependency.

[...]
You may want to look into local::lib, which makes the process of
maintaining your own set of modules much easier.

Sounds good, my external modules are always scattered all over :)
When MakeMaker is looking for dependancies, it searches the current
@INC. When you run Makefile.PL with PERL5LIB set, those values will be
added to @INC, so any modules in those directories will be found by
MakeMaker. Similarly, when you run 'make test' with PERl5LIB set, the
test scripts will see an @INC which has those modules in.

Thanks for explaining this so clearly.
...so you can't assume the module will work OK if you ignore the errors
and install it anyway.

True, and I will remember.

[...]
Doing nested lists like this certainly isn't straightforward. You may
find it easier to jump straight to using TT2 (that is, Template.pm on
CPAN). It's a little heavyweight for a simple job like this, but that
probably doesn't matter.

Right, it shouldn't matter, even if a procedure turns out slow because in
the end I convert everything into static html. It's just the sheer volume
of extra documentation to read. There's even a fairly thick book on the
subject of TT2 alone... But TT2 does indeed look interesting, so many
thanks for sharing this tip!

Tuxedo
 
T

Tuxedo

Ben Morrow wrote:

[...]
One of these two calls *doesn't* pass an arrayref as the second argument.

[...]

Should it be:

\@$kids

At least there are no confusing errors now. Can you give any further hints
how to print the items in a nested list structure? The script so-far is:

#!/usr/bin/perl -w

use warnings;
use strict;

my @pages = (
{ page => "1.1.html", title => "Level 1.1", children => [
{ page => "2.1.html", title => "Level 2.1" },
{ page => "2.2.html", title => "Level 2.2", children => [
{ page => "3.1.html", title => "Level 3.1" },
{ page => "3.2.html", title => "Level 3.2" },
] },
{ page => "2.3.html", title => "Level 2.3" },
] },
);

#and then build a hash of 'parents', like so

sub populate_parents;
sub populate_parents {
my ($parents, $pages, $parent) = @_;

for (@$pages) {
my $page = $_->{page};
push @{$parents->{$page}}, $parent;
my $kids = $_->{children};
$kids and populate_parents $parents, \@$kids, $page;
}
}

my %parents;
populate_parents \%parents, \@pages, undef;

# This will give you a data structure like

%parents = (
"1.1.html" => [undef],
"2.1.html" => [undef, "1.1.html"],
"3.1.html" => [undef, "1.1.html", "2.2.html"],
# ...
);

# Then, given a page name, you can build another hash

my $page = "3.1.html";
my $parents = $parents{$page};
my %class =
map +($parents->[$_] => "parent_level_$_"),
grep defined $parents->[$_],
0..$#$parents;

Thanks for your help in piecing this puzzle together. After all, this is
nothing for beginners.

I'm hoping I won't be needing a template plugin after all :)

Tuxedo
 
T

Tuxedo

Ben Morrow wrote:

[...]
I think you need to take a step back, and go through the whole thing
again with perlreftut and perldsc in your hand until you understand what
it's doing and how it does it. I'm not going to give you any more bits
of sample code until you've understood these bits, because I really
believe that using bits of code you don't understand is dangerous.

I'm always looking forward to a message from you. Each of your answers is a
challange for me. I admit, I'm not the brightest student but you can be
sure I tried my best. Actually, I'm sitting day and night over the code but
I'm afraid I need another hint. It's not that I don't want to learn, I
simply can't see the light at the end of the tunnel....

Thanks for your help so far.

Tuxedo
 
T

Tuxedo

Ben said:
Ben Morrow wrote:
[...]

Where are you stuck, specifically, when it comes to understanding the
code you've got? Once you've actually understood what that does you
should be able to write the printing code on your own.

If it was as simple as to pin-point one specific part I would have asked
that more specific question. As in most programs, the individual parts are
generally glued together in complex ways that can make it difficult to see
any one part clearly without understanding most of it to begin with.
However, the job needs to be done and there isn't enough time, as such I
will just generate the list in flat format across all pages and run a regex
search-and-replace modifying the relavant node and parent <li>'s. It is
more complicated to maintan as in changing a few more lines of regex calls
and certainly not very smart code, but the end-result is the same. It is
certainly not the way I like it but for now it is just simpler to deal with
than processing nested data structures.

I did a quick search and found it odd I could not find a single template or
module that does the job of generating nested ul's and li's specifically,
considering how complex it can be to build such procedures from scratch.

Thanks for your code and advise, it will surely come in handy once I've had
time to catch up with nested data structures in perl. This is not the kind
of stuff for a non-programmer or anyone below genius to learn overnight :)

Tuxedo
 
T

Tuxedo

Uri Guttman wrote:

[...]
my @pages = ( {
page => '1.1.html',
title => 'Level 1.1',
children => [
{
page => '2.1.html',
title => 'Level 2.1',
},
{
page => '2.2.html',
title => 'Level 2.2',
children => [
{
page => '3.1.html',
title => 'Level 3.1',
},
{
page => '3.2.html',
title => 'Level 3.2',
},
],
},
{
page => '2.3.html',
title => 'Level 2.3',
},
],
}, );

Yes, the above certainly looks and reads better. Well noted.

Thanks,
Tuxedo
 
T

Tuxedo

I wrote:

[...]

But for some reason it all breaks when I hit reply!

Must be my newsreader.

Tuxedo
 
T

Tuxedo

Ben Morrow wrote:

[...]
I disagree. If you were to start by picking one small part--even a
single line--and working out what it does, you would find you got
further than you think before you got stuck. It *will* be hard work, and
it *will* take time, but that's not something I can help with.

Sure, I completely agree! However complicated or simple is a relative term
however. My general impression from various perldocs is that much of it was
written by programmers for programmers, more as reference to those who are
already highly experienced, especially C-veterans. Nothing wrong with that
and I may be flamed for suggesting here that sometimes much perl
documentation could be better written, including more simple examples, that
is if it's to effectively address anyone wishing to learn perl from scratch.

[...]
OK. That may be a sensible solution for now.

Workable but far less than using an ideal data structure. In any case, it's
only pre-processing html, so the poor programming won't affect the end
result, at least not in another way than from a maintenance point of view.
It's not at all complex. Once you understand the data structures
involved it's actually quite simple, and until you do there's not much a
module can do to make it easier.

I have the same feeling. In fact, I think it is probably best done without
modules, unless the module happens to be designed for the very purpose of
generating nested list formats with current URL parameter and tree
structure indicators, including documentation with plenty of clear examples.

[...]
Noone said you have to learn it overnight.

I will look into your code at a later time.

Thanks again,
Tuxedo
 
J

Jürgen Exner

Tuxedo said:
I did a quick search and found it odd I could not find a single template or
module that does the job of generating nested ul's and li's specifically,
considering how complex it can be to build such procedures from scratch.

???

Sorry, but there is nothing, absolutely nothing, complex about
recursively walking through a LOL and printing each node.
Recursive data structures and algorithms are standard topic pretty early
on in any computer science program and you really can't do much useful
programming without them. They are a standard tool of the trade, like a
wrench or a blow torch is for a plumber.
This is not the kind
of stuff for a non-programmer or anyone below genius to learn overnight :)

Then that is your problem. A plumber needs to know how to use a blow
torch and a programmer needs to know how to use recursive data
structures. Neither is rocket science, but without the knowledge you
won't get far in either area, not even as a dabbling amateur.

jue
 
J

Jürgen Exner

Tuxedo said:
Sure, I completely agree! However complicated or simple is a relative term
however. My general impression from various perldocs is that much of it was
written by programmers for programmers, more as reference

Yes, that is certainly true.

Just like in a user manual for a car you wouldn't expect a comprehensive
"How to drive on public roads" manual, would you?
to those who are
already highly experienced, especially C-veterans.

Remove the "highly" and remove "C" (although there is a slight tendency
to explain things from a UNIX perspective).

The perldoc is certainly _NOT_ a learning manual for how to drive a car.
It expects that you are familiar with the standard terms and concepts of
the trade which you would have learned during your training, just like
you would have learned how to drive on public roads in your driving
school.
Nothing wrong with that
and I may be flamed for suggesting here that sometimes much perl
documentation could be better written, including more simple examples, that
is if it's to effectively address anyone wishing to learn perl from scratch.

And that is explicitely _NOT_ the purpose of these docs. There are
plenty other books and other resources to learn the basics about
programming (those principles don't change, no matter which programming
language you are using) and to learn(!) about the basics of Perl.

The gold standard for the latter is of course "Learning Perl" which will
provide you with a structured introduction where you learn Perl from the
ground up in a meaningful sequence.

Trying to learn programming (in general, not just the specifics of a
particular programming language) from the reference manual of a
particular language is the totally wrong approach. It's like trying to
learn how to pilot a plane from the user manual of a Boeing 737.

jue
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top