Great module, I like it.

Just a question, is there a way that we can generate a table of content like below using this module:
A. Section 1
1. Child Section 1.1
a. Grand Child Section 1.1.1
b. Grand Child Section 1.1.2
c. Grand Child Section 1.1.3
2. Child Section 1.2
a. Grand Child Section 1.2.1
b. Grand Child Section 1.2.2
c. Grand Child Section 1.2.3
d. Grand Child Section 1.2.4
3. Child Section 1.3
a. Grand Child Section 1.3.1
b. Grand Child Section 1.3.2
B. Section 2
1. Child Section 1.1
a. Grand Child Section 1.1.1
b. Grand Child Section 1.1.2
c. Grand Child Section 1.1.3
2. Child Section 1.2
a. Grand Child Section 1.2.1
b. Grand Child Section 1.2.2
c. Grand Child Section 1.2.3
d. Grand Child Section 1.2.4
3. Child Section 1.3
a. Grand Child Section 1.3.1
b. Grand Child Section 1.3.2
C. Section 3
1. Child Section 1.1
a. Grand Child Section 1.1.1
b. Grand Child Section 1.1.2
c. Grand Child Section 1.1.3
2. Child Section 1.2
a. Grand Child Section 1.2.1
b. Grand Child Section 1.2.2
c. Grand Child Section 1.2.3
d. Grand Child Section 1.2.4
3. Child Section 1.3
a. Grand Child Section 1.3.1
b. Grand Child Section 1.3.2
D. Section 4
1. Child Section 1.1
a. Grand Child Section 1.1.1
b. Grand Child Section 1.1.2
c. Grand Child Section 1.1.3
2. Child Section 1.2
a. Grand Child Section 1.2.1
b. Grand Child Section 1.2.2
c. Grand Child Section 1.2.3
d. Grand Child Section 1.2.4
3. Child Section 1.3
a. Grand Child Section 1.3.1
b. Grand Child Section 1.3.2
E. Section 5
1. Child Section 1.1
a. Grand Child Section 1.1.1
b. Grand Child Section 1.1.2
c. Grand Child Section 1.1.3
2. Child Section 1.2
a. Grand Child Section 1.2.1
b. Grand Child Section 1.2.2
c. Grand Child Section 1.2.3
d. Grand Child Section 1.2.4
3. Child Section 1.3
a. Grand Child Section 1.3.1
b. Grand Child Section 1.3.2

Thanks
Truyenle

Comments

AlexisWilke’s picture

You have to overload the tableofcontents_theme() functions. You can do that in your theme.

I offer 3 different theme functions:

* tableofcontents_toc--to generate the actual table of content
* tableofcontents_back_to_top--to generate the back to top link
* tableofcontents_number--to define the number (i.e. A, B, C, 1, 2, 3, a, b, c, etc.)

In your case, you should be able to limit yourself to the last one and generate a different number depending on the level.

No one offered code to allow such functionality in the module yet... so you have to do it by hand. If you implement such a function for your theme, posting a copy here would be wonderful for the other users of table of contents.

Thank you.
Alexis Wilke

truyenle’s picture

Thank AlexisWilke for the hints, let me have a look at that last theme function and post back if I can do it of course.

Truyenle

ice5nake’s picture

I've been looking over this module's code trying to figure out how to utilize these theme functions and I am not sure where to begin.

They all seem to rely on being able to pass a TOC object into them. Where do I get this TOC object from?

It's a global object across multiple functions and I honestly can't make out which way is which. Granted I've only done a little bit a digging but some help up front from someone familiar with the code would be appreciated.

AlexisWilke’s picture

ice5snake,

For numbering, you just overload the theme_tableofcontents_number() function.

In there you get the level: $toc->level_to

And you get the number: $toc->counters[$toc->level_to]

Then you can generate the number you want (i.e. level_to could be 2 and thus you'd create 1, 2, 3... for example, and if level_from is 1, generate A, B, C... instead.)

To generate the numbers, if the internal function is satisfactory, you may use _tableofcontents_convert_number() with the correct mode (0 for a decimal number, 1 for roman numbers, 2 for roman numbers in lowercase, etc.)

Very easy! 8-)

