Hi there, Iām Pilar. Iām starting with Frontity and Iāve struggling with custom handlers, custom pages and custom queries, browsing this thread and many others, reading the docs, etc. Iāve finally made it work so I wanted to share the code in case itās helpful for anyone, as yours has been to me
The base of my project is a large set of Galician traditional sayings or ārefranesā. The main user interaction will be the search (and also copying the text of the quote, sharing it as an image, etc. but thatās another story). For SEO reasons I want some popular searches to be on the menu and have their own url, like āsayings-about-winterā (instead of ādomain.com/?s=winterā), without having to categorize them. So I created a custom handler that takes the last word of that url pattern, whatever it is, (in this case, āwinterā) and shows all the posts that contain that specific word.
Thatās how I achieved it, I donāt know if itās a better way to to do it? It would be simpler with the future method described here, but for now itās working !
In mars-theme/src/index.js:
import Theme from "./components";
import image from "@frontity/html2react/processors/image";
import iframe from "@frontity/html2react/processors/iframe";
const searchUrls = {
priority: 1,
pattern: "/sayings-about-:search",
func: async ({ link, params, state, libraries, force }) => {
const response = await libraries.source.api.get({
endpoint: "posts",
params: { search: params.search }
});
const items = await libraries.source.populate({
response,
state,
force,
});
Object.assign(state.source.data[link], {
isSearchUrl: true,
//add queried posts to data
items,
});
}
}
const marsTheme = {
name: "@frontity/mars-theme",
roots: {
theme: Theme,
},
state: {
theme: {
},
},
},
actions: {
theme: {
init: ({ libraries }) => {
libraries.source.handlers.push(searchUrls);
},
},
},
};
export default marsTheme;
In src/components/index.js:
<Switch>
<Loading when={data.isFetching} />
<List when={data.isArchive} />
<Post when={data.isPostType} />
<ListSearch when={data.isSearchUrl} />
</Switch>
In components/list/list-search.js:
const ListSearch = ({ state, libraries, link }) => {
const data = state.source.get(state.router.link);
return (
<Container>
{data.items.map(({ type, id }) => {
const item = state.source[type][id];
// Render one Item component for each one.
return <Item key={item.id} item={item} />;
})}
<Pagination />
</Container>
);
};
Now if I go to /sayings-about-winter I see all the posts that contain the word āwinterā, and /sayings-about-spring shows all the posts containing āspringā, etc.
And I can add these links to the menu in frontity.settings.js (or anywhere else):
"menu": [
[
"Home",
"/"
],
[
"Sayings about winter",
"/sayings-about-winter/"
],
[
"Sayings about spring",
"/sayings-about-spring/"
],
],