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; 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) { findBySlug(slug, parentSlug) {
const categories = Category.list(); const categories = Category.list();
let category; let category;

View File

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

View File

@ -33,28 +33,9 @@ export default (filterArg, params) => {
model(modelParams) { model(modelParams) {
modelParams = this.serialize(modelParams); modelParams = this.serialize(modelParams);
const parts = modelParams.category_slug_path_with_id.split("/"); const category = Category.findBySlugPathWithID(
let category = null; modelParams.category_slug_path_with_id
);
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);
}
}
if (category) { if (category) {
return { category }; return { category };

View File

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