Skip to content

Instantly share code, notes, and snippets.

@vralle
Last active December 12, 2015 00:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vralle/a74c5878d85fe222904d to your computer and use it in GitHub Desktop.
Save vralle/a74c5878d85fe222904d to your computer and use it in GitHub Desktop.
Image Shortcode: Return images with WP markup
<?php namespace Vralle\Plugin\Shortcode\Img;
/*-------------------------------------------------------------------
* Register UI
*-----------------------------------------------------------------*/
function editor_ui() {
global $_wp_additional_image_sizes;
$default_sizes = [
'thumbnail' => esc_html__( 'Thumbnail' ),
'medium' => esc_html__( 'Medium' ),
'large' => esc_html__( 'Large' ),
'full' => esc_html__( 'Full size' ),
];
$sizes_available = [];
foreach ( apply_filters( 'image_size_names_choose', $default_sizes ) as $key => $name ) {
$size = get_option( "${key}_size_w" );
if ( false === $size ) {
if ( array_key_exists( $key, $_wp_additional_image_sizes ) ) {
$size = $_wp_additional_image_sizes[ $key ]['width'];
}
}
$size_str = $size ? " ({$size}px)" : '';
$sizes_available[$key] = esc_attr( "{$name}{$size_str}" );
}
shortcode_ui_register_for_shortcode( 'img',
[
'label' => esc_html__( 'Image', 'image-shortcake' ),
'listItemImage' => 'dashicons-format-image',
'attrs' => [
[
'label' => esc_html__( 'Choose Attachment', 'image-shortcake' ),
'attr' => 'id',
'type' => 'attachment',
'libraryType' => [ 'image' ],
'addButton' => esc_attr__( 'Select Image', 'image-shortcake' ),
'frameTitle' => esc_attr__( 'Select Image', 'image-shortcake' ),
],
[
'label' => esc_html__( 'Image size', 'image-shortcake' ),
'attr' => 'size',
'type' => 'select',
'value' => get_option( 'image_default_size' ),
'options' => $sizes_available,
],
[
'label' => esc_html__( 'Alt', 'image-shortcake' ),
'attr' => 'alt',
'type' => 'text',
'encode' => true,
'description' => esc_html__( 'Quote marks and HTML tags are not allowed', 'image-shortcake' ),
'meta' => [
'placeholder' => esc_attr__( 'Alt text for the image', 'image-shortcake' ),
]
],
[
'label' => esc_html__( 'Caption', 'image-shortcake' ),
'attr' => 'caption',
'type' => 'text',
'encode' => true,
'description' => esc_html__( 'Quote marks and HTML tags are not allowed', 'image-shortcake' ),
'meta' => [
'placeholder' => esc_attr__( 'Caption for the image', 'image-shortcake' ),
]
],
[
'label' => esc_html__( 'Alignment', 'image-shortcake' ),
'attr' => 'align',
'type' => 'select',
'value' => get_option( 'image_default_align' ) ? get_option( 'image_default_align' ) : 'center',
'options' => [
'left' => esc_attr__( 'Left', 'image-shortcake' ),
'center' => esc_attr__( 'Center', 'image-shortcake' ),
'right' => esc_attr__( 'Right', 'image-shortcake' ),
'none' => esc_attr__( 'None', 'image-shortcake' ),
],
],
[
'label' => esc_html__( 'Link to', 'image-shortcake' ),
'attr' => 'linkto',
'type' => 'select',
'value' => get_option( 'image_default_link_type' ) ? get_option( 'image_default_link_type' ) : 'file',
'options' => [
'none' => esc_attr__( 'None (no link)', 'image-shortcake' ),
'post' => esc_attr__( 'Link to attachment post', 'image-shortcake' ),
'file' => esc_attr__( 'Link to file', 'image-shortcake' ),
'custom' => esc_attr__( 'Custom link', 'image-shortcake' ),
],
],
[
'label' => esc_html__( 'Custom link', 'image-shortcake' ),
'attr' => 'url',
'type' => 'text',
'meta' => [
'placeholder' => esc_attr__( 'URL to link to (if above link is "custom")', 'image-shortcake' ),
]
],
],
]
);
}
add_action( 'register_shortcode_ui', __NAMESPACE__ . '\\editor_ui' );
function action_enqueue_shortcode_ui() {
wp_enqueue_script( 'image-shortcake-admin', plugin_dir_url( __FILE__ ) . 'img-admin.js' );
}
add_action( 'enqueue_shortcode_ui', __NAMESPACE__ . '\\action_enqueue_shortcode_ui' );
function img_shortcode( $attrs_in, $content = null, $shortcode_tag ) {
$attrs = shortcode_atts( [
// Attachments
'attachment' => 0,
'size' => get_option( 'image_default_size' ),
// Images attributes:
'src' => '',
'width' => '',
'height' => '',
'classes' => '',
'align' => get_option( 'image_default_align' ),
'caption' => '',
// Links setup
'linkto' => get_option( 'image_default_link_type' ),
'url' => '',
], $attrs_in, $shortcode_tag );
// exit if empty image
if ( empty( $attrs['attachment'] ) && empty( $attrs['src'] ) ) return;
$classes = setup_image_class( $attrs );
$image_attrs = get_image_attrs( $attrs, $classes );
// The Image does not have link by default
$have_link = false;
if( $attrs['attachment'] ) {
// Setup attrs for WP. Bulletproof?
$image_attrs = array_diff_key( $image_attrs, array_flip( ['src', 'href', 'url', 'width', 'height'] ) );
$id = intval( $attrs['attachment'] );
$image_html = wp_get_attachment_image( $id, $attrs['size'], false, $image_attrs );
} else {
$width = isset( $image_attrs['width'] ) ? intval( $image_attrs['width'] ) : '';
$height = isset( $image_attrs['height'] ) ? intval( $image_attrs['height'] ) : '';
// Bulletproof?
$image_attrs = array_diff_key( $image_attrs, array_flip( ['src', 'width', 'height', 'url', 'href' ] ) );
$image_html = '<img src="' . esc_url( $attrs['src'] ) . '" ' . \image_hwstring( $width, $height ) . attibutes_to_string( $image_attrs ) . ' >';
}
$link_attrs = get_link_attributes( $attrs );
if( $link_attrs ) {
$image_html = '<a' . attibutes_to_string( $link_attrs ) . '>' . $image_html . '</a>';
}
/*
* Filter the output.
* @param string HTML markup
* @param array List Shortcode attributes
* @param array List Image attributes
* @param array List link attributes
* @return html string
*/
return apply_filters( 'img_shortcake_output', $image_html, $attrs, $image_attrs, $link_attrs );
}
add_shortcode( 'img', __NAMESPACE__ . '\\img_shortcode' );
function setup_image_class( $attrs ) {
$classes_arr = explode( ' ', $attrs['classes'] );
$size = !empty( $attrs['attachment'] ) ? $attrs['size'] : 'embed';
$classes_arr[] = 'post__img--size-' . $size;
$classes_arr[] = 'post__img--' . $attrs['align'];
return trim( implode( ' ', $classes_arr ) );
}
/*
* @param array List Shortcode attributes
* @param string Image classes
* @return array List Image attributes
*/
function get_image_attrs( $attrs, $classes ) {
$image_attrs = [
'src' => empty( $attrs['src'] ) ? '' : $attrs['src'],
'class' => $classes,
'alt' => empty( $attrs['alt'] ) ? '' : $attrs['alt'],
'width' => empty( $attrs['width'] ) ? '' : $attrs['width'],
'height' => empty( $attrs['width'] ) ? '' : $attrs['height'],
];
// Trim keys with empty value
// After we can pass attributes to WP functions
$image_attrs = array_filter( $image_attrs );
/*
* Filter the image attributes
* @param array List Image attributes
* @param array List Shortcode attributes
*/
return apply_filters( 'img_shortcake_image_attributes', $image_attrs, $attrs );
}
function get_link_attributes ( $attrs ) {
$url = '';
// If link to file, return with link
if ( !empty( $attrs['linkto'] ) && 'file' === $attrs['linkto'] ) {
$url = wp_get_attachment_url( $attrs['attachment'] );
// If link to attachments post, return with link to post
} elseif ( !empty( $attrs['linkto'] ) && 'post' === $attrs['linkto'] ) {
$url = get_attachment_link( $attrs['attachment'] );
// If custom link exist, return Image with link
} elseif ( !empty( $attrs['url'] ) ) {
$url = $attrs['url'];
}
if( '' === $url )
return false;
// Some attributes are used by WP Media Editor:
// Support is necessary to the 'Send To Media', 'Converter'
$link_attrs_default = [
'url' => $url,
'class' => empty( $attrs['link_class'] ) ? '' : $attrs['link_class'],
'target' => empty( $attrs['link_target'] ) ? '' : $attrs['link_target'],
'rel' => empty( $attrs['link_rel'] ) ? '' : $attrs['link_rel'],
];
// Trim keys with empty value
$link_attrs = array_filter( $link_attrs_default );
/*
* Filter the link attributes.
* @param array List link attributes
* @param array List Shortcode attributes
*/
return apply_filters( 'img_shortcake_link_attributes', $link_attrs, $attrs );
}
/**
* Builds attributes string from array.
* @param array List of attributes and their value
* @return string of attributes
*/
function attibutes_to_string( $attrs ) {
$output = '';
foreach ( $attrs as $name => $value ) {
if( '' === $value ) {
$output .= ' ' . $name;
} elseif( 'src' === $name ) {
$output .= sprintf( ' %s="%s"', sanitize_key( $name ), esc_url( $value ) );
} elseif( 'url' === $name ) {
$output .= sprintf( ' href="%s"', esc_url( $value ) );
} else {
$output .= sprintf( ' %s="%s"', sanitize_key( $name ), esc_attr( $value ) );
}
}
return $output;
}
@vralle
Copy link
Author