function theme_tableofcontents_number($toc) {
  switch ($toc->level_from) {
  case 1:
    return _tableofcontents_convert_number(3, $toc->counters[$toc->level_to]);

  case 2:
    return _tableofcontents_convert_number(0, $toc->counters[$toc->level_to]);

  case 3:
    return _tableofcontents_convert_number(4, $toc->counters[$toc->level_to]);

  // ... (there are 6 levels)
  }
}

Of course, you may add stuff such as a period or parenthesis before and after:

return '[' . _tableofcontents_convert_number(4, $toc->counters[$toc->level_to]) . ']';

Thank you.
Alexis

ice5nake’s picture

Issue tags: +theme functions

Hmm ... I am not sure how to make this work for me. I want to have the ToC appear only when $node->printing is not true. $node-printing is set by the print module.

I figured I could do all the tableofcontents processing and rendering with functions in my template file.

Calling _tableofcontents_convert_number(0,0) returns NULL

AlexisWilke’s picture

Counters are expected to start at 1, probably why you get a NULL. Try with (0, 1).

I already do some test in regard to the print module to avoid the links when printing:

if (arg(0) == 'print' && is_numeric(arg(1)) && module_exists('print')) {

I don't know whether the printing flag will be set at the time the table of contents is generated...

Thank you.
Alexis

ice5nake’s picture

I don't think arg(0) == 'print' takes the PDF version into account.

What I would like to be possible it to just feed a function a string, my body in this case, and it converts it and add the ToC to the top.

I'd be happy to write the functions but I don't know where to start.

I appreciate your help but I honestly don't understand the direction you are pointing me in.

AlexisWilke’s picture

For the [toc] tag to work, you need to setup your filters properly. Once the filter is working, I would imagine that the PDF generation will take it in account automatically.

On the other hand, the automatic table of contents may not work every time.

To tell you the truth, I never tried the PDF feature. I have the Print but that's it.

Thank you.
Alexis

ice5nake’s picture

I experimented with the [toc] and that works fine.

But I don't want the ToC to appear in the PDF version and it is.

My thought was I could abandon the use of the [toc] tag and just embed the ToC in the template file somewhere. Then I could control its display using the $node->printing flag.

Could I try using a theme function to embed the ToC block in my template?

ice5nake’s picture

I am having no luck embedding the block using PHP code in my template. I tried:

$block = module_invoke('tableofcontents_block', 'block' , 'view', 0);

Which caused an infinite loop. And caused the page to run out of memory.

When I looked in the blocks DB table I didn't see a tableofcontents block anywhere.

It seems strange that it is so difficult to programmatically insert one of these wonderful table of contents into a theme template where we would most like it to be.

I am going to try to add a custom region to my custom template and see if I can make it work that way.

AlexisWilke’s picture

The implementation of the block is ugly. The module would need heavy refactor to remove the need for the block to call the node_view() function (which means node_view() is called twice!)

  $_tableofcontents_block_processing = TRUE;
  $text = node_view($node, FALSE, TRUE, FALSE);
  unset($_tableofcontents_block_processing);

I would think that creating a block area in your theme would indeed be the easiest way to do this.

I don't otherwise see how to fix your problem.

Thank you.
Alexis

ice5nake’s picture

I am calling

foreach (array('body_top') as $region) {
  $vars[$region] = theme('blocks', $region);
}

in phptemplate_preprocess_node() to load that particular region and pull it into my template. For some reason drupal_get_content isn't working to get that region.

The problem is my phptemplate_preprocess_node() calls phptemplate_preprocess_node_program()

The fact that phptemplate_preprocess_node_program() is being called twice was giving me problems because this function appends something to the end of another region. Which means it gets appended twice.

I got around this by using a static variable, see http://php.net/manual/en/language.variables.scope.php, which essentially just counted which call of phptemplate_preprocess_node_program() the program was on. And then I only appended the code the first time it was called.

So it turned out to be a little bit of a hack but a somewhat graceful hack. It works.

arronlee’s picture

Came across this thread looking to add a table of contents to an already existing document created from a template.
Thought I should share how I worked out to do it…

You need to go through your document, starting with the first element to include in your contents. Highlight the heading – or whatever you want to appear in the contents list – and click “Format” “Create new paragraph style from selection”. Then copy it and find the next heading. alt cmd V will copy the paragraph style (and probably capitalise the text)… continue through the doc. Then you can follow the instructions in this video and the TOC will pick up your paragraph style. You just need to check it in the inspector and it should create the contents