1

How would I amend the following foreach loop so each link displays the keys from each nested query, and not just the values? I am creating my own social sharing links, included using get-template-part, and very nearly have it, I think.

E.g. Twitter currently returns: https://twitter.com/intent/tweet?TITLE&PERMALINK
Instead of: https://twitter.com/intent/tweet?text=TITLE&url=PERMALINK (Note: text= and url= )

I have tried ( $social_links as $key => $value ) and
( $social_links as $social_link && $social_link as $key => $value )

Neither of which is obviously correct.

<?php
    // Setup the links
    $social_links = array(
        'facebook'  => array(
            'title' => 'Facebook',
            'base'  => 'https://www.facebook.com/sharer/sharer.php',
            'query' => array(
                'u'     => get_permalink(),
                't'     => get_the_title(),
            ),
        ),
        'twitter'   => array(
            'title' => 'Twitter',
            'base'  => 'https://twitter.com/intent/tweet',
            'query' => array(
                'text'  => get_the_title(),
                'url'   => get_permalink(),
            ),
        ),

        'pinterest' => array(
            'title' => 'Pinterest',
            'base'  => 'http://www.pinterest.com/pin/create/button/',
            'query' => array(
                'url'         => get_permalink(),
                'media'       => get_the_post_thumbnail_url(),
                'description' => get_the_title(),
            ),
        ),
        'linked-in' => array(
            'title' => 'LinkedIn',
            'base'  => 'https://www.linkedin.com/shareArticle',
            'query' => array(
                'mini'  => 'true',
                'url'   => get_permalink(),
                'title' => get_the_title(),
            ),
            // append '?refresh' to force new scrape
        ),              
    );
?>

<ul class="links-social">
<?php 
    // Loop through the links
    foreach( $social_links as $social_link ) : ?>
        <li>
            <a target="_blank" href="<?php echo $social_link['base']  . '?' . implode( '&', $social_link['query'] ); ?>">
                <?php echo $social_link['title']; ?>
            </a>
        </li>
<?php   
    endforeach;
?>
</ul>

1 Answer 1

0

Your issue has nothing to do with the foreach. The problem is this part:

implode( '&', $social_link['query'] )

implode() only connects the values. There's nothing in this code that adds the keys or an =.

If you want to add an array of key/values as a query string to a URL, WordPress provides a function for this called add_query_arg(), it accepts an array of key values and a URL to add them to.

In your case you'd use it like this:

<a target="_blank" href="<?php echo esc_url( add_query_arg( $social_link['query'], $social_link['base'] ) ); ?>">
    <?php echo $social_link['title']; ?>
</a>

Note my use of esc_url. As the documentation states:

Important: The return value of add_query_arg() is not escaped by default. Output should be late-escaped with esc_url() or similar to help prevent vulnerability to cross-site scripting (XSS) attacks.

Another thing to consider is that the values in the query string need to be URL encoded. You can do this with the urlencode() PHP function:

'title' => urlencode( get_the_title() ),

However you'll need to do this for every value if you do it like that. A way do to this with less code would be to use array_map() to apply urlencode() to every value just before putting into add_query_arg():

foreach( $social_links as $social_link ) :
    $query_args = array_map( 'urlencode', $social_link['query'] );
    ?>

    <li>
        <a target="_blank" href="<?php echo esc_url( add_query_arg( $query_args, $social_link['base'] ) ); ?>">
            <?php echo $social_link['title']; ?>
        </a>
    </li>

    <?php
endforeach;
2
  • I'd not come across add_query_arg() before, thanks Jacob! One slight concern, from my code, is that titles are returned with spaces. Do you happen to know of a way to introduce "%" or something similar to the string?
    – user110886
    Mar 1, 2018 at 3:51
  • 1
    I've updated my answer. Mar 1, 2018 at 4:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.