Display WordPress post content images and text separately - php

I'm looking at the WordPress blog and I'm trying to figure out how to display the image and text separately when displaying the content. The reason I want to do this is because I want to create a custom layout, and I need to be able to move the image around without grabbing all the text at the same time. Does anyone have any idea on how to do this?
Example of what i've already got: (UPDATED)
<?php
require('blog/wp-blog-header.php');
?>
<?php
$args = array( 'numberposts' => 2, 'post_status'=>"publish",'post_type'=>"post",'orderby'=>"post_date");
$postslist = get_posts( $args );
echo '<ul id="latest_posts">';
foreach
($postslist as $post) : setup_postdata($post);
echo get_content_without_tag( apply_filters( 'the_content', get_the_content() ), 'a' );
$image = get_tag_without_text( apply_filters( 'the_content', get_the_content() ), 'a' );
?>
<li>
<strong>
<?php the_date(); ?>
</strong>
<br />
<?php the_title(); ?>
<p>
<?php echo $image[0]; ?>
</p>
</li>
<?php endforeach; ?>
</ul>
ERROR:
Warning: DOMDocument::saveHTML() expects exactly 0 parameters, 1 given
in
/hsphere/local/home/poulaum/isosec.co.uk/blog/wp-includes/functions.php
on line 4874
and image to show what the above code displays:

You can make use of featured images. This featured image will not be included in post content. However, if you already have your images included in post content, then you need to strip the post content down in two parts, as you've said in your question.
I have two functions, one that returns all the images (or any html tag content) from the content and one function that returns the text without the desired tag/images. Both of these functions uses DOMDocument
The first function get_content_without_tag() returns the content which has been stripped from images. There are two parameters
$html -> The text with images to be stripped, in this case, use apply_filters( 'the_content', get_the_content() ) to use the post content
$tag -> The name of the tag to strip out, in this case, 'a' as a tags hold images
Here is the function
function get_content_without_tag( $html, $tag )
{
// Return false if no html or tag is passed
if ( !$html || !$tag )
return false;
$dom = new DOMDocument;
$dom->loadHTML( $html );
$dom_x_path = new DOMXPath( $dom );
while ($node = $dom_x_path->query( '//' . $tag )->item(0)) {
$node->parentNode->removeChild( $node );
}
return $dom->saveHTML();
}
You would then use this in place of the_content() where you would need to display text only, stripping out the complete <a/> tag in which the images are as follows
echo get_content_without_tag( apply_filters( 'the_content', get_the_content() ), 'a' )
The second function, get_tag_without_text() returns the content between the desired tag, in your case, images. The parameters are exactly the same as the first function. Here is the function
function get_tag_without_text( $html, $tag )
{
// Return false if no html or tag is passed
if ( !$html || !$tag )
return false;
$document = new DOMDocument();
$document->loadHTML( $html );
$tags = [];
$elements = $document->getElementsByTagName( $tag );
if ( $elements ) {
foreach ( $elements as $element ) {
$tags[] = $document->saveHtml($element);
}
}
return $tags;
}
This function returns an array of images should you use a tags, so, to display the first image, use the function as follow:
$image = get_tag_without_text( apply_filters( 'the_content', get_the_content() ), 'a' );
echo $image[0];
EDIT
The code above is was only tested with WP_Query and not with get_posts. I have fixed a few bugs in the code above and also in your code to make it work with get_posts
Here is a working example of your code. (Just remember to update the the functions with the new ones above)
<?php
$args = array(
'numberposts' => 2,
'post_status' => 'publish',
'post_type' => 'post',
'orderby' => 'date'
);
$postslist = get_posts( $args );
echo '<ul id="latest_posts">';
foreach ( $postslist as $post ) {
setup_postdata($post);
$content = get_content_without_tag( $post->post_content, 'a' );
$image = get_tag_without_text( $post->post_content, 'a' );
if ( $content )
echo apply_filters( 'the_content', $content );
?>
<li>
<strong>
<?php the_date(); ?>
</strong>
<br />
<a href="<?php the_permalink(); ?>" title="<?php the_title();?>">
<?php the_title(); ?>
</a>
<?php
if ( $image ) {
?>
<p>
<?php echo apply_filters( 'the_content', $image[0] ); ?>
</p>
<?php
}
?>
</li>
<?php
}
echo '</ul>';

Related

Get all attachments from current page in Wordpress

