Linking Reference

Template link functions, path resolution, and linking best practices

5 min read 923 words
Edit this page

Was this page helpful?

Template functions, path resolution rules, and advanced linking patterns.

Note

Do I need this? Use when generating links in Kida templates or debugging path resolution. For Markdown authoring syntax, see Linking Guide.

Template Functions

Use template functions in Kida templates for dynamic link generation.

ref(path, text=None)

Generate a cross-reference link:

KIDA
{{ ref('docs/getting-started') }}
{{ ref('docs/getting-started', 'Get Started') }}
{{ ref('id:install-guide') }}

Returns: Safe HTML link (<a href="...">...</a>)

Use cases:

  • Dynamic navigation menus
  • Related pages sections
  • Breadcrumbs

doc(path)

Get a page object for custom link generation:

KIDA
{% let page = doc('docs/getting-started') %}
{% if page %}
  <a href="{{ page.href }}">{{ page.title }}</a>
  <p>{{ page.description }}</p>
{% end %}

Returns: Page object or None

Use cases:

  • Custom link formatting
  • Accessing page metadata
  • Conditional rendering

anchor(heading, page_path=None)

Link to a heading:

KIDA
{{ anchor('Installation') }}
{{ anchor('Configuration', 'docs/getting-started') }}

Parameters:

  • heading: Heading text to find (case-insensitive)
  • page_path: Optional page path to restrict search

Returns: Safe HTML link with anchor fragment

Use cases:

  • Table of contents
  • "Jump to" links
  • Cross-page heading references

relref(path)

Get relative URL without generating a link:

KIDA
<a href="{{ relref('docs/api') }}" class="btn">API Docs</a>

{% let api_url = relref('docs/api') %}
{% if api_url %}
  <link rel="preload" href="{{ api_url }}" as="document">
{% end %}

Returns: URL string or empty string if not found

Use cases:

  • Custom link HTML
  • Meta tags
  • Preload/prefetch links

Path Resolution

Understanding how Bengal resolves paths helps you write reliable links.

Path Formats

Bengal accepts multiple path formats:

MARKDOWN
[[docs/getting-started]]        # Recommended: path without extension
[[docs/getting-started.md]]     # Also works: path with extension
[[getting-started]]             # Slug (if unique across site)
[[id:install-guide]]            # Custom ID

Resolution Order

When resolving a cross-reference:

  1. Custom ID (id:xxx) — Checked first, fastest lookup
  2. Path lookup (docs/page) — Most explicit, recommended
  3. Slug lookup (page-name) — Fallback, may be ambiguous

Relative Path Resolution

Relative paths resolve from the current page's directory:

MARKDOWN
<!-- File: docs/getting-started/installation.md -->

[[./quickstart]]              # docs/getting-started/quickstart.md
[[../reference/config]]       # docs/reference/config.md
[[../../_index]]              # _index.md (site root)

Rules:

  • .mdextension is optional
  • ./refers to current directory
  • ../goes up one level
  • Paths are normalized (trailing slashes, etc.)

Best Practices

When to Use Each Method

Use Markdown Links ([text](url)) when:

  • Linking to external URLs
  • You need full control over link text
  • Simple relative paths within a section

Use Cross-References ([[path]]) when:

  • Linking to internal pages
  • You want automatic title resolution
  • You want stable links that survive path changes (with IDs)
  • You're writing documentation

Use Template Functions (ref(), doc(), etc.) when:

  • Generating links dynamically in templates
  • Building navigation menus
  • Creating related pages sections
  • Conditional link rendering

Use Anchor Links (#heading) when:

  • Linking to specific sections
  • Creating table of contents
  • Cross-referencing specific content

Use Target Directives (:::{target}) when:

  • Creating anchors not tied to headings
  • Need stable anchors that survive content restructuring
  • Migrating from RST/Sphinx (.. _label:)
  • Anchoring before notes/warnings for direct linking

Reference with[[!target-id]]:

  • Explicit syntax avoids collisions with heading anchors
  • Makes intent clear (target directive vs heading)
  • Required for target directive references

Most Stable (survives path changes):

  • Custom IDs:[[id:my-page]]
  • Template functions with IDs:{{ ref('id:my-page') }}

Moderately Stable (survives minor changes):

  • Path-based cross-references:[[docs/page]]
  • Absolute markdown links:[text](/docs/page/)

Least Stable (breaks on path changes):

  • Relative markdown links:[text](../page.md)
  • Slug-based references (if slugs change)

Performance

All linking methods use O(1) lookups from pre-built indexes:

  • Cross-references: Built during discovery phase
  • Template functions: Use same index
  • Markdown links: Resolved during rendering

No performance difference between methods — choose based on use case.

Examples

KIDA
<nav>
  {% for item in site.menus.main %}
    <a href="{{ item.url }}">{{ item.name }}</a>
  {% end %}
</nav>
MARKDOWN
## Related Pages

- [[docs/tutorials/getting-started|Getting Started]]
- [[docs/reference/api|API Reference]]
- [[docs/tutorials/examples|Examples]]
KIDA
{% let related = site.pages | where('tags', page.tags, 'in') | limit(5) %}
{% if related %}
  <h2>Related Pages</h2>
  <ul>
    {% for page in related %}
      <li>{{ ref(page.path) }}</li>
    {% end %}
  </ul>
{% end %}

Table of Contents

MARKDOWN
## Table of Contents

- [[#introduction|Introduction]]
- [[#installation|Installation]]
- [[#configuration|Configuration]]
- [[#usage|Usage]]

Cross-Reference in Content

MARKDOWN
For detailed setup instructions, see [[docs/getting-started/installation|the installation guide]].

Once installed, configure your site as described in [[docs/reference/config#site-settings|Site Settings]].

Troubleshooting

If a link doesn't resolve:

  1. Check path spelling — Paths are case-sensitive
  2. Verify page exists — Usebengal checkto check
  3. Check path format — Use path without.mdextension
  4. Try absolute path — Use/docs/pageinstead of relative

Bengal validates links during build:

BASH
bengal check

This checks:

  • Cross-references resolve
  • Markdown links point to existing pages
  • Anchor links target valid headings

Debugging Broken References

Broken cross-references show visual indicators:

HTML
<span class="broken-ref" data-ref="nonexistent-page"
      title="Page not found: nonexistent-page">
  [nonexistent-page]
</span>

Use browser dev tools to inspect broken references and see what path was attempted.

See Also