Every site comes with social media profile links. Depending on its layout, these appear in different locations like header, footer, and sidebars. In this tutorial, we’ll learn how to create a WordPress social media shortcode that you can reuse in your themes. To configure the social links, we’ll extend the WordPress Customizer.
Extend the WordPress Customizer
Let’s start by accessing the WordPress Customizer, so we navigate to Appearance > Customize in our site dashboard. From there, we can modify different parts of our site, like setting the default homepage or adding some styles.
We’ll create a new Social Links section that will appear only when our theme is active. In my case, I’m working with a custom WordPress theme (Playground) that I’ve also used in a recent WordPress tutorial.
Inside this section, we’ll register four settings and their associated controls.
To build this functionality, we’ll use the Customize API. Within the functions.php
file of our theme, we’ll add this code:
1 |
function playground_customize_register( $wp_customize ) { |
2 |
$wp_customize->add_section( |
3 |
'social_links', |
4 |
array( |
5 |
'title' => __( 'Social Links', 'playground' ), |
6 |
)
|
7 |
);
|
8 |
|
9 |
$wp_customize->add_setting( |
10 |
'facebook', |
11 |
array( |
12 |
'sanitize_callback' => 'esc_url_raw', |
13 |
)
|
14 |
);
|
15 |
|
16 |
$wp_customize->add_control( |
17 |
'facebook', |
18 |
array( |
19 |
'type' => 'url', |
20 |
'section' => 'social_links', |
21 |
'label' => __( 'Facebook', 'playground' ), |
22 |
)
|
23 |
);
|
24 |
|
25 |
$wp_customize->add_setting( |
26 |
'instagram', |
27 |
array( |
28 |
'sanitize_callback' => 'esc_url_raw', |
29 |
)
|
30 |
);
|
31 |
|
32 |
$wp_customize->add_control( |
33 |
'instagram', |
34 |
array( |
35 |
'type' => 'url', |
36 |
'section' => 'social_links', |
37 |
'label' => __( 'Instagram', 'playground' ), |
38 |
)
|
39 |
);
|
40 |
|
41 |
$wp_customize->add_setting( |
42 |
'linkedin', |
43 |
array( |
44 |
'sanitize_callback' => 'esc_url_raw', |
45 |
)
|
46 |
);
|
47 |
|
48 |
$wp_customize->add_control( |
49 |
'linkedin', |
50 |
array( |
51 |
'type' => 'url', |
52 |
'section' => 'social_links', |
53 |
'label' => __( 'LinkedIn', 'playground' ), |
54 |
)
|
55 |
);
|
56 |
|
57 |
$wp_customize->add_setting( |
58 |
'youtube', |
59 |
array( |
60 |
'sanitize_callback' => 'esc_url_raw', |
61 |
)
|
62 |
);
|
63 |
|
64 |
$wp_customize->add_control( |
65 |
'youtube', |
66 |
array( |
67 |
'type' => 'url', |
68 |
'section' => 'social_links', |
69 |
'label' => __( 'Youtube', 'playground' ), |
70 |
)
|
71 |
);
|
72 |
}
|
73 |
add_action( 'customize_register', 'playground_customize_register' ); |
Make it More Readable
We can make this code a little more readable by storing the settings/controls inside an array of objects, as shown below:
1 |
function playground_customize_register( $wp_customize ) { |
2 |
$settings = array( |
3 |
(object) array( |
4 |
'id' => 'facebook', |
5 |
'label' => __( 'Facebook', 'playground' ), |
6 |
),
|
7 |
(object) array( |
8 |
'id' => 'instagram', |
9 |
'label' => __( 'Instagram', 'playground' ), |
10 |
),
|
11 |
(object) array( |
12 |
'id' => 'linkedin', |
13 |
'label' => __( 'LinkedIn', 'playground' ), |
14 |
),
|
15 |
(object) array( |
16 |
'id' => 'youtube', |
17 |
'label' => __( 'YouTube', 'playground' ), |
18 |
),
|
19 |
);
|
20 |
|
21 |
$wp_customize->add_section( |
22 |
'social_links', |
23 |
array( |
24 |
'title' => __( 'Social Links', 'playground' ), |
25 |
)
|
26 |
);
|
27 |
|
28 |
foreach ( $settings as $setting ) : |
29 |
$wp_customize->add_setting( |
30 |
$setting->id, |
31 |
array( |
32 |
'sanitize_callback' => 'esc_url_raw', |
33 |
)
|
34 |
);
|
35 |
|
36 |
$wp_customize->add_control( |
37 |
$setting->id, |
38 |
array( |
39 |
'type' => 'url', |
40 |
'section' => 'social_links', |
41 |
'label' => $setting->label, |
42 |
)
|
43 |
);
|
44 |
endforeach; |
45 |
}
|
46 |
add_action( 'customize_register', 'playground_customize_register' ); |
You can add more social media links (like the X in our static demo) by adding new entries in the $settings
array.
Change Menu Item Location
To change the location of our custom section, we have to modify its default priority which is 160. For example, a priority of less than 20 will be placed it above the Site Identity section.
Here’s how the code for that should look:
1 |
$wp_customize->add_section( |
2 |
'social_links', |
3 |
array( |
4 |
'title' => __( 'Social Links', 'playground' ), |
5 |
'priority' => 19, |
6 |
)
|
7 |
);
|
Theme modifications are stored in the wp_options table of the WordPress database. In my case, where I have the Playground theme enabled, I can see my theme’s settings inside the theme_mods_playground option name.
Generate the Shortcode
Our [socials]
shortcode will consist of the following three optional attributes:
- The
title
attribute that will be responsible for showing a heading before the icons. - The
fill
attribute that will specify the SVG icons’ fill color. The default color will be black. - The
fill_hover
attribute that will specify the SVG icons’ fill color on hover. The default hover color will be red.
To call it anywhere we want (e.g. in a sidebar or a widget), we can then use this syntax:
WordPress Shortcode API
To build it, we’ll use the Shortcode API. Inside the functions.php
file of our theme, we’ll add this code:
1 |
function socials_func( $atts ) { |
2 |
$atts = shortcode_atts( |
3 |
array( |
4 |
'title' => '', |
5 |
'fill' => '#000', |
6 |
'fill_hover' => '#FF0000', |
7 |
),
|
8 |
$atts
|
9 |
);
|
10 |
|
11 |
$title = $atts['title']; |
12 |
$fill = $atts['fill']; |
13 |
$fill_hover = $atts['fill_hover']; |
14 |
$facebook = get_theme_mod( 'facebook' ); |
15 |
$instagram = get_theme_mod( 'instagram' ); |
16 |
$linkedin = get_theme_mod( 'linkedin' ); |
17 |
$youtube = get_theme_mod( 'youtube' ); |
18 |
ob_start(); |
19 |
?>
|
20 |
<div class="socials-wrapper"> |
21 |
<?php if ( $title ) : ?> |
22 |
<h4>
|
23 |
<?php echo esc_html( $title ); ?> |
24 |
</h4>
|
25 |
<?php endif; ?> |
26 |
<ul class="socials"> |
27 |
<?php if ( $facebook ) : ?> |
28 |
<li>
|
29 |
<a href="<?php echo esc_url( $facebook ); ?>" aria-label="Find us on Facebook" title="Find us on Facebook" target="_blank"> |
30 |
<svg xmlns="https://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" aria-hidden="true" style="--fill: <?php echo esc_attr( $fill ); ?>; --fill-hover: <?php echo esc_attr( $fill_hover ); ?>"> |
31 |
<path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm3 8h-1.35c-.538 0-.65.221-.65.778v1.222h2l-.209 2h-1.791v7h-3v-7h-2v-2h2v-2.308c0-1.769.931-2.692 3.029-2.692h1.971v3z" /> |
32 |
</svg>
|
33 |
</a>
|
34 |
</li>
|
35 |
<?php
|
36 |
endif; |
37 |
if ( $instagram ) : |
38 |
?>
|
39 |
<li>
|
40 |
<a href="<?php echo esc_url( $instagram ); ?>" aria-label="Find us on Instagram" title="Find us on Instagram" target="_blank"> |
41 |
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" aria-hidden="true" style="--fill: <?php echo esc_attr( $fill ); ?>; --fill-hover: <?php echo esc_attr( $fill_hover ); ?>"> |
42 |
<path d="M14.829 6.302c-.738-.034-.96-.04-2.829-.04s-2.09.007-2.828.04c-1.899.087-2.783.986-2.87 2.87-.033.738-.041.959-.041 2.828s.008 2.09.041 2.829c.087 1.879.967 2.783 2.87 2.87.737.033.959.041 2.828.041 1.87 0 2.091-.007 2.829-.041 1.899-.086 2.782-.988 2.87-2.87.033-.738.04-.96.04-2.829s-.007-2.09-.04-2.828c-.088-1.883-.973-2.783-2.87-2.87zm-2.829 9.293c-1.985 0-3.595-1.609-3.595-3.595 0-1.985 1.61-3.594 3.595-3.594s3.595 1.609 3.595 3.594c0 1.985-1.61 3.595-3.595 3.595zm3.737-6.491c-.464 0-.84-.376-.84-.84 0-.464.376-.84.84-.84.464 0 .84.376.84.84 0 .463-.376.84-.84.84zm-1.404 2.896c0 1.289-1.045 2.333-2.333 2.333s-2.333-1.044-2.333-2.333c0-1.289 1.045-2.333 2.333-2.333s2.333 1.044 2.333 2.333zm-2.333-12c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm6.958 14.886c-.115 2.545-1.532 3.955-4.071 4.072-.747.034-.986.042-2.887.042s-2.139-.008-2.886-.042c-2.544-.117-3.955-1.529-4.072-4.072-.034-.746-.042-.985-.042-2.886 0-1.901.008-2.139.042-2.886.117-2.544 1.529-3.955 4.072-4.071.747-.035.985-.043 2.886-.043s2.14.008 2.887.043c2.545.117 3.957 1.532 4.071 4.071.034.747.042.985.042 2.886 0 1.901-.008 2.14-.042 2.886z" /> |
43 |
</svg>
|
44 |
</a>
|
45 |
</li>
|
46 |
<?php
|
47 |
endif; |
48 |
if ( $linkedin ) : |
49 |
?>
|
50 |
<li>
|
51 |
<a href="<?php echo esc_url( $linkedin ); ?>" aria-label="Find us on LinkedIn" title="Find us on LinkedIn" target="_blank"> |
52 |
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" aria-hidden="true" style="--fill: <?php echo esc_attr( $fill ); ?>; --fill-hover: <?php echo esc_attr( $fill_hover ); ?>"> |
53 |
<path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-2 16h-2v-6h2v6zm-1-6.891c-.607 0-1.1-.496-1.1-1.109 0-.612.492-1.109 1.1-1.109s1.1.497 1.1 1.109c0 .613-.493 1.109-1.1 1.109zm8 6.891h-1.998v-2.861c0-1.881-2.002-1.722-2.002 0v2.861h-2v-6h2v1.093c.872-1.616 4-1.736 4 1.548v3.359z" /> |
54 |
</svg>
|
55 |
</a>
|
56 |
</li>
|
57 |
<?php
|
58 |
endif; |
59 |
if ( $youtube ) : |
60 |
?>
|
61 |
<li>
|
62 |
<a href="<?php echo esc_url( $youtube ); ?>" aria-label="Find us on YouTube" title="Find us on YouTube" target="_blank"> |
63 |
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" aria-hidden="true" style="--fill: <?php echo esc_attr( $fill ); ?>; --fill-hover: <?php echo esc_attr( $fill_hover ); ?>"> |
64 |
<path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm4.441 16.892c-2.102.144-6.784.144-8.883 0-2.276-.156-2.541-1.27-2.558-4.892.017-3.629.285-4.736 2.558-4.892 2.099-.144 6.782-.144 8.883 0 2.277.156 2.541 1.27 2.559 4.892-.018 3.629-.285 4.736-2.559 4.892zm-6.441-7.234l4.917 2.338-4.917 2.346v-4.684z" /> |
65 |
</svg>
|
66 |
</a>
|
67 |
</li>
|
68 |
<?php endif; ?> |
69 |
</ul>
|
70 |
</div>
|
71 |
<?php
|
72 |
return ob_get_clean(); |
73 |
}
|
74 |
add_shortcode( 'socials', 'socials_func' ); |
Consider these things:
- We use the
get_theme_mod()
function to retrieve the social links values from the Customizer. - We do some checks to ensure that only the social icons that don’t have empty values will appear.
- We use the convenient
ob_start()
andob_get_clean()
functions to generate the markup. - We pass the selected colors in the SVGs as inline variables and handle them in the CSS.
- If you need this shortcode for a multilingual site, make the
aria-label
andtitle
attributes translatable.
Styles
Last but not least, we need to add the following styles to our styles:
1 |
.socials-wrapper h4 { |
2 |
font-size: 20px; |
3 |
text-align: center; |
4 |
margin: 0 0 20px; |
5 |
}
|
6 |
|
7 |
.socials { |
8 |
list-style: none; |
9 |
padding: 0; |
10 |
margin: 0; |
11 |
display: flex; |
12 |
justify-content: center; |
13 |
gap: 15px; |
14 |
}
|
15 |
|
16 |
.socials a { |
17 |
display: flex; |
18 |
}
|
19 |
|
20 |
.socials a svg { |
21 |
fill: var(--fill); |
22 |
transition: all 0.25s; |
23 |
}
|
24 |
|
25 |
.socials a:hover svg { |
26 |
fill: var(--fill-hover); |
27 |
transform: scale(1.2); |
28 |
}
|
Conclusion
Today, we learned how to create a social media shortcode with data coming from WordPress Customizer, which you can use anywhere in your WordPress theme. Hopefully, you’ve expanded your knowledge with one or two new things.
Exercise: practice yourself by extending this shortcode. For example, you might want to provide a color option for each social icon by creating new settings/controls in the Customizer.
As always, thanks a lot for reading!