├── README.md
├── Shortcode.php
└── composer.json
/README.md:
--------------------------------------------------------------------------------
1 | yii2-shortcodes
2 | ===============
3 |
4 | Wordpress style shortcodes support for Yii2
5 |
6 | Most part of the code taken from https://github.com/Easy-Forex/WordPress-Shortcodes
7 |
8 |
9 | Installation
10 | ------------
11 | ```code
12 | {
13 | "require": {
14 | "tpoxa/shortcodes": "dev-master"
15 | }
16 | }
17 | ```
18 | Configuration
19 | -------------
20 | In config file
21 | ```code
22 | /config/main.php
23 | ```
24 | Add shortcodes component
25 | ```code
26 | 'components' => array(
27 | ...
28 | 'shortcodes' => [
29 | 'class' => 'tpoxa\shortcodes\Shortcode',
30 | 'callbacks' => [
31 | 'lastphotos' => ['frontend\widgets\lastPhoto\lastPhoto', 'widget'],
32 | 'anothershortcode'=>function($attrs, $content, $tag){
33 | ///
34 | },
35 |
36 | ]
37 | ],
38 | ```
39 | Usage
40 | -----
41 | ```php
42 |
43 | echo \Yii::$app->shortcodes->parse('
44 |
some content [lastphotos limit=8] >
45 | ')
46 |
47 | ```
48 |
49 | Additional
50 | ----
51 | callbacks - An array of valid PHP callbacks. Keys should contain names of the shortcodes.
52 |
53 | lastPhoto example class - common Yii2 widget
54 |
55 | ```php
56 | namespace frontend\widgets\lastPhoto; // your App class
57 |
58 | use yii\base\Widget;
59 | class lastPhoto extends Widget {
60 |
61 | public $limit = 5; // this parameter will be overwritten by 8
62 |
63 | public function run() {
64 | // your widget content goes here
65 | }
66 |
67 | }
68 | ```
69 |
--------------------------------------------------------------------------------
/Shortcode.php:
--------------------------------------------------------------------------------
1 | getShortcodeList($content);
30 | foreach ($shortcodes as $shortcode) {
31 | // Only process known/supported shortcodes
32 | if (in_array($shortcode, array_keys($this->callbacks))) {
33 | $regexp = $this->getShortcodeRegexp($shortcode);
34 | $result = preg_replace_callback("/$regexp/s", array($this, 'parseSingle'), $result);
35 | }
36 | }
37 |
38 | return $result;
39 | }
40 |
41 | /**
42 | * Parse single shortcode
43 | *
44 | * Borrowed from WordPress wp/wp-includes/shortcode.php
45 | *
46 | * @param array $m Shortcode matches
47 | * @return string
48 | */
49 | protected function parseSingle($m) {
50 |
51 | // allow [[foo]] syntax for escaping a tag
52 | if ($m[1] == '[' && $m[6] == ']') {
53 | return substr($m[0], 1, -1);
54 | }
55 |
56 | $tag = $m[2];
57 | $attr = $this->shortcodeParseAtts($m[3]);
58 |
59 | if ($attr === '') {
60 | $attr = null;
61 | }
62 |
63 | if (isset($m[5])) {
64 | // enclosing tag - extra parameter
65 | return $m[1] . call_user_func($this->callbacks[$tag], $attr, $m[5], $tag) . $m[6];
66 | } else {
67 | // self-closing tag
68 | return $m[1] . call_user_func($this->callbacks[$tag], $attr, null, $tag) . $m[6];
69 | }
70 | }
71 |
72 | /**
73 | * Get the list of all shortcodes found in given content
74 | *
75 | * @param string $content Content to process
76 | * @return array
77 | */
78 | protected function getShortcodeList($content) {
79 | $result = array();
80 |
81 | preg_match_all("/\[([A-Za-z_]+[^\ \]]+)/", $content, $matches);
82 | if (!empty($matches[1])) {
83 | foreach ($matches[1] as $match) {
84 | $result[$match] = $match;
85 | }
86 | }
87 | return $result;
88 | }
89 |
90 | /**
91 | * Parses attributes from a shortcode
92 | *
93 | * Borrowed from WordPress wp/wp-includes/shortcode.php
94 | *
95 | * @param string $text
96 | * @return array
97 | */
98 | protected function shortcodeParseAtts($text) {
99 | $atts = array();
100 | $pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/';
101 | $text = preg_replace("/[\x{00a0}\x{200b}]+/u", " ", $text);
102 | if (preg_match_all($pattern, $text, $match, PREG_SET_ORDER)) {
103 | foreach ($match as $m) {
104 | if (!empty($m[1]))
105 | $atts[strtolower($m[1])] = stripcslashes($m[2]);
106 | elseif (!empty($m[3]))
107 | $atts[strtolower($m[3])] = stripcslashes($m[4]);
108 | elseif (!empty($m[5]))
109 | $atts[strtolower($m[5])] = stripcslashes($m[6]);
110 | elseif (isset($m[7]) and strlen($m[7]))
111 | $atts[] = stripcslashes($m[7]);
112 | elseif (isset($m[8]))
113 | $atts[] = stripcslashes($m[8]);
114 | }
115 | } else {
116 | $atts = ltrim($text);
117 | }
118 | return $atts;
119 | }
120 |
121 | /**
122 | * Returns a regular expression for matching a shortcode tag
123 | *
124 | * Borrowed from WordPress wp/wp-includes/shortcode.php
125 | *
126 | * @return string
127 | */
128 | protected function getShortcodeRegexp($tagregexp) {
129 |
130 | return
131 | '\\[' // Opening bracket
132 | . '(\\[?)' // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
133 | . "($tagregexp)" // 2: Shortcode name
134 | . '(?![\\w-])' // Not followed by word character or hyphen
135 | . '(' // 3: Unroll the loop: Inside the opening shortcode tag
136 | . '[^\\]\\/]*' // Not a closing bracket or forward slash
137 | . '(?:'
138 | . '\\/(?!\\])' // A forward slash not followed by a closing bracket
139 | . '[^\\]\\/]*' // Not a closing bracket or forward slash
140 | . ')*?'
141 | . ')'
142 | . '(?:'
143 | . '(\\/)' // 4: Self closing tag ...
144 | . '\\]' // ... and closing bracket
145 | . '|'
146 | . '\\]' // Closing bracket
147 | . '(?:'
148 | . '(' // 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags
149 | . '[^\\[]*+' // Not an opening bracket
150 | . '(?:'
151 | . '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
152 | . '[^\\[]*+' // Not an opening bracket
153 | . ')*+'
154 | . ')'
155 | . '\\[\\/\\2\\]' // Closing shortcode tag
156 | . ')?'
157 | . ')'
158 | . '(\\]?)'; // 6: Optional second closing brocket for escaping shortcodes: [[tag]]
159 | }
160 |
161 | }
162 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tpoxa/shortcodes",
3 | "description": "Wordpress style shorttags support for Yii2",
4 | "type": "yii2-extension",
5 | "keywords": ["yii2", "shortcode"],
6 | "license": "Apache-2.0",
7 | "authors": [
8 | {
9 | "name": "Maksym Trofimenko",
10 | "email": "gtpoxa@gmail.com"
11 | }
12 | ],
13 | "require": {
14 |
15 | },
16 | "autoload": {
17 | "psr-4": {
18 | "tpoxa\\shortcodes\\": ""
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------