DEV: Client side routing for routes with tag and category context

This moves also moves some of the logic to Category.
This commit is contained in:
Daniel Waterworth 2019-11-28 10:54:06 +00:00
parent 4eb8d1e717
commit 11a73b3f15
4 changed files with 77 additions and 53 deletions

View File

@ -287,6 +287,58 @@ Category.reopenClass({
return categories;
},
findBySlugAndParent(slug, parentCategory) {
return Category.list().find(category => {
if (Discourse.SiteSettings.slug_generation_method === "encoded") {
slug = encodeURI(slug);
}
return (
category.slug === slug &&
(category.parentCategory || null) === parentCategory
);
});
},
findBySlugPath(slugPath) {
let category = null;
for (const slug of slugPath) {
category = this.findBySlugAndParent(slug, category);
if (!category) {
return null;
}
}
return category;
},
findBySlugPathWithID(slugPathWithID) {
const parts = slugPathWithID.split("/");
let category = null;
if (parts.length > 0 && parts[parts.length - 1].match(/^\d+$/)) {
const id = parseInt(parts.pop(), 10);
category = Category.findById(id);
} else {
category = Category.findBySlugPath(parts);
if (
!category &&
parts.length > 0 &&
parts[parts.length - 1].match(/^\d+-/)
) {
const id = parseInt(parts.pop(), 10);
category = Category.findById(id);
}
}
return category;
},
findBySlug(slug, parentSlug) {
const categories = Category.list();
let category;

View File

@ -211,10 +211,11 @@ export default function() {
this.route("tags", { resetNamespace: true }, function() {
this.route("show", { path: "/:tag_id" });
this.route("showCategory", { path: "/c/:category/:tag_id" });
this.route("showCategoryNone", { path: "/c/:category/none/:tag_id" });
this.route("showParentCategory", {
path: "/c/:parent_category/:category/:tag_id"
this.route("showCategory", {
path: "/c/*category_slug_path_with_id/:tag_id"
});
this.route("showCategoryNone", {
path: "/c/*category_slug_path_with_id/none/:tag_id"
});
Site.currentProp("filters").forEach(filter => {
@ -222,13 +223,10 @@ export default function() {
path: "/:tag_id/l/" + filter
});
this.route("showCategory" + filter.capitalize(), {
path: "/c/:category/:tag_id/l/" + filter
path: "/c/*category_slug_path_with_id/:tag_id/l/" + filter
});
this.route("showCategoryNone" + filter.capitalize(), {
path: "/c/:category/none/:tag_id/l/" + filter
});
this.route("showParentCategory" + filter.capitalize(), {
path: "/c/:parent_category/:category/:tag_id/l/" + filter
path: "/c/*category_slug_path_with_id/none/:tag_id/l/" + filter
});
});
this.route("intersection", {

View File

@ -33,28 +33,9 @@ export default (filterArg, params) => {
model(modelParams) {
modelParams = this.serialize(modelParams);
const parts = modelParams.category_slug_path_with_id.split("/");
let category = null;
if (parts.length > 0 && parts[parts.length - 1].match(/^\d+$/)) {
const id = parseInt(parts.pop(), 10);
category = Category.findById(id);
} else {
const [slug, parentSlug] = [...parts].reverse();
category = Category.findBySlug(slug, parentSlug);
if (
!category &&
parts.length > 0 &&
parts[parts.length - 1].match(/^\d+-/)
) {
const id = parseInt(parts.pop(), 10);
category = Category.findById(id);
}
}
const category = Category.findBySlugPathWithID(
modelParams.category_slug_path_with_id
);
if (category) {
return { category };

View File

@ -39,12 +39,7 @@ export default DiscourseRoute.extend(FilterModeMixin, {
this.set("filterType", this.navMode.split("/")[0]);
if (params.category) {
this.set("categorySlug", params.category);
}
if (params.parent_category) {
this.set("parentCategorySlug", params.parent_category);
}
this.set("categorySlugPathWithID", params.category_slug_path_with_id);
if (tag && tag.get("id") !== "none" && this.currentUser) {
// If logged in, we should get the tag's user settings
@ -64,31 +59,29 @@ export default DiscourseRoute.extend(FilterModeMixin, {
controller.set("loading", true);
const params = filterQueryParams(transition.to.queryParams, {});
const categorySlug = this.categorySlug;
const parentCategorySlug = this.parentCategorySlug;
const category = this.categorySlugPathWithID
? Category.findBySlugPathWithID(this.categorySlugPathWithID)
: null;
const topicFilter = this.navMode;
const tagId = tag ? tag.id.toLowerCase() : "none";
let filter;
if (categorySlug) {
const category = Category.findBySlug(categorySlug, parentCategorySlug);
if (parentCategorySlug) {
filter = `tags/c/${parentCategorySlug}/${categorySlug}/${tagId}/l/${topicFilter}`;
} else if (this.noSubcategories) {
filter = `tags/c/${categorySlug}/none/${tagId}/l/${topicFilter}`;
} else {
filter = `tags/c/${categorySlug}/${tagId}/l/${topicFilter}`;
}
if (category) {
category.setupGroupsAndPermissions();
this.set("category", category);
if (category) {
category.setupGroupsAndPermissions();
this.set("category", category);
filter = `tags/c/${Category.slugFor(category)}`;
if (this.noSubcategories) {
filter += "/none";
}
filter += `/${tagId}/l/${topicFilter}`;
} else if (this.additionalTags) {
this.set("category", null);
filter = `tags/intersection/${tagId}/${this.additionalTags.join("/")}`;
this.set("category", null);
} else {
filter = `tags/${tagId}/l/${topicFilter}`;
this.set("category", null);
filter = `tags/${tagId}/l/${topicFilter}`;
}
return findTopicList(this.store, this.topicTrackingState, filter, params, {