1
votes

I'm building a simple plugin that uses the geoservices web service and what I'm trying to do is dynamically change the content on a WordPress page based on their location. I have it working somewhat but my issue is that it's returning both the location-specific text AND the default. I know it's because i'm using the shortcode instance more than once but I don't know how to change it to ONLY show the location specific content and if the location is not set or does not match the shortcode params then fall back to the default one. I don't want to add "default" as a shortcode param because it could contain HTML or something else.

Here is an example of my shortcode:

[geo city="Orlando"]<a href="#">555-123-6349</a>[/geo][geo city="Raleigh"]<a href="#">919-999-9999</a>[/geo][geo city="Default"]<a href="#">Default text here</a>[/geo]

So based on the above, the desired result would show Orlando's phone number if the user is from Orlando or it would show Raleigh number if they are from Raleigh. Otherwise, if they are not from either of those places, it would use the default.

Here is my shortcode:

function geo_services( $atts , $content = null ) {

    // Attributes
    extract(shortcode_atts(array(
      'city' => '',
      'state' => '',
   ), $atts));

    require_once('geoplugin.class.php');

    $geoplugin = new geoPlugin();

    $geoplugin->locate();

    if($city === $geoplugin->city){
        return $content;
    } elseif ($state === $geoplugin->region){
        return $content;
    } elseif ($city === 'Default') {
        return $content;
    }


}
add_shortcode( 'geo', 'geo_services' );

And here is what is happening when I use the example shortcode above: enter image description here

2

2 Answers

1
votes

I believe you may be misunderstanding how shortcodes work in WP. In your example, you have added 3 shortcodes to the content. Each of those shortcodes is going to run. Not one or the other. So doing,

[geo city="Orlando"]<a href="#">555-123-6349</a>[/geo][geo city="Raleigh"]<a href="#">919-999-9999</a>[/geo][geo city="Default"]<a href="#">Default text here</a>[/geo]

means that each of those will be called and evaluated. $geoplugin->city is always going to return the city of the user, regardless of what attributes you supplied. And since you are returning $content in all cases, it will always spit out the content that you added inside the shortcode. This is why you are seeing all 3 responses.

Instead, I would try the approach below. If your goal is to spit out content based on the city of the user, you really don't need to supply an attribute to the shortcode. See the following example:

//in your post/page content, simply use the shortcode geo
[geo]

//your function should be
function geo_services( $atts , $content = null ) {

    //
    require_once('geoplugin.class.php');

    //
    $geoplugin = new geoPlugin();
    $geoplugin->locate();

    //
    switch( $geoplugin->city ) {
        case 'Orlando':
                return '<a href="#">555-123-6349</a>';
            break;
        case 'Raleigh':
                return '<a href="#">919-999-9999</a>';
            break;
        default:
                return '<a href="#">Default text here</a>';
            break;
    }

}
add_shortcode( 'geo', 'geo_services' );
0
votes

Providing another answer based on OP comments. If you really need to manage the content via the WYSIWYG, then you could supply the content for each city as an attribute.

//add shortcode to post/page content
[geo orlando="555-123-6349" raleigh="919-999-9999" default="Custom default text here"]

//your function should be
function geo_services( $atts , $content = null ) {

    //don't use extract since we expect X number of atts now
    $atts = shortcode_atts(array(
        'default' => 'Default text here'
    ), $atts);

    //
    require_once('geoplugin.class.php');

    //
    $geoplugin = new geoPlugin();
    $geoplugin->locate();

    //was the city provided as an attribute?
    if( isset($atts[ strtolower($geoplugin->city) ]) ) {
        return $atts[ strtolower($geoplugin->city) ];
    }else {
        return $atts['default'];
    }

}

add_shortcode( 'geo', 'geo_services' );

You may have to get creative with the HTML portion of the content, but now you can include X number of cities, with their custom content, in the shortcode itself. If the city is not supplied, or does not match, it will fallback to the default.