instead of state={state}
, are you trying to pass the full frontity state into that component? or just specific elements? The Frontity state variable is different from application state (the state in React). The Frontity state behaves more as a very large prop object.
Thatās it! Thank you very much @min
Here you can check an example of a component using the state, the FeaturedMedia component. As you could see, you just have to pass the state
while defining the component and once you want to use it you donāt have to pass it as a prop
anymore.
For example in your case, defining <MyCustomPage />
should look something like this:
import React from "react";
import { connect } from "frontity";
const MyCustomPage = ({ state }) => {
... //Your component
};
export default connect(MyCustomPage);
After that, you can use the component without passing state
again: (data.isMyCustomPage && <MyCustomPage />)
.
Let us know if it works in your case You can read a bit more about Frontity state at our docs.
Is a bit weird. When I load the home then navigate to localhost:3000/my-custom-page
everything is ok. But if I load the url directly state.source.post
is an empty object.
Are you trying to load a post or a page? Could you tell us a bit more about your case to check what could be the best solution?
In my site http://tusjuegos.io/ I want a view that list the blog post instead of linking to blog.tusjuegos.io (because Iām having SEO issues). So the path of the view must be http://tusjuegos.io/blog
This is what I have:
// src/index.js
const blogListHandler = {
pattern: '/blog/',
func: ({ state }) => {
state.source.data['/blog/'].isBlogList = true
}
}
const marsTheme = {
...
actions: {
theme: {
init: ({ libraries }) => {
libraries.source.handlers.push(blogListHandler )
}
}
},
....
}
Then on src/components/index.js
<Content>
{(data.isFetching && <Loading />) ||
(data.isBlogList && <BlogList />) ||
(data.isArchive && <List />) ||
(data.isPostType && <Post />) ||
(data.is404 && <Page404 />)}
</Content>
My component looks like this
const BlogList = ({ state }) => {
const items = Object.keys(state.source.post).map(
id => state.source.post[id]
)
console.log(JSON.parse(JSON.stringify(state)), items)
return ....
}
export default connect(BlogList)
Oh okay! If I understood it correctly you are trying to fetch the lists of posts in both the home and the /blog
but format it differently right?
I think the problem may be cause because in your handler, that is executed if you access "/blog"
, you are not fetching the posts, you are just adding the isBlogList
value.
In order to fix that problem, you could reuse the post archive
handler used for the homepage. Something like this:
// src/index.js
const blogListHandler = {
pattern: '/blog/',
priority: 10,
func: async ({ route, params, state, libraries }) => {
state.source.data["/blog/"].isBlogList = true;
const archive = libraries.source.handlers.find(
handler => handler.name == "post archive"
);
await archive.func({ route, params, state, libraries });
}
}
As itās going to have also the property isArchive
you may need to change your conditions inside index.js
in order to prevent duplicating the content.
@David Could you confirm if reusing the post archive
handler is a good approach or should it be done in a different way?
Why not using state.source.homepage
and state.source.postsPage
to change the homepage to /blog
?
Both the homepage and /blog
are pointing to latest posts. I thought that it wasnāt possible just with state.source.homepage
and state.source.postsPage
settings because they have to match the WP Settings, and as far as I know you can only point the latest posts to another url if you set the homepage to a static page.
Oh, I see
Thatās right. I just copied your snipped and it works.
Could you please clarify this?
ā¦you may need to change your conditions inside
index.js
in order to prevent duplicating the content.
Glad it works
Sure! As you are reusing the post archive
handler, the prop isArchive
is going to be passed to /blog
url. So in the src/components/index.js
itās going to be matching two conditions, both data.isBlogList
and data.isArchive
:
<Content>
{(data.isFetching && <Loading />) ||
(data.isBlogList && <BlogList />) ||
(data.isArchive && <List />) ||
(data.isPostType && <Post />) ||
(data.is404 && <Page404 />)}
</Content>
What I meant is just that you have to be careful to load just the <BlogList />
component, so you donāt get your content duplicated.
Hi, when I put the handler for my custom page. But when I click on the URL, itās reloading the page as for sure its redirection to a custom page. Is there any way that we donāt get the reload effect and get the page in front of us. Like in case of Menus
, when we click on any of the menu, the page does not get reloaded instead it only fetch the data of that page.
hereās our website url:
http://app.moosaconsulting.com/
Please check by clicking on strategy under section Who We Work With section.
Cheers,
I added the custom page but when I click on that link I am getting reLoad effect. But when I click on nav-menu link it just loads the body of the page not reload the whole page? Can I do the same for my custom page? Is there any suggestion for this?
Thanks
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