Calling & Displaying Attachments from Sub-Pages - WordPress - php

I'm new to WordPress (duh) and trying something I'm very close to getting.
I have several Sub-Pages, each of which has attachments - images. I simply want to display these images. The client will regularly be adding more subpages so the code has to know to only display the images of its self, so to speak. An issue I'm running into is each subpage is displaying all the attachments of all subpages.
In my Functions.php I have this code to determine if the page is infact a subpage:
//find out if it is a suppage to use in page.php as function 'is_subpage'
function is_subpage() {
global $post; // load details about this page
if ( is_page() && $post->post_parent ) { // test to see if the page has a parent
return $post->post_parent; // return the ID of the parent post
} else { // there is no parent so ...
return false; // ... the answer to the question is false
}
}
In my page.php I have an If statement, for all my usual pages. It culminates in this:
elseif ( is_subpage() ) {
get_template_part( 'exhibition-template' );
get_template_part( 'normalfooter' );
}
In exhibition-template.php, where I want my images to appear I have this:
<?php
if ( is_subpage( $post->ID ) ) { //I think I screwed up here, innermost brackets
$args = array(
'order' => 'ASC',
'post_type' => 'attachment',
'post_parent' => $post->ID, //or is my issue here...?
'post_mime_type' => 'image',
'post_status' => null,
'numberposts' => -1,
);
$attachments = get_posts($args);
if ($attachments) {
foreach ($attachments as $attachment) {
echo wp_get_attachment_link($attachment->ID, 'large', false, false);
}
}
}
?>
However, what happens is each and every subpage simply displays all the images across all subpages, and frankly, I'm just too DUMB to know how to progress, or what to play with, where to start.
Any ideas?

It looks like you have a few issues.
When testing to see if a page is a subpage you should test to see if $post->post_parent is greater than 0. So like this:
if ( is_page() && $post->post_parent > 0 ) {
return $post->post_parent;
} else {
return false;
}
You do not need to pass any arguments into if ( is_subpage( $post->ID ) )... You could also just use WordPress' get_attached_media() function to get these attachements as well. This is how your exhibition-template.php could look:
if ( is_subpage() ) {
$attachments = get_attached_media('image', $post->ID);
foreach ($attachments as $attachment) {
echo wp_get_attachment_link($attachment->ID, 'large', false, false);
}
}

Related

Checking for alt text on images added to Wordpress content

I want to require that Wordpress editors must add alt text to images.
The site uses the classic editor and images are added into the content editor. I have chosen to do this in php by checking if images have alt text when saving the post. If all images do not have alt tags, then prevent the post from being published and show a message in the admin.
Here is the code I have. My problem is that the code to return the alt text always returns an empty string. Can someone help me pin down what I'm doing wrong? Also, not averse to a different approach altogether...
add_action('save_post', 'check_content_for_images');
function check_content_for_images($post_id) {
$attachments = get_children( array(
'post_parent' => $post_id,
'post_type' => 'attachment',
'numberposts' => -1, // show all -1
'post_status' => 'inherit',
'post_mime_type' => 'image',
) );
// loop through images and check that it has an alt attribute
$counter = 0;
foreach ($attachments as $attachment_id => $attachment) {
// $img = wp_get_attachment_image($attachment_id, 'full');
$alt_text = get_post_meta($attachment_id, '_wp_attachment_image_alt', true);
if(empty($alt_text)) {
$counter++;
}
}
if ( count($attachments) > $counter) {
// set a transient to show the users an admin message
set_transient( "post_not_ok", "not_ok" );
// // unhook this function so it doesn't loop infinitely
remove_action('save_post', 'check_content_for_images');
// // update the post set it to draft
wp_update_post(array('ID' => $post_id, 'post_status' => 'draft'));
// // re-hook this function
add_action('save_post', 'check_content_for_images');
} else {
delete_transient( "post_not_ok" );
}
}
/**
* Do not show post published message
*/
add_filter( 'post_updated_messages', 'abc_remove_all_messages' );
function abc_remove_all_messages( $messages ) {
if ( get_option( 'abc_post_error' ) ) {
return array();
} else {
return $messages;
}
}
// add a admin message to inform the user the post has been saved as draft.
function showAdminMessages()
{
// check if the transient is set, and display the error message
if ( get_transient( "post_not_ok" ) == "not_ok" ) {
// Shows as an error message. You could add a link to the right page if you wanted.
showMessage("One or more of the images included in this post is missing ALT text. Please ensure all images have ALT text", true);
// delete the transient to make sure it gets shown only once.
delete_transient( "post_not_ok" );
}
}
add_action('admin_notices', 'showAdminMessages');
// function to display the errormessage
function showMessage($message, $errormsg = false)
{
if ($errormsg) {
echo '<div id="message" class="error">';
}
else {
echo '<div id="message" class="updated fade">';
}
echo "<p><strong>$message</strong></p></div>";
}

The right way to close $query->is_home() loop

