Wordpress: Function to add images in text editor - wordpress

I'm really new to Wordpress and slowly getting my head around it but I've come across a problem and I don't know how to fix it.
I'm creating pages using the text editor in the backend and I'm pasting html in there. All's working well and I can output images using this function in functions.php (i found this snippet somwhere but can't remember where)
// Create the shortcode
function template_url( $atts, $content = null ) {
return '<img src="'. get_template_directory_uri() .'/'. $content .'" alt="" />';
}
// Add as shortcode
add_shortcode("template", "template_url");
and i call it like this
[template]images/my-image.jpg[/template]
The problem is how do i add some alt text and also add a class to the image

You can add shortcode with your custom attributes like this:-
Add Following code for adding shortcode:
function template_url( $atts, $content = null )
{
extract(
shortcode_atts( array(
'alt' => '',
'width' => '',
'height' => ''
), $atts )
);
//And this variable you can use like this:-
return '<img src="'. get_template_directory_uri() .'/'. $content .'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"/>';
}
add_shortcode("template", "template_url");
And use this shortcode in editor:-
[template alt="this is alter text" width="400" height="300"]images/my-image.jpg[/template]
I hope this will be helpful.

Related

Escape ACF fields with new lines

I'm using a Text Area field within ACF.
I've set the "New Lines" option to "Automatically add paragraphs".
Here's how the PHP looks within my template file:
<?php
$notice = '<p>Some text.</p>';
$text = get_field( 'text', 'option' );
if ( $text ) {
echo str_replace( '<p>', '<p class="footer__paragraph">', $text );
}
else {
echo $notice;
}
?>
You'll see that I'm using str_replace to add a custom CSS class to the <p> tags.
I'd usually escape output, like so <?php echo esc_html( $text ); ?>. This obviously doesn't work because autop adds a <p> tag to each line.
Is it possible to escape output whilst maintaining my custom classes?
Yes it's feasible by whitelisting the tags and attributes you're interested in. Wordpress has a special function for that:
wp_ksesDocs
Here's how it works! You could pass it an array of tags that you want to accept while escaping every other tags and attributes. For example if you only need to keep you p tag and your custom class and escape everything else, then you could do something like this:
$text = get_field( 'text', 'option' );
$whitelist_tags = array(
'p' => array(
'class' => array('footer__paragraph')
)
);
echo wp_kses( $text, $whitelist_tags );
This will keep your p tag with your custom class and escape every other tags and attributes.
Let me know if that was what you were looking for!

Wordpress: map existing page content instead of a copy

I have a page with several subpages in wordpress. The page should display the same content as the second subpage. When I edit the page, there is an option to copy the content from the subpage into it, but then I would have to maintain two instances of the text. Is there a possibility to map existing page content into a page? I'm using Wordpress.com so I cannot edit any files/links on the server.
You could use a shortcode that fetches the content of a page specified. In functions.php:
add_action( 'init', 'so20477735_init', 11 );
function so20477735_init()
{
add_shortcode( 'duplicate_page', 'so20477735_shortcode_callback' );
}
function so20477735_shortcode_callback( $atts, $content = null )
{
extract( shortcode_atts( array(
'page_id' => 0
), $atts ) );
$page_data = get_page( $page_id );
$return = '';
if( ! is_null( $page_data ) )
$return .= $page_data->post_content;
return $return;
}
Example usage:
[duplicate_page page_id="12"]
EDIT
I missed the fact you're using wp.com. You should be able to do something similar with the display posts shortcode:
http://en.support.wordpress.com/display-posts-shortcode/

Force alt attribute on post-thumbnail wordpress