vralle commented Nov 23, 2015

// Test Shortcode attrs
function test_img_shortcode_attr ( $atts ) {

    $atts['classes'] .= 'post__img';
    return $atts;
}
add_filter( 'shortcode_atts_img', __NAMESPACE__ . '\\test_img_shortcode_attr', 10, 1 );

// Test WP Images attrs
function add_schema_to_wp_images( $attrs, $attachment, $size ) {

    $attr['itemprop'] = 'image';

    return $attrs;
}
add_filter( 'wp_get_attachment_image_attributes',  __NAMESPACE__ . '\\add_schema_to_wp_images', 10, 3 );

// Test Images attrs
function fix_schema_to_wp_images_with_link( $image_attrs, $attrs ) {

    if ( 'file' === $attrs['linkto'] ) {
        $image_attrs['itemptop'] = 'thumbnail';
    }

    return $image_attrs;
}
add_filter( 'img_shortcake_image_attributes',  __NAMESPACE__ . '\\fix_schema_to_wp_images_with_link', 10, 2 );


// Test Links attrs
function add_schema_to_wp_image_links( $attrs_link, $attrs ) {

    if ( 'file' === $attrs['linkto'] ) {
        $attrs_link['itemprop'] = 'contentUrl';
    }

    return $attrs_link;
}
add_filter( 'img_shortcake_link_attributes',  __NAMESPACE__ . '\\add_schema_to_wp_image_links', 10, 2 );


// Test Output
function img_shorcake_output( $image_html, $attrs, $image_attrs, $link_attrs ) {

    if( 'file' !== $attrs['linkto'] )
        return $image_html;

    $attachment = get_post( $attrs['attachment'] );

    $title = trim(strip_tags( $attachment->post_title ));

    $excerpt = trim(strip_tags( $attachment->post_excerpt ));

    $output = '<figure class="post__figure post__figure--animated" itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
    $output .= $image_html;
    $output .= '<figcaption itemprop="caption description">';
    $output .= '<a class="link link--full-size" href="' . esc_url( $link_attrs['url'] ) . '"><span class="text">' . $title . '</span> <span class="icon icon--max"></span></a>';
    $output .= '</figcaption>';
    $output .= '</figure>';

    return $output;
}
add_filter( 'img_shortcake_output', __NAMESPACE__ . '\\img_shorcake_output', 10, 5 );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment