wordpress gutenberg validation error on save function - wordpress

so i am playing with wordpress gutenberg block dev. and already made some simple one. now i am trying to make a more complicated one of a slider.
everything works untill the save function where i get validation error and a bizzare notice about EndTag which i do not get.
this is my save function , for now i am just trying to save the slides titles. if i console log within the map, i do get what i want.
save: function( props ) {
const { slides } = props.attributes;
const id = props.attributes.id;
const displaySlides = slides.map((slide) => {
return (
<div>
<span>{slide.title}</span>
</div>
)
});
return (
<div>
{displaySlides}
</div>
)
},
and here is the error i get in my dev tools:
notice that the titles are there but still i get validation error!!
what an i missing here? and what is it the EndTag thing?
best regards

Your edit function node list doesn't match up with save function node list. That's why you are getting this error. Look closely, there's a node list WP expected but it got a different node list.

Related

Algolia - AutoComplete with Suggestion + Search Results Page - NextJS

Am implementing the Algolia search in my NextJS app. I have the datasource and indices already setup. What am trying to setup is something like what Gucci is doing in their search. Gucci is using Algolia for their search functionality.
I tried using the react-instantsearch-dom package of Algolia. And I updated my /pages/_app.js file like this(only relevant code is written here):
/**
* /pages/_app.js
*
*/
//-------- Algolia
import algoliasearch from 'algoliasearch/lite';
import { InstantSearch } from 'react-instantsearch-dom';
const searchClient = algoliasearch( 'xxxxxxxxxx', 'yyyyyyyyyyyyyyy' );
//-------- /Algolia
function MyApp({ Component, pageProps }) {
return (
<>
<InstantSearch searchClient={searchClient} indexName={ 'abc_test_products' }>
<Component {...pageProps} />
</InstantSearch>
</>
)
}
export default MyApp
This way I could use the components of react-instantsearch-dom anywhere.
Am confused at three things here.
Doubt 1:
How can I pass the algolia query and filters to the search results page like here and display the results using the components : https://www.gucci.com/us/en/st/newsearchpage?facetFilters=categoryLevel1_en%3AChildren&searchString=handbags&search-cat=header-search
So basically when the user clicks one of the algolia search suggestions(from the dropdown after clicking the search box at the top right corner of the page), they are taken to a search results page and there it seems like Algolia search is instantiated and displays the results.
Doubt 2:
How can I display the auto suggestions and product images side by side?
Doubt 3:
Displaying dynamic filter/refinement options. I understood that if there's a brand attribute in our Algoia indices/dataset, I can include that in the search filter like this:
<RefinementList attribute="brand" />
But if there are different attribute that I want to display the refinement list, say "Color", "Brand", etc. how would I display the title of the refinement option and the list dynamically from the search results.
Your UI example looks like a mash-up of a Query Suggestions panel on the left and a Hits list on the right. You can customize what a hit looks like before you render to get the image in there. And the filter menus automatically update as the user filters.
I haven't tried to get the query params into the URL, that would be interesting. I think you'd have to add useRouter into your Next page and then push the Algolia params onto the string using onClick.
Below is an example I built, maybe it helps you:
const Search = () => {
const Hit = ({ hit }) => {
return (
<HitContainer>
<span>{hit.type}</span>
<h2><a href={hit.path}>{hit.title}</a></h2>
{
hit.content &&
<p>{ `${hit.content.substring(0,150)} ...` }</p>
}
<hr />
</HitContainer>
)
}
return (
<>
<InstantSearch
searchClient={ AlgoliaReactClient }
indexName="MAINSITE" >
<CustomSearchBox
translations={{
submitTitle: 'Submit your search query.',
resetTitle: 'Clear your search query.',
placeholder: 'What are you looking for?',
}}
/>
<HitsAndFilters>
<AllFilters>
<h3>Topics</h3>
<FilterMenu
attribute="topics"
limit={5}
showMore
/>
<h3>Locations</h3>
<FilterMenu
attribute="locations"
limit={5}
showMore
/>
</AllFilters>
<AllHits hitComponent={Hit} />
</HitsAndFilters>
</InstantSearch>
</>
)
}

Contentful and Next JS - Issues with content not showing

So at the moment, I have a site I'm creating with Next Js on the front-end with contentful used as my CMS.
I have quite a few pages that use the contentful function to fetch the data:
export async function getStaticProps() {
const client = createClient({
space: process.env.NEXT_CONTENTFUL_SPACE_ID,
accessToken: process.env.NEXT_CONTENTFUL_ACCESS_TOKEN,
});
const res = await client.getEntries({ content_type: "MYCONTENT" });
return {
props: {
MYCONTENT: res.items,
},
};
}
So imagine this code on about 30 pages. I then filter and map through the items that I need using this code:
{MYCONTNET
.filter((e) => e.fields.tag === "design tools")
.map((content) => {
return (
<ToolsCard
key={content.fields.title}
title={content.fields.title}
para={content.fields.tagline}
url={content.fields.url}
img={content.fields.img.fields.file.url}
/>
);
})}
It was going well until I recently came across an issue whereby not all the items get passed to the front end.
My only solution is to republish the content on contentful but when I do it seems to have an effect on the other pages. Even when I tried to console log I cant see the data being passed.
It shows me this image and here is a more detailed image
I'm not sure what the issue is, it was working fine, but when I started adding more content this issue came up.
If anyone can help, that would be great. Thanks in advance.
Answer:
So I didn't realise, I needed to increase the limit parameter. I had over 113 but the default was 100.