I try to get all attachments from a current wordpress page. But my code only shows me the first result. What´s the issue?
My code
<?php
$attachments = get_children(array(
'post_parent' => $post->ID,
'post_status' => 'any',
'post_type' => 'attachment',
'post_mime_type' => 'image'
)
);
foreach($attachments as $att_id => $attachment) {
if (get_post_meta( $attachment->ID, '_bildnachweis', true )) {
$full_img_caption = get_post_meta( $attachment->ID, '_bildnachweis', true );
echo $full_img_caption; // Here I need more results, but the browser shows me only one.
}
}
?>
echo $full_img_caption; shows me only one result instead of three existing images for the page. There is a problem with my foreach loop?
I think you should use false instead of true in this line: get_post_meta( $attachment->ID, '_bildnachweis', true ) to get all values. true will only return the first value. https://developer.wordpress.org/reference/functions/get_post_meta/
I found a way that works:
<?php
//This will return the HTML source of the page as a string.
$htmlString = $post->post_content;
//Create a new DOMDocument object.
$htmlDom = new DOMDocument;
//Load the HTML string into our DOMDocument object.
#$htmlDom->loadHTML($htmlString);
//Extract all img elements / tags from the HTML.
$imageTags = $htmlDom->getElementsByTagName('img');
//Create an array to add extracted images to.
$extractedImages = array();
//Loop through the image tags that DOMDocument found.
foreach($imageTags as $imageTag){
//Get the alt text of the image.
$classText = $imageTag->getAttribute('class');
//Add the image details to our $extractedImages array.
$extractedImages[] = array(
'class' => $classText
);
}
?>
<div id="image-copyright" class="container">
<strong>Bildnachweis:</strong>
<?php
foreach($extractedImages as $image) {
$unsplittedImage = $image["class"];
$imageID = explode("wp-image-", $unsplittedImage)[1];
$full_img_caption = get_post_meta( $imageID, '_bildnachweis', true );
if ($full_img_caption) {
echo "<span class='single-author'>". $full_img_caption ."</span>";
}
?>
<?php
}
?>
</div>

Wordpress post_title() notice

here is my scenario: I got an index.php which loads every page I got one below the other. It's a one-pager in the end.
I found this snippet online and It helped me a lot by creating this.
<?php
$mypages = get_pages( array('child_of' => 1503, 'sort_column' => 'menu_order') );
foreach( $mypages as $page ) {
$content = $page->post_content;
if ( ! $content ) // Check for empty page
continue;
$content = apply_filters( 'the_content', $content );
?>
<section>
<div class="headlines info-header"><img src="<?php echo get_template_directory_uri(); ?>/assets/images/arrow.png" alt="arrow"><?php echo $page->post_title; ?></div>
<div class="page-content"><?php echo $content; ?></div>
</section>
<?php
}
?>
It seems to work just fine. But now to the problem part of this. I want to display the posts also on this one page. My try was to create another page news and place a widget on this page which shows the latests posts, filtered by category.
But now the page title won't show up anymore, all I got is the following
notice: NOTICE: TRYING TO GET PROPERTY 'POST_TITLE' OF NON-OBJECT IN
So I thought the problem might have to do with the little <?php echo $page->post_title; ?> I already tried to just get the_titlebut I ended up getting the same error.
I'm kinda new to Wordpress so I don't know how to deal with this.
Is there another way to get the page title on my index.php?
Best,
Dominik
I managed to fix this. As #delboy1978uk told me, I check if the title is not empty by adding 2 lines of code.
Here is the final code:
<?php
$mypages = get_pages( array('child_of' => 1503, 'sort_column' => 'menu_order') );
foreach( $mypages as $page ) {
$content = $page->post_content;
$title = $page->post_title;
if ( ! $content ) // Check for empty page
if ( ! $title) // Check for empty title < NEW!
continue;
$content = apply_filters( 'the_content', $content );
?>
<section>
<div class="headlines info-header"><img src="<?php echo get_template_directory_uri(); ?>/assets/images/arrow.png" alt="arrow"><?php echo $title; ?></div>
<div class="page-content"><?php echo $content; ?></div>
</section>
<?php
}
?>

wordpress shortcode render content in dashboard also

I am using a simple wordpress shortcode
function my_recent_post()
{
echo 'hello';
}
add_shortcode( 'recent', 'my_recent_post' );
with the shortcode [recent] and its working fine and visible in front page,
but the problem is, its printing the hello in the dashboard also.
below is the screenshot, can anyone please help.
Update:
I was actually trying to show posts, so can you help me with this, because it renders the lists of posts in the dashboard itself like the "hello". I tried:
function lorem_function() {
global $post;
$args = array( 'posts_per_page' => 10, 'order'=> 'ASC', 'orderby' => 'title' );
$postslist = get_posts( $args );
foreach ( $postslist as $post ) :
setup_postdata( $post ); ?>
<div>
<?php the_date(); ?> <br /> <?php the_title(); ?> <?php the_excerpt(); ?>
</div>
<?php endforeach;
wp_reset_postdata();
return;
}
add_shortcode('lorem', 'lorem_function');
Based on your comments to me & Nikita Dudarev, what you need to do is create a variable to hold all the post information and then return it. Using the function you posted as an example:
function lorem_function() {
global $post;
$args = array( 'posts_per_page' => 10, 'order'=> 'ASC', 'orderby' => 'title' );
$postslist = get_posts( $args );
// create a variable to hold the post information
$html ="";
foreach ( $postslist as $post ) :
setup_postdata( $post );
$backgroundstyle = "";
// get the featured image and set it as the background
if ( has_post_thumbnail() ) { // make sure the post has a featured image
$imageurl = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'medium' ); // you can change "medium" to "thumbnail or full depending on the size you need
// add the css for the background image. You can include background-size etc ad required
$backgroundstyle = "background-image: url('".$imageurl[0]."');";
}
// add the information to the variable
$html .= '<div style="'.$backgroundstyle.'">';
$html .= get_the_date();
$html .= "<br />";
$html .= get_the_title();
$html .= get_the_excerpt();
$html .= "</div>";
endforeach;
wp_reset_postdata();
return $html;
}
add_shortcode('lorem', 'lorem_function');
Note that the_date(), the_title() and the_excerpt() all display the information (just like echo).
Instead you must use get_the_date(), get_the_title() and get_the_excerpt() - these get the same information, but instead of displaying it directly, they return it as a variable which you can then store in your html string to be returned.
Update:
As you don't want to use the variable name on each line for whatever reason, you can do it like this:
$html .= "<div>".get_the_date()."<br />".get_the_title().get_the_excerpt()."</div>";
I'm not sure why you specifically want to change it to do that - it makes absolutely no difference to how it works, it just makes it harder to read and identify any errors :-)
Your function must return a value, not output
function my_recent_post()
{
return 'hello';
}
add_shortcode( 'recent', 'my_recent_post' );

