summaryrefslogtreecommitdiffstats
path: root/wp-includes/shortcodes.php
blob: 490f7a68261dfecb95017b089a795832d94e23d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?php

/*

An API for creating shortcode tags that support attributes and enclosed content, such as:

[shortcode /]
[shortcode foo="bar" baz="bing" /]
[shortcode foo="bar"]content[/shortcode]

tag and attrbute parsing regexp code based on the Textpattern tag parser.

To apply shortcode tags to content:

$out = do_shortcode($content);

Simplest example of a shortcode tag using the API:

// [footag foo="bar"]
function footag_func($atts) {
	return "foo = {$atts[foo]}";
}
add_shortcode('footag', 'footag_func');

Example with nice attribute defaults:

// [bartag foo="bar"]
function bartag_func($atts) {
	extract(shortcode_atts(array(
		'foo' => 'no foo',
		'baz' => 'default baz',
	), $atts));

	return "foo = {$foo}";
}
add_shortcode('bartag', 'bartag_func');

Example with enclosed content:

// [baztag]content[/baztag]
function baztag_func($atts, $content='') {
	return "content = $content";
}
add_shortcode('baztag', 'baztag_func');

*/

$shortcode_tags = array();

function add_shortcode($tag, $func) {
	global $shortcode_tags;

	if ( is_callable($func) )
		$shortcode_tags[$tag] = $func;
}

function remove_shortcode($tag) {
	global $shortcode_tags;

	unset($shortcode_tags[$tag]);
}

function remove_all_shortcodes() {
	global $shortcode_tags;

	$shortcode_tags = array();
}

function do_shortcode($content) {
	global $shortcode_tags;

	if (empty($shortcode_tags) || !is_array($shortcode_tags))
		return $content;

	$pattern = get_shortcode_regex();
	return preg_replace_callback('/'.$pattern.'/s', 'do_shortcode_tag', $content);
}

function get_shortcode_regex() {
	global $shortcode_tags;
	$tagnames = array_keys($shortcode_tags);
	$tagregexp = join( '|', array_map('preg_quote', $tagnames) );

	return '\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\1\])?';
}

function do_shortcode_tag($m) {
	global $shortcode_tags;

	$tag = $m[1];
	$attr = shortcode_parse_atts($m[2]);

	if ( isset($m[4]) ) {
		// enclosing tag - extra parameter
		return call_user_func($shortcode_tags[$tag], $attr, $m[4]);
	} else {
		// self-closing tag
		return call_user_func($shortcode_tags[$tag], $attr);
	}
}

function shortcode_parse_atts($text) {
	$atts = array();
	$pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/';
	$text = preg_replace("/[\x{00a0}\x{200b}]+/u", " ", $text);
	if ( preg_match_all($pattern, $text, $match, PREG_SET_ORDER) ) {
		foreach ($match as $m) {
			if (!empty($m[1]))
				$atts[strtolower($m[1])] = stripcslashes($m[2]);
			elseif (!empty($m[3]))
				$atts[strtolower($m[3])] = stripcslashes($m[4]);
			elseif (!empty($m[5]))
				$atts[strtolower($m[5])] = stripcslashes($m[6]);
			elseif (isset($m[7]) and strlen($m[7]))
				$atts[] = stripcslashes($m[7]);
			elseif (isset($m[8]))
				$atts[] = stripcslashes($m[8]);
		}
	} else {
		$atts = ltrim($text);
	}
	return $atts;
}

function shortcode_atts($pairs, $atts) {
	$atts = (array)$atts;
	$out = array();
	foreach($pairs as $name => $default) {
		if ( array_key_exists($name, $atts) )
			$out[$name] = $atts[$name];
		else
			$out[$name] = $default;
	}
	return $out;
}

/* 
 * stip all the shortcodes from a post's content 
 * returns the content without shortcodes
 */
function strip_shortcodes( $content ) { 
	
	global $shortcode_tags;

	if (empty($shortcode_tags) || !is_array($shortcode_tags))
		return $content;

	$pattern = get_shortcode_regex();

	return preg_replace('/'.$pattern.'/s', '', $content);
	
}

add_filter('the_content', 'do_shortcode', 11); // AFTER wpautop() 

?>