I have tried a lot of ways to close this loop, but my page always crashes or it does not work the right way. I am new to Wordpress and might have some wrong logic here.
The goal is that when I publish a post with category "weekspicture", there will be automatically published copy of the post 1062. It works fine otherwise, just publishes the post 1062 seven times instead of one.
I have tried to google this problem, but do not understand how should I properly close the loop? Or is that the problem anyway?
function poll_after_weekspicture($query) {
if ( $query->is_home() ) {
if ( get_post_type( $post->ID ) == 'post' && in_category(
'weekspicture') ) {
$new_post_id = copyofpoll($post);
// Give the category 14
wp_set_post_categories( $new_post_id, array('14') );
// Here I am trying to close the loop
wp_reset_postdata();
}
}
return $query;
}
And in case it matters, here the function copyofpoll(). The $weekspicture_id does not yet do anything, that is not mistake.
function copyofpoll($weekspicture_id){
$title = get_the_title('1062');
$oldpost = get_post('1062');
$post = array(
'post_title' => 'Automatic poll',
'post_status' => 'publish',
'post_type' => $oldpost->post_type,
'post_author' => 1
);
$new_post_id = wp_insert_post($post);
// Copy post metadata
$data = get_post_custom('1062');
foreach ( $data as $key => $values) {
foreach ($values as $value) {
add_post_meta( $new_post_id, $key, $value );
}
}
return $new_post_id;
}

Exclude specific category from Related Posts

Looking to exclude specific category (ID = 100) from "Related Posts" feed at bottom of Blog pages. Extra bonus if it can also exclude from the sidebar archive (not sure if they are connected??)
I'm using WP Theme "TheFox", have asked them - not part of their theme.
I "think" it has to do in the functions.php. I have found some similar questions, and code, but have not had any luck.
I'm a complete noob for .php, so be gentle :)
I've found some other attempts, no luck. Not registering or effecting the feed.
$categories_to_exclude [ 100 ];
$first_cat = false;
$categories = get_the_category( $post->ID );
while ( ! empty( $categories ) && false === $first_cat ) {
if ( in_array($categories[0]->cat_ID, $categories_to_exclude) ) {
array_shift($categories);
}
else {
$first_cat = $categories[0]->cat_ID;
}
}
What I could gather from your question is that You want to ignore one category (may be more) in the related post query?
use the following CODE (some explanation is given within the CODE in comments):
// set the category ID (or multiple category IDs)
// you want to ignore in the following array
$cats_to_ignore = array( 2 );
$categories = wp_get_post_categories( get_the_ID() );
$category_in = array_diff( $categories, $cats_to_ignore );
// ignore only if we have any category left after ignoring
if( count( $category_in ) == 0 ) {
$category_in = $categories;
}
$cat_args = array(
'category__in' => $category_in,
'posts_per_page' => 4,
'orderby' => 'date',
'post__not_in' => array( get_the_ID() )
);
$cat_query = new WP_Query( $cat_args );
while ( $cat_query->have_posts() ) : $cat_query->the_post();
/* just example markup for related posts */
echo '<h2>' . get_the_title() . '</h2>';
endwhile;
// reset $post after custom loop ends (if you need the main loop after this point)
wp_reset_postdata();
Use the below code, it must work
$categories_to_exclude [ 81, 11, 21 ];
$first_cat = false;
$categories = get_the_category( $post->ID );
while ( ! empty( $categories ) && false === $first_cat ) {
if ( in_array($categories[0]->cat_ID, $categories_to_exclude) ) {
array_shift($categories);
}
else {
$first_cat = $categories[0]->cat_ID;
}
}
You get the categories with get_the_category. Then in the while loop you skip the first category if it's 81, and look again. If it's not 81 (and you still have categories available), you asign it to $first_cat and carry on.

Custom Fields not showing in custom post type post

I have a custom post type named "Designer" Each posts will be using different unique Advanced Custom Fields as each posts has unique templates.With the below code I am able to give rules for each posts in Designer post type and save but the custom fields are not displaying on post edit pages on backend.
Normally this code should ork but no idea what happend to the code
Please Help.
add_filter('acf/location/rule_types', 'acf_location_rules_types');
function acf_location_rules_types( $choices )
{
$choices['Custom Post types']['cpt_parent'] = 'Custom post type parent';
return $choices;
}
add_filter('acf/location/rule_values/cpt_parent', 'acf_location_rules_values_cpt_parent');
function acf_location_rules_values_cpt_parent( $choices )
{
$args = array(
'hierarchical' => true,
'_builtin' => false
);
$posttypes = get_post_types( $args );
if( $posttypes )
{
foreach( $posttypes as $posttype ):
if( $posttype != 'acf' ):
$args = array(
'post_type' => 'designer',
'posts_per_page' => -1,
'post_status' => 'publish'
);
$customposts = get_posts( $args );
if ( $customposts ) {
foreach( $customposts as $custompost ){
$choices[ $custompost->ID] = $custompost->post_title;
}
}
endif;
endforeach;
}
return $choices;
}
//MATCH THE RULE
add_filter('acf/location/rule_match/cpt_parent', 'acf_location_rules_match_cpt_parent', 10, 3);
function acf_location_rules_match_cpt_parent( $match, $rule, $options )
{
global $post;
$selected_post = (int) $rule['value'];
// post parent
$post_parent = $post->post_parent;
if( $options['page_parent'] ) {
$post_parent = $options['page_parent'];
}
if ($rule['operator'] == "=="){
$match = ( $post_parent == $selected_post );
}
elseif ($rule['operator'] != "!="){
$match = ( $post_parent != $selected_post );
}
return $match;
}
Your Artist Collection field group is set to only appear on one post, the post Designer Post 1 which is a Designer Post type.
I don't understand what all the code is for? Just create a different field group for each post that needs a different field group and a separate rule for each.
Ok sorry I understand the issue now and I have recreated the issue on my local install.
On the line of code below you are looking for the post_parent but I think you should be looking for the ID.
I changed this:
$post_parent = $post->post_parent;
to this:
$post_parent = $post->ID;
and it's working for me.
If I understand your problem correctly, in wp-admin post edit page click on screen options on the upper right corner. In the menu that appears make sure the Custom fields is selected. This will make the custom fields appear for edit.

