How to best do this?

Hello, I have following site structure:

content/

├── city1/
│ ├── suburb1a/

│ ├── suburb1b/
│ ├── suburb1c/, etc

├── city2/
│ ├── suburb2a/

│ ├── suburb2b/
│ ├── suburb2c/, etc

There will be many cities and each city can have many suburbs.

I also have:

content/

├── services/
│ ├── service1/
│ ├── service2/
│ ├── service3/
│ ├── service4/
│ ├── service5/, etc

Each suburb will have links to every service.

I need to pass the city and suburb into each service. IE each service page must have programmatic access to eg the title of the parent city and suburb pages, and maybe some other info, so that eg service1 content can include “service1 in suburb1a, city1”

So far I see 2 ways to do this:

Option 1 - Make each suburb a section and have service leaf bundles under it:

├── city2/
│   ├── suburb2a/

│         ├── service1/
│         ├── service2/
│         ├── service3/
│         ├── service4/
│         ├── service5/, etc


The problem with this is that if I have many cities and many suburbs and each suburb has dedicated set of services, is that there will a lot of sections and pages in the site. And each service is duplicated for each suburb. Eg service1 is exactly the same for each suburb, and so this is not reusing reusable code or content.

My understanding is that Hugo does not programmatically create index.md/html pages, and so this would also be a fair bit of work to manually create pages.

I can (and have) developed Python code to create service leaf bundles under each suburb but I would rather stick to just using Hugo.

The advantage of this option that it is fairly easy and secure to pass info from a parent city and suburb to each service, just using Hugo code.

Option 2 - I have figured out how to create links in each suburb page to every service and pass info in the URL of the link:

In baseof.html:

<script>
document.addEventListener("DOMContentLoaded", function () {
  const params = new URLSearchParams(window.location.search);

  const foo = params.get("foo");
  const bar = params.get("bar");

  if (foo) {
    document.querySelectorAll(".foo-target").forEach(el => {
      el.textContent = foo;
    });
  }

  if (bar) {
    document.querySelectorAll(".bar-target").forEach(el => {
      el.textContent = bar;
    });
  }
});
</script>

In /suburb1a/index.html:

<a href="/services/service1/?foo=suburb1a&bar=city1">Service1</a>

In /service1/index.html:

<span class="foo-target"></span>
<br>
<span class="bar-target"></span>

This works fine.

The advantage of this is that I only need to have one page for each service. This means not having to produce dedicated service pages under each suburb.

The disadvantage is that I am showing the suburb and city in the URL of the link, which is not elegant and subject to manipulation and XSS.

So both the options I have come up with IMHO are not ideal.

I was wondering if anyone would have any other suggestions as to how to achieve this? Or how to improve either option that I have listed?

Any help is much appreciated and thanks in advance :slight_smile:

that has changed : see Content adapters so you could.

But for me that sounds like a perfect fit for: Taxonomies

1 Like

@irkode thanks for your reply - wow I did not know Hugo can now create pages - very cool.

I took a look at Taxonomies and I am not understanding how I would pass info between pages and subpages using this method. Sorry if I am missing something, but if you have further info on how to do this, could you please explain?

just to make sure, we are not talking about runtime passing of values. all statically rendered at build time.

easiest for me would be if you set up a small repo with a few pages to play with to have real values to pass.

you need service → suburb and the city (transitive)?

1 Like

Hi @irkode - Thanks for your further help. I am not familiar with github or git etc so I am not sure I could provide a sample repo, but I hope my explanation below is helpful.

just to make sure, we are not talking about runtime passing of values. all statically rendered at build time.

I would like to have this happen during build time.

you need service → suburb and the city (transitive)?

I think I may have made my original post overly complex. To try and answer your question:

If I have:

content/

├── city1/

├── city2/

├── services/
│ ├── service1/
│ ├── service2/
│ ├── service3/
│ ├── service4/
│ ├── service5/, etc

In each city I would like to have links to all the services. And each service needs to have the name (title) of the city that linked to the service.

So that eg if City1 links to service1, then the content of service1 needs to say eg “Service1 in City1”

If City2 links to service1, then the content of service1 needs to say eg “Service1 in City2”

So far I have figured out how to do this in only 2 ways:

Option one - Pass parameters in the URL in the link that is in the city and links to the service eg this would be a link in the city that links to a service and passes the city name to the service:

<a href="/services/service1/?foo=city1">Service1</a>


Option two - Put a copy of the service folder containing all the services under each city.

The folder structure would then be:

content/

├── city1/

  ├── services/
     ├── service1/
     ├── service2/
     ├── service3/
     ├── service4/
     ├── service5/, etc

├── city2/

  ├── services/
     ├── service1/
     ├── service2/
     ├── service3/
     ├── service4/
     ├── service5/, etc

Then I can use this in the template of each service, eg

{{ .Title }} in {{ .Parent.Parent.Title }}

to get eg the content “Service1 in City1” in each service page.

But both of these options have disadvantages.

So I appreciate you mentioning that taxonomies might be used for this purpose but unfortunately I dont quite understand how.

I hope this answers your question (without me providing a sample repo) and maybe I have explained things better this time.

ok, got that - but that’s a dynamic usage :wink: you want the referrer

also taxonomies do not provide that live “who has called me”. It just enables to link and group with tags.

so your options are:

  • URL query, or (javascript) or a combination.
  • manually brute force copy page
  • new create aliases for the called service pages won’t solve the referrer problem.
  • new automatic: use Content Adapters to generate these when building

coming to taxonomy

  • i was curious, so here is an ugly/nifty showcase how to use a “link” taxonomy.
git clone --single-branch -b topic-56908-services2Cities2SubUrbs https://github.com/irkode/hugo-forum.git  topic-56908-services2Cities2SubUrbs
cd topic-56908-services2Cities2SubUrbs
hugo server
  • content files: and frontmatter fields (id, links)
    browse City → service 2 and see the page
  • hugo.toml - taxonomy definition
  • layouts/term.html - render the “link taxonomy terms”
    info from city and service page
  • layouts/services/view_service.html - renders the actual service page using a content view template

Hugo creates the 1:1 bridges(links). the actual displayed page is the link page (term) which embeds the service page content.

up to the audience to judge: :wink:

[ ] nifty
[ ] ugly

1 Like

@irkode Wow thanks very much for providing these additional options!

Very much appreciated.

I will learn and try them in the next few days.

@irkode - I downloaded and ran the sample site that you provided.

It does exactly what I am looking for.

I think is a great solution!

  • It does not involve passing parameters in the URL which is subject to manipulation and XSS
  • It does not involve having to manually copy the services section under each city, which in my case could have been hundreds of duplicate services sections

So your solution solves both the of these problems that I had with my previous options.

I had no idea that taxonomy could be used like this and so I want to thank you soooooo much for taking the time and effort to help me out and create the sample site. That is really amazing support and I am very grateful!

up to the audience to judge:

[ x] nifty
[ ] ugly

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.