Insert Pages - Version 2.4

Version Description

  • Add insert_pages_apply_nesting_check filter. Use it to disable the deep nesting check which prevents inserted pages from being embedded within other inserted pages. Example usage: function theme_init() { // Disable nesting check to allow inserted pages within inserted pages. add_filter( 'insert_pages_apply_nesting_check', function ( $should_apply ) { return false; } ); } add_action( 'init', 'theme_init' );
Download this release

Release Info

Developer figureone
Plugin Icon wp plugin Insert Pages
Version 2.4
Comparing to
See all releases

Code changes from version 1.4 to 2.4

assets/css/wpinsertpages.css DELETED
@@ -1,206 +0,0 @@
1
- #wp-insertpage-backdrop {
2
- display: none;
3
- position: fixed;
4
- top: 0;
5
- left: 0;
6
- right: 0;
7
- bottom: 0;
8
- min-height: 360px;
9
- background: #000;
10
- opacity: .7;
11
- filter: alpha(opacity=70);
12
- z-index: 100100;
13
- }
14
-
15
- #wp-insertpage-wrap {
16
- display: none;
17
- background-color: #fff;
18
- -webkit-box-shadow: 0 3px 6px rgba(0,0,0,.3);
19
- box-shadow: 0 3px 6px rgba(0,0,0,.3);
20
- width: 500px;
21
- height: 470px;
22
- overflow: hidden;
23
- margin-left: -250px;
24
- margin-top: -125px;
25
- position: fixed;
26
- top: 50%;
27
- left: 50%;
28
- z-index: 100105;
29
- -webkit-transition: height .2s,margin-top .2s;
30
- transition: height .2s,margin-top .2s;
31
- }
32
-
33
- #wp-insertpage {
34
- line-height: 1.4em;
35
- font-size: 12px;
36
- }
37
-
38
- #wp-insertpage ol,
39
- #wp-insertpage ul {
40
- list-style: none;
41
- margin: 0;
42
- padding: 0;
43
- }
44
-
45
- #wp-insertpage input[type="text"] {
46
- -webkit-box-sizing: border-box;
47
- }
48
-
49
- #wp-insertpage input[type="text"],
50
- #wp-insertpage textarea {
51
- border-width: 1px;
52
- border-style: solid;
53
- -moz-border-radius: 4px;
54
- -khtml-border-radius: 4px;
55
- -webkit-border-radius: 4px;
56
- border-radius: 4px;
57
- font-size: 12px;
58
- margin: 1px;
59
- padding: 3px;
60
- }
61
-
62
- #wp-insertpage #insertpage-options {
63
- padding: 0 0 14px;
64
- border-bottom: 1px solid #dfdfdf;
65
- margin: 0 6px 14px;
66
- }
67
- #wp-insertpage #insertpage-internal-toggle {
68
- display: inline-block;
69
- cursor: pointer;
70
- padding-left: 18px;
71
- }
72
- #wp-insertpage .toggle-arrow {
73
- background: transparent url( '../img/toggle-arrow.png' ) top left no-repeat;
74
- height: 23px;
75
- line-height: 23px;
76
- }
77
- #wp-insertpage .toggle-arrow-active {
78
- background-position: center left;
79
- }
80
- #wp-insertpage label input[type="text"] {
81
- width: 360px;
82
- margin-top: 5px;
83
- }
84
- #wp-insertpage label span {
85
- display: inline-block;
86
- width: 80px;
87
- text-align: right;
88
- padding-right: 5px;
89
- }
90
- #wp-insertpage-wrap.search-panel-visible #insertpage-search-panel {
91
- display: block;
92
- }
93
- #wp-insertpage .insertpage-search-wrapper {
94
- margin: 5px 0 9px;
95
- display: block;
96
- overflow: hidden;
97
- }
98
- #wp-insertpage .insertpage-search-wrapper span {
99
- float: left;
100
- margin-top: 4px;
101
- }
102
- #wp-insertpage .insertpage-search-wrapper input[type="text"] {
103
- float: left;
104
- width: 320px;
105
- }
106
- #wp-insertpage .insertpage-search-wrapper .spinner {
107
- display: none;
108
- vertical-align: text-bottom;
109
- }
110
- #wp-insertpage #insertpage-search-panel label span.search-label {
111
- display: inline-block;
112
- width: 120px;
113
- text-align: right;
114
- padding-right: 5px;
115
- max-width: 24%;
116
- }
117
- #wp-insertpage .insertpage-search-field {
118
- float: left;
119
- width: 250px;
120
- max-width: 70%;
121
- }
122
- #wp-insertpage .insertpage-format {
123
- width: auto;
124
- padding: 10px 0 0;
125
- margin: 0 0 0 40px;
126
- }
127
- #wp-insertpage .query-results {
128
- border: 1px #dfdfdf solid;
129
- margin: 0 5px 5px;
130
- background: #fff;
131
- height: 185px;
132
- overflow: auto;
133
- position: relative;
134
- }
135
- #wp-insertpage li,
136
- #wp-insertpage .query-notice {
137
- clear: both;
138
- margin-bottom: 0;
139
- border-bottom: 1px solid #f1f1f1;
140
- color: #333;
141
- padding: 4px 6px;
142
- cursor: pointer;
143
- position: relative;
144
- }
145
- #wp-insertpage li:hover {
146
- background: #eaf2fa;
147
- color: #151515;
148
- }
149
- #wp-insertpage li.unselectable {
150
- border-bottom: 1px solid #dfdfdf;
151
- }
152
- #wp-insertpage li.unselectable:hover {
153
- background: #fff;
154
- cursor: auto;
155
- color: #333;
156
- }
157
- #wp-insertpage li.selected {
158
- background: #ddd;
159
- color: #333;
160
- }
161
- #wp-insertpage li.selected .item-title {
162
- font-weight: bold;
163
- }
164
- #wp-insertpage .item-title {
165
- display: inline-block;
166
- width: 80%;
167
- }
168
- #wp-insertpage .item-info {
169
- text-transform: uppercase;
170
- color: #666;
171
- font-size: 11px;
172
- position: absolute;
173
- right: 12px;
174
- top: 4px;
175
- bottom: 0;
176
- }
177
- #wp-insertpage #insertpage-search-results {
178
- display: none;
179
- }
180
- #wp-insertpage #insertpage-search-panel {
181
- float: left;
182
- width: 100%;
183
- }
184
- #wp-insertpage .river-waiting {
185
- display: none;
186
- padding: 10px 0;
187
- }
188
- #wp-insertpage .river-waiting .spinner {
189
- margin: 0 auto;
190
- display: block;
191
- float: none;
192
- }
193
- #wp-insertpage .submitbox {
194
- padding: 5px 10px;
195
- font-size: 11px;
196
- overflow: auto;
197
- height: 29px;
198
- }
199
- #wp-insertpage-cancel {
200
- line-height: 25px;
201
- float: left;
202
- }
203
- #wp-insertpage-update {
204
- line-height: 23px;
205
- float: right;
206
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/img/insertpages_toolbar_icon-2x.png DELETED
Binary file
assets/img/insertpages_toolbar_icon.png DELETED
Binary file
assets/img/toggle-arrow.png DELETED
Binary file
assets/js/wpinsertpages.js DELETED
@@ -1,604 +0,0 @@
1
- // Modified from WordPress Advanced Link dialog, wp-includes/js/wplink.js
2
- /* global ajaxurl, tinymce, wpLinkL10n, setUserSetting, wpActiveEditor */
3
- var wpInsertPages;
4
-
5
- (function($){
6
- var inputs = {}, rivers = {}, editor, searchTimer, RiverInsertPages, QueryInsertPages;
7
-
8
- wpInsertPages = {
9
- timeToTriggerRiverInsertPages: 150,
10
- minRiverInsertPagesAJAXDuration: 200,
11
- riverBottomThreshold: 5,
12
- keySensitivity: 100,
13
- lastSearch: '',
14
- textarea: '',
15
-
16
- init : function() {
17
- inputs.wrap = $( '#wp-insertpage-wrap' );
18
- inputs.dialog = $( '#wp-insertpage' );
19
- inputs.backdrop = $( '#wp-insertpage-backdrop' );
20
- inputs.submit = $('#wp-insertpage-submit' );
21
- inputs.close = $( '#wp-insertpage-close' );
22
- // Page info
23
- inputs.slug = $( '#insertpage-slug-field' );
24
- inputs.pageID = $( '#insertpage-pageID' );
25
- inputs.parentPageID = $( '#insertpage-parent-pageID' );
26
- // Format field (title, link, content, all, choose a custom template ->)
27
- inputs.format = $( '#insertpage-format-select' );
28
- // Custom template select field
29
- inputs.template = $( '#insertpage-template-select' );
30
- inputs.search = $( '#insertpage-search-field' );
31
- // Build RiverInsertPagess
32
- rivers.search = new RiverInsertPages( $( '#insertpage-search-results' ) );
33
- rivers.recent = new RiverInsertPages( $( '#insertpage-most-recent-results' ) );
34
- rivers.elements = inputs.dialog.find( '.query-results' );
35
-
36
- // Bind event handlers
37
- inputs.dialog.keydown( wpInsertPages.keydown );
38
- inputs.dialog.keyup( wpInsertPages.keyup );
39
- inputs.submit.click( function( event ){
40
- event.preventDefault();
41
- wpInsertPages.update();
42
- });
43
- inputs.close.add( inputs.backdrop ).add( '#wp-insertpage-cancel a' ).click( function( event ) {
44
- event.preventDefault();
45
- wpInsertPages.close();
46
- });
47
-
48
- $( '#insertpage-internal-toggle' ).click( wpInsertPages.toggleInternalLinking );
49
-
50
- rivers.elements.on('river-select', wpInsertPages.updateFields );
51
-
52
- inputs.format.change( function() {
53
- if ( inputs.format.val() == 'template' ) {
54
- inputs.template.removeAttr( 'disabled' );
55
- inputs.template.focus();
56
- } else {
57
- inputs.template.attr( 'disabled', 'disabled' );
58
- }
59
- });
60
-
61
- inputs.search.keyup( function() {
62
- var self = this;
63
-
64
- window.clearTimeout( searchTimer );
65
- searchTimer = window.setTimeout( function() {
66
- wpInsertPages.searchInternalLinks.call( self );
67
- }, 500 );
68
- });
69
-
70
- /* for this to work, inputs.slug needs to populate inputs.pageID with id when it changes
71
- inputs.pageID.change(function() {
72
- if (inputs.pageID.val() == inputs.parentPageID.val()) { // trying to embed a page in itself
73
- inputs.submit.attr('disabled','disabled');
74
- } else {
75
- inputs.submit.removeAttr('disabled');
76
- }
77
- });
78
- */
79
- },
80
-
81
- open: function( editorId ) {
82
- var ed, node, bookmark, cursorPosition = -1;
83
-
84
- wpInsertPages.range = null;
85
-
86
- if ( editorId ) {
87
- window.wpActiveEditor = editorId;
88
- }
89
-
90
- if ( ! window.wpActiveEditor ) {
91
- return;
92
- }
93
-
94
- this.textarea = $( '#' + window.wpActiveEditor ).get( 0 );
95
-
96
- if ( typeof tinymce !== 'undefined' ) {
97
- ed = tinymce.get( wpActiveEditor );
98
-
99
- if ( ed && ! ed.isHidden() ) {
100
- editor = ed;
101
-
102
- // Get cursor state (used later to determine if we're in an existing shortcode)
103
- node = editor.selection.getNode();
104
- bookmark = editor.selection.getBookmark( 0 );
105
- cursorPosition = node.innerHTML.indexOf( '<span data-mce-type="bookmark"' );
106
- editor.selection.moveToBookmark( bookmark );
107
-
108
- } else {
109
- editor = null;
110
- }
111
-
112
- if ( editor && tinymce.isIE ) {
113
- editor.windowManager.bookmark = editor.selection.getBookmark();
114
- }
115
- }
116
-
117
- if ( ! wpInsertPages.isMCE() && document.selection ) {
118
- this.textarea.focus();
119
- this.range = document.selection.createRange();
120
- }
121
-
122
- inputs.wrap.show();
123
- inputs.backdrop.show();
124
-
125
- wpInsertPages.refresh( cursorPosition );
126
- },
127
-
128
- isMCE: function() {
129
- return editor && ! editor.isHidden();
130
- },
131
-
132
- refresh: function( cursorPosition ) {
133
- // Refresh rivers (clear links, check visibility)
134
- rivers.search.refresh();
135
- rivers.recent.refresh();
136
-
137
- if ( wpInsertPages.isMCE() )
138
- wpInsertPages.mceRefresh( cursorPosition );
139
- else
140
- wpInsertPages.setDefaultValues();
141
-
142
- // Focus the Slug field and highlight its contents.
143
- // If this is moved above the selection changes,
144
- // IE will show a flashing cursor over the dialog.
145
- inputs.slug.focus()[0].select();
146
-
147
- // Load the most recent results if this is the first time opening the panel.
148
- if ( ! rivers.recent.ul.children().length )
149
- rivers.recent.ajax();
150
- },
151
-
152
- mceRefresh: function( cursorPosition ) {
153
- var shortcode, bookmark, regexp, match, matches;
154
-
155
- // Get the existing shortcode the cursor is in (or get the entire node if cursor not in one)
156
- shortcode = '';
157
- content = editor.selection.getNode().innerHTML;
158
- if ( content.indexOf( '[insert page=' ) >= 0 ) {
159
- // Find occurrences of shortcode in current node and see if the cursor
160
- // position is inside one of them.
161
- regexp = /\[insert page=[^\]]*]/g;
162
- while ( ( match = regexp.exec( content ) ) != null ) {
163
- startPos = match.index;
164
- endPos = startPos + match[0].length;
165
- if ( cursorPosition > startPos && cursorPosition < endPos ) {
166
- shortcode = match[0];
167
- break;
168
- }
169
- }
170
- }
171
-
172
- // If cursor is in a shortcode, set the proper values.
173
- if ( shortcode.indexOf( '[insert page=' ) == 0 ) {
174
- // Expand selection to the entire shortcode that the cursor is inside
175
- range = editor.selection.getRng();
176
- node = editor.selection.getNode();
177
- selectedChild = null;
178
- offset = 0;
179
- for ( i = 0; i < node.childNodes.length; i++ ) {
180
- selectedChild = node.childNodes[i];
181
- length = ( selectedChild.outerHTML ) ? selectedChild.outerHTML.length : selectedChild.textContent.length;
182
- if ( cursorPosition < offset + length ) {
183
- break;
184
- }
185
- offset += length;
186
- }
187
- range.setStart( selectedChild, startPos - offset );
188
- range.setEnd( selectedChild, endPos - offset );
189
- editor.selection.setRng( range );
190
-
191
- // Set slug/id (also set the slug as the search term)
192
- regexp = /page=['"]([^['"]*)['"]/;
193
- matches = regexp.exec( shortcode );
194
- if ( matches.length > 1 ) {
195
- inputs.slug.val( matches[1] );
196
- inputs.search.val( matches[1] );
197
- inputs.search.keyup();
198
- }
199
-
200
- regexp = /display=['"]([^['"]*)['"]/;
201
- matches = regexp.exec( shortcode );
202
- if ( matches.length > 1 ) {
203
- if ( matches[1] == 'title' || matches[1] == 'link' || matches[1] == 'content' || matches[1] == 'all' ) {
204
- inputs.format.val( matches[1] );
205
- inputs.template.val( 'all' );
206
- } else {
207
- inputs.format.val( 'template' );
208
- inputs.template.val( matches[1] );
209
- }
210
- inputs.format.change();
211
- }
212
-
213
- // Update save prompt.
214
- inputs.submit.val( 'Update' );
215
-
216
- // If there's no link, set the default values.
217
- } else {
218
- wpInsertPages.setDefaultValues();
219
- }
220
- },
221
-
222
- setDefaultValues : function() {
223
- // Set URL and description to defaults.
224
- // Leave the new tab setting as-is.
225
- inputs.slug.val('');
226
- inputs.pageID.val('');
227
- inputs.format.val('title');
228
- inputs.format.change();
229
- inputs.template.val('all');
230
- inputs.search.val( '' );
231
- inputs.search.keyup();
232
- },
233
-
234
- close: function() {
235
- if ( ! wpInsertPages.isMCE() ) {
236
- wpInsertPages.textarea.focus();
237
-
238
- if ( wpInsertPages.range ) {
239
- wpInsertPages.range.moveToBookmark( wpInsertPages.range.getBookmark() );
240
- wpInsertPages.range.select();
241
- }
242
- } else {
243
- editor.focus();
244
- }
245
-
246
- inputs.backdrop.hide();
247
- inputs.wrap.hide();
248
- },
249
-
250
- getAttrs: function() {
251
- return {
252
- page: inputs.slug.val(),
253
- pageID: inputs.pageID.val(),
254
- display: inputs.format.val()=='template' ? inputs.template.val() : inputs.format.val(),
255
- };
256
- },
257
-
258
- update : function() {
259
- var link,
260
- attrs = wpInsertPages.getAttrs(),
261
- b;
262
-
263
- wpInsertPages.close();
264
- editor.focus();
265
-
266
- if ( tinymce.isIE ) {
267
- editor.selection.moveToBookmark( editor.windowManager.bookmark );
268
- }
269
-
270
- // If the values are empty, undo and return
271
- if ( ! attrs.page || attrs.page == '' ) {
272
- editor.execCommand("mceBeginUndoLevel");
273
- b = editor.selection.getBookmark();
274
- editor.selection.setContent('');
275
- editor.selection.moveToBookmark(b);
276
- editor.execCommand("mceEndUndoLevel");
277
- return;
278
- }
279
-
280
- editor.execCommand("mceBeginUndoLevel");
281
- editor.selection.setContent("[insert " +
282
- "page='" + attrs.page +"' " +
283
- "display='" + attrs.display + "'" +
284
- "]");
285
- editor.execCommand("mceEndUndoLevel");
286
- },
287
-
288
- updateFields : function( e, li, originalEvent ) {
289
- inputs.slug.val( li.children('.item-slug').val() );
290
- inputs.pageID.val( li.children('.item-id').val() );
291
- if ( originalEvent && originalEvent.type == "click" )
292
- inputs.slug.focus();
293
- },
294
-
295
- searchInternalLinks : function() {
296
- var t = $(this), waiting,
297
- search = t.val();
298
-
299
- if ( search.length > 2 ) {
300
- rivers.recent.hide();
301
- rivers.search.show();
302
-
303
- // Don't search if the keypress didn't change the title.
304
- if ( wpInsertPages.lastSearch == search )
305
- return;
306
-
307
- wpInsertPages.lastSearch = search;
308
- waiting = t.parent().find( '.spinner' ).show();
309
-
310
- rivers.search.change( search );
311
- rivers.search.ajax( function() {
312
- waiting.hide();
313
- });
314
- } else {
315
- rivers.search.hide();
316
- rivers.recent.show();
317
- }
318
- },
319
-
320
- next : function() {
321
- rivers.search.next();
322
- rivers.recent.next();
323
- },
324
- prev : function() {
325
- rivers.search.prev();
326
- rivers.recent.prev();
327
- },
328
-
329
- keydown : function( event ) {
330
- var fn, key = $.ui.keyCode;
331
-
332
- switch( event.which ) {
333
- case key.UP:
334
- fn = 'prev';
335
- case key.DOWN:
336
- fn = fn || 'next';
337
- clearInterval( wpInsertPages.keyInterval );
338
- wpInsertPages[ fn ]();
339
- wpInsertPages.keyInterval = setInterval( wpInsertPages[ fn ], wpInsertPages.keySensitivity );
340
- break;
341
- default:
342
- return;
343
- }
344
- event.preventDefault();
345
- },
346
- keyup: function( event ) {
347
- var key = $.ui.keyCode;
348
-
349
- switch( event.which ) {
350
- case key.ESCAPE:
351
- wpInsertPages.cancel();
352
- break;
353
- case key.UP:
354
- case key.DOWN:
355
- clearInterval( wpInsertPages.keyInterval );
356
- break;
357
- default:
358
- return;
359
- }
360
- event.preventDefault();
361
- },
362
-
363
- delayedCallback : function( func, delay ) {
364
- var timeoutTriggered, funcTriggered, funcArgs, funcContext;
365
-
366
- if ( ! delay )
367
- return func;
368
-
369
- setTimeout( function() {
370
- if ( funcTriggered )
371
- return func.apply( funcContext, funcArgs );
372
- // Otherwise, wait.
373
- timeoutTriggered = true;
374
- }, delay);
375
-
376
- return function() {
377
- if ( timeoutTriggered )
378
- return func.apply( this, arguments );
379
- // Otherwise, wait.
380
- funcArgs = arguments;
381
- funcContext = this;
382
- funcTriggered = true;
383
- };
384
- },
385
-
386
- toggleInternalLinking : function( event ) {
387
- var panel = $('#insertpage-options'),
388
- widget = inputs.dialog.wpdialog('widget'),
389
- // We're about to toggle visibility; it's currently the opposite
390
- visible = !panel.is(':visible'),
391
- win = $(window);
392
-
393
- $(this).toggleClass('toggle-arrow-active', visible);
394
-
395
- inputs.dialog.height('auto');
396
- panel.slideToggle( 300, function() {
397
- setUserSetting('wpInsertPages', visible ? '1' : '0');
398
- inputs[ visible ? 'slug' : 'search' ].focus();
399
-
400
- // Move the box if the box is now expanded, was opened in a collapsed state,
401
- // and if it needs to be moved. (Judged by bottom not being positive or
402
- // bottom being smaller than top.)
403
- var scroll = win.scrollTop(),
404
- top = widget.offset().top,
405
- bottom = top + widget.outerHeight(),
406
- diff = bottom - win.height();
407
-
408
- if ( diff > scroll ) {
409
- widget.animate({'top': diff < top ? top - diff : scroll }, 200);
410
- }
411
- });
412
- event.preventDefault();
413
- }
414
- }
415
-
416
- RiverInsertPages = function( element, search ) {
417
- var self = this;
418
- this.element = element;
419
- this.ul = element.children( 'ul' );
420
- this.contentHeight = element.children( '#link-selector-height' );
421
- this.waiting = element.find('.river-waiting');
422
-
423
- this.change( search );
424
- this.refresh();
425
-
426
- $( '#wp-insertpage .query-results, #wp-insertpage #link-selector' ).scroll( function() {
427
- self.maybeLoad();
428
- });
429
- element.on( 'click', 'li', function( event ) {
430
- self.select( $( this ), event );
431
- });
432
- };
433
-
434
- $.extend( RiverInsertPages.prototype, {
435
- refresh: function() {
436
- this.deselect();
437
- this.visible = this.element.is(':visible');
438
- },
439
- show: function() {
440
- if ( ! this.visible ) {
441
- this.deselect();
442
- this.element.show();
443
- this.visible = true;
444
- }
445
- },
446
- hide: function() {
447
- this.element.hide();
448
- this.visible = false;
449
- },
450
- // Selects a list item and triggers the river-select event.
451
- select: function( li, event ) {
452
- var liHeight, elHeight, liTop, elTop;
453
-
454
- if ( li.hasClass('unselectable') || li == this.selected )
455
- return;
456
-
457
- this.deselect();
458
- this.selected = li.addClass('selected');
459
- // Make sure the element is visible
460
- liHeight = li.outerHeight();
461
- elHeight = this.element.height();
462
- liTop = li.position().top;
463
- elTop = this.element.scrollTop();
464
-
465
- if ( liTop < 0 ) // Make first visible element
466
- this.element.scrollTop( elTop + liTop );
467
- else if ( liTop + liHeight > elHeight ) // Make last visible element
468
- this.element.scrollTop( elTop + liTop - elHeight + liHeight );
469
-
470
- // Trigger the river-select event
471
- this.element.trigger('river-select', [ li, event, this ]);
472
- },
473
- deselect: function() {
474
- if ( this.selected )
475
- this.selected.removeClass('selected');
476
- this.selected = false;
477
- },
478
- prev: function() {
479
- if ( ! this.visible )
480
- return;
481
-
482
- var to;
483
- if ( this.selected ) {
484
- to = this.selected.prev('li');
485
- if ( to.length )
486
- this.select( to );
487
- }
488
- },
489
- next: function() {
490
- if ( ! this.visible )
491
- return;
492
-
493
- var to = this.selected ? this.selected.next('li') : $('li:not(.unselectable):first', this.element);
494
- if ( to.length )
495
- this.select( to );
496
- },
497
- ajax: function( callback ) {
498
- var self = this,
499
- delay = this.query.page == 1 ? 0 : wpInsertPages.minRiverInsertPagesAJAXDuration,
500
- response = wpInsertPages.delayedCallback( function( results, params ) {
501
- self.process( results, params );
502
- if ( callback )
503
- callback( results, params );
504
- }, delay );
505
-
506
- this.query.ajax( response );
507
- },
508
- change: function( search ) {
509
- if ( this.query && this._search == search )
510
- return;
511
-
512
- this._search = search;
513
- this.query = new QueryInsertPages( search );
514
- this.element.scrollTop(0);
515
- },
516
- process: function( results, params ) {
517
- var list = '', alt = true, classes = '',
518
- firstPage = params.page == 1;
519
-
520
- if ( !results ) {
521
- if ( firstPage ) {
522
- list += '<li class="unselectable"><span class="item-title"><em>'
523
- + wpInsertPagesL10n.noMatchesFound
524
- + '</em></span></li>';
525
- }
526
- } else {
527
- $.each( results, function() {
528
- classes = alt ? 'alternate' : '';
529
- classes += this['title'] ? '' : ' no-title';
530
- list += classes ? '<li class="' + classes + '">' : '<li>';
531
- list += '<input type="hidden" class="item-permalink" value="' + this['permalink'] + '" />';
532
- list += '<input type="hidden" class="item-slug" value="' + this['slug'] + '" />';
533
- list += '<input type="hidden" class="item-id" value="' + this['ID'] + '" />';
534
- list += '<span class="item-title">';
535
- list += this['title'] ? this['title'] : wpInsertPagesL10n.noTitle;
536
- list += '</span><span class="item-info">' + this['info'] + '</span></li>';
537
- alt = ! alt;
538
- });
539
- }
540
-
541
- this.ul[ firstPage ? 'html' : 'append' ]( list );
542
- },
543
- maybeLoad: function() {
544
- var self = this,
545
- el = this.element,
546
- bottom = el.scrollTop() + el.height();
547
-
548
- if ( ! this.query.ready() || bottom < this.ul.height() - wpInsertPages.riverBottomThreshold )
549
- return;
550
-
551
- setTimeout(function() {
552
- var newTop = el.scrollTop(),
553
- newBottom = newTop + el.height();
554
-
555
- if ( ! self.query.ready() || newBottom < self.ul.height() - wpInsertPages.riverBottomThreshold )
556
- return;
557
-
558
- self.waiting.show();
559
- el.scrollTop( newTop + self.waiting.outerHeight() );
560
-
561
- self.ajax( function() {
562
- self.waiting.hide();
563
- });
564
- }, wpInsertPages.timeToTriggerRiverInsertPages );
565
- }
566
- });
567
-
568
- QueryInsertPages = function( search ) {
569
- this.page = 1;
570
- this.allLoaded = false;
571
- this.querying = false;
572
- this.search = search;
573
- };
574
-
575
- $.extend( QueryInsertPages.prototype, {
576
- ready: function() {
577
- return !( this.querying || this.allLoaded );
578
- },
579
- ajax: function( callback ) {
580
- var self = this,
581
- query = {
582
- //action : 'wp-insertpage-ajax',
583
- action : 'insertpage',
584
- page : this.page,
585
- '_ajax_inserting_nonce' : $('#_ajax_inserting_nonce').val()
586
- };
587
-
588
- if ( this.search )
589
- query.search = this.search;
590
-
591
- query.pageID = inputs.pageID.val();
592
-
593
- this.querying = true;
594
- $.post( ajaxurl, query, function(r) {
595
- self.page++;
596
- self.querying = false;
597
- self.allLoaded = !r;
598
- callback( r, query );
599
- }, "json" );
600
- }
601
- });
602
-
603
- $(document).ready( wpInsertPages.init );
604
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/js/wpinsertpages_plugin.js DELETED
@@ -1,70 +0,0 @@
1
- (function() { // Start a new namespace to avoid collisions
2
-
3
- function isRetinaDisplay() {
4
- if (window.matchMedia) {
5
- var mq = window.matchMedia("only screen and (-moz-min-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 2.6/2), only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (min-device-pixel-ratio: 1.3), only screen and (min-resolution: 1.3dppx)");
6
- if (mq && mq.matches || (window.devicePixelRatio > 1)) {
7
- return true;
8
- } else {
9
- return false;
10
- }
11
- }
12
- }
13
-
14
- tinymce.PluginManager.add( 'wpInsertPages', function( editor, url ) {
15
- var insertPagesButton;
16
-
17
- // Register a command so that it can be invoked by using tinyMCE.activeEditor.execCommand( 'WP_InsertPages' );
18
- editor.addCommand( 'WP_InsertPages', function() {
19
- if ( ( ! insertPagesButton || ! insertPagesButton.disabled() ) && typeof window.wpInsertPages !== 'undefined' ) {
20
- window.wpInsertPages.open( editor.id );
21
- }
22
- })
23
-
24
- function setState( button, node ) {
25
- var parentIsShortcode = false,
26
- bookmark, cursorPosition, regexp, match, startPos, endPos,
27
- parentIsAnchor = editor.dom.getParent( node, 'a' ),
28
- parentIsImg = editor.dom.getParent( node, 'img' );
29
-
30
- // Get whether cursor is in an existing shortcode
31
- content = node.innerHTML;
32
- if ( content.indexOf( '[insert page=' ) >= 0 ) {
33
- // Find the cursor position in the current node.
34
- bookmark = editor.selection.getBookmark( 0 );
35
- cursorPosition = node.innerHTML.indexOf( '<span data-mce-type="bookmark"' );
36
- editor.selection.moveToBookmark( bookmark );
37
-
38
- // Find occurrences of shortcode in current node and see if the cursor
39
- // position is inside one of them.
40
- regexp = /\[insert page=[^\]]*]/g;
41
- while ( ( match = regexp.exec( content ) ) != null ) {
42
- startPos = match.index;
43
- endPos = startPos + match[0].length;
44
- if ( cursorPosition > startPos && cursorPosition < endPos ) {
45
- parentIsShortcode = true;
46
- break;
47
- }
48
- }
49
- }
50
-
51
- button.disabled( parentIsAnchor || parentIsImg );
52
- button.active( parentIsShortcode );
53
- }
54
-
55
- editor.addButton( 'wpInsertPages_button', {
56
- image: url + '/../img/insertpages_toolbar_icon' + ( isRetinaDisplay() ? '-2x' : '' ) + '.png',
57
- tooltip: 'Insert page',
58
- cmd: 'WP_InsertPages',
59
-
60
- onPostRender: function() {
61
- insertPagesButton = this;
62
-
63
- editor.on( 'nodechange', function( event ) {
64
- setState( insertPagesButton, event.element );
65
- });
66
- }
67
- });
68
- })
69
-
70
- } )();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
insert-pages.php CHANGED
@@ -5,7 +5,7 @@ Plugin Name: Insert Pages
5
  Plugin URI: https://bitbucket.org/figureone/insert-pages
