4

I'm stuck. For a new site I need to display numbers before the main h1 title and in the submenu's.

Example:

  • 1 Home
  • 2 About
    • 01 history
    • 02 strategy (active page)
    • 03 profile
    • etc. etc.

In the active page (strategy) the title needs to be 02 strategy. So the number is based on the position inside the parent. If I reorder strategy to the first position, the number needs to be 1.

Can someone help me please?

preview http://durk.com/example.png

2 Answers 2

6

What about using CSS for your numbers? (Yes, this answer makes your question sound a bit off-topic, sorry for that, hehe)

Mainmenu:

.mainNav {
  counter-reset: mainNav;
}
.mainNav-item {
  counter-increment: mainNav;
}
.mainNav-item::before {
  content: counter(mainNav) ". ";
}

Submenu (double digits):

.subNav {
  counter-reset: subNav;
}
.subNav-item {
  counter-increment: subNav;
}
.subNav-item::before {
  content: counter(subNav, decimal-leading-zero) ". ";
  color: gold;
}

.

Edit:

Misunderstood that <h1> problem at first. I don't think that there's a dedicated function in Craft to get the position in a structure.

But you can get the entry position like so. You have to get all the structure entries that are on the same structure level with a new ElementCriteriaModel (→ new DB Queries) and then you do a conditional to find the position of the current entry.

{# Get the IDs of all the sections #}
{% set currentSectionId = entry.id %}
{% set allSectionIds = craft.entries.section('myStructure').level(1).ids() %}

{# Define var before loop #}
{% set sectionNumber = '' %}

{# Loop through all section IDs and find the one that matches the current #}
{% for key, sectionId in allSectionIds if sectionId == currentSectionId %}

    {# Use array key to calculate the section's position #}
    {% set sectionNumber = key + 1 %}

{% endfor %}

{# Save the section's position in a custom data attribute #}
<h1 data-section-no="{{ sectionNumber }}">Test</h1>

Use CSS to style your heading:

h1:before {
  content: attr(data-section-no) ". ";
}
3
  • Oh thats smart! I will try it. But how to display the number before the h1 title in the page? 02. hisory Aug 11, 2014 at 14:16
  • Use the mainNav class on it or modify the CSS to your needs, @Johannes.
    – carlcs
    Aug 11, 2014 at 14:18
  • IGNORE that comment, totally misunderstood what you where after @Johannes. See my new edit for that <h1> problem.
    – carlcs
    Aug 11, 2014 at 16:42
3

You can write a recursive macro to display the site structure. In that macro, when you are looping through the entries loop.index will be the the loop index, and e.level will be the depth of entry e in the structure. Here is a macro to print the navigation.

{% macro recursiveNav(entries) %}
{% import _self as self %}
  <ul>
    {% for e in entries %}
      {# loop.index is our index, e.level is our level #}
      <li>
        {# using twig range here to output right number of 0s #}
        {% if e.level > 1 %}{% for i in range(2, e.level) %}0{% endfor %}{% endif %}{{loop.index}}
        {{e.link}}
        {% if e.hasDescendants %}
          {{self.recursiveNav(e.children)}}
        {% endif %}
      </li>
    {% endfor %}
  </ul>
{% endmacro %}

{% import _self as self %}
{% set entries = craft.entries.section('sitecontent').level(1) %}
{# call recursive nav, pass it level 1 entries #}
{{ self.recursiveNav(entries) }}

If all you want is the title for a particular entry (02 strategy e.g.), you can use almost the same recursive macro to do that:

{% macro recursiveTitle(entries, distinguishedId) %}
{% import _self as self %}
  {% for e in entries %}
    {% if e.id == distinguishedId %}
      {# this is the one we want #}
      {% if e.level > 1 %}{% for i in range(2, e.level) %}0{% endfor %}{% endif %}{{loop.index}}
      {{e.title}}
    {% endif %}
    {% if e.hasDescendants %}
      {{self.recursiveTitle(e.children, distinguishedId)}}
    {% endif %}
  {% endfor %}
{% endmacro %}

{% import _self as self %}
{% set entries = craft.entries.section('sitecontent').level(1) %}
{# call recursive title, pass it level 1 entries and id of our active entry #}
{{ self.recursiveTitle(entries, entry.id) }}

There is no way to pass data out of a macro, so the recursiveNav can't also save the index and level of the active entry for later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.