{linkBase} brings consistency to linking

9 hours ago by David Grudl  

One of the most valuable features of Nette Application is its flexible directory structure, which seamlessly adapts to a project's growing needs. Imagine you're building an e-shop. You start with a frontend and administration, each with its own presenters. Gradually, the application expands – perhaps what was originally a simple OrderPresenter eventually evolves into a complete order module with presenters like OrderDetail, OrderEdit, OrderDispatch, and others. Thanks to the flexible structure, you can make this reorganization very easily and elegantly.

However, this flexibility can present one developer challenge: what happens when a single layout suddenly gets used by presenters that are at “different levels” in the directory structure?

For example, we have @layout.latte for administration, where we want navigation with links to various sections:

<nav>
    <a n:href="Dashboard:">Dashboard</a>
    <a n:href="Products:Overview:">Products</a>
    <a n:href="Users:list">Users</a>
</nav>

When this layout is used by the Admin:Dashboard presenter, the links will correctly lead to Admin:Dashboard:default, Admin:Users:list, etc. But what if the same layout is used by the Admin:Products:Detail presenter? Relative links will suddenly be derived from it and lead to non-existent targets (e.g., Admin:Products:Dashboard:default).

Previously, this was solved by writing all links as absolute paths (or using aliases):

{* Everything absolute *}
<nav>
    <a n:href=":Admin:Dashboard:">Dashboard</a>
    <a n:href=":Admin:Products:Overview:">Products</a>
    <a n:href=":Admin:Users:list">Users</a>
</nav>

This works, but has its drawbacks. Especially if you later decide to move the module elsewhere or rename it.

The solution: {linkBase}

Nette Application 3.2.7 introduces an elegant solution in the form of a new Latte tag {linkBase}. It defines the base from which all relative links in the template will be derived.

{linkBase Admin}

<nav>
    <a n:href="Dashboard:">Dashboard</a>
    <a n:href="Products:Overview:">Products</a>
    <a n:href="Users:list">Users</a>
</nav>

Now it doesn't matter which presenter calls the layout. All relative links will be derived from the Admin module:

  • Dashboard:Admin:Dashboard:default
  • Products:Overview:Admin:Products:Overview:default
  • Users:listAdmin:Users:list

{linkBase} only affects relative links – those that don't start with a colon. Absolute links (:Admin:Dashboard) and links to the current presenter (this, show) remain unchanged.

The tag applies to the entire template and works with all ways of creating links: {link}, {plink}, n:href.

Bonus: |absoluteUrl filter

Nette Application 3.2.7 also brings another useful addition – the Latte filter |absoluteUrl. It normalizes URLs to absolute form, which is useful when you need a guaranteed absolute address:

<meta property="og:image" content={$imagePath|absoluteUrl}>

Update to Nette Application 3.2.7 and tell us what you think of the new features.

David Grudl Open-source creator and AI specialist who opens doors to the world of artificial intelligence. His projects including Nette and Texy! power websites you visit daily. He contributes to Uměligence and La Trine while hosting Tech Guys. Through AI workshops, he champions technology that genuinely improves people's lives.