i want to force the attribute "alt" on thumbnail when admin add new thumbnail on wordpress.
if there is javascript hook on saving thumbnail validator on the input "title" that's well be great!
Thank you.
Found this, place it in your functions.php file in your theme directory
function add_alt_tags($content)
{
global $post;
preg_match_all('/<img (.*?)\/>/', $content, $images);
if(!is_null($images))
{
foreach($images[1] as $index => $value)
{
if(!preg_match('/alt=/', $value))
{
$new_img = str_replace('<img', '<img alt="'.$post->post_title.'"', $images[0][$index]);
$content = str_replace($images[0][$index], $new_img, $content);
}
}
}
return $content;
}
add_filter('the_content', 'add_alt_tags', 99999);
Find more here http://www.paulund.co.uk/add-missing-alt-tags-to-wordpress-images
This is going on my snippet site. Hope it helps
By default, the image returned does not have a title or alt attribute. (Since WordPress 4.7, the alt attribute is no longer added automatically. It will only have an alt attribute if you specifically entered "Alt text" while uploading the image, or if you go back to the Media library and enter "Alt text" for the image).
Currently website(s) traffic from Google search is considerably higher if your images all have (title attribute tags), as well as (alt tags). So, I add the title and alt attributes to post thumbnails with the following function which goes in your theme "functions.php" file. The value for the title and alt attributes will be taken from the title of the image, which is the title of the attachment (not the actual post title).
function eln_add_img_title( $attr, $attachment = null ) {
$img_title = trim( strip_tags( $attachment->post_title ) );
$attr['title'] = $img_title;
$attr['alt'] = $img_title;
return $attr;
}
add_filter( 'wp_get_attachment_image_attributes','eln_add_img_title', 10, 2
);
If you don't want the image attributes taken from default image name
you can change the code so the image attributes taken from
"post_title" as follow:
// Force adding missing image alt & title for WordPress.
function eln_add_img_title( $attr, $attachment = null ) {
$img_title = trim( strip_tags( $attachment->post_title ) );
$attr['title'] = the_title_attribute( 'echo=0' );
$attr['alt'] = the_title_attribute( 'echo=0' );
return $attr;
}
add_filter( 'wp_get_attachment_image_attributes','isa_add_img_title', 10, 2 );
Hope this help you and save your time, Have a nice day :)

Custom Fields/Values displaying out of order

I'm using the Types Wordpress plugin to enable custom fields. The plugin allows you to rearrange the order of the images in the admin page editor. Here's my code in my single.php to display multiple images in the custom field and have a link to itself to also use Fancybox:
<?php
$mykey_values_img = get_post_custom_values('wpcf-image');
if ($mykey_values_img != null) {
foreach ( $mykey_values_img as $key => $value ) {
?>
<img src="<?php echo $value; ?>" />
<?php
} //foreach
} //if
?>
Problem:
Right now this code works perfectly on my local copy running on MAMP. However, when I put it online hosted on iPage, the images are out of order. I don't know what's causing this discrepancy. When I use the shortcode from Types to display the images instead of the php above they are in order, but I don't have the option of using Fancybox. I was also wondering if there is a better way to display an image from Wordpress that will insert the alt tag for the image.
I just encountered this problem too, and your first answer led me to a tighter solution.
I also used types_render_field(), but if you include a 'raw' parameter, you can avoid the string manipulation.
$images_raw = types_render_field('image', array('raw'=>'true','separator'=>';'));
$images = explode(';', $images_raw);
foreach ($images as $link) {
echo '' . $link . '">"';
}
Then, if you're nasty, you can get the ID of the attachment from its SRC. Using that ID, you can get all the info you need about that attachment, like a caption, or whatnot.
I figured out a work around to get it working. Its not ideal but it works.
The Types plugin came with its own php function to display the custom field called types_render_field. It displayed my images in order. To get fancybox working I had to do sort of a hack on the string. Here's the code:
$images = ( types_render_field( "image", array( 'size' => 'full', 'alt' => get_the_title(), 'title' => get_the_title() ) ) );
$imgArray = explode(">", $images);
foreach ( $imgArray as $value ) {
$pos1 = strpos($value, 'src="', 0)+5;
$pos2 = strpos($value, '" ', $pos1);
$link = substr($value, $pos1, $pos2 - $pos1);
echo ''.$value.">";
}

Wordpress : excluding images 'inserted into post' from get_children

