skip to Main Content

I have created a wordpress function called svg_icon();, for print or echo inline svg icon.
I want to print a inline svg based on arrays key and atts,
Here is my function code


function svg_icon($atts = array()) {

    $atts = shortcode_atts([
        'icon' => false,
        'label' => false,
    ], $atts);

    if (empty($atts['icon']))
        return;

    $config = [
        'arrow' => [
            '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"><path d="M21.883 12l-7.527 6.235.644.765 9-7.521-9-7.479-.645.764 7.529 6.236h-21.884v1h21.883z"/></svg>'
        ],
        'hamburger' => [
            '<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m13 16.745c0-.414-.336-.75-.75-.75h-9.5c-.414 0-.75.336-.75.75s.336.75.75.75h9.5c.414 0 .75-.336.75-.75zm9-5c0-.414-.336-.75-.75-.75h-18.5c-.414 0-.75.336-.75.75s.336.75.75.75h18.5c.414 0 .75-.336.75-.75zm-4-5c0-.414-.336-.75-.75-.75h-14.5c-.414 0-.75.336-.75.75s.336.75.75.75h14.5c.414 0 .75-.336.75-.75z" fill-rule="nonzero"/></svg>'
        ],
        'close' => [
            '<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m12.002 2.005c5.518 0 9.998 4.48 9.998 9.997 0 5.518-4.48 9.998-9.998 9.998-5.517 0-9.997-4.48-9.997-9.998 0-5.517 4.48-9.997 9.997-9.997zm0 1.5c-4.69 0-8.497 3.807-8.497 8.497s3.807 8.498 8.497 8.498 8.498-3.808 8.498-8.498-3.808-8.497-8.498-8.497zm0 7.425 2.717-2.718c.146-.146.339-.219.531-.219.404 0 .75.325.75.75 0 .193-.073.384-.219.531l-2.717 2.717 2.727 2.728c.147.147.22.339.22.531 0 .427-.349.75-.75.75-.192 0-.384-.073-.53-.219l-2.729-2.728-2.728 2.728c-.146.146-.338.219-.53.219-.401 0-.751-.323-.751-.75 0-.192.073-.384.22-.531l2.728-2.728-2.722-2.722c-.146-.147-.219-.338-.219-.531 0-.425.346-.749.75-.749.192 0 .385.073.531.219z" fill-rule="nonzero"/></svg>'
        ]
    ];




    if (array_key_exists($atts['icon'], $config)) {
        $repl = '<svg aria-hidden="true" role="img" focusable="false" ';
        $svg = preg_replace('/^<svg /', $repl, trim($atts['icon']));

        $svg = preg_replace("/([nt]+)/", ' ', $svg); // Remove newlines & tabs.
        $svg = preg_replace('/>s*</', '><', $svg); // Remove white space between SVG tags.

        if (!empty($atts['label'])) {
            $svg = str_replace('<svg ', '<svg aria-label="'. esc_attr($atts['label']) .'"', $svg);
            $svg = str_replace('aria-hidden="true"', '', $svg);
        }

        return $svg;
    }
}

printing svg icon.

echo svg_icon([
    'icon' => 'hamburger',
    'label' => 'Main Menu',
]);

I’m getting error. Its print only first $config array key (arrow) and nothing.
Please help anyone to mofify my function code,

Please anyone modify this function I’m new.
Your help is greatly appreciated Thanks!

2

