I'm using the Dazzling theme with the WooCommerce Plugin and on the WooCommerce pages that have products on them, the product image is also showing up as my featured image. I have a featured image set, but the product image seems be overwriting it.
The Feature image I have set is for all the shop pages is home_off.jpg. The cart and checkout pages look fine and are loading the proper feature image (no product images on those pages) So I guess the product image on the catalogue pages is using same/similar post_thumbnail code?
the code snippet I'm using to load my featured image as the background of a div is
<?php if (has_post_thumbnail( $post->ID ) ): ?>
<?php $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ),
'single-post-thumbnail' ); ?>
<div id="featureImg" style="background-image: url('<?php echo $image[0]; ?>')">
</div>
<?php endif; ?>
You can see it best on this page http://dev.tdfinternational.net/index.php/product/finding-your-place-the-tdf-map-book/
But cart, checkout, etc, are looking good!
http://dev.tdfinternational.net/index.php/cart/
Any idea how to keep this from happening?
Ok, so what I recommend is that you create separate metabox for your posts and pages that will have the ability to use different image as your breadcrumbs image.
Create metabox
In your functions.php or wherever you put your metaboxes, put this code (should be working):
add_action( 'add_meta_boxes', 'my_add_custom_box' );
function my_add_custom_box($postType) {
$types = array('page', 'post');
if(in_array($postType, $types)){
add_meta_box(
'breadcrumbs-image-metabox-options',
esc_html__('Breadcrumbs', 'yourtheme' ),
'breadcrumbs_image_meta_box',
$postType,
'side',
'low'
);
}
}
if (!function_exists('breadcrumbs_image_meta_box') ) {
function breadcrumbs_image_meta_box($post) {
$custom = get_post_custom( $post->ID );
$breadcrumbs_image = (isset($custom["breadcrumbs_image"][0])) ? $custom["breadcrumbs_image"][0] : '';
wp_nonce_field( 'breadcrumbs_meta_box', 'breadcrumbs_meta_box_nonce' );
?>
<style type="text/css">
.hidden{display: none;}
.postbox .separator{padding-top: 0;margin-top: 20px;}
</style>
<p class="separator">
<input id="breadcrumbs_image_input" type="hidden" name="breadcrumbs_image" value="<?php echo esc_html($breadcrumbs_image); ?>"/>
<a title="<?php esc_html_e('Set Breadcrumbs Image', 'mytheme'); ?>" href="#" id="add-post-breadcrumbs_image">
<?php
if(!empty($custom["breadcrumbs_image"][0]) ){
echo '<img width="254" src="'.esc_url($breadcrumbs_image).'" />';
} else{
esc_html_e('Set Breadcrumbs Image', 'mytheme');
} ?></a>
<?php
if (empty($custom["breadcrumbs_image"][0])) {
echo '<a title="'.esc_html__('Remove Breadcrumbs Image', 'mytheme').'" href="#" id="remove-post-breadcrumbs_image" class="hidden">'.esc_html__('Remove Breadcrumbs Image', 'mytheme').'</a>';
} else{
echo '<a title="'.esc_html__('Remove Breadcrumbs Image', 'mytheme').'" href="#" id="remove-post-breadcrumbs_image" >'.esc_html__('Remove Breadcrumbs Image', 'mytheme').'</a>';
}
?>
</p>
<?php
}
}
add_action( 'save_post', 'save_breadcrumbs_image_meta_box' );
if ( ! function_exists( 'save_breadcrumbs_image_meta_box' ) ){
function save_breadcrumbs_image_meta_box( $post_id ){
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if( !current_user_can( 'edit_pages' ) ) {
return;
}
if( !isset( $_POST['breadcrumbs_meta_box_nonce'] ) || !wp_verify_nonce( $_POST['breadcrumbs_meta_box_nonce'], 'breadcrumbs_meta_box' ) ) {
return;
}
$breadcrumbs_image = (isset($_POST["breadcrumbs_image"]) && $_POST["breadcrumbs_image"]!='') ? $_POST["breadcrumbs_image"] : '';
update_post_meta($post_id, "breadcrumbs_image", $breadcrumbs_image);
}
}
add_action('admin_enqueue_scripts', 'backend_scripts');
if ( ! function_exists( 'backend_scripts' ) ){
function backend_scripts() {
wp_enqueue_script( 'breadcrumbs_image_upload', get_template_directory_uri().'/js/admin.js' );
}
}
The first part creates a breadcrumbs metabox in your pages and posts. For woocommerce product you should probably add product to the $types array.
Then you create a metabox and save function for it. Now, since you want to have the functionality of a Featured image, you'll need some jquery to make it all work. That's why you need to enqueue a separate script that will appear only in your backend (that's why you're hooking to admin_enqueue_scripts).
And in your admin.js that you've put in your js theme folder, just put this:
jQuery(document).ready(function($) {
"use strict";
//Breadcrumbs Image
$(document).on('click', '#add-post-breadcrumbs_image', upload_breadcrumbs_image_button);
function upload_breadcrumbs_image_button(e) {
e.preventDefault();
var $input_field = $(this).prev();
var $image = $('#add-post-breadcrumbs_image');
var custom_uploader = wp.media.frames.file_frame = wp.media({
title: 'Add Breadcrumbs Image',
button: {
text: 'Add Breadcrumbs Image'
},
multiple: false
});
custom_uploader.on('select', function() {
var attachment = custom_uploader.state().get('selection').first().toJSON();
$input_field.val(attachment.url);
$image.html('');
$image.html('<img width="254" src="'+attachment.url+'" />');
$('#remove-post-breadcrumbs_image').removeClass('hidden');
});
custom_uploader.open();
}
$(document).on('click', '#remove-post-breadcrumbs_image', remove_breadcrumbs_image_button);
function remove_breadcrumbs_image_button(e){
e.preventDefault();
var $input_field = $('#breadcrumbs_image_input');
var $image = $('#add-post-breadcrumbs_image');
$input_field.val('');
var title = $image.attr('title');
$image.html(title);
$('#remove-post-breadcrumbs_image').addClass('hidden');
}
});
I've tested it in Twenty Fifteen and it's working:
And you can then use it by simply
$custom = get_post_custom(get_the_ID());
$custom['breadcrumbs_image'][0];
Hope this helps :)
Related
I would like to add a meta box to a custom post type that works like the product gallery meta box that Woocommerce uses. I actually have Woocommerce installed on this project.
I found the code that Woocommerce uses to create the product gallery meta box, and I can get the meta box to display, but the jQuery is not there to pull up the media lightbox that Wordpress uses to add images. I don't know if there is a hook I need to add or if I should enqueue a script?
Here is what I have so far (based on the WooCommerce code but altered for my use)
<?php
function add_mtg_meta_boxes() {
add_meta_box('mtg_hotel_gallery_meta_box', 'Hotel Gallery', 'setup_mtg_hotel_gallery_meta_box', 'meeting', 'side', 'low');
}
add_action('add_meta_boxes', 'add_mtg_meta_boxes');
function setup_mtg_hotel_gallery_meta_box($post) {
echo '<input type="hidden" name="mtg_hotel_gallery_meta_box_nonce" value="'. wp_create_nonce('mtg_hotel_gallery_meta_box'). '" />';
?>
<div id="product_images_container">
<ul class="product_images">
<?php
if ( metadata_exists( 'post', $post->ID, '_product_image_gallery' ) ) {
$product_image_gallery = get_post_meta( $post->ID, '_product_image_gallery', true );
} else {
// Backwards compatibility.
$attachment_ids = get_posts( 'post_parent=' . $post->ID . '&numberposts=-1&post_type=attachment&orderby=menu_order&order=ASC&post_mime_type=image&fields=ids&meta_key=_woocommerce_exclude_image&meta_value=0' );
$attachment_ids = array_diff( $attachment_ids, array( get_post_thumbnail_id() ) );
$product_image_gallery = implode( ',', $attachment_ids );
}
$attachments = array_filter( explode( ',', $product_image_gallery ) );
$update_meta = false;
$updated_gallery_ids = array();
if ( ! empty( $attachments ) ) {
foreach ( $attachments as $attachment_id ) {
$attachment = wp_get_attachment_image( $attachment_id, 'thumbnail' );
// if attachment is empty skip
if ( empty( $attachment ) ) {
$update_meta = true;
continue;
}
echo '<li class="image" data-attachment_id="' . esc_attr( $attachment_id ) . '">
' . $attachment . '
<ul class="actions">
<li>' . __( 'Delete', 'woocommerce' ) . '</li>
</ul>
</li>';
// rebuild ids to be saved
$updated_gallery_ids[] = $attachment_id;
}
// need to update product meta to set new gallery ids
if ( $update_meta ) {
update_post_meta( $post->ID, '_product_image_gallery', implode( ',', $updated_gallery_ids ) );
}
}
?>
</ul>
<input type="hidden" id="product_image_gallery" name="product_image_gallery" value="<?php echo esc_attr( $product_image_gallery ); ?>" />
</div>
<p class="add_product_images hide-if-no-js">
<?php _e( 'Add product gallery images', 'woocommerce' ); ?>
</p>
<?php
}
function save_mtg_hotel_gallery_meta_box($post_id) {
// check nonce
if (!isset($_POST['mtg_gallery_meta_box_nonce']) || !wp_verify_nonce($_POST['mtg_gallery_meta_box_nonce'], 'mtg_gallery_meta_box')) {
return $post_id;
}
// check capabilities
if ('meeting' == $_POST['post_type']) {
if (!current_user_can('edit_post', $post_id)) {
return $post_id;
}
} elseif (!current_user_can('edit_page', $post_id)) {
return $post_id;
}
// exit on autosave
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return $post_id;
}
$attachment_ids = isset( $_POST['product_image_gallery'] ) ? array_filter( explode( ',', wc_clean( $_POST['product_image_gallery'] ) ) ) : array();
update_post_meta( $post_id, '_product_image_gallery', implode( ',', $attachment_ids ) );
}
add_action('save_post', 'save_mtg_hotel_gallery_meta_box');
?>
First To Enable the Wordpress Wp Media Uploader you have to enqueue the media js by using wp_enqueue_media(); inside you functions.php admin_enqueue_scripts hook,
function enqueue_media_uploader() {
wp_enqueue_media();
}
add_action( 'admin_enqueue_scripts', 'enqueue_media_uploader' );
and then you have to assign an id to your anchor which clicked media.uploader
will pop up.Like this...
<?php _e( 'Add product gallery images', 'woocommerce' ); ?>
And then to bind the onclick listener to add_product_image id add this line of code to your custom js file...
jQuery('#add_product_image').click(function(e) {
e.preventDefault();
var image = wp.media({
title: 'Upload Image',
multiple: false
}).open()
.on('select', function(e){
var uploaded_image = image.state().get('selection').first();
var image_url = uploaded_image.toJSON().url;
var image_id = uploaded_image.toJSON().id;
});
});
Here image_url var is uploaded or selected image src url and image_id var is id of the image or attachment.
I have customised my Wordpress site design to use the featured image for posts quite excessively. This is why I need to require all post made by non-admins to require a set featured image.
How is this possible?
You need to hook the Publish Action in a custom PlugIn you write. Although this is to require a title, this should get you started, you just need to check if a featured image was assigned.
add_action( 'pre_post_update', 'bawdp_dont_publish' );
function bawdp_dont_publish()
{
global $post;
if ( strlen( $post->title ) < 10 ) {
wp_die( 'The title of your post have to be 10 or more !' );
}
}
Look at (has_post_thumbnail( $post->ID )) to determine if a post has a featured image.
Given Gary's example above, I've written the following to my functions.php file:
function featured_image_requirement() {
if(!has_post_thumbnail()) {
wp_die( 'You forgot to set the featured image. Click the back button on your browser and set it.' );
}
}
add_action( 'pre_post_update', 'featured_image_requirement' );
I'd much rather see this in a plugin as well - there's one called Mandatory Field but it doesn't work with scheduled posts. Both are not really eloquent solutions.
you can use a plugin
https://wordpress.org/plugins/require-featured-image/
or you can copy and paste below code in your wordpress theme functions.php file:
<?php
/**
* Require a featured image to be set before a post can be published.
*/
add_filter( 'wp_insert_post_data', function ( $data, $postarr ) {
$post_id = $postarr['ID'];
$post_status = $data['post_status'];
$original_post_status = $postarr['original_post_status'];
if ( $post_id && 'publish' === $post_status && 'publish' !== $original_post_status ) {
$post_type = get_post_type( $post_id );
if ( post_type_supports( $post_type, 'thumbnail' ) && ! has_post_thumbnail( $post_id ) ) {
$data['post_status'] = 'draft';
}
}
return $data;
}, 10, 2 );
add_action( 'admin_notices', function () {
$post = get_post();
if ( 'publish' !== get_post_status( $post->ID ) && ! has_post_thumbnail( $post->ID ) ) { ?>
<div id="message" class="error">
<p>
<strong><?php _e( 'Please set a Featured Image. This post cannot be published without one.' ); ?></strong>
</p>
</div>
<?php
}
} );
Is it possible to build an option in Wordpress which allows user to customise placement of featured image?
Currently the theme I am building, puts the featured image as a banner across the top of the post. Have some users requesting for option to be able to have featured images appear top right of the post with text wrapping around it.
Not sure about how to approach this. My first thought is to put an option in the customiser but I'm concerned this will apply to all blog posts rather than on an individual basis.
Another idea is to build a metabox into the post editing screen (underneath feat. image box) and then build a function to hook into wp post.
I've scoured over google on ways how to do this but all I can find so far is information on how to edit content.php to universally change/edit placement of all featured images.
It's hard to give an exact answer without knowing how your template is marked up, but I think you'll have two options of doing this. Either use a plugin (Advanced Custom Fields), or the solution you mentioned of adding a meta box to the post editor.
I would recommend Option 1 because the plugin is stable, configurable, and will save you some time if you need to add more fields.
Option 1: Use Advanced Custom Fields
Download and install the plugin from their site: https://www.advancedcustomfields.com
Use the plugin to add a custom field. These directions might help: https://www.advancedcustomfields.com/resources/creating-a-field-group/
Make note of the Field Name as you will need this in your code. You might use something such as image_placement. I'd recommend setting up a select box with values such as Left, Center, and Right.
Then, in your PHP template file, you'll want something like this:
<?php if( get_option('image_placement') === 'left' ) : ?>
// Write the markup here when the image be left-aligned
<?php else if( get_option('image_placement') === 'right' ) : ?>
// Write the markup here when the image should be right-aligned
<?php else : ?>
// Write the markup here when the image should be shown as a banner
<?php endif; ?>
Option 2: Add a custom meta box to each post
Add the following code to your functions.php:
// add the meta box to the post editor page
function add_image_meta_box( $post ) {
add_meta_box( 'image_meta_box', 'Image Placement', 'image_build_meta_box', 'post', 'side', 'low' );
}
add_action( 'add_meta_boxes', 'add_image_meta_box' );
// build the front-end for the meta box (shown on the post editor page)
function image_build_meta_box( $post ) {
wp_nonce_field( basename( __FILE__ ), 'image_meta_box_nonce' );
$image_placement = get_post_meta( $post->ID, '_post_image_placement' );
?>
<h3>Image Placement URL</h3>
<select name="image_placement">
<option value="left" <?php ($image_placement[0] === 'left') ?; echo 'selected'; ?>>Left</option>
<option value="center" <?php ($image_placement[0] === 'center') ?; echo 'selected'; ?>>Center</option>
<option value="right" <?php ($image_placement[0] === 'right') ?; echo 'selected'; ?>>Right</option>
</select>
<?php
}
// save the setting
function image_save_meta_box_data( $post_id ) {
// Check the user's permissions.
if ( !current_user_can( 'edit_post', $post_id ) ) {
return;
}
$image_placement = $_POST['image_placement'];
if( isset( $image_placement ) ){
update_post_meta( $post_id, '_post_image_placement', sanitize_text_field( $image_placement ) );
}
}
add_action( 'save_post', 'image_save_meta_box_data' );
This will add a field to each of your posts which can be used in the markup like thus:
<?php $image_placement = get_post_meta( $post->ID, '_post_image_placement' )[0]; ?>
<?php if( $image_placement === 'left' ) : ?>
// Write the markup here when the image be left-aligned
<?php else if( $image_placement === 'right' ) : ?>
// Write the markup here when the image should be right-aligned
<?php else : ?>
// Write the markup here when the image should be shown as a banner
<?php endif; ?>
kudos to #rideron89 for helping me with the solution. So here it is if anyone needs to use it (in some implementation):
I'm keeping functions.php a bit clean so I put it into another php file within 'incl' folder and it gets included within functions.php"
// add the meta box to the post editor page
function add_image_meta_box( $post ) {
add_meta_box( 'image_meta_box', 'Featured Image Placement', 'image_build_meta_box', 'post', 'side', 'low' );
}
add_action( 'add_meta_boxes', 'add_image_meta_box' );
// build the front-end for the meta box (shown on the post editor page)
function image_build_meta_box( $post ) {
wp_nonce_field( basename( __FILE__ ), 'image_meta_box_nonce' );
$image_placement_array = get_post_meta( $post->ID, '_post_image_placement' );
$image_placement = implode (" ",$image_placement_array);
?>
<p>Please select the layout/alignment of your featured image <em>(default is full width banner)</em></p>
<select name="image_placement">
<option value="default" name="feat_img_align" <?php if($image_placement === 'default'){ echo "selected"; } ?>>Default</option>
<option value="left" name="feat_img_align" <?php if($image_placement === 'left'){ echo "selected"; } ?>>Left</option>
<option value="right" name="feat_img_align" <?php if($image_placement === 'right'){ echo "selected"; } ?>>Right</option>
</select>
<?php
}
// save the setting
function image_save_meta_box_data( $post_id ) {
// Check the user's permissions.
if ( !current_user_can( 'edit_post', $post_id ) ) {
return;
}
$image_placement = $_POST['image_placement'];
if( isset( $image_placement ) ){
update_post_meta( $post_id, '_post_image_placement', sanitize_text_field( $image_placement ) );
}
}
add_action( 'save_post', 'image_save_meta_box_data' );
The code that I inserted into the post content.php template was:
<?php
$post_feat_img = quick_resize_to_ratio_and_size(get_post_thumbnail_id($post->ID),1,1,250);
$alt_text = get_post_meta(get_post_thumbnail_id($post->ID), '_wp_attachment_image_alt', true);
$image_placement_array = get_post_meta( $post->ID, '_post_image_placement' );
$image_placement = implode (" ",$image_placement_array);
?>
<?php if ($image_placement === 'default') { ?>
<p><?php echo get_the_post_thumbnail($post->ID, 'large', array( 'class'=>'img-responsive center-block img-thumbnail')); ?></p>
<?php } else if ($image_placement === 'left') { ?>
<img src="<?php echo $post_feat_img; ?>" alt="<?php echo $alt_text ?>" class="alignFeatleft img-thumbnail img-responsive">
<?php } else if ($image_placement === 'right') { ?>
<img src="<?php echo $post_feat_img; ?>" alt="<?php echo $alt_text ?>" class="alignFeatRight img-thumbnail img-responsive">
<?php } else { ?>
<p><?php echo get_the_post_thumbnail($post->ID, 'large', array( 'class'=>'img-responsive center-block img-thumbnail')); ?></p>
<?php } ?>
<?php the_content(); ?>
I'm building a Woocommerce site.
In the Shop grid overview, I'm showing the Featured Image of each product (see link). This Featured image will be cropped to maintain the same image ratio in the Shop Grid.
In the Single Product page, I managed to hide the Featured Image, and make the first of the thumbnails appear in big (see link).
I did so with the following code:
<div class="images">
<?php
$imgid = $product->get_gallery_attachment_ids();
?>
<a href="<?php echo wp_get_attachment_url( $imgid[0] ); ?>"
class="woocommerce-main-image zoom first"
rel="lightbox[product-gallery]">
<img src="<?php echo wp_get_attachment_url( $imgid[0] ); ?>" alt="">
</a>
<?php do_action( 'woocommerce_product_thumbnails' ); ?>
</div>
<script>
jQuery('.thumbnails.columns-3 a:first-child').hide()
</script>
The first part will find the first image in the gallery array and show it in big size (class woocommerce-main-image zoom first) while linking to the lightbox.
Then I call the thumbnails, and I hide the first one using jQuery to avoid a duplicate (first big size image and first thumb are the same).
The problem now is that in the Lightbox, the first image will appear duplicated, as it exists two times in the array, the first one I call in big, and the one from the thumbs array.
Any tips on how to not show the image twice in the lightbox?
Someone mentioned that I should filter the following function, but as of now I don't know how to do that.
public function get_gallery_attachment_ids() {
return apply_filters( 'woocommerce_product_gallery_attachment_ids', array_filter( (array) explode( ',', $this->product_image_gallery ) ), $this );
}
I think that using Multiple Post Thumbnails is the easiest solution. It is exactly for displaying different featured images in different locations.
Option #1: Multiple Post Thumbnails
You would install the plugin and then add the following to your theme's functions.php. It isn't 100% tested so there may be a stray typo or something. Full documentation is here.
// register the new thumbnail
function so_31835142_register_extra_thumbnail() {
if (class_exists('MultiPostThumbnails')) {
new MultiPostThumbnails(
array(
'label' => __('Product Loop Image', 'your-theme'),
'id' => 'product-loop-image',
'post_type' => 'product'
)
);
}
}
add_action( 'after_setup_theme', 'so_31835142_register_extra_thumbnail' );
// remove the existing loop thumbnail
function so_31835142_swap_loop_product_thumbnail(){
if (class_exists('MultiPostThumbnails')) {
remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10 );
add_action( 'woocommerce_before_shop_loop_item_title', 'so_31835142_loop_product_thumbnail', 10 );
}
}
add_action( 'woocommerce_before_shop_loop_item, 'so_31835142_swap_loop_product_thumbnail' );
// Display the Secondary Thumbnail
function so_31835142_loop_product_thumbnail(){
global $product;
$thumbnail = MultiPostThumbnails::get_post_thumbnail(
'product',
'product-loop-image',
$product->id,
'shop_catalog'
);
if ( $thumbnail ) {
return $thumbnail;
} elseif ( wc_placeholder_img_src() ) {
return wc_placeholder_img( $size );
}
}
Then to use it, you'd set "Product Loop Image" the same way you traditionally set the "featured image". And this new image would be used in the loop.
Option #2: Template Overrides
But as an alternative, if you insist, you can write a custom single-product/product-image.php template and put it in your theme's woocommerce templates folder.
In this alternative we will only show images from the image gallery on the single product page, $product->get_gallery_attachment_ids(), and we will use a basic PHP loop and counter system to display the images differently depending on where they are in the loop. IE. the first image will display as the post thumbnail used to display and the remaining items will display as thumbs.
This section I have tested, so it should (in theory) be good to go.
<?php
/**
* Single Product Image
*
* #author WooThemes
* #package WooCommerce/Templates
* #version 2.0.14
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
global $post, $woocommerce, $product;
?>
<div class="images">
<?php
$attachment_ids = $product->get_gallery_attachment_ids();
if ( $attachment_ids ) {
$loop = 0;
$columns = apply_filters( 'woocommerce_product_thumbnails_columns', 3 );
$attachment_count = count( $attachment_ids );
foreach ( $attachment_ids as $attachment_id ) {
// here's your first image
if( $loop === 0 ){
$image_title = esc_attr( get_the_title( $attachment_id ) );
$image_caption = get_post( $attachment_id )->post_excerpt;
$image_link = wp_get_attachment_url( $attachment_id );
$image = wp_get_attachment_image( $attachment_id, apply_filters( 'single_product_large_thumbnail_size', 'shop_single' ), null, array(
'title' => $image_title,
'alt' => $image_title
) );
if ( $attachment_count > 0 ) {
$gallery = '[product-gallery]';
} else {
$gallery = '';
}
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '%s', $image_link, $image_caption, $image ), $post->ID );
// resume the thumbnails for the rest
} else {
// open the thumbnails div
if( $loop === 1 ) { ?>
<div class="thumbnails <?php echo 'columns-' . $columns; ?>">
<?php }
$classes = array( 'zoom' );
if ( $loop == 0 || $loop % $columns == 0 )
$classes[] = 'first';
if ( ( $loop + 1 ) % $columns == 0 )
$classes[] = 'last';
$image_link = wp_get_attachment_url( $attachment_id );
if ( ! $image_link )
continue;
$image_title = esc_attr( get_the_title( $attachment_id ) );
$image_caption = esc_attr( get_post_field( 'post_excerpt', $attachment_id ) );
$image = wp_get_attachment_image( $attachment_id, apply_filters( 'single_product_small_thumbnail_size', 'shop_thumbnail' ), 0, $attr = array(
'title' => $image_title,
'alt' => $image_title
) );
$image_class = esc_attr( implode( ' ', $classes ) );
echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', sprintf( '%s', $image_link, $image_class, $image_caption, $image ), $attachment_id, $post->ID, $image_class );
// close the thumbnails div
if( $loop === $attachment_count ) { ?>
</div>
<?php }
}
$loop++;
}
?>
<?php
} else {
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '<img src="%s" alt="%s" />', wc_placeholder_img_src(), __( 'Placeholder', 'woocommerce' ) ), $post->ID );
}
?>
</div>
I have customised my Wordpress site design to use the featured image for posts quite excessively. This is why I need to require all post made by non-admins to require a set featured image.
How is this possible?
You need to hook the Publish Action in a custom PlugIn you write. Although this is to require a title, this should get you started, you just need to check if a featured image was assigned.
add_action( 'pre_post_update', 'bawdp_dont_publish' );
function bawdp_dont_publish()
{
global $post;
if ( strlen( $post->title ) < 10 ) {
wp_die( 'The title of your post have to be 10 or more !' );
}
}
Look at (has_post_thumbnail( $post->ID )) to determine if a post has a featured image.
Given Gary's example above, I've written the following to my functions.php file:
function featured_image_requirement() {
if(!has_post_thumbnail()) {
wp_die( 'You forgot to set the featured image. Click the back button on your browser and set it.' );
}
}
add_action( 'pre_post_update', 'featured_image_requirement' );
I'd much rather see this in a plugin as well - there's one called Mandatory Field but it doesn't work with scheduled posts. Both are not really eloquent solutions.
you can use a plugin
https://wordpress.org/plugins/require-featured-image/
or you can copy and paste below code in your wordpress theme functions.php file:
<?php
/**
* Require a featured image to be set before a post can be published.
*/
add_filter( 'wp_insert_post_data', function ( $data, $postarr ) {
$post_id = $postarr['ID'];
$post_status = $data['post_status'];
$original_post_status = $postarr['original_post_status'];
if ( $post_id && 'publish' === $post_status && 'publish' !== $original_post_status ) {
$post_type = get_post_type( $post_id );
if ( post_type_supports( $post_type, 'thumbnail' ) && ! has_post_thumbnail( $post_id ) ) {
$data['post_status'] = 'draft';
}
}
return $data;
}, 10, 2 );
add_action( 'admin_notices', function () {
$post = get_post();
if ( 'publish' !== get_post_status( $post->ID ) && ! has_post_thumbnail( $post->ID ) ) { ?>
<div id="message" class="error">
<p>
<strong><?php _e( 'Please set a Featured Image. This post cannot be published without one.' ); ?></strong>
</p>
</div>
<?php
}
} );