How to separate gallery from content in wordpress?

What I want to do
I have a website that uses a CMS I wrote some time ago, and now I am trying to migrate it to wordpress.
At the existing implementation, when someone writes a post, they can add some extra images that are shown as a gallery at the end of the post, as you can see in this page for example (sorry for non english page): http://apollonpatras.gr/news/562/i-bradia-ton-xorigon-parousiasi-xorigikou-programmatos-kai-eisitirion-diarkeias/.
How I think I can do it
I am thinking about letting the users create wordpress galleries and at post save time intercept the post contents and store the gallery image ids in a postmeta field so I can show them however I want.
Also, I will have to strip the galleries from the content before they are shown, since I will show them in my own way later.
What I am trying so far
add_filter('content_save_pre', 'intercept_galleries', 99);
function intercept_galleries($content) {
if (get_post_type() !== 'post') {
return $content;
}
if (has_shortcode($content, 'gallery')) {
// The [gallery] short code exists.
$a = get_post_gallery(0, false);
update_post_meta(get_the_ID(), 'has_gallery', 1);
update_post_meta(get_the_ID(), 'gallery_items', $a['ids']);
} else {
update_post_meta(get_the_ID(), 'has_gallery', 0);
update_post_meta(get_the_ID(), 'gallery_items', "");
}
return $content;
}
add_filter('the_content', 'remove_shortcodes_from_content');
function remove_shortcodes_from_content($content) {
return strip_shortcodes($content);
}
Where it goes wrong
Looks like when the post is originally saved, the postmeta field "has_gallery" is set to 1, but the field "gallery_items" is empty.
When I go to the wordpress editor and just hit update, the fields are absolutely correct.
Also the hook to remove shortcodes from the content is working.
What am I looking for
How can I fix this problem? Also, is there something wrong/stupid with the way I decided to do this? Would some other way be cleaner/easier/faster etc?
Thank you for your time
I've done this a few times and here's how I do it.
First I create a function that will display the gallery in the way that I want. You can modify this according to how you require you gallery markup to be:
function my_gallery_shortcode( $attr ) {
$post = get_post();
if ( ! empty( $attr['ids'] ) ) {
$attr['include'] = $attr['ids'];
}
extract( shortcode_atts( array(
'order' => 'ASC',
'orderby' => 'post__in',
'id' => $post->ID,
'columns' => 3,
'size' => 'large',
'include' => '',
), $attr));
$id = (int) $id;
$columns = (int) $columns;
if ( 'RAND' == $order ) {
$orderby = 'none';
}
if ( ! empty( $include ) ) {
$_attachments = get_posts( array( 'include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby ) );
$attachments = array();
foreach ( $_attachments as $key => $val ) {
$attachments[$val->ID] = $_attachments[$key];
}
}
if ( empty( $attachments ) ) {
return '';
}
$output = '<div class="slideshow"><ul>';
foreach ( $attachments as $id => $attachment ) {
$thumb = wp_get_attachment_image_src( $id, 'large', false );
$output .= '<li><img src="' . $thumb[0] . '" width="' . $thumb[1] . '" height="' . $thumb[2] . '" alt="' . get_post_meta( $id, '_wp_attachment_image_alt', true ) . '" /></li>';
}
$output .= '</ul></div>';
return $output;
}
You can complicate or simply the function above according to your requirements.
Then in your theme's functions.php add this:
add_shortcode( 'gallery', 'my_gallery_shortcode' );
Now you have two choices:
1) You can allow your user to add a gallery to the main page content by way of them editing the page in question and going to Media > Create Gallery
This will insert the gallery short code which will be formatted according to your function my_gallery_shortcode(), however the gallery can be managed via WordPress's gallery functionality in the admin area and is stored in the database by WordPress in the conventional way.
or
2) You could create a separate WYSIWYG field either through additional code in your functions.php file, or by using a plugin such as Advanced Custom Fields. You would then use this additional WYSIWYG field to allow the user to insert the gallery shortcode in the same way as above. This is virtually the same as option 1 above but you'd have more flexibility as to where you output and position the gallery on the page.
I hope this helps anyone looking to do the same thing.

Categories