I am trying to recreate a WordPress slider on Gatsby
I want to see if there is a way to query multiple images by id. I don't want to use many queries but a single one using an array of IDs - if it's possible of course :-)
What the query would be for example if I wanted the 110,200,250,300,400 media of the WordPress library?
Is it more efficient to add the images to my src folder?
Thank you!
I was strugling with similar thing and this query is what worked for me:
query MyQuery {
mediaItems(where: {in: [10, 12, 14]}) {
edges {
node {
sourceUrl
srcSet
}
}
}
}
Considering you are running latest plugin versions
Answer 1
Your query could look something like this:
query ImageQuery {
allWpMediaItem(filter: {databaseId: {in: [390, 164]}}) {
nodes {
localFile {
childImageSharp {
gatsbyImageData(layout: CONSTRAINED, formats: [AVIF, WEBP, JPG])
}
}
}
}
}
Obviously you have to adjust the image options to your needs.
Answer 2
If you actually want to define a set of images to return under a custom query you would need to extend the WPGraphQL schema and return the array of images. The easiest option I can think of is to create a Custom Post Type Slider and add a Repeater field through Advanced Custom Fields. Since ACF is supported with a WPGraphQL Extension it is pretty simple to add it to the schema. You just have to add the Post Type to the schema too. See the docs here: https://www.wpgraphql.com/docs/custom-post-types/
Related
I use Wordpress, Gatsby + GraphQL and I want to build a blog. Unfortunately all blog posts needs to have all "features" for example featured image.
The problem is when I remove all posts. So my blog is now empty but gatsby build fails because it expects featured image to exists. The same problem is if I have posts but they do not have featured image. If I want to run gatsby successfully I need at least one post with featured image.
Example GraphQL query
{
allWordpressPost {
edges {
node {
id
title
content
featured_media {
source_url
}
}
}
}
}
Error
GraphQLError: Cannot query field "featured_media" on type "wordpress__POST".
I'm worried because my only solution is to create a dummy post with all these things. What if I want to create a blog for my client and he deletes this dummy post? Is there a better way?
I don't have much experience with gatsby so I would be happy for suggestions.
Thank you
I had a similar issue that I was able to work around, but without seeing more of your code this is just a guess. When you render the data in your Post template file you can do a "not null" check. It could look something like {data.featured_media !== null ? (<img src={{ data.source_url}} /> ) : null }
Is it possible to assign different templates to child pages of post types?
The main purpose is to keep a clean URL but also differentiate the child pages from the parents (with the use of ACF).
Of course this is possible, there are a lot of different possibilities how to achieve this.
First of all lets have a look on the WordPress template hierarchy which you really should understand:
As you can see there is a single-$posttype.php template (replace $posttype with your post type slug). This is what you should use to differentiate templates between post types.
If you want to differentiate templates within the same posttype I would recommend the following implementation within single-$posttype.php:
if(get_post_meta($post->ID,'template',true)=="templateA") {
get_template_part("templateA");
} else if(get_post_meta($post->ID,'template',true)=="templateB") {
get_template_part("templateB");
} else {
get_template_part("templateDefault");
}
Adjust this code to your needs.
I'm using Gatsby with the Wordpress source plugin. So far so good. But the thing is I am querying fields that might or might not be there, in this case, the featured image of a post.
Here is my query:
{
allWordpressPost(sort: { fields: [date] }) {
edges {
node {
title
excerpt
slug
featured_media
better_featured_image {
wordpress_id
alt_text
caption
description
media_type
post
source_url
}
}
}
}
}
It works well when the featured image is set, but fails miserably otherwise.
And so my question: Is there any way in GraphQL to query an optional field? To add a default value to a required field?
I am all too new to GraphQL so I'm not even sure that's possible at this point.
Thank you.
This article explains the back story, but in short, you need to make sure that at least 1 of your WordPress posts has the featured image. Then the better_featured_image field will always exist.
In javascript, if you try to access allWordpressPost.edges.node.better_featured_image.wordpress_id and better_featured_image does not exist, you'll get a syntax error.
Without knowing what "fails miserably" specifically means, not sure what else to suggest.
I am using WP REST API v1.2.5 (as v2 doesn't seem to work on the website I'm working on) and I want to retrieve all pdf objects from Media without getting all the other images, videos etc. How could I do this (without adding a custom endpoint if possible).
to get all media I use:
/wp-json/media
I can't find a filter that would only return the pdfs on my site though. Any help would be appreciated. Thanks!
I found a solution thanks to this post:
https://1fix.io/blog/2015/02/28/wordpress-rest-api-media/
Basically you need to add the following php code to the WP REST API plugin:
add_filter( 'query_vars', function( $query_vars ) {
$query_vars[] = 'post_parent';
return $query_vars;
});
This enables media to be filtered by post parent (which for some reason isn't available by default) using the following syntax:
.../wp-json/media?filter[post_parent]=YOUR_ID
So if I want to get all media attached to an article with ID 984, I would do this:
.../wp-json/media?filter[post_parent]=984
I hope this helps anyone else facing the same problem.
If you have pdfs in your media library, this works for me:
<your_wordpress_install_base_url>/wp-json/wp/v2/media?search=.pdf
Or for example to display 25 .jpg images per page, by page number:
<your_wordpress_install_base_url>/wp-json/wp/v2/media?search=.jpg&per_page=25
Here's what I've been trying to figure out how to do for hours now.
I want the author role to be able to upload content into the media library from their posts, and to be able to view the entire media library. What I don't want is to let the author role delete any media, even their own.
I've thought about automatically switching authors to a 'media' user upon upload completion, but I was hoping there'd be a cleaner way.
Any ideas?
There's no built-in capability for "delete_media." I think this is encompassed by "delete_posts," since uploads are treated as posts. (Note that authors can delete only their own posts and attachments.)
Adding a role or capability is possible, but you'd have to replace the default media admin screens, where the delete action is controlled by the "delete_posts" cap. You don't want to mess with the core files upload.php etc. So you'd have to restrict access to them, then write your own panels for authors. You probably don't want to do this. :-)
There's a better way, however. If you assign uploads to an administrator when they are saved then authors will not be able to delete them. You can use the add_attachment and edit_attachment action hooks to change the post_author to an administrator id.
Hope that helps.
There are a number of places where WordPress will let users delete images, so trying to hide them all can be challenging (and dangerous, because a new plug-in or version of WordPress could add another). However, you can add the following function to prevent deletions and throw an error (not pretty, but effective). You could enhance this by adding a custom capability for deleting images, if you wanted a finer level of control.
add_action('delete_attachment', 'DontDeleteMedia', 11, 1);
function DontDeleteMedia($postID)
{
if (!current_user_can('manage_options')) {
exit('You cannot delete media.');
}
}
add this code in your functions.php file:
add_action('media_row_actions','users_own_attachments', 2, 1);
function users_own_attachments( $wp_query_obj ) {
if( !current_user_can( 'delete_plugins' ) ){
unset($wp_query_obj['delete']);
return $wp_query_obj;
}
}