Navigation, Structure, Usage, WOES! As some of you may have seen I've been asking on here and on Slack regarding the best way to go about creating a navigation on a site.

As yet, nothing I have tried is working and any code that I've been given to try also hasn't worked. (Thanks to everyone who has given code so far though).

Therefore I have literally stripped down everything in the hope that someone might be able to tell me where I'm going wrong as I'm sure that something as simple as this shouldn't be as difficult.

I have a completely fresh install of Craft 2 with the standard templates that come with Craft and I have then created a Structure called (creatively enough) Navigation of which the hierarchy can be seen below.

Home
Services
---- Service 1
---- Service 2
--------- Sub Service 1
---- Service 3
Galleries
---- Gallery 1
---- Gallery 2
............

The above is actually just an example but reflects the sort of items that could go into the site.

Any of the items above could also be either an entry, a single or a template that has a channel on it and so on and so forth.

First up I'm not sure if I actually need to place any information into the Entry URL Format and Entry Template settings for the section as I'm guessing these aren't maybe all that important as the section is literally just being used for creating navigation on the site. That said I did fill them out with standard information just in case.

Next on the standard news/_entry.html template I placed this code :

{% set pages = craft.entries.section('navigation') %}
&lt;nav&gt;
    &lt;ul&gt;
        {% nav page in pages %}
            &lt;li&gt;
                {{ page.getLink() }}
                {% ifchildren %}
                    &lt;ul&gt;
                        {% children %}
                    &lt;/ul&gt;
                {% endifchildren %}
            &lt;/li&gt;
        {% endnav %}
    &lt;/ul&gt;
&lt;/nav&gt;


This allows me to spit out the entire navigation which is good so far but in my Structure section I have an Entries field which allows me to choose an entry. I first of all have no idea of how to spit out this as the link instead of the {{ page.getLink() }} code above.

My Entries field is called singleEntrySelector and I tried {{ page.singleEntrySelector }} to see if it would spit anything out but that didn't work and I got an error on the page.

So I'm wondering how do I go about spitting out the content of the singleEntrySelector field so that my navigation items can point to the correct URL?

Once that is working I'd like to have it so that when I'm on say Sub Service 1 that I can create a secondary navigation on the page which will show me everything from Services down to (in this example) Service 3 so pretty much a very standard secondary navigation output.

That should (I'm hoping) allow me to do what I need here although I am definitely open to other ways of approaching this if I'm completely seeing things wrong here?

Many thanks,

Mark

P.S. I'd also like to be able to in the end spit out the navigation using whatever HTML code I need to as I will be utilising this on a responsive site and so have no idea yet as to what code I will need to encapsulate it all in. Therefore if the {% nav %} tag isn't the right fit here in that it won't allow me to do that then I'd really appreciate being shown how to spit it out in some other way that will allow me to do just that.
First up I'm not sure if I actually need to place any information into the Entry URL Format and Entry Template settings for the section


Nope, you can probably just un-check the Entries in this section have their own URLs checkbox in the Section settings and don't worry about it – I'm guessing the nav items should only function as pointers to "actual" entries, and won't need their own URLs or template.


  [...] in my Structure section I have an Entries field which allows me to
  choose an entry. I first of all have no idea of how to spit out this
  as the link instead of the {{ page.getLink() }} code above.


You can't use the getLink() function when the URL you want is the URL for the entry in the Entries field, and not the actual URL for the nav item (phew). You'll have to build the &lt;a&gt; tag yourself – something like this should work:

{% set pages = craft.entries.section('navigation') %}
&lt;nav&gt;
    &lt;ul&gt;
        {% nav page in pages %}
        &lt;li&gt;
            &lt;a href="{{ page.singleEntrySelector.first().url|default }}"&gt;{{ page.title }}&lt;/a&gt;
            {% ifchildren %}
                &lt;ul&gt;
                    {% children %}
                &lt;/ul&gt;
            {% endifchildren %}
        &lt;/li&gt;
        {% endnav %}
    &lt;/ul&gt;
&lt;/nav&gt;


The crucial part here is the page.singleEntrySelector.first().url|default part for the &lt;a&gt; tags's href attribute.

It's important to realize that whenever you call an Entries attribute/field – such as page. singleEntrySelector in this case – Craft returns an instance of ElementCriteriaModel, which essentially is an array-like object. That means that even if the Entries field only has 1 entry inside it, you can't call page. singleEntrySelector.url directly – you'll need to explicitly select an entry inside the model, either by looping over it, calling a specific index (page. singleEntrySelector[0].url) or use the first() method to return the first entry. This is true for Asset, Tags, User and Category fields as well – basically any fieldtype that returns one or more related elements. 

If you're wondering about the |default filter applied to the URL, that's there to prevent Craft from throwing an error if the page doesn't actually have an entry selected in the singleEntrySelector field. If you make the latter a required field, you can skip the |default part.


  [...] I'd like to have it so that when I'm on say Sub
  Service 1 that I can create a secondary navigation on the page which
  will show me everything from Services down to (in this example)
  Service 3 so pretty much a very standard secondary navigation output.


To output a sub navigation containing all nav "descendants" of the current entry, you'll first need to find the relevant nav item using the current entry in a relation query. Then, you can use the descendantOf() method to build the pages array, using the nav item as the ancestor: 

{% set navItem = craft.entries.section('navigation').relatedTo(entry).first() %}
{% if navItem %}
{% set pages = craft.entries.descendantOf(navItem) %}
&lt;nav&gt;
    &lt;ul&gt;
        {% nav page in pages %}
            &lt;li&gt;
                &lt;a href="{{ page.singleEntrySelector.first().url | default }}"&gt;{{ page.title }}&lt;/a&gt;
            ...
{% endif %}


If you want the sub nav to display the entire sub tree for the current entry – not just the descendents – this is how that could look:

{# Get the related nav item for the current entry #}
{% set navItem = craft.entries.section('navigation').relatedTo(entry).first() %}
{% if navItem %}
    {# Get the top level item #}
    {% set topItem = navItem.getAncestors().level(1).first()|default(navItem) %}
    {# Build a "pages" array w/ the top item and its descendents (child entries) #}
{% set pages = craft.entries.id([topItem.id]|merge(topItem.getDescendants().ids()|default([]))) %}
&lt;nav&gt;
    &lt;ul&gt;
    ....


Note: If you use the same Entry for the Entries field multiple times in your Navigation Structure, results may vary. The examples above will pull the first nav item that has a relationship with the current entry, and disregard any others. However, a many-to-one relationship between the Navigation Structure's entries and the entries in the Entries field, with single sub tree output for the sub nav doesn't really compute – so I've disregarded that particular issue and assumed the relationship will always be one-to-one.