Shortcoder - Version 4.1.7

Version Description

  • New: Categorize, search and filter shortcodes using "tags".
  • New: Last used shortcode editor will be saved along with shortcode.
  • New: Enclosed shortcode content can now be used as shortcode parameter.
  • New: Active line highlight has been enabled for code editor.
  • Fix: Codemirror has been updated to latest version.
  • Fix: Minor admin interface enhancements.
Download this release

Release Info

Developer vaakash
Plugin Icon 128x128 Shortcoder
Version 4.1.7
Comparing to
See all releases

Code changes from version 4.1.6 to 4.1.7

admin/css/style-insert.css CHANGED
@@ -104,7 +104,7 @@ hr{
104
  top: 7px;
105
  }
106
  .sc_options .button{
107
- background: #fff;
108
  border: 1px solid transparent;
109
  color: #888;
110
  font-size: 11px;
@@ -115,6 +115,7 @@ hr{
115
  .sc_options .button:hover{
116
  box-shadow: 0 1px 4px -3px #333;
117
  color: #333;
 
118
  }
119
  .sc_shortcode:hover .sc_options .button{
120
  border-color: #607D8B;
@@ -130,12 +131,13 @@ hr{
130
  }
131
 
132
  .sc_menu{
133
- float: right;
134
  }
135
  .sc_menu .button{
136
  border: 1px solid #cecece;
137
  color: #333;
138
  opacity: 0.8;
 
139
  }
140
  .sc_menu .button:hover{
141
  opacity: 1;
@@ -146,6 +148,38 @@ hr{
146
  cursor: auto;
147
  }
148
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  .coffee_box{
150
  padding: 10px;
151
  border: 1px solid #4CAF50;
@@ -173,11 +207,14 @@ hr{
173
  .coffee_box p{
174
  font-size: 13px;
175
  }
 
 
 
 
 
 
 
 
176
 
177
  @media screen and (max-width:750px){
178
- .sc_menu {
179
- display: block;
180
- margin: 10px 0 0 -40px;
181
- float: none;
182
- }
183
  }
104
  top: 7px;
105
  }
106
  .sc_options .button{
107
+ background: transparent;
108
  border: 1px solid transparent;
109
  color: #888;
110
  font-size: 11px;
115
  .sc_options .button:hover{
116
  box-shadow: 0 1px 4px -3px #333;
117
  color: #333;
118
+ background-color: #fff;
119
  }
120
  .sc_shortcode:hover .sc_options .button{
121
  border-color: #607D8B;
131
  }
132
 
133
  .sc_menu{
134
+ margin: 0 0 1em 0;
135
  }
136
  .sc_menu .button{
137
  border: 1px solid #cecece;
138
  color: #333;
139
  opacity: 0.8;
140
+ margin: 0 5px 0 0;
141
  }
142
  .sc_menu .button:hover{
143
  opacity: 1;
148
  cursor: auto;
149
  }
150
 
151
+ .sc_tags {
152
+ padding: 0.75em 0 0 0;
153
+ background: #ffffff8a;
154
+ border: 1px solid #dfdfdf;
155
+ border-radius: 3px;
156
+ display: none;
157
+ }
158
+ .sc_tags li {
159
+ float: left;
160
+ list-style: none;
161
+ margin: 0;
162
+ font-size: 13px;
163
+ margin: 0 1em 1em 1em;
164
+ color: #287aa0;
165
+ font-weight: bold;
166
+ cursor: pointer;
167
+ }
168
+ .sc_tags li.active{
169
+ opacity: 0.5;
170
+ }
171
+ .sc_tags li:hover{
172
+ color: #333;
173
+ }
174
+
175
+ .sc_tags_disp {
176
+ font-size: 13px;
177
+ margin: 0;
178
+ border-right: 1px solid #dfdfdf;
179
+ padding: 0 10px 0 0;
180
+ color: #888;
181
+ }
182
+
183
  .coffee_box{
184
  padding: 10px;
185
  border: 1px solid #4CAF50;
207
  .coffee_box p{
208
  font-size: 13px;
209
  }
210
+ .clearfix:after{
211
+ clear: both;
212
+ content: ".";
213
+ display: block;
214
+ height: 0;
215
+ visibility: hidden;
216
+ font-size: 0;
217
+ }
218
 
219
  @media screen and (max-width:750px){
 
 
 
 
 
220
  }
admin/css/style.css CHANGED
@@ -1,5 +1,5 @@
1
  .wrap{
2
- max-width: 900px;
3
  margin: 0 auto;
4
  }
5
 
@@ -24,7 +24,6 @@ h1.sc_title .title-count {
24
  padding: 20px;
25
  border: 1px solid #dfdfdf;
26
  border-radius: 3px;
27
- overflow: hidden;
28
  box-shadow: 0 0 4px -3px;
29
  }
30
 
@@ -32,7 +31,7 @@ h1.sc_title .title-count {
32
  border-bottom: 1px solid #dfdfdf;
33
  margin: -20px -20px 20px -20px;
34
  padding: 1em;
35
- background: linear-gradient(#fdfdfd, #Fafafa);
36
  position: relative;
37
  }
38
 
@@ -69,7 +68,7 @@ h1.sc_title .title-count {
69
  }
70
  .sc_controls {
71
  position: absolute;
72
- top: 20px;
73
  right: 0;
74
  }
75
  .sc_list .sc_controls a {
@@ -77,6 +76,7 @@ h1.sc_title .title-count {
77
  border-radius: 50%;
78
  margin: 0 0 0 15px;
79
  border: 1px solid transparent;
 
80
  }
81
  .sc_list .sc_controls a:hover{
82
  border: 1px solid #dfdfdf;
@@ -106,7 +106,7 @@ h1.sc_title .title-count {
106
  position: absolute;
107
  top: -2px;
108
  font-size: 20px;
109
- width: 86%;
110
  padding: 16px;
111
  left: -22px;
112
  display: none;
@@ -124,6 +124,78 @@ h1.sc_title .title-count {
124
  color: #F44336;
125
  }
126
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  .sc_menu{
128
  position: absolute;
129
  top: 10px;
@@ -147,7 +219,16 @@ h1.sc_title .title-count {
147
  }
148
  .sc_section label select{
149
  font-size: 12px;
150
- margin-left: 10px;
 
 
 
 
 
 
 
 
 
151
  }
152
 
153
  #sc_name{
@@ -253,7 +334,7 @@ h1.sc_title .title-count {
253
  }
254
  .top_sharebar > * {
255
  vertical-align: middle;
256
- margin-left: 5px;
257
  float: right;
258
  }
259
  .share_text {
@@ -267,7 +348,7 @@ h1.sc_title .title-count {
267
  background: #333;
268
  color: #fff;
269
  text-decoration: none;
270
- padding: 4px 10px;
271
  border-radius: 2em;
272
  font-size: 12px;
273
  line-height: 2em;
@@ -358,6 +439,7 @@ h1.sc_title .title-count {
358
  position: relative;
359
  padding-left: 50px;
360
  box-shadow: 0 2px 1px -2px;
 
361
  }
362
  .sc_note:before {
363
  content: "\f348";
@@ -368,6 +450,51 @@ h1.sc_title .title-count {
368
  opacity: 0.8;
369
  top: 12px;
370
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
 
372
  .rate_link{
373
  float: right;
@@ -399,14 +526,6 @@ h1.sc_title .title-count {
399
  color: #000;
400
  }
401
 
402
- .button em {
403
- display: none;
404
- }
405
-
406
- .button:hover em {
407
- display: inline-block;
408
- }
409
-
410
  .fright{
411
  float: right;
412
  }
@@ -424,14 +543,56 @@ h1.sc_title .title-count {
424
  visibility: hidden;
425
  font-size: 0;
426
  }
427
- .sc_switch_editor{
428
- margin: 2px 0 0 5px !important;
429
- }
430
- .sc_switch_editor .dashicons {
431
- margin-top: 4px !important;
432
- }
433
 
434
  .CodeMirror{
435
  border: 1px solid #ccc;
436
  margin-top: 15px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
  }
1
  .wrap{
2
+ max-width: 1000px;
3
  margin: 0 auto;
4
  }
5
 
24
  padding: 20px;
25
  border: 1px solid #dfdfdf;
26
  border-radius: 3px;
 
27
  box-shadow: 0 0 4px -3px;
28
  }
29
 
31
  border-bottom: 1px solid #dfdfdf;
32
  margin: -20px -20px 20px -20px;
33
  padding: 1em;
34
+ background: #fafafa;
35
  position: relative;
36
  }
37
 
68
  }
69
  .sc_controls {
70
  position: absolute;
71
+ top: 7px;
72
  right: 0;
73
  }
74
  .sc_list .sc_controls a {
76
  border-radius: 50%;
77
  margin: 0 0 0 15px;
78
  border: 1px solid transparent;
79
+ display: inline-block;
80
  }
81
  .sc_list .sc_controls a:hover{
82
  border: 1px solid #dfdfdf;
106
  position: absolute;
107
  top: -2px;
108
  font-size: 20px;
109
+ width: 92%;
110
  padding: 16px;
111
  left: -22px;
112
  display: none;
124
  color: #F44336;
125
  }
126
 
127
+ .sc_tags_list {
128
+ display: inline-block;
129
+ vertical-align: middle;
130
+ position: relative;
131
+ }
132
+ .sc_tags_list li {
133
+ float: left;
134
+ background: transparent;
135
+ padding: 0.5em;
136
+ border-radius: 3px;
137
+ margin-left: 0.75em;
138
+ color: #717171;
139
+ /*box-shadow: 0 1px 2px -1px;*/
140
+ cursor: pointer;
141
+ }
142
+ .sc_tags_list li:hover {
143
+ box-shadow: 0 1px 2px -1px;
144
+ background: #fff;
145
+ }
146
+ .sc_tags_list:before {
147
+ content: "\f323";
148
+ font-family: Dashicons;
149
+ position: absolute;
150
+ left: -15px;
151
+ top: 10px;
152
+ color: #9c9c9c;
153
+ }
154
+
155
+
156
+ .sc_tags_filt_btn{
157
+ padding: 0 !important;
158
+ }
159
+ .sc_tags_filt_btn .sc_tags_filt_icon{
160
+ padding: 0 10px;
161
+ }
162
+ .sc_tags_filt_btn.active .sc_tags_filt_icon{
163
+ padding: 0 5px;
164
+ }
165
+ .sc_tags_filt_btn:active, .sc_tags_filt_btn.active{
166
+ transform: none !important;
167
+ }
168
+ .sc_tags_filt_btn.active .sc_tags_filter_wrap{
169
+ display: inline-block;
170
+ }
171
+ .sc_tags_filter_wrap{
172
+ width: 260px;
173
+ display: none;
174
+ }
175
+ .sc_tags_filter_wrap .selectize-input{
176
+ height: 26px;
177
+ padding: 2px !important;
178
+ border-radius: 0 3px 3px 0;
179
+ border: none;
180
+ border-left: 1px solid #dfdfdf;
181
+ }
182
+ .sc_tags_filter_wrap .selectize-control{
183
+ margin: 0;
184
+ text-align: left;
185
+ }
186
+ .sc_tags_filter_wrap .item{
187
+ background: #e1f6ff !important;
188
+ color: #2196F3 !important;
189
+ font-size: 10px;
190
+ }
191
+ .sc_tags_filter_wrap .item:hover{
192
+ opacity: 0.5;
193
+ }
194
+ .sc_tags_filter_wrap .item.active{
195
+ color: red !important;
196
+ background: #ffe1e1 !important;
197
+ }
198
+
199
  .sc_menu{
200
  position: absolute;
201
  top: 10px;
219
  }
220
  .sc_section label select{
221
  font-size: 12px;
222
+ margin-top: 10px;
223
+ }
224
+
225
+ .sc_settings {
226
+ display: flex;
227
+ flex-wrap: wrap;
228
+ }
229
+ .sc_settings .sc_section {
230
+ flex: 1;
231
+ margin-bottom: 0;
232
  }
233
 
234
  #sc_name{
334
  }
335
  .top_sharebar > * {
336
  vertical-align: middle;
337
+ margin-left: 10px;
338
  float: right;
339
  }
340
  .share_text {
348
  background: #333;
349
  color: #fff;
350
  text-decoration: none;
351
+ padding: 2px 10px;
352
  border-radius: 2em;
353
  font-size: 12px;
354
  line-height: 2em;
439
  position: relative;
440
  padding-left: 50px;
441
  box-shadow: 0 2px 1px -2px;
442
+ display: none;
443
  }
444
  .sc_note:before {
445
  content: "\f348";
450
  opacity: 0.8;
451
  top: 12px;
452
  }
453
+ .sc_note_btn {
454
+ margin: 0 0 0 5px;
455
+ font-size: 15px;
456
+ height: 15px;
457
+ vertical-align: middle;
458
+ }
459
+
460
+ .sc_editor_list {
461
+ position: relative;
462
+ display: inline-block;
463
+ }
464
+ .sc_editor_list select{
465
+ padding: 0 30px !important;
466
+ }
467
+ .sc_editor_list:before {
468
+ font-family: Dashicons;
469
+ position: absolute;
470
+ left: 10px;
471
+ top: 6px;
472
+ }
473
+ .sc_editor_icon_text:before{
474
+ content: "\f215";
475
+ }
476
+ .sc_editor_icon_visual:before{
477
+ content: "\f177";
478
+ }
479
+ .sc_editor_icon_code:before{
480
+ content: "\f475";
481
+ }
482
+ .sc_editor_list:after{
483
+ font-family: Dashicons;
484
+ content: "\f140";
485
+ position: absolute;
486
+ right: 25px;
487
+ top: 15px;
488
+ font-size: 15px;
489
+ padding: 0;
490
+ width: 0;
491
+ height: 0;
492
+ line-height: 0;
493
+ }
494
+
495
+ .sc_cm_menu .sc_editor_list{
496
+ margin-left: 5px;
497
+ }
498
 
499
  .rate_link{
500
  float: right;
526
  color: #000;
527
  }
528
 
 
 
 
 
 
 
 
 
529
  .fright{
530
  float: right;
531
  }
543
  visibility: hidden;
544
  font-size: 0;
545
  }
 
 
 
 
 
 
546
 
547
  .CodeMirror{
548
  border: 1px solid #ccc;
549
  margin-top: 15px;
550
+ }
551
+
552
+ @media screen and (max-width: 950px) {
553
+ .sc_settings {
554
+ display: block;
555
+ }
556
+ .sc_settings .sc_section {
557
+ margin-bottom: 20px;
558
+ }
559
+ }
560
+
561
+ [tooltip]{
562
+ margin: 20px 60px;
563
+ position:relative;
564
+ display:inline-block;
565
+ }
566
+ [tooltip]::before {
567
+ content: "";
568
+ position: absolute;
569
+ top:-6px;
570
+ left:50%;
571
+ transform: translateX(-50%);
572
+ border-width: 4px 6px 0 6px;
573
+ border-style: solid;
574
+ border-color: rgba(0,0,0,0.7) transparent transparent transparent;
575
+ z-index: 99;
576
+ opacity:0;
577
+ }
578
+ [tooltip]::after {
579
+ content: attr(tooltip);
580
+ position: absolute;
581
+ left:50%;
582
+ top:-6px;
583
+ transform: translateX(-50%) translateY(-100%);
584
+ background: rgba(0,0,0,0.7);
585
+ text-align: center;
586
+ color: #fff;
587
+ padding: 2px 8px !important;
588
+ font-size: 12px;
589
+ min-width: 80px;
590
+ border-radius: 5px;
591
+ pointer-events: none;
592
+ padding: 4px 4px;
593
+ z-index:99;
594
+ opacity:0;
595
+ }
596
+ [tooltip]:hover::after,[tooltip]:hover::before {
597
+ opacity:1
598
  }
admin/js/script-insert.js CHANGED
@@ -109,6 +109,47 @@ $(document).ready(function(){
109
  }
110
  });
111
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  });
113
 
114
  })( jQuery );
109
  }
110
  });
111
 
112
+ $( document ).on( 'click', '.tags_filter_btn', function(){
113
+ $( '.sc_tags' ).slideToggle();
114
+ });
115
+
116
+ $( document ).on( 'click', '.sc_tags li', function(){
117
+
118
+ $(this).toggleClass( 'active' );
119
+ var tags_sel = [];
120
+
121
+ $('.sc_tags li.active').each(function(){
122
+ var tag = $(this).attr('data-value');
123
+ tags_sel.push(tag);
124
+ });
125
+
126
+ if(tags_sel.length == 0){
127
+ $('.sc_wrap .sc_shortcode').show();
128
+ return true;
129
+ }
130
+
131
+ $('.sc_wrap .sc_shortcode').each(function(){
132
+ var tags = $(this).attr('data-tags');
133
+ var tags_split = $.map(tags.split(','), $.trim);
134
+ var has_tag = false;
135
+
136
+ $.each(tags_sel, function(i, tag){
137
+ if(tags_split.includes(tag)){
138
+ has_tag = true;
139
+ return true;
140
+ }
141
+ });
142
+
143
+ if(has_tag){
144
+ $(this).show();
145
+ }else{
146
+ $(this).hide();
147
+ }
148
+
149
+ });
150
+
151
+ });
152
+
153
  });
154
 
155
  })( jQuery );