Answers


  1. The issue with your code lies in the $config array structure. Each key in the $config array should have a corresponding array of SVG strings. Currently, you have defined each SVG string as a separate array element, causing the function to only return the first key-value pair from $config.

    $config = [
        'arrow' => '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"><path d="M21.883 12l-7.527 6.235.644.765 9-7.521-9-7.479-.645.764 7.529 6.236h-21.884v1h21.883z"/></svg>',
        'hamburger' => '<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m13 16.745c0-.414-.336-.75-.75-.75h-9.5c-.414 0-.75.336-.75.75s.336.75.75.75h9.5c.414 0 .75-.336.75-.75zm9-5c0-.414-.336-.75-.75-.75h-18.5c-.414 0-.75.336-.75.75s.336.75.75.75h18.5c.414 0 .75-.336.75-.75zm-4-5c0-.414-.336-.75-.75-.75h-14.5c-.414 0-.75.336-.75.75s.336.75.75.75h14.5c.414 0 .75-.336.75-.75z" fill-rule="nonzero"/></svg>',
        'close' => '<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m12.002 2.005c5.518 0 9.998 4.48 9.998 9.997 0 5.518-4.48 9.998-9.998 9.998-5.517 0-9.997-4.48-9.997-9.998 0-5.517 4.48-9.997 9.997-9.997zm0 1.5c-4.69 0-8.497 3.807-8.497 8.497s3.807 8.498 8.497 8.498 8.498-3.808 8.498-8.498-3.808-8.497-8.498-8.497zm0 7.425 2.717-2.718c.146-.146.339-.219.531-.219.404 0 .75.325.75.75 0 .193-.073.384-.219.531l-2.717 2.717 2.727 2.728c.147.147.22.339.22.531 0 .427-.349.75-.75.75-.192 0-.384-.073-.53-.219l-2.729-2.728-2.728 2.728c-.146.146-.338.219-.53.219-.401 0-.751-.323-.751-.75 0-.192.073-.384.22-.531l2.728-2.728-2.722-2.722c-.146-.147-.219-.338-.219-.531 0-.425.346-.749.75-.749.192 0 .385.073.531.219z" fill-rule="nonzero"/></svg>',
    ];
    
    Login or Signup to reply.
  2. There’s a lot of things that I’d clean up in your function.

    First, WordPress’s shortcode_atts can usually be replaced with PHP’s null coalescing operator in user-land code. (The shortcode_atts function also makes a final call to a hook which is why I wouldn’t recommend removing it from core or plugins.)

    Second, arrays are great for storing things, but I think it really makes code more readable when you can get variables, so I’m pulling the two keys into dedicated variables.

    Third, in Sanjay Dihora’s original post, they were trying to say that you were using an array of arrays, but you just need an array of strings, so I simplified that.

    Fourth, your first preg_replace call attempted to add code to the selected SVG each time, and that’s not necessary, just add that code to the SVGs in the array.

    Fifth, no need for the whitespace clean up, the SVGs are already clean as-is.

    Lastly, I added some type signatures to the function.

    Below is the updated version. The spirit of what you were attempting is mostly here, so I wouldn’t say you were very far off. There was just some complicated things that could be simplified.

    function svg_icon(array $atts = []): ?string
    {
        // Get the provided values or a default value
        $icon = $atts['icon'] ?? false;
        $label = $atts['label'] ?? false;
        
        // This is required, so if it not set bail
        if (!$icon) {
            return null;
        }
        
        // These are our possible SVGs
        static $config = [
            'arrow' => '<svg aria-hidden="true" role="img" focusable="false" width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"><path d="M21.883 12l-7.527 6.235.644.765 9-7.521-9-7.479-.645.764 7.529 6.236h-21.884v1h21.883z"/></svg>',
            'hamburger' => '<svg aria-hidden="true" role="img" focusable="false" clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m13 16.745c0-.414-.336-.75-.75-.75h-9.5c-.414 0-.75.336-.75.75s.336.75.75.75h9.5c.414 0 .75-.336.75-.75zm9-5c0-.414-.336-.75-.75-.75h-18.5c-.414 0-.75.336-.75.75s.336.75.75.75h18.5c.414 0 .75-.336.75-.75zm-4-5c0-.414-.336-.75-.75-.75h-14.5c-.414 0-.75.336-.75.75s.336.75.75.75h14.5c.414 0 .75-.336.75-.75z" fill-rule="nonzero"/></svg>',
            'close' => '<svg aria-hidden="true" role="img" focusable="false" clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m12.002 2.005c5.518 0 9.998 4.48 9.998 9.997 0 5.518-4.48 9.998-9.998 9.998-5.517 0-9.997-4.48-9.997-9.998 0-5.517 4.48-9.997 9.997-9.997zm0 1.5c-4.69 0-8.497 3.807-8.497 8.497s3.807 8.498 8.497 8.498 8.498-3.808 8.498-8.498-3.808-8.497-8.498-8.497zm0 7.425 2.717-2.718c.146-.146.339-.219.531-.219.404 0 .75.325.75.75 0 .193-.073.384-.219.531l-2.717 2.717 2.727 2.728c.147.147.22.339.22.531 0 .427-.349.75-.75.75-.192 0-.384-.073-.53-.219l-2.729-2.728-2.728 2.728c-.146.146-.338.219-.53.219-.401 0-.751-.323-.751-.75 0-.192.073-.384.22-.531l2.728-2.728-2.722-2.722c-.146-.147-.219-.338-.219-.531 0-.425.346-.749.75-.749.192 0 .385.073.531.219z" fill-rule="nonzero"/></svg>',
        ];
        
        // If the requested icon doesn't exist, bail
        if (!$svg = $config[$icon] ?? null) {
            return null;
        }
        
        // If we have a label, un-hide the SVG and set the ARIA attribute
        if (!empty($label)) {
            $svg = str_replace('<svg ', '<svg aria-label="'.esc_attr($label).'"', $svg);
            $svg = str_replace('aria-hidden="true"', '', $svg);
        }
    
        return $svg;
    
    }
    

    Demo here: https://3v4l.org/HHWJKW#v8.2.6

    One thing I would note is that I’m hoping this is expected to be run as a shortcode. If that’s not the case, I would encourage you to simplify this code even further to just this: https://3v4l.org/UvAjF#v8.2.6

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search