Hey @hammad, I think you are not using the <Link>
component for those links, which internally uses actions.router.set()
. Check it out!
yeah, I have corrected an hour ago after reading the doc.
btw A ton of thanks for your response.
Hi there,
I have to add different custom pages to my website so every time I have to add a custom handler to add my page to chakra-theme
. Is it possible to create my custom posts on WordPress with all applied styles and then load them dynamically from WordPress?
Or I have to style the post/page in frontity again?
@hammad, I think you should use gutenberg blocks. Adding more styles in the content has usually been an anti pattern in WordPress, I think.
By the way, the other day I realized that there is another way to add a custom, non-WordPress page to Frontity.
Instead of creating a custom handler, like this:
const signUpHandler = {
pattern: "/sign-up/",
func: ({ state }) => {
state.source.data["/sign-up/"].isSignUp = true;
}
}
You can add the data to the state
:
const myPackage = {
state: {
source: {
data: {
"/sign-up/": {
isReady: true,
isFetching: false,
isSignUp: true
}
}
}
}
}
actions.source.fetch("/sign-up")
wonāt do the fetch because isReady
is true.
The only case where it wouldnāt work is if someone does actions.source.fetch("/sign-up", { force: true })
but that should never happen with a custom page like this.
Can someone help me with adding a custom page to the frontity project.
I added the following ā¦
const signUpHandler = {
pattern: "/signup/",
func: ({ route, state }) => {
Object.assign(state.source.data[route], {
type: "page",
isSignUp: true,
});
},
};
ā¦
actions: {
theme: {
actions: {
init: ({ libraries }) => {
libraries.source.handlers.push(signUpHandler);
},
},
beforeSSR: before,
beforeCSR: before,
toggleMobileMenu: ({ state }) => {
state.theme.isMobileMenuOpen = !state.theme.isMobileMenuOpen;
},
closeMobileMenu: ({ state }) => {
state.theme.isMobileMenuOpen = false;
},
},
},
ā¦
frontity.settings
["Sign up", "/signup/"],
ā¦
signup.js
import React, { useEffect } from "react";
//import { connect, styled } from "frontity";
const Signup = () => {
return (
<div>
<h2>Sign up Page</h2>
</div>
);
};
export default Signup;
ā¦
theme index.js
<Switch>
<Signup when={data.isSignUp} />
<Loading when={data.isFetching} />
<List when={data.isArchive} />
<Post when={data.isPostType} />
<PageError when={data.isError} />
ā¦
I keep getting 404 error. and react_devtools_backend.js:2273 ServerError: post type from endpoints āposts,pages,mediaā with slug āsignupā not found
Any guidance is much appreciated.
I think you forgot to add a priority
to the handler. For example priority: 10
.
By the way, instead of a handler, you can try adding that data to the state:
const myPackage = {
state: {
source: {
data: {
"/signup/": {
isReady: true,
isFetching: false,
isSignUp: true,
},
},
},
},
};
Let me know if that works
Yes adding the priority:10 to the handler fixed it!!! And also I added the init wrong, if you see code above, I inserterted the init in actions.theme.actions.init whilst it should have been actions.theme.initā¦ Thank you so much!!!
Hi ! I created a new route to custom component when I will call an external API using your code. I can get a listing without any problem. Now I want to fetch to a specific id to fetch to a new component
data: {
"/hello/:id": {
isReady: true,
isFetching: false,
isHello: true,
},
},
However it wonāt workā¦ any suggestion ?
If you want to use a pattern you need to create a handler:
const helloHandler = {
pattern: "/hello/:id",
func: ({ state, link, params }) => {
state.source.data[link].isReady = true;
state.source.data[link].isHello = true;
state.source.data[link].id = params.id;
},
};
And then add it to libraries.source.handlers
.
Hello @luisherranz, I tried your solution but when I am typing any id I get a 404 page
const helloHandler = {
pattern: "/hello/:id",
func: ({ state, link, params }) => {
state.source.data[link].isHello = true;
state.source.data[link].id = params.id;
},
};
And
packages: [
{
name: "@awsmin/f1",
state: {
theme: {
menu: [
["Nos occasions", "/"],
["L'atelier", "/category/nature/"],
["Nos services", "/category/travel/"],
["Qui sommes-nous", "/tag/japan/"],
["ActualitƩs", "/about-us/"],
["Nous contacter", "/about-us/"],
],
featured: {
showOnList: false,
showOnPost: false,
},
},
},
actions: {
theme: {
init: ({ libraries }) => {
// Use html2react to process the <img> tags inside the content HTML.
// libraries.html2react.processors.push(image);
// Add the handler to wp-source.
libraries.source.handlers.push(helloHandler);
},
},
},
and my index.js I create a component with sample h1 at that time
<Switch>
<Loading when={data.isFetching} />
<List when={data.isArchive} />
<HomeScreen when={data.isHome} />
<VehicleScreen when={data.isOffers} />
<Entretien when={data.isEntretien} />
<Hello when={data.isHello} />
<Jobs when={data.isAwsmJobOpenings} />
<Page when={data.isPage} />
<Post when={data.isPostType} />
<PageError when={data.isError} />
</Switch>
Can you please provide a repo or code-sandbox with your code? This is especially helpful to find solutions of technical issues with specific code
I use it, can fix this problem !
const profilePage = {
name: 'member',
priority: 1,
pattern: '/member/:user',
func: ({ state, link, params }) => {
state.source.data[link].isProfile = true
state.source.data[link].user = params.user
},
}
]
actions: {
actions: {
init: ({ libraries }) => {
libraries.source.handlers.push(profilePage)
},
},
theme: {
...
}
Yeah I succeed
Hey @floriandupuis1996 itād be great if you can share with the rest how you finally solved and what was the issue you were having
Ths thing is I had handler in frontity.settings.js instead of indexā¦ now I am looking to get the param.id display on my component but this is not easy taskā¦
any idea ?
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/"
],
],
Welcome to the community. It looks like youāre doing great on your journey with Frontity!
Thanks for presenting this solution. Iām sure other Frontity users will find it useful.
Weād love to know more about what youāre building with Frontity. Weāre always looking for projects to feature in our showcase page.
Hi, here is my frontity page: http://api-tech.pl/ but I have problem with routes,
I canāt get to the site directly from the link for example http://api-tech.pl/kontakt give me 404;
also when Iām for example first render FOTOGRAFIA > PODLASIE (PHOTOGRAPHY > PODLASIE)
looks good, and after refresh my gallery disappear.
I thought something wrong in Theme index.js and with handlers
<Main>
{data.isPodlasiePage && <PodlasiePage />}
{data.isFrontPage && <Home />}
{data.isGoryPage && <GoryPage />}
{data.isTimelapsePage && <TimelapsePage />}
{data.isCommercialPage && <ComercialMoviesPage />}
{data.isGoPodlasiePage && <GoPodlasiePage />}
{data.isColaboPage && <CollaborationPage />}
{data.isContactPage && <ContactPage />}
{data.isPolitykaPage && <PrivacyPolicyPage />}
<Switch>
<Loading when={data.isFetching} />
<List when={data.isArchive} />
<PageError when={data.isError} />
</Switch>
and here:
const homeHandler = {
pattern: "/",
func: ({ state }) => {
state.source.data["/"].isFrontPage = true;
state.source.data["/"].isArchive = false;
}
}
const fotografiaHandler = {
pattern: "/fotografia/",
func: ({ state }) => {
state.source.data["/astrofoto/"].isShovvPage = true;
state.source.data["/astrofoto/"].isArchive = false;
}
}
const podlasieHandler = {
pattern: "/podlasie/",
func: ({ state }) => {
state.source.data["/podlasie/"].isPodlasiePage = true;
state.source.data["/podlasie/"].isArchive = false;
}
}
// const astroHandler = {
// pattern: "/astrofoto/",
// func: ({ state }) => {
// state.source.data["/astrofoto/"].isAstroPage = true;
// state.source.data["/astrofoto/"].isArchive = false;
// }
// }
const goryHandler = {
pattern: "/gory/",
func: ({ state }) => {
state.source.data["/gory/"].isGoryPage = true;
state.source.data["/gory/"].isArchive = false;
// state.source.data["/gory/"].isPostType = false;
}
}
const wadirumHandler = {
pattern: "/wadirum/",
func: ({ state }) => {
state.source.data["/wadirum/"].isWadirumPage = true;
state.source.data["/wadirum/"].isArchive = false;
console.log('inside handler')
}
}
const colaboHandler = {
pattern: "/wspolpraca/",
func: ({ state }) => {
state.source.data["/wspolpraca/"].isColaboPage = true;
state.source.data["/wspolpraca/"].isArchive = false;
}
}
const timelapseHandler = {
pattern: "/timelapse/",
func: ({ state }) => {
state.source.data["/timelapse/"].isTimelapsePage = true;
state.source.data["/timelapse/"].isArchive = false;
}
}
const commercialHandler = {
pattern: "/komercyjne/",
func: ({ state }) => {
state.source.data["/komercyjne/"].isCommercialPage = true;
state.source.data["/komercyjne/"].isArchive = false;
}
}
const goPodlasieHandler = {
pattern: "/go-podlasie/",
func: ({ state }) => {
state.source.data["/go-podlasie/"].isGoPodlasiePage = true;
state.source.data["/go-podlasie/"].isArchive = false;
}
}
const contactHandler = {
pattern: "/kontakt/",
func: ({ state }) => {
state.source.data["/kontakt/"].isContactPage = true;
}
}
const privacyPolicyHandler = {
pattern: "/polityka-prywatnosci/",
func: ({ state }) => {
state.source.data["/polityka-prywatnosci/"].isPolitykaPage = true;
state.source.data["/polityka-prywatnosci/"].isArchive = false;
}
}
const marsTheme = {
name: "@frontity/mars-theme",
roots: {
/**
* In Frontity, any package can add React components to the site.
* We use roots for that, scoped to the `theme` namespace.
*/
theme: Theme,
},
state: {
/**
* State is where the packages store their default settings and other
* relevant state. It is scoped to the `theme` namespace.
*/
theme: {
autoPrefetch: "in-view",
menu: [],
isMobileMenuOpen: false,
featured: {
showOnList: false,
showOnPost: false,
},
},
},
/**
* Actions are functions that modify the state or deal with other parts of
* Frontity like libraries.
*/
actions: {
theme: {
toggleMobileMenu: ({ state }) => {
state.theme.isMobileMenuOpen = !state.theme.isMobileMenuOpen;
},
closeMobileMenu: ({ state }) => {
state.theme.isMobileMenuOpen = false;
},
init: ({ libraries }) => {
// Use html2react to process the <img> tags inside the content HTML.
libraries.html2react.processors.push(image);
// Add the handler to wp-source.
libraries.source.handlers.push(homeHandler);
libraries.source.handlers.push(fotografiaHandler);
libraries.source.handlers.push(podlasieHandler);
// libraries.source.handlers.push(astroHandler);
libraries.source.handlers.push(goryHandler);
libraries.source.handlers.push(wadirumHandler);
libraries.source.handlers.push(colaboHandler);
libraries.source.handlers.push(timelapseHandler);
libraries.source.handlers.push(commercialHandler);
libraries.source.handlers.push(goPodlasieHandler);
libraries.source.handlers.push(contactHandler);
libraries.source.handlers.push(privacyPolicyHandler);
console.log('init')
},
beforeSSR: async ({actions}) => {
await actions.source.fetch("/contact");
await actions.source.fetch("/gora");
}
},
},
also in my index.js I used the approach below with same effect.
<ContactPage when={data.isContactPage}/>
<Home when={data.isFrontPage}/>
<PodlasiePage when={data.isPodlasiePage}/>
Can anybody tell me how to get it right?
Looks like itās working now, maybe you fixed it already
Hi @rborowski.shovv,
As @furrysmile2 says, your categories links seem to be working fine from both Server side and Client Side navigation
Is it working now for you?