• Resolved FireSamurai

    (@firesamurai)


    Hi,

    I’m wondering why a switch/case scenario I’ve written will not recognize the parameters in a shortcode function.

    Here is a compact version of it:

    <?php
    add_shortcode( 'the_shortcode' , 'the_shortcode_function' );
    function the_shortcode_function( $atts, $content=null ) {
    	extract( shortcode_atts( array(
    		'term'	=> '',
    		'url'	=> 'https://originalurl.com'
    	), $atts ) );
    
    	$output = '<a href="'.$url.'">Link text</a>';
    
    	switch( $term ) {
    		case 'foo':
    			$url = 'https://foourl.com';
    			return $output;
    			break;
    		case 'bar':
    			$url = 'https://barurl.com';
    			return $output;
    			break;
    		default:
    			return $output;
    	}
    
    }
    ?>

    To my untrained eye, I would think that case ‘foo’: would return
    <a href="https://foourl.com">Link text</a>

    And case ‘bar’: would return
    <a href="https://barurl.com">Link text</a>

    However, both foo and bar return the default URL string
    <a href="https://originalurl.com">Link text</a>

    Could somebody explain to me what is happening to prevent my desired output? Much thanks!

Viewing 10 replies - 1 through 10 (of 10 total)
  • You are evaluating switch( $term ) {

    $term is never defined, so it will only return your default.

    You need to develop your understanding of the PHP language.

    For instance the “break;” after “return” makes no sense.

    Also you seem to be confused that the statement:
    $output = '<a href="'.$url.'">Link text</a>';
    Means that the value of $output is set at that point using the value of $url at that point in the code.

    Thread Starter FireSamurai

    (@firesamurai)

    Thanks for the feedback. Because term is left empty in the shortcode attributes, the default case is displayed.

    When tested,
    [the_shortcode]
    does indeed display the default case. However,
    [the_shortcode term="foo"]
    also displays the default case.

    If I change
    return $output;
    to
    return "this is foo.";
    then
    [the_shortcode term="foo"]
    will display, “this is foo.”

    (Hopefully having those on separate lines isn’t confusing to read.)

    Because of this, I’m inclined to think the error lies with how I’m asking the switch to return $output. For some reason the $url parameter that is assigned in the individual case is not being recognized by the $output in that same case.

    Thread Starter FireSamurai

    (@firesamurai)

    RossMitchell. You are correct, I do need to. Hence my question. I want to understand the correct way of doing this so that I can write better code. If you are willing, could you explain the ‘why’ in your observations? Thanks.

    Because my code isn’t working, I’m aware that $output is not set with the $url value. I can move $output into each of the individual cases and it will work that way. However, I’m trying to figure out if there’s a way to do it so that I don’t have to keep re-writing the output for each case.

    Joey

    (@leglesslizard)

    Hey,

    Everything prefixed with the “$” symbol is a variable in PHP. All this does is holds a value (this can be a string, integer, array, object etc.). So whenever you want access to these values you have to reference the variable exactly. For example, I can set $term to equal 1 by writing:
    $term = 1;

    Now every time I want to use 1 within my code I can reference $term:

    echo $term + 1; // 2
    echo "I have " . $term . " bunny."; // I have 1 bunny.

    The extract function in PHP takes an array and creates variables using the keys and assigns those variables the corresponding value. So what you want to do in your code is check which attribute has been assigned ($term?) and then just return the desired string e.g.

    case 'foo':
        return '<a href="https://foourl.com">Link Text</a>';

    If you are hardcoding the urls like above then this approach would work but as has been said, getting a grasp on variables will help you a tonne when working on little functions like this ?? A good way to see what is happening in your code is to use breakpoints and analyse what variable have been assigned at what points in your code. If you don’t know how to use breakpoints then try this, if I wanted to see what was going to be returned in your code example I would do:

    case 'foo':
        $url = 'https://foourl.com';
        var_dump($output);
        die();
        return $output;

    This will dump out on the screen the value of $output at that moment and kill the application. This gives you a nice idea of what’s going on and you can dump out multiple values as a comma separated list using var_dump() BUT do remember to remove it (along with the die()!) if you want your application to work :p

    A nice simple explanation of what the shortcode_atts() function does can be found here too.

    Hope that helps some,
    Joey

    Thread Starter FireSamurai

    (@firesamurai)

    Hi Joey, thanks a ton for the explanation; it does help!

    Thread Starter FireSamurai

    (@firesamurai)

    Thanks for everyone’s feedback and input. Here’s my new code, which is working:

    add_shortcode( 'the_shortcode' , 'the_shortcode_function' );
    function the_shortcode_function( $atts, $content=null ) {
    
    	$output = '';
    
    	$the_shortcode_atts = shortcode_atts( array(
    		'term'	=> '',
    		'url'	=> 'https://originalurl.com'
    	), $atts );
    
    	$term = $the_shortcode_atts[ 'term' ];
    	$url  = $the_shortcode_atts[ 'url' ];
    
    	$output .= '<a href="' . $url . '">Link text</a>';
    
    	switch( $term ) {
    		case 'foo':
    			$newurl = 'https://foourl.com';
    			$newoutput = str_replace($url, $newurl, $output);
    			break;
    		case 'bar':
    			$newurl = 'https://barurl.com';
    			$newoutput = str_replace($url, $newurl, $output);
    			break;
    		default:
    			$newoutput = 'Nothing here.';
    	}
    
    	return $newoutput;
    
    }

    If you have any further suggestions, I’m all ears. I’ll leave this ticket open for a couple days before closing, just in case.

    Joey

    (@leglesslizard)

    Glad you got it working ??

    I would just make one minor adjustment. Currently your steps are:
    – Set the output, term and url variables
    – Check term variable and carry out code depending on it’s value
    – Set another url variable and another output variable
    – Return the newest output variable

    I would shorten this down to the following:
    – Set the term variable
    – Check term variable and carry out code depending on it’s value
    – Return output

    Currently you are creating a link with a url that is never going to be used ($url) as this is either not returned (default) or replaced by another url. Therefore, there is no real need to set it in the first place. This also avoids the need to run a string replace.
    Returning the values when they are found allows your application to carry on immediately. No big deal assigning the return value to a variable but if it’s just going to be returned anyway, why the extra step? ??

    So, my cases would look like:

    case 'foo':
        return '<a href="value_of_new_url_here">Link text</a>';

    I wouldn’t bother with the $output, $url, $newoutput or $newurl variables at all ??
    There’s nothing wrong with what you have there (and I’m definitely not an expert!) but I try and minimise to only what I need where possible as long as I don’t compromise readability.

    Regards,
    Joey

    P.S. I hope what I’ve written makes sense but as an extra “but why?” type statement…variables you’ll use here there and everywhere and they’re great. But they are there to remove the need to hardcode values and avoid repetition. In your example your variables are only used once and you are hardcoding (writing the values rather than pulling them in from somewhere else, think static vs dynamic) anyway ?? so you don’t always have to create variables.

    Thread Starter FireSamurai

    (@firesamurai)

    Joey,

    You’ve been super helpful, and I appreciate it. I’m sending all the good karma & juju your way right now.

    Cheers!

    Joey

    (@leglesslizard)

    you’re very welcome ?? when you get all savvy with your code just remember to help someone out if you get the time ^^ we all start in the same boat.

    All the best.

Viewing 10 replies - 1 through 10 (of 10 total)
  • The topic ‘Switch/Case Doesn't recognize shortcode parameters. Why?’ is closed to new replies.