admin/js/script.js CHANGED
@@ -3,6 +3,7 @@ $(document).ready(function(){
3
 
4
  var delete_ctext = 'Are you sure want to delete this shortcode ?';
5
  var last_sort = 'desc';
 
6
 
7
  var init = function(){
8
  if(window.sc_cm_editor){
@@ -10,13 +11,32 @@ $(document).ready(function(){
10
  lineNumbers: true,
11
  mode: "htmlmixed",
12
  indentWithTabs: false,
13
- lineWrapping: true
 
14
  });
15
  sc_cm.setSize( null, 500 );
16
  sc_cm.on( 'change', function(){
17
  sc_cm.save();
18
  });
19
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
21
 
22
  var sort = function( ele, orderby ){
@@ -46,6 +66,46 @@ $(document).ready(function(){
46
  }
47
  }
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  $( document ).on( 'click', '.sc_delete', function(e){
50
 
51
  e.preventDefault();
@@ -130,18 +190,15 @@ $(document).ready(function(){
130
  }
131
 
132
  $( '.wp-media-buttons' ).append( insert_button );
 
133
 
134
  if( window.sc_cm_editor ){
135
- $( '.CodeMirror' ).before( insert_button );
 
136
  }
137
 
138
  $( '.params_wrap' ).appendTo( 'body' );
139
 
140
- $( '.quicktags-toolbar' ).append(function(){
141
- var html = '<a href="#" class="ed_button button button-small fright sc_switch_editor" data-type="1" title="Enable visual editor"><span class="dashicons dashicons-visibility"></span> Visual editor</a>';
142
- html += '<a href="#" class="ed_button button button-small fright sc_switch_editor" data-type="2" title="Enable code editor"><span class="dashicons dashicons-editor-code"></span> Code editor (beta)</a>';
143
- return html;
144
- });
145
  });
146
 
147
  $( document ).on( 'click', '.sc_insert_params', function(e){
@@ -157,6 +214,23 @@ $(document).ready(function(){
157
  }).toggle();
158
  });
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  $( document ).on( 'click', '.cp_btn', function(){
161
 
162
  var $cp_box = $( '.cp_box' );
@@ -185,7 +259,7 @@ $(document).ready(function(){
185
 
186
  $( document ).on( 'click', '.sort_btn', function(){
187
  last_sort = ( last_sort == 'asc' ) ? 'desc' : 'asc';
188
- sort( $( '.sc_list li' ), last_sort );
189
  $( '.sort_icon' ).toggleClass( 'dashicons-arrow-down-alt' );
190
  $( '.sort_icon' ).toggleClass( 'dashicons-arrow-up-alt' );
191
  });
@@ -204,6 +278,10 @@ $(document).ready(function(){
204
  $( '#import_form' ).submit();
205
  });
206
 
 
 
 
 
207
  $( document ).on( 'click', '.search_btn', function(e){
208
  var $search_box = $(this).find('.search_box');
209
  if(e.target === $search_box[0]){
@@ -211,12 +289,13 @@ $(document).ready(function(){
211
  }
212
  $(this).toggleClass('active');
213
  $search_box.focus();
 
214
  });
215
 
216
  $( document ).on( 'keyup', '.search_box', function(){
217
  var search_term = $(this).val();
218
  var re = new RegExp(search_term, 'gi');
219
- $('.sc_list li').each(function(){
220
  var name = $(this).attr('data-name');
221
  if(name.match(re) === null){
222
  $(this).hide();
@@ -231,7 +310,7 @@ $(document).ready(function(){
231
  $(this).parent().removeClass('filtered');
232
  }
233
 
234
- var visible = $('.sc_list li:visible').length;
235
  var $no_scs_msg = $('.sc_list').find('p');
236
  if( visible == 0 ){
237
  if( $no_scs_msg.length == 0 ){
@@ -243,9 +322,8 @@ $(document).ready(function(){
243
 
244
  });
245
 
246
- $( document ).on( 'click', '.sc_switch_editor', function(e){
247
- e.preventDefault();
248
- window.location = window.location + '&editor=' + $(this).data('type');
249
  });
250
 
251
  init();
3
 
4
  var delete_ctext = 'Are you sure want to delete this shortcode ?';
5
  var last_sort = 'desc';
6
+ var tags_filt_api = false;
7
 
8
  var init = function(){
9
  if(window.sc_cm_editor){
11
  lineNumbers: true,
12
  mode: "htmlmixed",
13
  indentWithTabs: false,
14
+ lineWrapping: true,
15
+ styleActiveLine: true
16
  });
17
  sc_cm.setSize( null, 500 );
18
  sc_cm.on( 'change', function(){
19
  sc_cm.save();
20
  });
21
  }
22
+
23
+ if( $.fn.selectize ){
24
+
25
+ $('.sc_edit_tags').selectize({
26
+ create: true
27
+ });
28
+
29
+ if( $('.sc_tags_filter').length ){
30
+
31
+ $tags_filter_ele = $('.sc_tags_filter').selectize({
32
+ onChange: filter_list_tags
33
+ });
34
+
35
+ tags_filt_api = $tags_filter_ele[0].selectize;
36
+
37
+ }
38
+ }
39
+
40
  }
41
 
42
  var sort = function( ele, orderby ){
66
  }
67
  }
68
 
69
+ var filter_list_tags = function(){
70
+
71
+ var sel_tags = tags_filt_api.items;
72
+ var $sc_list = $( '.sc_list > li' );
73
+
74
+ if( sel_tags.length == 0){
75
+ $sc_list.show();
76
+ return true;
77
+ }
78
+
79
+ $sc_list.each(function(){
80
+ var $sc_item = $( this );
81
+ var sc_tags = $sc_item.attr( 'data-tags' );
82
+
83
+ if( typeof sc_tags === 'undefined' ){
84
+ $sc_item.hide();
85
+ return true;
86
+ }else{
87
+ $sc_item.show();
88
+ }
89
+
90
+ var sc_tags_split = sc_tags.split( ',' );
91
+ var has_tag = false;
92
+
93
+ $.each( sel_tags, function( i, tag ){
94
+ if( sc_tags_split.includes( tag ) ){
95
+ has_tag = true;
96
+ return true;
97
+ }
98
+ });
99
+
100
+ if( has_tag ){
101
+ $sc_item.show();
102
+ }else{
103
+ $sc_item.hide();
104
+ }
105
+
106
+ });
107
+ }
108
+
109
  $( document ).on( 'click', '.sc_delete', function(e){
110
 
111
  e.preventDefault();
190
  }
191
 
192
  $( '.wp-media-buttons' ).append( insert_button );
193
+ $( '.sc_editor_list' ).appendTo( '.wp-media-buttons' );
194
 
195
  if( window.sc_cm_editor ){
196
+ $( '.sc_cm_menu' ).append( insert_button );
197
+ $( '.sc_editor_list' ).appendTo( '.sc_cm_menu' );
198
  }
199
 
200
  $( '.params_wrap' ).appendTo( 'body' );
201
 
 
 
 
 
 
202
  });
203
 
204
  $( document ).on( 'click', '.sc_insert_params', function(e){
214
  }).toggle();
215
  });
216
 
217
+ $( document ).on( 'click', '.sc_tags_filt_icon', function(e){
218
+
219
+ e.preventDefault();
220
+ $( this ).closest( '.sc_tags_filt_btn' ).toggleClass( 'active' );
221
+
222
+ });
223
+
224
+ $( document ).on( 'click', '.sc_tags_list li', function(e){
225
+
226
+ if(tags_filt_api){
227
+ var tag = $(this).attr( 'data-tag-id' );
228
+ tags_filt_api.addItem( tag );
229
+ $( '.sc_tags_filt_btn' ).addClass( 'active' );
230
+ }
231
+
232
+ });
233
+
234
  $( document ).on( 'click', '.cp_btn', function(){
235
 
236
  var $cp_box = $( '.cp_box' );
259
 
260
  $( document ).on( 'click', '.sort_btn', function(){
261
  last_sort = ( last_sort == 'asc' ) ? 'desc' : 'asc';
262
+ sort( $( '.sc_list > li' ), last_sort );
263
  $( '.sort_icon' ).toggleClass( 'dashicons-arrow-down-alt' );
264
  $( '.sort_icon' ).toggleClass( 'dashicons-arrow-up-alt' );
265
  });
278
  $( '#import_form' ).submit();
279
  });
280
 
281
+ $( document ).on( 'change', '.sc_editor', function(e){
282
+ window.location = window.location + '&editor=' + $(this).val();
283
+ });
284
+
285
  $( document ).on( 'click', '.search_btn', function(e){
286
  var $search_box = $(this).find('.search_box');
287
  if(e.target === $search_box[0]){
289
  }
290
  $(this).toggleClass('active');
291
  $search_box.focus();
292
+
293
  });
294
 
295
  $( document ).on( 'keyup', '.search_box', function(){
296
  var search_term = $(this).val();
297
  var re = new RegExp(search_term, 'gi');
298
+ $('.sc_list > li').each(function(){
299
  var name = $(this).attr('data-name');
300
  if(name.match(re) === null){
301
  $(this).hide();
310
  $(this).parent().removeClass('filtered');
311
  }
312
 
313
+ var visible = $('.sc_list > li:visible').length;
314
  var $no_scs_msg = $('.sc_list').find('p');
315
  if( visible == 0 ){
316
  if( $no_scs_msg.length == 0 ){
322
 
323
  });
324
 
325
+ $( document ).on( 'click', '.sc_note_btn', function(e){
326
+ $('.sc_note').slideToggle();
 
327
  });
328
 
329
  init();
admin/sc-admin.php CHANGED
@@ -37,9 +37,11 @@ class Shortcoder_Admin{
37
  if( $hook == self::$pagehook ){
38
 
39
  wp_enqueue_style( 'sc-admin-css', SC_ADMIN_URL . '/css/style.css', array(), SC_VERSION );
 
40
 
41
  wp_enqueue_script( 'jquery' );
42
  wp_enqueue_script( 'sc-admin-js', SC_ADMIN_URL . '/js/script.js', array( 'jquery' ), SC_VERSION );
 
43
 
44
  }
45
  }
@@ -91,33 +93,32 @@ class Shortcoder_Admin{
91
  echo '<h3 class="page_title">' . __( 'List of shortcodes created', 'shortcoder' ) . ' (' . count( $shortcodes ) . ')';
92
  echo '<span class="sc_menu">';
93
 
94
- echo '<span class="button search_btn" title="' . __( 'Search shortcodes', 'shortcoder' ) . '"><span class="dashicons dashicons-search"></span><input type="search" class="search_box" placeholder="Search ..."/></span>';
 
 
 
 
 
 
 
 
 
95
 
96
- echo '<label for="import" class="button"><span class="dashicons dashicons-download"></span><em>' . __( 'Import shortcodes', 'shortcoder' ) . '</em></label>';
97
 
98
  echo '<a href="' . self::get_link(array(
99
  'action' => 'sc_export',
100
  '_wpnonce' => wp_create_nonce( 'sc_export_data' )
101
- ), 'admin-ajax.php' ) . '" class="button"><span class="dashicons dashicons-upload"></span><em>' . __( 'Export shortcodes', 'shortcoder' ) . '</em></a>';
102
 
103
 
104
- echo '<button class="button sort_btn" title="' . __( 'Sort list', 'shortcoder' ) . '"><span class="dashicons dashicons-menu"></span> <span class="dashicons dashicons-arrow-down-alt sort_icon"></span></button>';
105
 
106
  echo '<a href="' . self::get_link(array( 'action' => 'new' )) . '" class="button button-primary sc_new_btn"><span class="dashicons dashicons-plus"></span> ' . __( 'Create a new shortcode', 'shortcoder' ) . '</a>';
107
 
108
  echo '</span>';
109
  echo '</h3>';
110
 
111
- if( isset( $g[ 'sort' ] ) ){
112
- $sort = $g[ 'sort' ];
113
- if( $sort == 'asc' ){
114
- uksort($shortcodes, 'strcasecmp' );
115
- }else if( $sort == 'desc' ){
116
- uksort($shortcodes, 'strcasecmp' );
117
- $shortcodes = array_reverse( $shortcodes, True );
118
- }
119
- }
120
-
121
  echo '<ul class="sc_list" data-empty="' . __( 'No shortcodes are created. Go ahead create one !', 'shortcoder' ) . '">';
122
  foreach( $shortcodes as $name => $data ){
123
 
@@ -137,9 +138,21 @@ class Shortcoder_Admin{
137
 
138
  $disabled_text = ( $data[ 'disabled' ] == '1' ) ? '<small class="disabled_text">' . __( 'Temporarily disabled', 'shortcoder' ) . '</small>' : '';
139
 
140
- echo '<li data-name="' . esc_attr( $name ) . '">';
 
 
141
  echo '<a href="' . $link . '" class="sc_link" title="' . __( 'Edit shortcode', 'shortcoder' ) . '">' . esc_attr( $name ) . $disabled_text . '</a>';
 
142
  echo '<span class="sc_controls">';
 
 
 
 
 
 
 
 
 
143
  echo '<a href="#" class="sc_copy" title="' . __( 'Copy shortcode', 'shortcoder' ) . '"><span class="dashicons dashicons-editor-code"></span></a>';
144
  echo '<a href="' . $delete_link . '" class="sc_delete" title="' . __( 'Delete', 'shortcoder' ) . '"><span class="dashicons dashicons-trash"></span></a>';
145
  echo '</span>';
@@ -200,7 +213,7 @@ class Shortcoder_Admin{
200
  echo '</div>';
201
  echo '</h3>';
202
 
203
- echo '<form method="post">';
204
 
205
  echo '<div class="sc_section">';
206
  echo '<label for="sc_name">' . __( 'Name', 'shortcoder' ) . '</label>';
@@ -210,24 +223,25 @@ class Shortcoder_Admin{
210
  echo '</div></div>';
211
 
212
  echo '<div class="sc_section">';
213
- echo '<label for="sc_content">' . __( 'Shortcode content', 'shortcoder' ) . '</label>';
 
 
214
 
215
- $editor_type = isset( $g[ 'editor' ] ) ? intval( $g[ 'editor' ] ) : 0;
 
 
 
 
 
216
 
217
- if( $editor_type == 2 ){
218
- self::load_codemirror_editor( $values[ 'content' ] );
219
- }else{
220
- wp_editor( $values[ 'content' ], 'sc_content', array( 'wpautop'=> false, 'textarea_rows'=> 15, 'tinymce' => ( $editor_type == 1 ) ) );
221
  }
 
222
 
223
- echo '</div>';
224
-
225
- echo '<p class="sc_note">' . __( 'Note: You can use any HTML, JavaScript, CSS as shortcode content. Shortcoder does not manipulate the shortcode content. What you provide above is what you get as output. Please verify the shortcode content for any syntax or JavaScript errors.', 'shortcoder' ) . '</p>';
226
 
227
- echo '<h4>' . __( 'Settings', 'shortcoder' ) . '</h4>';
228
- echo '<div class="sc_section">';
229
- echo '<label><input type="checkbox" name="sc_disable" value="1" ' . checked( $values[ 'disabled' ], '1', false ) . '/> ' . __( 'Temporarily disable this shortcode', 'shortcoder' ) . '</label>';
230
- echo '<label><input type="checkbox" name="sc_hide_admin" value="1" ' . checked( $values[ 'hide_admin' ], '1', false ) . '/> ' . __( 'Disable this Shortcode for administrators' ) . '</label>';
231
  echo '</div>';
232
 
233
  $device_options = array(
@@ -236,8 +250,16 @@ class Shortcoder_Admin{
236
  'desktop_only' => __( 'On desktops alone', 'shortcoder' )
237
  );
238
 
239
- echo '<h4>' . __( 'Visibility', 'shortcoder' ) . '</h4>';
 
240
  echo '<div class="sc_section">';
 
 
 
 
 
 
 
241
  echo '<label>' . __( 'Show this shortcode', 'shortcoder' );
242
  echo '<select name="sc_devices">';
243
  foreach( $device_options as $id => $name ){
@@ -246,10 +268,22 @@ class Shortcoder_Admin{
246
  echo '</select></label>';
247
  echo '</div>';
248
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  wp_nonce_field( 'sc_edit_nonce' );
250
 
251
  echo '<footer class="page_footer">';
252
- echo '<button class="button button-primary">' . $action_btn . '</button>';
253
 
254
  if( $action == 'edit' ){
255
  $delete_link = self::get_link(array(
@@ -295,6 +329,8 @@ class Shortcoder_Admin{
295
  'sc_disable' => 0,
296
  'sc_hide_admin' => 0,
297
  'sc_devices' => 'all',
 
 
298
  ));
299
 
300
  if( !trim( $p[ 'sc_name' ] ) ){
@@ -308,7 +344,9 @@ class Shortcoder_Admin{
308
  'content' => $p[ 'sc_content' ],
309
  'disabled' => $p[ 'sc_disable' ],
310
  'hide_admin' => $p[ 'sc_hide_admin' ],
311
- 'devices' => $p[ 'sc_devices' ]
 
 
312
  );
313
 
314
  if( array_key_exists( $name, $shortcodes ) ){
@@ -420,14 +458,26 @@ class Shortcoder_Admin{
420
 
421
  }
422
 
423
- public static function load_codemirror_editor( $value ){
424
- echo '<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/codemirror.min.css" rel="stylesheet">';
425
- echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/codemirror.min.js"></script>';
426
- echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/mode/htmlmixed/htmlmixed.min.js"></script>';
427
- echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/mode/css/css.min.js"></script>';
428
- echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/mode/xml/xml.min.js"></script>';
429
- echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/mode/javascript/javascript.min.js"></script>';
430
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  echo '<textarea name="sc_content" id="sc_content">' . esc_textarea( $value ) . '</textarea>';
432
 
433
  echo '<script>var sc_cm_editor = true;</script>';
37
  if( $hook == self::$pagehook ){
38
 
39
  wp_enqueue_style( 'sc-admin-css', SC_ADMIN_URL . '/css/style.css', array(), SC_VERSION );
40
+ wp_enqueue_style( 'sc-selectize', 'https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.4/css/selectize.min.css', array(), SC_VERSION );
41
 
42
  wp_enqueue_script( 'jquery' );
43
  wp_enqueue_script( 'sc-admin-js', SC_ADMIN_URL . '/js/script.js', array( 'jquery' ), SC_VERSION );
44
+ wp_enqueue_script( 'sc-selectize', 'https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.4/js/standalone/selectize.min.js', array( 'jquery' ), SC_VERSION );
45
 
46
  }
47
  }
93
  echo '<h3 class="page_title">' . __( 'List of shortcodes created', 'shortcoder' ) . ' (' . count( $shortcodes ) . ')';
94
  echo '<span class="sc_menu">';
95
 
96
+ echo '<button class="button sc_tags_filt_btn" tooltip="' . __( 'Filter by tags', 'shortcoder' ) . '"><span class="dashicons dashicons-tag sc_tags_filt_icon"></span>';
97
+ echo '<div class="sc_tags_filter_wrap"><select class="sc_tags_filter" multiple>';
98
+ $all_tags = Shortcoder::get_tags();
99
+ foreach($all_tags as $tag){
100
+ echo '<option value="' . $tag . '">' . $tag . '</option>';
101
+ }
102
+ echo '</select></div>';
103
+ echo '</button>';
104
+
105
+ echo '<span class="button search_btn" tooltip="' . __( 'Search shortcodes', 'shortcoder' ) . '"><span class="dashicons dashicons-search"></span><input type="search" class="search_box" placeholder="Search ..."/></span>';
106
 
107
+ echo '<label for="import" class="button" tooltip="' . __( 'Import shortcodes', 'shortcoder' ) . '"><span class="dashicons dashicons-download"></span></label>';
108
 
109
  echo '<a href="' . self::get_link(array(
110
  'action' => 'sc_export',
111
  '_wpnonce' => wp_create_nonce( 'sc_export_data' )
112
+ ), 'admin-ajax.php' ) . '" class="button" tooltip="' . __( 'Export shortcodes', 'shortcoder' ) . '"><span class="dashicons dashicons-upload"></span></a>';
113
 
114
 
115
+ echo '<button class="button sort_btn" tooltip="' . __( 'Sort list', 'shortcoder' ) . '"><span class="dashicons dashicons-menu"></span> <span class="dashicons dashicons-arrow-down-alt sort_icon"></span></button>';
116
 
117
  echo '<a href="' . self::get_link(array( 'action' => 'new' )) . '" class="button button-primary sc_new_btn"><span class="dashicons dashicons-plus"></span> ' . __( 'Create a new shortcode', 'shortcoder' ) . '</a>';
118
 
119
  echo '</span>';
120
  echo '</h3>';
121
 
 
 
 
 
 
 
 
 
 
 
122
  echo '<ul class="sc_list" data-empty="' . __( 'No shortcodes are created. Go ahead create one !', 'shortcoder' ) . '">';
123
  foreach( $shortcodes as $name => $data ){
124
 
138
 
139
  $disabled_text = ( $data[ 'disabled' ] == '1' ) ? '<small class="disabled_text">' . __( 'Temporarily disabled', 'shortcoder' ) . '</small>' : '';
140
 
141
+ $selected_tags = implode( ',', $data[ 'tags' ] );
142
+
143
+ echo '<li data-name="' . esc_attr( $name ) . '" data-tags="' . esc_attr( $selected_tags ) . '">';
144
  echo '<a href="' . $link . '" class="sc_link" title="' . __( 'Edit shortcode', 'shortcoder' ) . '">' . esc_attr( $name ) . $disabled_text . '</a>';
145
+
146
  echo '<span class="sc_controls">';
147
+
148
+ if( isset( $data[ 'tags' ] ) && !empty( $data[ 'tags' ] ) && is_array( $data[ 'tags' ] ) ){
149
+ echo '<ul class="sc_tags_list">';
150
+ foreach( $data['tags'] as $tag ){
151
+ echo '<li data-tag-id="' . $tag . '">' . $tag . '</li>';
152
+ }
153
+ echo '</ul>';
154
+ }
155
+
156
  echo '<a href="#" class="sc_copy" title="' . __( 'Copy shortcode', 'shortcoder' ) . '"><span class="dashicons dashicons-editor-code"></span></a>';
157
  echo '<a href="' . $delete_link . '" class="sc_delete" title="' . __( 'Delete', 'shortcoder' ) . '"><span class="dashicons dashicons-trash"></span></a>';
158
  echo '</span>';
213
  echo '</div>';
214
  echo '</h3>';
215
 
216
+ echo '<form method="post" id="sc_edit_form">';
217
 
218
  echo '<div class="sc_section">';
219
  echo '<label for="sc_name">' . __( 'Name', 'shortcoder' ) . '</label>';
223
  echo '</div></div>';
224
 
225
  echo '<div class="sc_section">';
226
+ echo '<label for="sc_content">' . __( 'Shortcode content', 'shortcoder' ) . '<span class="dashicons dashicons-info sc_note_btn" title="Open note"></span></label>';
227
+
228
+ echo '<p class="sc_note">' . __( 'Note: You can use any HTML, JavaScript, CSS as shortcode content. Shortcoder does not manipulate the shortcode content. What you provide above is what you get as output. Please verify the shortcode content for any syntax or JavaScript errors.', 'shortcoder' ) . '</p>';
229
 
230
+ $editors_list = array(
231
+ 'text' => 'Text editor',
232
+ 'visual' => 'Visual editor',
233
+ 'code' => 'Code editor'
234
+ );
235
+ $editor = ( isset( $g[ 'editor' ] ) && array_key_exists( $g[ 'editor' ], $editors_list ) ) ? $g[ 'editor' ] : $values[ 'editor' ];
236
 
237
+ echo '<span class="sc_editor_list sc_editor_icon_' . $editor . '"><select name="sc_editor" class="sc_editor button">';
238
+ foreach( $editors_list as $id => $name ){
239
+ echo '<option value="' . $id . '" ' . selected( $editor, $id ) . '>' . $name . '</option>';
 
240
  }
241
+ echo '</select></span>';
242
 
243
+ self::load_editor( $editor, $values[ 'content' ] );
 
 
244
 
 
 
 
 
245
  echo '</div>';
246
 
247
  $device_options = array(
250
  'desktop_only' => __( 'On desktops alone', 'shortcoder' )
251
  );
252
 
253
+ echo '<div class="sc_settings">';
254
+
255
  echo '<div class="sc_section">';
256
+ echo '<h4>' . __( 'Settings', 'shortcoder' ) . '</h4>';
257
+ echo '<label><input type="checkbox" name="sc_disable" value="1" ' . checked( $values[ 'disabled' ], '1', false ) . '/> ' . __( 'Temporarily disable this shortcode', 'shortcoder' ) . '</label>';
258
+ echo '<label><input type="checkbox" name="sc_hide_admin" value="1" ' . checked( $values[ 'hide_admin' ], '1', false ) . '/> ' . __( 'Disable this Shortcode for administrators' ) . '</label>';
259
+ echo '</div>';
260
+
261
+ echo '<div class="sc_section">';
262
+ echo '<h4>' . __( 'Visibility', 'shortcoder' ) . '</h4>';
263
  echo '<label>' . __( 'Show this shortcode', 'shortcoder' );
264
  echo '<select name="sc_devices">';
265
  foreach( $device_options as $id => $name ){
268
  echo '</select></label>';
269
  echo '</div>';
270
 
271
+ echo '<div class="sc_section">';
272
+ echo '<h4>' . __( 'Tags', 'shortcoder' ) . '</h4>';
273
+ echo '<select name="sc_tags[]" class="sc_edit_tags" multiple>';
274
+ $all_tags = Shortcoder::get_tags();
275
+ foreach($all_tags as $tag){
276
+ echo '<option value="' . $tag . '" ' . ( in_array( $tag, $values[ 'tags' ] ) ? 'selected="selected"' : '' ) . '>' . $tag . '</option>';
277
+ }
278
+ echo '</select>';
279
+ echo '</div>';
280
+
281
+ echo '</div>';
282
+
283
  wp_nonce_field( 'sc_edit_nonce' );
284
 
285
  echo '<footer class="page_footer">';
286
+ echo '<button class="button button-primary sc_save">' . $action_btn . '</button>';
287
 
288
  if( $action == 'edit' ){
289
  $delete_link = self::get_link(array(
329
  'sc_disable' => 0,
330
  'sc_hide_admin' => 0,
331
  'sc_devices' => 'all',
332
+ 'sc_editor' => 'text',
333
+ 'sc_tags' => array()
334
  ));
335
 
336
  if( !trim( $p[ 'sc_name' ] ) ){
344
  'content' => $p[ 'sc_content' ],
345
  'disabled' => $p[ 'sc_disable' ],
346
  'hide_admin' => $p[ 'sc_hide_admin' ],
347
+ 'devices' => $p[ 'sc_devices' ],
348
+ 'editor' => $p[ 'sc_editor' ],
349
+ 'tags' => $p[ 'sc_tags' ]
350
  );
351
 
352
  if( array_key_exists( $name, $shortcodes ) ){
458
 
459
  }
460
 
461
+ public static function load_editor( $type, $value ){
462
+
463
+ if( $type == 'code' ){
464
+ self::load_codemirror_editor( $value );
465
+ }else{
466
+ wp_editor( $value, 'sc_content', array( 'wpautop'=> false, 'textarea_rows'=> 15, 'tinymce' => ( $type == 'visual' ) ) );
467
+ }
468
 
469
+ }
470
+
471
+ public static function load_codemirror_editor( $value ){
472
+ echo '<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/codemirror.min.css" rel="stylesheet">';
473
+ echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/codemirror.min.js"></script>';
474
+ echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/mode/htmlmixed/htmlmixed.min.js"></script>';
475
+ echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/mode/css/css.min.js"></script>';
476
+ echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/mode/xml/xml.min.js"></script>';
477
+ echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/mode/javascript/javascript.min.js"></script>';
478
+ echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/addon/selection/active-line.min.js"></script>';
479
+
480
+ echo '<div class="sc_cm_menu"></div>';
481
  echo '<textarea name="sc_content" id="sc_content">' . esc_textarea( $value ) . '</textarea>';
482
 
483
  echo '<script>var sc_cm_editor = true;</script>';
admin/sc-insert.php CHANGED
@@ -7,17 +7,27 @@
7
  </head>
8
  <body>
9
 
10
- <h2 class="sc_head">Insert shortcode to editor
11
- <span class="sc_menu">
 
12
  <input type="search" class="button search_box" placeholder="Search ..." />
 
13
  <a href="#" class="button sort_btn">Sort list</a>
14
  <?php
15
  if( Shortcoder::can_edit_sc( 'manage_options' ) ){
16
  echo '<a href="' . admin_url( 'options-general.php?page=shortcoder&action=new' ) . '" target="_blank" class="button new_btn">Create new shortcode</a>';
17
  }
18
  ?>
19
- </span>
20
- </h2>
 
 
 
 
 
 
 
 
21
 
22
  <div class="sc_wrap">
23
  <?php
@@ -34,8 +44,11 @@ if( empty( $shortcodes ) ){
34
  $name = esc_attr( $key );
35
  $value = wp_parse_args( $value, Shortcoder::defaults() );
36
  $disabled_text = ( $value[ 'disabled' ] == '1' ) ? '<small class="disabled_text">Temporarily disabled</small>' : '';
 
37
 
38
  $options = '<span class="sc_options">';
 
 
39
  $options .= '<button class="button sc_quick_insert">Quick insert</button>';
40
 
41
  if( Shortcoder::can_edit_sc( 'manage_options' ) ){
@@ -44,7 +57,7 @@ if( empty( $shortcodes ) ){
44
 
45
  $options .= '</span>';
46
 
47
- echo '<div class="sc_shortcode" data-name="' . $name . '">';
48
  echo '<div class="sc_shortcode_name">' . $name . $disabled_text . $options . '</div>';
49
  preg_match_all('/%%[^%\s]+%%/', $value['content'], $matches );
50
 
7
  </head>
8
  <body>
9
 
10
+ <h2 class="sc_head">Insert shortcode to editor</h2>
11
+
12
+ <div class="sc_menu">
13
  <input type="search" class="button search_box" placeholder="Search ..." />
14
+ <a href="#" class="button tags_filter_btn">Filter by tags</a>
15
  <a href="#" class="button sort_btn">Sort list</a>
16
  <?php
17
  if( Shortcoder::can_edit_sc( 'manage_options' ) ){
18
  echo '<a href="' . admin_url( 'options-general.php?page=shortcoder&action=new' ) . '" target="_blank" class="button new_btn">Create new shortcode</a>';
19
  }
20
  ?>
21
+ </div>
22
+
23
+ <ul class="sc_tags clearfix">
24
+ <?php
25
+ $all_tags = Shortcoder::get_tags();
26
+ foreach($all_tags as $tag){
27
+ echo '<li data-value="' . $tag . '">' . $tag . '</li>';
28
+ }
29
+ ?>
30
+ </ul>
31
 
32
  <div class="sc_wrap">
33
  <?php
44
  $name = esc_attr( $key );
45
  $value = wp_parse_args( $value, Shortcoder::defaults() );
46
  $disabled_text = ( $value[ 'disabled' ] == '1' ) ? '<small class="disabled_text">Temporarily disabled</small>' : '';
47
+ $selected_tags = esc_attr( implode( ', ', $value[ 'tags' ] ) );
48
 
49
  $options = '<span class="sc_options">';
50
+ $options .= '<span class="sc_tags_disp">' . $selected_tags . '</span>';
51
+
52
  $options .= '<button class="button sc_quick_insert">Quick insert</button>';
53
 
54
  if( Shortcoder::can_edit_sc( 'manage_options' ) ){
57
 
58
  $options .= '</span>';
59
 
60
+ echo '<div class="sc_shortcode" data-name="' . $name . '" data-tags="' . $selected_tags . '">';
61
  echo '<div class="sc_shortcode_name">' . $name . $disabled_text . $options . '</div>';
62
  preg_match_all('/%%[^%\s]+%%/', $value['content'], $matches );
63
 
includes/import.php CHANGED
@@ -11,8 +11,8 @@ class Shortcoder_Import{
11
  public static function import_form(){
12
 
13
  echo '<form method="post" enctype="multipart/form-data" id="import_form">';
14
- echo '<p class="import_desc"> ' . __( 'Are you sure want to import shortcodes ?', 'shortcoder' ) . '</p>';
15
- echo '<p class="import_desc2"> ' . __( 'Do you want to delete existing shortcodes and perform a clean import ? (selecting "cancel" will overwrite existing shortcodes)', 'shortcoder' ) . '</p>';
16
  echo '<input type="checkbox" name="fresh_import" id="fresh_import" value="1" />';
17
  echo '<input type="file" name="import" id="import" accept="text/plain"/>';
18
  wp_nonce_field( 'sc_import_data' );
11
  public static function import_form(){
12
 
13
  echo '<form method="post" enctype="multipart/form-data" id="import_form">';
14
+ echo '<p class="import_desc">' . __( 'Are you sure want to import shortcodes ?', 'shortcoder' ) . '</p>';
15
+ echo '<p class="import_desc2">' . __( 'Do you want to delete existing shortcodes and perform a clean import ? (selecting "cancel" will overwrite existing shortcodes)', 'shortcoder' ) . '</p>';
16
  echo '<input type="checkbox" name="fresh_import" id="fresh_import" value="1" />';
17
  echo '<input type="file" name="import" id="import" accept="text/plain"/>';
18
  wp_nonce_field( 'sc_import_data' );
readme.txt CHANGED
@@ -6,8 +6,8 @@ Tags: shortcode, html, javascript, shortcodes, short code, posts, pages, widgets
6
  Donate link: https://goo.gl/qMF3iE
7
  License: GPLv2 or later
8
  Requires at least: 3.3
9
- Tested up to: 4.9.4
10
- Stable tag: 4.1.6
11
 
12
  Create custom "Shortcodes" easily for HTML, JavaScript snippets and use the shortcodes within posts, pages & widgets.
13
 
@@ -91,6 +91,14 @@ Note: When you disable a shortcode, the shortcode will not be executed in the pa
91
 
92
  == Changelog ==
93
 
 
 
 
 
 
 
 
 
94
  = 4.1.6 =
95
  * New: Date variables can noe be added into shortcode content.
96
  * Fix: Error "trying to get property of non-object" is handled.
6
  Donate link: https://goo.gl/qMF3iE
7
  License: GPLv2 or later
8
  Requires at least: 3.3
9
+ Tested up to: 4.9.6
10
+ Stable tag: 4.1.7
11
 
12
  Create custom "Shortcodes" easily for HTML, JavaScript snippets and use the shortcodes within posts, pages & widgets.
13
 
91
 
92
  == Changelog ==
93
 
94
+ = 4.1.7 =
95
+ * New: Categorize, search and filter shortcodes using "tags".
96
+ * New: Last used shortcode editor will be saved along with shortcode.
97
+ * New: Enclosed shortcode content can now be used as shortcode parameter.
98
+ * New: Active line highlight has been enabled for code editor.
99
+ * Fix: Codemirror has been updated to latest version.
100
+ * Fix: Minor admin interface enhancements.
101
+
102
  = 4.1.6 =
103
  * New: Date variables can noe be added into shortcode content.
104
  * Fix: Error "trying to get property of non-object" is handled.
shortcoder.php CHANGED
@@ -4,11 +4,11 @@ Plugin Name: Shortcoder
4
  Plugin URI: https://www.aakashweb.com/
5
  Description: Shortcoder is a plugin which allows to create a custom shortcode and store HTML, JavaScript and other snippets in it. So if that shortcode is used in any post or pages, then the code stored in the shortcode get executed in that place. You can create a shortcode for Youtube videos, adsense ads, buttons and more.
6
  Author: Aakash Chakravarthy
7
- Version: 4.1.6
8
  Author URI: https://www.aakashweb.com/
9
  */
10
 
11
- define( 'SC_VERSION', '4.1.6' );
12
  define( 'SC_PATH', plugin_dir_path( __FILE__ ) ); // All have trailing slash
13
  define( 'SC_URL', plugin_dir_url( __FILE__ ) );
14
  define( 'SC_ADMIN_URL', trailingslashit( plugin_dir_url( __FILE__ ) . 'admin' ) );
@@ -48,7 +48,7 @@ class Shortcoder{
48
 
49
  }
50
 
51
- public static function execute_shortcode( $atts, $content ) {
52
 
53
  $shortcodes = self::list_all();
54
 
@@ -110,7 +110,7 @@ class Shortcoder{
110
 
111
  }
112
 
113
- $sc_content_final = self::replace_wp_params( $sc_content_final );
114
  return '<!-- Start shortcoder -->' . do_shortcode( $sc_content_final ) . '<!-- End shortcoder v' . SC_VERSION . '-->';
115
 
116
  }else{
@@ -150,7 +150,7 @@ class Shortcoder{
150
 
151
  }
152
 
153
- public static function replace_wp_params( $content ){
154
 
155
  $params = self::wp_params_list();
156
  $all_params = array();
@@ -162,6 +162,8 @@ class Shortcoder{
162
  $metadata = Shortcoder_Metadata::metadata();
163
  $to_replace = array();
164
 
 
 
165
  foreach( $all_params as $id => $name ){
166
  if( array_key_exists( $id, $metadata ) ){
167
  $placeholder = '$$' . $id . '$$';
@@ -217,10 +219,31 @@ class Shortcoder{
217
  'year' => __( 'Year', 'shortcoder' ),
218
  'year_2d' => __( 'Year - 2 digit', 'shortcoder' ),
219
  )
 
 
 
 
 
 
220
  )
221
  ));
222
  }
223
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  public static function on_activate(){
225
 
226
  $shortcodes = self::list_all();
@@ -242,7 +265,9 @@ class Shortcoder{
242
  'content' => '',
243
  'disabled' => 0,
244
  'hide_admin' => 0,
245
- 'devices' => 'all'
 
 
246
  );
247
  }
248
 
4
  Plugin URI: https://www.aakashweb.com/
5
  Description: Shortcoder is a plugin which allows to create a custom shortcode and store HTML, JavaScript and other snippets in it. So if that shortcode is used in any post or pages, then the code stored in the shortcode get executed in that place. You can create a shortcode for Youtube videos, adsense ads, buttons and more.
6
  Author: Aakash Chakravarthy
7
+ Version: 4.1.7
8
  Author URI: https://www.aakashweb.com/
9
  */
10
 
11
+ define( 'SC_VERSION', '4.1.7' );
12
  define( 'SC_PATH', plugin_dir_path( __FILE__ ) ); // All have trailing slash
13
  define( 'SC_URL', plugin_dir_url( __FILE__ ) );
14
  define( 'SC_ADMIN_URL', trailingslashit( plugin_dir_url( __FILE__ ) . 'admin' ) );
48
 
49
  }
50
 
51
+ public static function execute_shortcode( $atts, $enc_content ) {
52
 
53
  $shortcodes = self::list_all();
54
 
110
 
111
  }
112
 
113
+ $sc_content_final = self::replace_wp_params( $sc_content_final, $enc_content );
114
  return '<!-- Start shortcoder -->' . do_shortcode( $sc_content_final ) . '<!-- End shortcoder v' . SC_VERSION . '-->';
115
 
116
  }else{
150
 
151
  }
152
 
153
+ public static function replace_wp_params( $content, $enc_content ){
154
 
155
  $params = self::wp_params_list();
156
  $all_params = array();
162
  $metadata = Shortcoder_Metadata::metadata();
163
  $to_replace = array();
164
 
165
+ $metadata[ 'enclosed_content' ] = $enc_content;
166
+
167
  foreach( $all_params as $id => $name ){
168
  if( array_key_exists( $id, $metadata ) ){
169
  $placeholder = '$$' . $id . '$$';
219
  'year' => __( 'Year', 'shortcoder' ),
220
  'year_2d' => __( 'Year - 2 digit', 'shortcoder' ),
221
  )
222
+ ),
223
+ 'sc_cnt' => array(
224
+ 'name' => __( 'Shortcode enclosed content', 'shortcoder' ),
225
+ 'params' => array(
226
+ 'enclosed_content' => __( 'Shortcode enclosed content', 'shortcoder' )
227
+ )
228
  )
229
  ));
230
  }
231
 
232
+ public static function get_tags(){
233
+
234
+ $shortcodes = self::list_all();
235
+ $all_tags = array();
236
+
237
+ foreach( $shortcodes as $id => $opts ){
238
+ if( isset( $opts['tags'] ) && !empty( $opts['tags'] ) && is_array($opts['tags']) ){
239
+ $all_tags = array_merge( $all_tags, $opts['tags'] );
240
+ }
241
+ }
242
+
243
+ return array_unique($all_tags);
244
+
245
+ }
246
+
247
  public static function on_activate(){
248
 
249
  $shortcodes = self::list_all();
265
  'content' => '',
266
  'disabled' => 0,
267
  'hide_admin' => 0,
268
+ 'devices' => 'all',
269
+ 'editor' => 'text',
270
+ 'tags' => array()
271
  );
272
  }
273