6
  Description: Insert Pages lets you embed any WordPress content (e.g., pages, posts, custom post types) into other WordPress content using the Shortcode API.
7
  Author: Paul Ryan
8
- Version: 1.4
9
  Author URI: http://www.linkedin.com/in/paulrryan
10
  License: GPL2
11
  */
@@ -13,7 +13,7 @@ License: GPL2
13
  /* Copyright 2011 Paul Ryan (email: prar@hawaii.edu)
14
 
15
  This program is free software; you can redistribute it and/or modify
16
- it under the terms of the GNU General Public License, version 2, as
17
  published by the Free Software Foundation.
18
 
19
  This program is distributed in the hope that it will be useful,
@@ -27,11 +27,11 @@ License: GPL2
27
  */
28
 
29
  /* Shortcode Format:
30
- [insert page='{slug}|{id}' display='title|link|content|all|{custom-template.php}']
31
  */
32
 
33
  // Define the InsertPagesPlugin class (variables and functions)
34
- if (!class_exists('InsertPagesPlugin')) {
35
  class InsertPagesPlugin {
36
  // Save the id of the page being edited
37
  protected $pageID;
@@ -42,18 +42,22 @@ if (!class_exists('InsertPagesPlugin')) {
42
  }
43
 
44
  // Getter/Setter for pageID
45
- function getPageID() { return $this->pageID; }
46
- function setPageID($id) { return $this->pageID = $id; }
 
 
 
 
47
 
48
  // Action hook: Wordpress 'init'
49
  function insertPages_init() {
50
- add_shortcode('insert', array($this, 'insertPages_handleShortcode_insert'));
51
  }
52
 
53
  // Action hook: Wordpress 'admin_init'
54
  function insertPages_admin_init() {
55
  // Add TinyMCE toolbar button filters only if current user has permissions
56
- if (current_user_can('edit_posts') && current_user_can('edit_pages') && get_user_option('rich_editing')=='true') {
57
 
58
  // Register the TinyMCE toolbar button script
59
  wp_enqueue_script(
@@ -62,13 +66,17 @@ if (!class_exists('InsertPagesPlugin')) {
62
  array( 'wpdialogs' ),
63
  '20140819'
64
  );
65
- wp_localize_script( 'wpinsertpages', 'wpInsertPagesL10n', array(
66
- 'update' => __('Update'),
67
- 'save' => __('Insert Page'),
68
- 'noTitle' => __('(no title)'),
69
- 'noMatchesFound' => __('No matches found.'),
70
- 'l10n_print_after' => 'try{convertEntities(wpLinkL10n);}catch(e){};',
71
- ));
 
 
 
 
72
 
73
  // Register the TinyMCE toolbar button styles
74
  wp_enqueue_style(
@@ -88,60 +96,128 @@ if (!class_exists('InsertPagesPlugin')) {
88
 
89
 
90
  // Shortcode hook: Replace the [insert ...] shortcode with the inserted page's content
91
- function insertPages_handleShortcode_insert($atts, $content=null) {
92
- global $wp_query, $post;
93
- extract(shortcode_atts(array(
94
  'page' => '0',
95
  'display' => 'all',
96
- ), $atts));
 
97
 
98
- // Validation checks
99
- if ($page==='0')
100
  return $content;
101
- //if (!preg_match('/_(title|link|content|all|.*\.tpl\.php/)', $display, $matches))
102
- // return $content;
103
- if ($page==$post->ID || $page==$post->post_name) // trying to embed same page in itself
 
104
  return $content;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
  // Get page object from slug or id
107
  $temp_query = clone $wp_query; // we're starting a new loop within the main loop, so save the main query
108
  $temp_post = $wp_query->get_queried_object(); // see: http://codex.wordpress.org/The_Loop#Multiple_Loops_Example_2
109
- if (is_numeric($page)) {
110
- query_posts("p=".intval($page)."&post_type=any");
 
 
 
 
 
 
 
 
 
 
111
  } else {
112
- query_posts("name=".esc_attr($page)."&post_type=any");
 
 
 
113
  }
114
 
 
 
 
 
 
 
 
 
 
 
 
115
  // Start our new Loop
116
- while (have_posts()) {
117
  ob_start(); // Start output buffering so we can save the output to string
118
 
119
  // Show either the title, link, content, everything, or everything via a custom template
120
- switch ($display) {
121
- case "title":
122
- the_post();
123
- echo "<h1>"; the_title(); echo "</h1>";
124
- break;
125
- case "link":
126
- the_post();
127
- echo "<a href='"; the_permalink(); echo "'>"; echo the_title(); echo "</a>";
128
- break;
129
- case "content":
130
- the_post();
131
- echo the_content();
132
- break;
133
- case "all":
134
- the_post();
135
- echo "<h1>"; the_title(); echo "</h1>";
136
- echo the_content();
137
- echo the_meta();
138
- break;
139
- default: // display is either invalid, or contains a template file to use
140
- $template = locate_template($display);
141
- if (strlen($template) > 0) {
142
- include($template); // execute the template code
143
- }
144
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  }
146
 
147
  $content = ob_get_contents(); // Save off output buffer
@@ -151,7 +227,7 @@ if (!class_exists('InsertPagesPlugin')) {
151
  $wp_query = clone $temp_query; // Restore main Loop's wp_query
152
  $post = $temp_post;
153
 
154
- $content = "<div id='insertPages_Content'>$content</div>";
155
  return $content;
156
  //return do_shortcode($content); // careful: watch for infinite loops with nested inserts
157
  }
@@ -172,22 +248,22 @@ if (!class_exists('InsertPagesPlugin')) {
172
  /**
173
  * Modified from /wp-admin/includes/internal-linking.php, function wp_link_dialog()
174
  * Dialog for internal linking.
 
175
  * @since 3.1.0
176
  */
177
  function insertPages_wp_tinymce_dialog() {
178
- $search_panel_visible = '1' == get_user_setting( 'wplink', '0' ) ? ' search-panel-visible' : '';
179
 
180
  // display: none is required here, see #WP27605
181
- ?>
182
- <div id="wp-insertpage-backdrop" style="display: none"></div>
183
- <div id="wp-insertpage-wrap" class="wp-core-ui<?php echo $search_panel_visible; ?>" style="display: none">
184
  <form id="wp-insertpage" tabindex="-1">
185
  <?php wp_nonce_field( 'internal-inserting', '_ajax_inserting_nonce', false ); ?>
186
  <input type="hidden" id="insertpage-parent-pageID" value="<?php echo $_GET['post'] ?>" />
187
- <div id="link-modal-title">
188
  <?php _e( 'Insert page' ) ?>
189
  <div id="wp-insertpage-close" tabindex="0"></div>
190
- </div>
191
  <div id="insertpage-selector">
192
  <div id="insertpage-search-panel">
193
  <div class="insertpage-search-wrapper">
@@ -211,26 +287,29 @@ if (!class_exists('InsertPagesPlugin')) {
211
  </div>
212
  </div>
213
  </div>
214
- <?php $show_internal = '1' == get_user_setting( 'wpInsertPages', '0' ); ?>
215
- <p class="howto toggle-arrow <?php if ( $show_internal ) echo 'toggle-arrow-active'; ?>" id="insertpage-internal-toggle"><?php _e( 'Options' ); ?></p>
216
- <div id="insertpage-options"<?php if ( ! $show_internal ) echo ' style="display:none"'; ?>>
217
- <div>
218
- <label for="insertpage-slug-field"><span><?php _e( 'Slug or ID' ); ?></span>
219
  <input id="insertpage-slug-field" type="text" tabindex="10" autocomplete="off" />
220
  <input id="insertpage-pageID" type="hidden" />
221
  </label>
222
  </div>
223
  <div class="insertpage-format">
224
- <label for="insertpage-format-select"><?php _e( 'Display' ); ?>
 
225
  <select name="insertpage-format-select" id="insertpage-format-select">
226
  <option value='title'>Title</option>
227
  <option value='link'>Link</option>
 
 
228
  <option value='content'>Content</option>
229
  <option value='all'>All (includes custom fields)</option>
230
  <option value='template'>Use a custom template &raquo;</option>
231
  </select>
232
  <select name="insertpage-template-select" id="insertpage-template-select" disabled="true">
233
- <option value='all'><?php _e('Default Template'); ?></option>
234
  <?php page_template_dropdown(); ?>
235
  </select>
236
  </label>
@@ -252,6 +331,7 @@ if (!class_exists('InsertPagesPlugin')) {
252
 
253
  /** Modified from:
254
  * Internal linking functions.
 
255
  * @package WordPress
256
  * @subpackage Administration
257
  * @since 3.1.0
@@ -259,31 +339,46 @@ if (!class_exists('InsertPagesPlugin')) {
259
  function insertPages_insert_page_callback() {
260
  check_ajax_referer( 'internal-inserting', '_ajax_inserting_nonce' );
261
  $args = array();
262
- if ( isset( $_POST['search'] ) )
263
  $args['s'] = stripslashes( $_POST['search'] );
264
- $args['pagenum'] = !empty($_POST['page']) ? absint($_POST['page']) : 1;
265
- $args['pageID'] = !empty($_POST['pageID']) ? absint($_POST['pageID']) : 0;
 
266
 
267
  $results = $this->insertPages_wp_query( $args );
268
 
269
- if (!isset($results))
270
- die('0');
271
- echo json_encode($results);
 
272
  echo "\n";
273
  die();
274
  }
 
275
  /** Modified from:
276
  * Performs post queries for internal linking.
 
277
  * @since 3.1.0
278
- * @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments.
279
  * @return array Results.
280
  */
281
  function insertPages_wp_query( $args = array() ) {
282
  $pts = get_post_types( array( 'public' => true ), 'objects' );
283
- $pt_names = array_keys( $pts );
 
 
 
 
 
 
 
 
 
 
 
284
 
285
  $query = array(
286
- 'post_type' => $pt_names,
287
  'suppress_filters' => true,
288
  'update_post_term_cache' => false,
289
  'update_post_meta_cache' => false,
@@ -291,13 +386,14 @@ if (!class_exists('InsertPagesPlugin')) {
291
  'order' => 'DESC',
292
  'orderby' => 'post_date',
293
  'posts_per_page' => 20,
294
- 'post__not_in' => array($args['pageID']),
295
  );
296
 
297
  $args['pagenum'] = isset( $args['pagenum'] ) ? absint( $args['pagenum'] ) : 1;
298
 
299
- if ( isset( $args['s'] ) )
300
  $query['s'] = $args['s'];
 
301
 
302
  $query['offset'] = $args['pagenum'] > 1 ? $query['posts_per_page'] * ( $args['pagenum'] - 1 ) : 0;
303
 
@@ -305,17 +401,18 @@ if (!class_exists('InsertPagesPlugin')) {
305
  $get_posts = new WP_Query;
306
  $posts = $get_posts->query( $query );
307
  // Check if any posts were found.
308
- if ( ! $get_posts->post_count )
309
  return false;
 
310
 
311
  // Build results.
312
  $results = array();
313
  foreach ( $posts as $post ) {
314
- if ( 'post' == $post->post_type )
315
  $info = mysql2date( __( 'Y/m/d' ), $post->post_date );
316
- else
317
  $info = $pts[ $post->post_type ]->labels->singular_name;
318
-
319
  $results[] = array(
320
  'ID' => $post->ID,
321
  'title' => trim( esc_html( strip_tags( get_the_title( $post ) ) ) ),
@@ -327,25 +424,28 @@ if (!class_exists('InsertPagesPlugin')) {
327
  return $results;
328
  }
329
 
 
 
 
 
 
 
 
 
330
  }
331
  }
332
 
333
  // Initialize InsertPagesPlugin object
334
- if (class_exists('InsertPagesPlugin')) {
335
  $insertPages_plugin = new InsertPagesPlugin();
336
  }
337
 
338
  // Actions and Filters handled by InsertPagesPlugin class
339
- if (isset($insertPages_plugin)) {
340
  // Actions
341
- add_action('init', array($insertPages_plugin, 'insertPages_init'), 1); // Register Shortcodes here
342
- add_action('admin_head', array($insertPages_plugin, 'insertPages_admin_init'), 1); // Add TinyMCE buttons here
343
- add_action('before_wp_tiny_mce', array($insertPages_plugin, 'insertPages_wp_tinymce_dialog'), 1); // Preload TinyMCE popup
344
- add_action('wp_ajax_insertpage', array($insertPages_plugin, 'insertPages_insert_page_callback')); // Populate page search in TinyMCE button popup in this ajax call
 
345
  }
346
-
347
-
348
-
349
-
350
-
351
- ?>
5
  Plugin URI: https://bitbucket.org/figureone/insert-pages
6
  Description: Insert Pages lets you embed any WordPress content (e.g., pages, posts, custom post types) into other WordPress content using the Shortcode API.
7
  Author: Paul Ryan
8
+ Version: 2.4
9
  Author URI: http://www.linkedin.com/in/paulrryan
10
  License: GPL2
11
  */
13
  /* Copyright 2011 Paul Ryan (email: prar@hawaii.edu)
14
 
15
  This program is free software; you can redistribute it and/or modify
16
+ it under the terms of the GNU General Public License, version 2, as
17
  published by the Free Software Foundation.
18
 
19
  This program is distributed in the hope that it will be useful,
27
  */
28
 
29
  /* Shortcode Format:
30
+ [insert page='{slug}|{id}' display='title|link|excerpt|excerpt-only|content|all|{custom-template.php}' class='any-classes']
31
  */
32
 
33
  // Define the InsertPagesPlugin class (variables and functions)
34
+ if ( !class_exists( 'InsertPagesPlugin' ) ) {
35
  class InsertPagesPlugin {
36
  // Save the id of the page being edited
37
  protected $pageID;
42
  }
43
 
44
  // Getter/Setter for pageID
45
+ function getPageID() {
46
+ return $this->pageID;
47
+ }
48
+ function setPageID( $id ) {
49
+ return $this->pageID = $id;
50
+ }
51
 
52
  // Action hook: Wordpress 'init'
53
  function insertPages_init() {
54
+ add_shortcode( 'insert', array( $this, 'insertPages_handleShortcode_insert' ) );
55
  }
56
 
57
  // Action hook: Wordpress 'admin_init'
58
  function insertPages_admin_init() {
59
  // Add TinyMCE toolbar button filters only if current user has permissions
60
+ if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && get_user_option( 'rich_editing' )=='true' ) {
61
 
62
  // Register the TinyMCE toolbar button script
63
  wp_enqueue_script(
66
  array( 'wpdialogs' ),
67
  '20140819'
68
  );
69
+ wp_localize_script(
70
+ 'wpinsertpages',
71
+ 'wpInsertPagesL10n',
72
+ array(
73
+ 'update' => __( 'Update' ),
74
+ 'save' => __( 'Insert Page' ),
75
+ 'noTitle' => __( '(no title)' ),
76
+ 'noMatchesFound' => __( 'No matches found.' ),
77
+ 'l10n_print_after' => 'try{convertEntities(wpLinkL10n);}catch(e){};',
78
+ )
79
+ );
80
 
81
  // Register the TinyMCE toolbar button styles
82
  wp_enqueue_style(
96
 
97
 
98
  // Shortcode hook: Replace the [insert ...] shortcode with the inserted page's content
99
+ function insertPages_handleShortcode_insert( $atts, $content = null ) {
100
+ global $wp_query, $post, $wp_current_filter;
101
+ extract( shortcode_atts( array(
102
  'page' => '0',
103
  'display' => 'all',
104
+ 'class' => '',
105
+ ), $atts ) );
106
 
107
+ // Validation checks.
108
+ if ( $page === '0' ) {
109
  return $content;
110
+ }
111
+
112
+ // Trying to embed same page in itself.
113
+ if ( $page == $post->ID || $page == $post->post_name ) {
114
  return $content;
115
+ }
116
+
117
+ $should_apply_nesting_check = true;
118
+ /**
119
+ * Filter the flag indicating whether to apply deep nesting check
120
+ * that can prevent circular loops. Note that some use cases rely
121
+ * on inserting pages that themselves have inserted pages, so this
122
+ * check should be disabled for those individuals.
123
+ *
124
+ * @param bool $apply_the_content_filter Indicates whether to apply the_content filter.
125
+ */
126
+ $should_apply_nesting_check = apply_filters( 'insert_pages_apply_nesting_check', $should_apply_nesting_check );
127
+
128
+ // Don't allow inserted pages to be added to the_content more than once (prevent infinite loops).
129
+ if ( $should_apply_nesting_check ) {
130
+ $done = false;
131
+ foreach ( $wp_current_filter as $filter ) {
132
+ if ( 'the_content' == $filter ) {
133
+ if ( $done ) {
134
+ return $content;
135
+ } else {
136
+ $done = true;
137
+ }
138
+ }
139
+ }
140
+ }
141
 
142
  // Get page object from slug or id
143
  $temp_query = clone $wp_query; // we're starting a new loop within the main loop, so save the main query
144
  $temp_post = $wp_query->get_queried_object(); // see: http://codex.wordpress.org/The_Loop#Multiple_Loops_Example_2
145
+
146
+ // Convert slugs to page IDs to standardize query_posts() lookup below.
147
+ if ( ! is_numeric( $page ) ) {
148
+ $page_object = get_page_by_path( $page, OBJECT, get_post_types() );
149
+ $page = $page_object ? $page_object->ID : $page;
150
+ }
151
+
152
+ if ( is_numeric( $page ) ) {
153
+ $args = array(
154
+ 'p' => intval( $page ),
155
+ 'post_type' => get_post_types(),
156
+ );
157
  } else {
158
+ $args = array(
159
+ 'name' => esc_attr( $page ),
160
+ 'post_type' => get_post_types(),
161
+ );
162
  }
163
 
164
+ query_posts( $args );
165
+
166
+ $should_apply_the_content_filter = true;
167
+ /**
168
+ * Filter the flag indicating whether to apply the_content filter to post
169
+ * contents and excerpts that are being inserted.
170
+ *
171
+ * @param bool $apply_the_content_filter Indicates whether to apply the_content filter.
172
+ */
173
+ $should_apply_the_content_filter = apply_filters( 'insert_pages_apply_the_content_filter', $should_apply_the_content_filter );
174
+
175
  // Start our new Loop
176
+ while ( have_posts() ) {
177
  ob_start(); // Start output buffering so we can save the output to string
178
 
179
  // Show either the title, link, content, everything, or everything via a custom template
180
+ // Note: if the sharing_display filter exists, it means Jetpack is installed and Sharing is enabled;
181
+ // This plugin conflicts with Sharing, because Sharing assumes the_content and the_excerpt filters
182
+ // are only getting called once. The fix here is to disable processing of filters on the_content in
183
+ // the inserted page. @see https://codex.wordpress.org/Function_Reference/the_content#Alternative_Usage
184
+ switch ( $display ) {
185
+ case "title":
186
+ the_post(); ?>
187
+ <h1><?php the_title(); ?></h1>
188
+ <?php break;
189
+ case "link":
190
+ the_post(); ?>
191
+ <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
192
+ <?php break;
193
+ case "excerpt":
194
+ the_post(); ?>
195
+ <h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
196
+ <?php if ( $should_apply_the_content_filter ) the_excerpt(); else echo get_the_excerpt(); ?>
197
+ <?php break;
198
+ case "excerpt-only":
199
+ the_post(); ?>
200
+ <?php if ( $should_apply_the_content_filter ) the_excerpt(); else echo get_the_excerpt(); ?>
201
+ <?php break;
202
+ case "content":
203
+ the_post(); ?>
204
+ <?php if ( $should_apply_the_content_filter ) the_content(); else echo get_the_content(); ?>
205
+ <?php break;
206
+ case "all":
207
+ the_post(); ?>
208
+ <h1><?php the_title(); ?></h1>
209
+ <?php if ( $should_apply_the_content_filter ) the_content(); else echo get_the_content(); ?>
210
+ <?php the_meta(); ?>
211
+ <?php break;
212
+ default: // display is either invalid, or contains a template file to use
213
+ $template = locate_template( $display );
214
+ if ( strlen( $template ) > 0 ) {
215
+ include $template; // execute the template code
216
+ } else { // Couldn't find template, so fall back to printing a link to the page.
217
+ the_post(); ?>
218
+ <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><?php
219
+ }
220
+ break;
221
  }
222
 
223
  $content = ob_get_contents(); // Save off output buffer
227
  $wp_query = clone $temp_query; // Restore main Loop's wp_query
228
  $post = $temp_post;
229
 
230
+ $content = "<div data-post-id='$page' class='insert-page insert-page-$page $class'>$content</div>";
231
  return $content;
232
  //return do_shortcode($content); // careful: watch for infinite loops with nested inserts
233
  }
248
  /**
249
  * Modified from /wp-admin/includes/internal-linking.php, function wp_link_dialog()
250
  * Dialog for internal linking.
251
+ *
252
  * @since 3.1.0
253
  */
254
  function insertPages_wp_tinymce_dialog() {
255
+ $options_panel_visible = '1' == get_user_setting( 'wplink', '0' ) ? ' options-panel-visible' : '';
256
 
257
  // display: none is required here, see #WP27605
258
+ ?><div id="wp-insertpage-backdrop" style="display: none"></div>
259
+ <div id="wp-insertpage-wrap" class="wp-core-ui<?php echo $options_panel_visible; ?>" style="display: none">
 
260
  <form id="wp-insertpage" tabindex="-1">
261
  <?php wp_nonce_field( 'internal-inserting', '_ajax_inserting_nonce', false ); ?>
262
  <input type="hidden" id="insertpage-parent-pageID" value="<?php echo $_GET['post'] ?>" />
263
+ <div id="insertpage-modal-title">
264
  <?php _e( 'Insert page' ) ?>
265
  <div id="wp-insertpage-close" tabindex="0"></div>
266
+ </div>
267
  <div id="insertpage-selector">
268
  <div id="insertpage-search-panel">
269
  <div class="insertpage-search-wrapper">
287
  </div>
288
  </div>
289
  </div>
290
+ <p class="howto" id="insertpage-options-toggle"><?php _e( 'Options' ); ?></p>
291
+ <div id="insertpage-options-panel">
292
+ <div class="insertpage-options-wrapper">
293
+ <label for="insertpage-slug-field">
294
+ <span><?php _e( 'Slug or ID' ); ?></span>
295
  <input id="insertpage-slug-field" type="text" tabindex="10" autocomplete="off" />
296
  <input id="insertpage-pageID" type="hidden" />
297
  </label>
298
  </div>
299
  <div class="insertpage-format">
300
+ <label for="insertpage-format-select">
301
+ <?php _e( 'Display' ); ?>
302
  <select name="insertpage-format-select" id="insertpage-format-select">
303
  <option value='title'>Title</option>
304
  <option value='link'>Link</option>
305
+ <option value='excerpt'>Excerpt</option>
306
+ <option value='excerpt-only'>Excerpt only (no title)</option>
307
  <option value='content'>Content</option>
308
  <option value='all'>All (includes custom fields)</option>
309
  <option value='template'>Use a custom template &raquo;</option>
310
  </select>
311
  <select name="insertpage-template-select" id="insertpage-template-select" disabled="true">
312
+ <option value='all'><?php _e( 'Default Template' ); ?></option>
313
  <?php page_template_dropdown(); ?>
314
  </select>
315
  </label>
331
 
332
  /** Modified from:
333
  * Internal linking functions.
334
+ *
335
  * @package WordPress
336
  * @subpackage Administration
337
  * @since 3.1.0
339
  function insertPages_insert_page_callback() {
340
  check_ajax_referer( 'internal-inserting', '_ajax_inserting_nonce' );
341
  $args = array();
342
+ if ( isset( $_POST['search'] ) ) {
343
  $args['s'] = stripslashes( $_POST['search'] );
344
+ }
345
+ $args['pagenum'] = !empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
346
+ $args['pageID'] = !empty( $_POST['pageID'] ) ? absint( $_POST['pageID'] ) : 0;
347
 
348
  $results = $this->insertPages_wp_query( $args );
349
 
350
+ if ( !isset( $results ) ) {
351
+ die( '0' );
352
+ }
353
+ echo json_encode( $results );
354
  echo "\n";
355
  die();
356
  }
357
+
358
  /** Modified from:
359
  * Performs post queries for internal linking.
360
+ *
361
  * @since 3.1.0
362
+ * @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments.
363
  * @return array Results.
364
  */
365
  function insertPages_wp_query( $args = array() ) {
366
  $pts = get_post_types( array( 'public' => true ), 'objects' );
367
+ $post_types = array_keys( $pts );
368
+
369
+ /**
370
+ * Filter the post types that appear in the list of pages to insert.
371
+ *
372
+ * By default, all post types will apear.
373
+ *
374
+ * @since 2.0
375
+ *
376
+ * @param array $post_types Array of post type names to include.
377
+ */
378
+ $post_types = apply_filters( 'insert_pages_available_post_types', $post_types );
379
 
380
  $query = array(
381
+ 'post_type' => $post_types,
382
  'suppress_filters' => true,
383
  'update_post_term_cache' => false,
384
  'update_post_meta_cache' => false,
386
  'order' => 'DESC',
387
  'orderby' => 'post_date',
388
  'posts_per_page' => 20,
389
+ 'post__not_in' => array( $args['pageID'] ),
390
  );
391
 
392
  $args['pagenum'] = isset( $args['pagenum'] ) ? absint( $args['pagenum'] ) : 1;
393
 
394
+ if ( isset( $args['s'] ) ) {
395
  $query['s'] = $args['s'];
396
+ }
397
 
398
  $query['offset'] = $args['pagenum'] > 1 ? $query['posts_per_page'] * ( $args['pagenum'] - 1 ) : 0;
399
 
401
  $get_posts = new WP_Query;
402
  $posts = $get_posts->query( $query );
403
  // Check if any posts were found.
404
+ if ( ! $get_posts->post_count ) {
405
  return false;
406
+ }
407
 
408
  // Build results.
409
  $results = array();
410
  foreach ( $posts as $post ) {
411
+ if ( 'post' == $post->post_type ) {
412
  $info = mysql2date( __( 'Y/m/d' ), $post->post_date );
413
+ } else {
414
  $info = $pts[ $post->post_type ]->labels->singular_name;
415
+ }
416
  $results[] = array(
417
  'ID' => $post->ID,
418
  'title' => trim( esc_html( strip_tags( get_the_title( $post ) ) ) ),
424
  return $results;
425
  }
426
 
427
+ function insertPages_add_quicktags() {
428
+ if ( wp_script_is( 'quicktags' ) ) : ?>
429
+ <script type="text/javascript">
430
+ QTags.addButton( 'ed_insert_page', '[insert page]', "[insert page='your-page-slug' display='title|link|excerpt|excerpt-only|content|all']\n", '', '', 'Insert Page', 999 );
431
+ </script>
432
+ <?php endif;
433
+ }
434
+
435
  }
436
  }
437
 
438
  // Initialize InsertPagesPlugin object
439
+ if ( class_exists( 'InsertPagesPlugin' ) ) {
440
  $insertPages_plugin = new InsertPagesPlugin();
441
  }
442
 
443
  // Actions and Filters handled by InsertPagesPlugin class
444
+ if ( isset( $insertPages_plugin ) ) {
445
  // Actions
446
+ add_action( 'init', array( $insertPages_plugin, 'insertPages_init' ), 1 ); // Register Shortcodes here
447
+ add_action( 'admin_head', array( $insertPages_plugin, 'insertPages_admin_init' ), 1 ); // Add TinyMCE buttons here
448
+ add_action( 'before_wp_tiny_mce', array( $insertPages_plugin, 'insertPages_wp_tinymce_dialog' ), 1 ); // Preload TinyMCE popup
449
+ add_action( 'wp_ajax_insertpage', array( $insertPages_plugin, 'insertPages_insert_page_callback' ) ); // Populate page search in TinyMCE button popup in this ajax call
450
+ add_action( 'admin_print_footer_scripts', array( $insertPages_plugin, 'insertPages_add_quicktags' ) );
451
  }
 
 
 
 
 
 
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Contributors: figureone, the_magician
3
  Tags: insert, pages, shortcode, embed
4
  Requires at least: 3.0.1
5
- Tested up to: 3.9.2
6
  Stable tag: trunk
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -48,6 +48,20 @@ The possibilities are endless!
48
 
49
  == Frequently Asked Questions ==
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  = Do I have to use the toolbar button to Insert Pages? =
52
 
53
  No! You can type out the shortcode yourself if you'd like, it's easy. Here's the format:
@@ -72,6 +86,60 @@ Just one! The plugin prevents you from embedding a page in itself, but you can t
72
 
73
  == Changelog ==
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  = 1.4 =
76
  * Update for WordPress 3.9 (update to work under tinymce4);
77
  * Can now edit existing shortcodes (click inside them, then click the toolbar button).
@@ -93,6 +161,9 @@ Just one! The plugin prevents you from embedding a page in itself, but you can t
93
 
94
  == Upgrade Notice ==
95
 
 
 
 
96
  = 1.2 =
97
  Added retina toolbar icon.
98
 
2
  Contributors: figureone, the_magician
3
  Tags: insert, pages, shortcode, embed
4
  Requires at least: 3.0.1
5
+ Tested up to: 4.2.1
6
  Stable tag: trunk
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
48
 
49
  == Frequently Asked Questions ==
50
 
51
+ = How do I limit the list of pages in the dialog to certain post types? =
52
+
53
+ You can hook into the 'insert_pages_available_post_types' filter to limit the post types displayed in the dialog. Here's an example filter that just shows Posts:
54
+
55
+ `/**
56
+ * Filter the list of post types to show in the insert pages dialog.
57
+ *
58
+ * @param $post_types Array of post type names to include in the insert pages list.
59
+ */
60
+ function only_insert_posts( $post_types ) {
61
+ return array( 'post' );
62
+ }
63
+ add_filter( 'insert_pages_available_post_types', 'only_insert_posts' );`
64
+
65
  = Do I have to use the toolbar button to Insert Pages? =
66
 
67
  No! You can type out the shortcode yourself if you'd like, it's easy. Here's the format:
86
 
87
  == Changelog ==
88
 
89
+ = 2.4 =
90
+ * Add insert_pages_apply_nesting_check filter. Use it to disable the deep nesting check which prevents inserted pages from being embedded within other inserted pages. Example usage:
91
+ `function theme_init() {
92
+ // Disable nesting check to allow inserted pages within inserted pages.
93
+ add_filter( 'insert_pages_apply_nesting_check', function ( $should_apply ) { return false; } );
94
+ }
95
+ add_action( 'init', 'theme_init' );`
96
+
97
+ = 2.3 =
98
+ * Remove insertPages_Content id from div wrapper to allow multiple pages to be embedded; replace with insert-page class. Example: `<div data-post-id='123' class='insert-page insert-page-123'>...</div>`
99
+ * New shortcode attribute: class. You can now add custom classes to the div wrapper around your inserted page:
100
+ `[insert page='123' display='all' class='my-class another-class']`
101
+ This results in:
102
+ `<div data-post-id='123' class='insert-page insert-page-123 my-class another-class'>...</div>`
103
+
104
+ = 2.2 =
105
+ * Revert previous fix for conflict with Jetpack's Sharing widget (affected other users negatively).
106
+ * New fix for conflict with Jetpack's Sharing widget. Use it in your theme like so:
107
+ `// If Jetpack Sharing widget is enabled, disable the_content filter for inserted pages.
108
+ function theme_init() {
109
+ if ( has_filter( 'the_content', 'sharing_display' ) ) {
110
+ add_filter( 'insert_pages_apply_the_content_filter', function ( $should_apply ) { return false; } );
111
+ }
112
+ }
113
+ add_action( 'init', 'theme_init' );`
114
+
115
+ = 2.1 =
116
+ * Add quicktag button for Insert Pages to the Text Editor.
117
+ * Fix conflict with Jetpack's Sharing widget.
118
+ * Add stronger infinite loop protection (will stop expanding shortcodes nested within an embedded page).
119
+ * Fix potential infinite loop if custom template can't be found.
120
+
121
+ = 2.0 =
122
+ * Add insert_pages_available_post_types filter to limit post types shown in insert pages dialog (see FAQ for example filter hook). Props @noahj for the feature request.
123
+ * Add excerpt-only display to output the excerpt without the title above it. Props @kalico for the feature request.
124
+
125
+ = 1.9 =
126
+ * Add data-post-id attribute to div container for each inserted page, now you can reference via jQuery with .data( 'postId' ). Props to Robert Payne for the pull request, thanks!
127
+
128
+ = 1.8 =
129
+ * Fix for custom post types marked as exclude_from_search not inserting correctly.
130
+
131
+ = 1.7 =
132
+ * Tested and works on WordPress 4.1;
133
+ * New display format: excerpt. Props to bitbucket user grzegorzdrozd for the pull request. https://bitbucket.org/figureone/insert-pages/commits/0f6402c98058858f76f3f865bb3f8c5aba4cda65
134
+
135
+ = 1.6 =
136
+ * Fix for long page template names causing Display field to wrap in the tinymce popup;
137
+ * Marked as WordPress 4.0 compatible.
138
+
139
+ = 1.5 =
140
+ * Fix for options button toggle in tinymce popup;
141
+ * Fix popup display on small screen sizes (mobile-friendly).
142
+
143
  = 1.4 =
144
  * Update for WordPress 3.9 (update to work under tinymce4);
145
  * Can now edit existing shortcodes (click inside them, then click the toolbar button).
161
 
162
  == Upgrade Notice ==
163
 
164
+ = 2.3 =
165
+ Warning: If you apply CSS rules to #insertPages_Content, this update will require you to modify those styles. The element id "insertPages_Content" was removed so multiple pages can be embedded on a single page. You may apply styles instead to the "insert-page" class.
166
+
167
  = 1.2 =
168
  Added retina toolbar icon.
169