createPages in Gatsby issues ; duplications and unrendered content

I've had a few errors trying to render single blog posts.
I tried using the page template with /post/{post_name} and I was getting this error:
warn Non-deterministic routing danger: Attempting to create page: "/blog/", but
page "/blog" already exists
This could lead to non-deterministic routing behavior
I tried again with /blog/{post_name}.
I now have both routes, which I'm not sure how to clean up; but more importantly, on those pages, nothing renders, even though there should be an h1 with it's innerhtml set to the node.title and likewise a div for the content.
I've uploaded my config and components to https://github.com/zackrosegithub/gatsby so you can have a look.
Not sure how to fix
I just want to see my content rendered on the screen.
Developer tools don't seem to help when there's no content rendered as I can't find anything to inspect to try to access it another way.
Thank you for your help
Your approach is partially correct. You are using a promise-based approach but when using then() you are already settling and partially resolving it so you don't need to use the callback of resolve(), which may be causing a duplication of the promise function so try removing it.
Additionally, you may want to use a more friendly approach using async/await functions. Something like:
exports.createPages = async ({ graphql, actions, reporter }) => {
const yourQuery= await graphql(
`
{
allWordpressPost {
edges{
node{
id
title
slug
excerpt
content
}
}
}
}
`
if (yourQuery.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`);
return;
}
const postTemplate = path.resolve("./src/templates/post.js")
_.each(yourQuery.data.allWordpressPost.edges, edge => {
createPage({
path: `/post/${edge.node.slug}/`,
component: slash(postTemplate),
context: edge.node,
})
})
})
// and so on for the rest of the queries
};
In addition, place a console.log(pageContext) in your postTemplate to get what's reaching that point and name the template as:
const Post = ({pageContext}) => {
console.log("your pageContext is", pageContext);
return <div>
<h1>
{pageContext.title}
</h1>
</div>
}
export default Post;

What is the cypress cy.contains() equivalent in webdriverio?

I have mainly worked with cypress previously for e2e automated testing, I have now started working on webdriverIO. So for a cypress command such as
cy.get("[data-testid='nav-bar']").contains("Search Box").click();
What would be the equivalent for this in webdriverIO? I have tried the following approach in a PageObject Model.
class HomePage extends Page {
get navBar() {
return browser.$("[data-testid='nav-bar']");
}
openSearchBox() {
this.navBar().click('//*[text="Search Box"]');
}
}
However, this approach does not seem to work, any help on this would be appreciated.
Leaving Page Objects asside for now, you'd type this in WebdriverIO:
const bar = $('[data-testid='nav-bar']');
expect(bar.getText()).toInclude('Search Box');
bar.click();
You can use chai for the assertion instead of Jest Matchers:
const expectChai = require('chai').expect;
// ...
expectChai(bar.getText()).to.have.string('Search Box');
// ...
The exact analog to
cy.get("[data-testid='nav-bar']").contains("Search Box").click();
can be achieved with xpath selector
$("[data-testid='nav-bar']").$("./*[descendant-or-self::*[contains(text(), 'Search Box')]]").click();
It looks a bit ugly though, consider adding a custom command that would mimic Cypress's contains:
// put this to `before` hook in your wdio.conf.js
browser.addCommand('cyContains', function(text) {
this.waitForExist()
return this.$(`./*[descendant-or-self::*[contains(text(), '${text}')]]`)
}, true)
$("[data-testid='nav-bar']").cyContains("Search Box").click();
P.S.
Check out the selector in the browser console right on this page, paste in the browser console
$x("//span[descendant-or-self::*[contains(text(), 'Search Box')]]")

Show Loading Screen Until Data Is Populated - React & Meteor

I'm trying to populate a table and only want to show the data when everything has been fetched. I'd like to show a basic "Loading..." text. Currently I have this:
getNames() {
return Names.find().fetch();
}
render() {
let mapData = this.getNames().map((name) => {
return <Name key={name.id} name={name} />
});
if (!mapData) {
return (<h1>Loading...</h1>);
}
return (
<ul>
{mapData}
</ul>
);
}
This is just a basic example, but I'm grabbing alot of data from Names.find().fetch()... though it seems that once mapData starts getting populated, the data will partially load (showing possibly the first few items, then completing).
I know I'm not doing this correctly. I'm just wondering how other people deal with properly showing a progress bar in React.
I thought about just setting a delay in componentDidMount, but that doesn't seem to be a great solution.
Any help would be greatly appreciated!
Thanks!
T
Meteor.subscribe takes a callback that will be called once the subscription has loaded its data.
See: http://docs.meteor.com/#/full/meteor_subscribe

Resources