'Alternative to closing php tag and entering straight HTML when echo doesn't work

I apologize in advance for the horrible title; I'm sure there's a better way to ask this question, but I couldn't come up with it. I'll try to do a better job with an example.

I was recently working on a project in Wordpress using Woocommerce, and needed to create a shortcode in my functions.php file. This was a custom shortcode to display Woocommerce product "cards", each of which needing to be wrapped with a link around them. My issue arose when trying to echo out a link using the_permalink(). What kept happening was the permalink was being displayed on the front end, rather than simply linking the content that I wanted to link. I've heard that this problem can arise when using echo sometimes, although I'm not exactly sure why. Aside from all that, the code worked fine. However, due to the link displaying like it was, I ended up having to use this code:

echo '<div class="featured-products-carousel owl-theme owl-carousel">';
    if ( $products_query->have_posts() ) {
        while ( $products_query->have_posts() ) : $products_query->the_post();
            $thumb_image = kdmfi_get_featured_image_src( 'featured-image-2', 'full' ); ?>
            <a href="<?php the_permalink(); ?>" class="featured-link">
                <div class="featured-product">
                    <div class="featured-img">
                        <?php
                        if ( isset($thumb_image) ) {
                            kdmfi_the_featured_image( 'featured-image-2', 'full');
                        } else {
                            echo ('<img width="300" height="300" src="' . get_template_directory_uri() . '/images/woocommerce-placeholder.png" class="cat-thumbnail-img cat-placeholder-img" alt="Category Placeholder Image">');
                        } ?>
                    </div>
                    <div class="featured-text">
                        <div class="featured-product-title"><?php woocommerce_template_loop_product_title(); ?></div>
                        <div class="featured-product-price"><?php woocommerce_template_single_price(); ?></div>
                    </div>
                </div>
            </a>
        <?php endwhile;
    } else {
        echo __( 'No products found' );
    }
echo '</div>';

You'll see that on the same line where I declare the variable $thumb_image, I had to close php so that I could use straight HTML for <a href="<?php the_permalink(); ?>">. Originally, I was trying to do it by not closing php and using echo before all my HTML tags, but then I ran into the issue I explained above. Therefore, my question is three-fold:

  1. Why does echo display the_permalink(), rather than just linking it? I also tried get_the_permalink() as well, with the same results.
  2. Is there a better way to get around this problem so that you don't need to close php and then reopen it after your HTML? Or is closing php in this situation and doing what I did best practice? It just seems like there should be a better way.
  3. Where else might echo cause problems like the one I ran into? Is there a clear set of situations where using echo should be avoided in lieu of something else? If so, what are those situations?

Please let me know if any further information is necessary or would be helpful to have in order to answer my questions.

Thank you!



Solution 1:[1]

As per the CODEX documentation:

Function Description
the_permalink( int|WP_Post $post ) Displays the permalink for the current post.
get_permalink( int|WP_Post $post, bool $leavename = false ) Retrieves the full permalink for the current post or post ID.

The difference is subtile. the_permalink is used to DISPLAY the current post permalink and get_permalink is used to RETRIEVE it.

In Wordpress, functions starting with the_ are a a container for the same get_ version. They the_ version echo`-it out and sanitize it.

You never echo something that is already echo-ed out.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1