Exclude excerpt from wordpress wp_query

Hellow everyone!
I am showing blog of posts in additional wp template and everything works fine, but I've made some kind of gallery from it, and I don't need to show anything except gallery and title.
Inside posts I have this:
[gallery ids="1618,...,1634"]
<h2>...</h2>
<p>...</p>
text without format, etc.
As you can see, I am using a gallery shortcode. I need it to be shown, but all other content to be excluded from the loop.
Really appreciate your help in this question...
My template code:
<?php
/*
* Template name: Блог
*/
$current_page = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'posts_per_page' => 9,
'paged' => $current_page,
'cat' => 8
);
query_posts( $args );
$wp_query->is_archive = true;
$wp_query->is_home = false;
while(have_posts()): the_post();
?>
<div class="foto_posts">
<?php the_content() ?>
<?php echo '' . get_the_title() . '';?>
</div>
<?php
endwhile;
if(function_exists('page_navi_slider')) page_navi_slider();
try to replace <?php the_content() ?> to <?php the_title() ?>
if you just want to show gallery shortcode try this
replace
<?php the_content() ?>
to
$pattern = get_shortcode_regex();
preg_match('/'.$pattern.'/s', $post->post_content, $matches);
if (is_array($matches) && $matches[2] == 'gallery') {
$shortcode = $matches[0];
echo do_shortcode($shortcode);
}
Try this for getting galleries and videos use the get_post_meta_key()
<?php get_post_meta($post_id,'key_name',1);?>
If it returns an array then traverse that array to get the images link and video links
add_shortcode('gallery', 'gallery_shortcode_fancybox');
function gallery_shortcode_fancybox($attr) {
$attachment_ids = explode(',',$attr['ids']);
$args = array(
'post__in' => $attachment_ids,
//'cat' => 8 if category needs to be shown pass it in shortcode , same as ids
);
$gallery_posts = query_posts( $args );
foreach ($gallery_posts as $key => $value) {
//do the stuff here
echo '<h2>'. $value->post_title;'</h2>';
$feat_image = wp_get_attachment_url( get_post_thumbnail_id($value->ID);
echo '<p><img src="'.$feat_image.'" ></p>';
}
}

Simple Wordpress Loop result completely wrong and full of breaks and <p> elements

I am trying to make a simple loop through my wordpress posts but when it comes to output the whole thing the loop puts it anywhere but not where I said, it should be. For example the loop adds breaks and but they are not in my posts. I had this problem once but dont know anymore what i have done to get over this problem.
MY LOOP:
<?php
$args = array(
'post_type' => 'post',
'posts_per_page' => 4
);
$loop = new WP_Query($args);
if ($loop->have_posts()) {
while ($loop->have_posts()) : $loop->the_post();
$post_id = get_the_ID();
$content = the_content();
$headline = get_post_meta($post_id, 'headline', true);
$subtitle = get_post_meta($post_id, 'untertitel', true);
$class = wp_get_post_terms( $post_id, 'post_tag', $termsargs );
$bgimage = wp_get_attachment_url( get_post_thumbnail_id($post->ID) );
echo '<section class="section zutaten '.$class[0].'" style="background-image: url('.$bgimage.')">';
echo '<article class="zutaten-beschreibung">';
echo '<header>';
echo '<h2><strong>'.$headline.'</strong></h2>';
echo '<h3>'.$subtitle.'</h3>';
echo '<div class="zutaten-beschreibung-content">';
echo $content;
echo '</div>';
echo '</header>';
echo '</article>';
echo '</section>';
endwhile;
} else {
echo __('Fehler!');
}
wp_reset_postdata();
?>
RESULT:
What is going wrong here?
The function the_content() is printing the data. you should use get_the_content() instead.
I can see what's going wrong here. The echo $content; line is printing improper HTML. I know this because you've said in your caption there are many <p> tags where they should not be; and you're not (visibly) printing any <p> tags in this block of code.
Investigate what this method is returning: $content = the_content(); That should do the trick.

Categories