So very useful, thank you so much!
I have tried using this code but doesn’t seem to work.
I can see the breadcrumbsContainer and its white background but its not generating the breadcrumbs within it.
I have tried it as a component and directly as part of the theme under “Custom CSS/HTML”.
Any idea what I could be doing wrong?
Yes @DogBite the solution is to add the Script tags at the top and bottom of the header.html…
At the top:
<script type="text/discourse-plugin" version="0.8">
At the bottom:
<script>
Like so…
<script type="text/discourse-plugin" version="0.8">
api.onPageChange((url) => {
updateBreadcrumbs(url);
});
const updateBreadcrumbs = (url) => {
// Helper function to reset the breadcrumbs container
const resetBreadcrumbs = () => {
$("#breadcrumbsContainer").empty();
// If on the homepage
if (url === '/') {
$("#breadcrumbsContainer").append(`
<li class="breadcrumb-item">
<a href="YOUR HOME"><i class="home">HOME</i></a>
</li>
<li class="breadcrumb-item active">
Community
</li>
`);
} else {
$("#breadcrumbsContainer").append(`
<li class="breadcrumb-item">
<a href="YOUR HOME"><i class="home">HOME</i></a>
</li>
<li class="breadcrumb-item">
<a href="/">Community</a>
</li>
`);
}
};
resetBreadcrumbs();
if (url.includes('/c/')) {
// If on a category page
const categorySlugOrId = url.split('/')[2];
$.ajax({
type: "GET",
url: `/c/${categorySlugOrId}/show.json`,
success: function(response) {
if (response && response.category && response.category.name) {
const categoryTitle = response.category.name;
$("#breadcrumbsContainer").append(`
<li class="breadcrumb-item active">
${categoryTitle}
</li>
`);
}
},
error: function(error) {
console.error("Error fetching category details", error);
}
});
} else if (url.includes('/t/')) {
// If on a topic page
const topicId = url.split('/')[2];
$.ajax({
type: "GET",
url: `/t/${topicId}.json`,
success: function(response) {
if (response && response.title) {
const topicTitle = response.title;
const categoryId = response.category_id;
// Now, fetch the category name using the category ID
$.ajax({
type: "GET",
url: `/c/${categoryId}/show.json`,
success: function(categoryResponse) {
if (categoryResponse && categoryResponse.category) {
const categoryTitle = categoryResponse.category.name;
const categoryURL = `/c/${categoryResponse.category.slug}`;
$("#breadcrumbsContainer").append(`
<li class="breadcrumb-item">
<a href="${categoryURL}">${categoryTitle}</a>
</li>
<li class="breadcrumb-item active">
${topicTitle}
</li>
`);
}
},
error: function(error) {
console.error("Error fetching category details for topic", error);
}
});
}
},
error: function(error) {
console.error("Error fetching topic details", error);
}
});
}
}
<script>
Here I rolled a very simple Breadcrumbs (as links) Theme Component (where the home page shows no breadcrumb)… PRs are welcome!
Also (importantly) this currently only works correctly with Categories – it does not handle Subcategories!
How it looks on a Category List page…
How it looks on a Topic page…
Looking a bit more into this, a breadcrumbs component has been added to Discourse earlier this year: FEATURE: Introduce DBreadcrumbs components (#27049) · discourse/discourse@1239178 · GitHub. It’s currently only rendered on select Admin pages.
So I had done a test component to render breadcrumbs: Manuel Kostka / Discourse / Components / Breadcrumbs · GitLab. The current template is:
<template>
{{#if this.currentPage}}
{{bodyClass "has-breadcrumbs"}}
<ul class="breadcrumbs {{concat '--' settings.plugin_outlet}}">
<li class="breadcrumbs__item --home">
{{#if this.homePage}}
{{i18n "js.home"}}
{{else}}
<a href="/">{{i18n "js.home"}}</a>
{{/if}}
</li>
{{#if this.parentCategory}}
<li class="breadcrumbs__item --parent">
<a href="/c/{{this.parentCategoryLink}}">
{{this.parentCategoryName}}</a>
</li>
{{/if}}
{{#unless this.homePage}}
<li class="breadcrumbs__item --current">
{{this.currentPage}}
</li>
{{/unless}}
</ul>
{{/if}}
</template>
I did a branch now that uses the new dbreadcrumbs component: Files · dbreadcrumbs · Manuel Kostka / Discourse / Components / Breadcrumbs · GitLab. That would make the template more concise and I guess generally provide better consistency and accessibility:
<template>
{{#if this.currentPage}}
{{bodyClass "has-breadcrumbs"}}
<DBreadcrumbsContainer class="{{concat '--' settings.plugin_outlet}}" />
<DBreadcrumbsItem @path="/" @label={{i18n "js.home"}} />
{{#if this.parentCategory}}
<DBreadcrumbsItem
@path="/c/{{this.parentCategoryLink}}"
@label={{this.parentCategoryName}}
/>
{{/if}}
{{#unless this.homePage}}
<DBreadcrumbsItem @path="" @label={{this.currentPage}} />
{{/unless}}
{{/if}}
</template>
However, using DBreadcrumbsItem
, the order of parent-category and sub-category gets mixed up on the rendered component. The current category is inserted first:
I wonder if it’s because of that behavior, stated on the commit message?
- DBreadcrumbsItem - The component that registers a LinkTo
for the breadcrumb trail. The breadcrumb > trail > will
show based on the order these items are rendered on the page.