I have a page which has a slideshow at the top, and images inserted inline into the content area.
I need to exclude the images that have been inserted into the post from the slideshow.
Currently I am excluding the 'Featured Image', but this limits me to one image that can be inserted into the post.
Here is my existing code:
$thumbnail = get_post_thumbnail_id();
$images = get_children( 'post_type=attachment&post_mime_type=image&order=asc&orderby=menu_order&post_parent='.$post->ID .'&exclude='.$thumbnail);
Previously I have used the description field of the image meta data to exclude images by entering 'exclude'. This isn't as nice for the end user as I'd like it to be.
Any suggestions, plugins or code based!
Update:
I've updated the code, so now I get any image URLs from the post_content and check them against the slideshow images.
$content = $post->post_content;
$inlineImages = array();
preg_match( '/src="([^"]*)"/i', $content, $inlineImages ) ;
$thumbnail = get_post_thumbnail_id($post->ID);
$images = get_children( 'post_type=attachment&post_mime_type=image&order=asc&orderby=menu_order&post_parent='.$post->ID .'&exclude='.$thumbnail);
if ($images) {
echo '<div id="slideshow">';
foreach ( $images as $attachment_id => $attachment ) {
$image = wp_get_attachment_image_src( $attachment_id,array(900,265));
if (!in_array($image[0],$inlineImages)) {
echo '<img src="'.$image[0].'" width="'. $image[1] .'" height="'. $image[2].'">';
}
}
echo '</div>';
}
This is an OK solution, although the regex could be improved.
A nicer step would be to add the array of images to a custom field field, which
is updated on post / page update or publish.
Any suggestions on how to go about this?
Just needed to do the same thing. Your original approach is the way I wanted to do it -- simply exclude any images that had been inserted into the post from appearing in the slider. But I didn't want the client to have to do anything special to make it happen. Here's my code.
$args = array( 'post_type' => 'attachment', 'post_mime_type'=>'image','numberposts' => -1, 'post_status' => null, 'post_parent' => $post->ID );
$attachments = get_posts($args);
preg_match_all("/<img[^']*?src=\"([^']*?)\"[^']*?>/", $post->post_content, $matches, PREG_PATTERN_ORDER);
/* $matches[1] holds the urls as an array */
foreach ( $attachments as $attachment ) {
if(in_array($attachment->guid, $matches[1])){ continue;}
wp_get_attachment_image( $attachment->ID , 'slider_size');
}
First bit gets all of the images associated with the post. The $preg_match_all gets all of the images in the post body. Then as we loop through the images to display them in the slider the in_array checks the urls of the images that were inserted with the url of the image about to be added to the slider and skips on to the next one if there is a match.
Thanks for you post, got me thinking in the right direction.
I've updated the code, so now I get any image URLs from the post_content and check them against the slideshow images.
$content = $post->post_content;
$inlineImages = array();
preg_match( '/src="([^"]*)"/i', $content, $inlineImages ) ;
$thumbnail = get_post_thumbnail_id($post->ID);
$images = get_children( 'post_type=attachment&post_mime_type=image&order=asc&orderby=menu_order&post_parent='.$post->ID .'&exclude='.$thumbnail);
if ($images) {
echo '<div id="slideshow">';
foreach ( $images as $attachment_id => $attachment ) {
$image = wp_get_attachment_image_src( $attachment_id,array(900,265));
if (!in_array($image[0],$inlineImages)) {
echo '<img src="'.$image[0].'" width="'. $image[1] .'" height="'. $image[2].'">';
}
}
echo '</div>';
}
I think the easiest thing to do would be using the Meteor Slideshow plugin to create a slideshow for each page, then insert the shortcode for the proper slideshow in the content area of the proper page. Yes, it means you'll have to edit each page "outside" the page editor, but it also gives you easy, complete control over which photos do and do not appear in each slideshow, and the shortcode is very easy to put in with the page editor.
The Media Custom Fields plugin lets you add custom data to media items exactly as you would with custom post fields, providing a user-friendly way of flagging slideshow-only images. From the plugin FAQ:
In addition to giving you the option to add custom fields, your custom fields will show up in all appropriate places. If you go to the media section to manage your media like you usually do, they will show up on the edit media form. The custom fields also show up when you are uploading an image to a post, and in all other expected locations.
One approach is to install this plugin and add a custom field such as Slide with value TRUE to your slide images via the Dashboard -> Media menu. Then your filter code might be:
$thumbnail = get_post_thumbnail_id();
$images = get_children( /* removed for brevity */ );
if ($images) {
// ..
foreach ( $images as $attachment_id => $attachment ) {
// skip images not marked for slideshow
if ( !get_post_meta($attachment_id, 'Slide') ) continue;
// otherwise do slideshow things
}
// ..
}
Note that with this approach the value for Slide can be set to anything except the empty string. You may want to define Slide as a class constant somewhere to avoid hard-coding.
Advantages
Doesn't require any work on the poster's part
Future-proof: the plugin appears to be based on good-old post functionality, and attachments are just one kind of post anyway, so there's nothing weird.
Here is another approach to this.
I would not prefer using urls, because the picture inserted inside the content area could be of different size like medium, thumbnail or full. So, the url only would not match.
Using the above code,
function printMeImages() {
$content = $post->post_content;
$inlineImages = array();
// populate ids of images from wp-image-id
preg_match_all( '/wp-image-([^"]*)"/i', $content, $inlineImages ) ;
$thumbnail = get_post_thumbnail_id($post->ID);
$images = get_children( 'post_type=attachment&post_mime_type=image&order=asc&orderby=menu_order&post_parent='.$post->ID .'&exclude='.$thumbnail);
$out = "";
if ($images) {
$out .= '<ul id="slideshow">';
foreach ( $images as $attachment_id => $attachment ) {
$image = wp_get_attachment_image_src( $attachment_id,'desiredImageSize');
// $inlineImages[1] has ids to be discarded
if (!in_array($attachment_id,$inlineImages[1])) {
$out .= '<li><img src="'.$image[0].'" width="'. $image[1] .'" height="'. $image[2].'"></li>';
}
}
$out .= '</ul>';
}
return $out;
}
The images which are not set as featured and not used inside the post are retrieved.
For performance reasons I would not execute the code while the page is being rendered, but rather bind the code to the save_post hook. When the post content is edited and saved, the hook will be called and all attached images (or their ids) which are not used in the content are saved into a postmeta table. When the slider is rendered the image ids can be accessed via get_post_meta($post_id, 'image_ids_for_slider').
Like this I can avoid to do the preg_match_all operation on page rendering. This might not be a performance reason when the post content is small and when there's only one slider loaded, but generally I find this a approach a little cleaner for scaling reasons.
//hook this function to save post action
function save_ids_of_image_attachments_not_used_in_the_content( $post_id, $post ) {
$args = array( 'post_type' => 'attachment',
'post_mime_type'=>'image',
'numberposts' => -1,
'post_status' => null,
'post_parent' => $post_id
);
$attachments = get_posts($args);
preg_match_all("/<img[^']*?src=\"([^']*?)\"[^']*?>/", $post->post_content, $matches, PREG_PATTERN_ORDER);
$ids_of_attached_images_not_in_content = array();
/* $matches[1] holds the urls as an array */
foreach ( $attachments as $attachment ) {
if(in_array($attachment->guid, $matches[1])){
continue;
}
$ids_of_attached_images_not_in_content[] = $attachment->ID;
}
// save the image_ids as postmeta
update_post_meta($post_id, 'image_ids_for_slider', $ids_of_attached_images_not_in_content);
}
add_action( 'save_post', 'save_ids_of_image_attachments_not_used_in_the_content', 10, 2 );
I haven't fully understood your problem, but how about excluding the div ID within which the slideshow is present?
$thumbnail = get_post_thumbnail_id();
$images = get_children('post_type=attachment&post_mime_type=image&order=asc&orderby=menu_order&post_parent='.$post->ID .'&exclude='.$thumbnail. '&NAME');
Replace 'NAME' after thumbnail.' in the parenthesis.
Hope this helps.

Resources