Insert Pages - Version 1.4

Version Description

  • Update for WordPress 3.9 (update to work under tinymce4);
  • Can now edit existing shortcodes (click inside them, then click the toolbar button).
Download this release

Release Info

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

Version 1.4

assets/css/wpinsertpages.css ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
Binary file
assets/img/insertpages_toolbar_icon.png ADDED
Binary file
assets/img/toggle-arrow.png ADDED
Binary file
assets/js/wpinsertpages.js ADDED
@@ -0,0 +1,604 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ 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
+ */
12
+
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,
20
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
+ GNU General Public License for more details.
23
+
24
+ You should have received a copy of the GNU General Public License
25
+ along with this program; if not, write to the Free Software
26
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
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;
38
+
39
+ // Constructor
40
+ public function InsertPagesPlugin() {
41
+ //$this->pageID = '1'; echo $_GET['post'];
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(
60
+ 'wpinsertpages',
61
+ plugins_url( '/assets/js/wpinsertpages.js', __FILE__ ),
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(
75
+ 'wpinsertpagescss',
76
+ plugins_url( '/assets/css/wpinsertpages.css', __FILE__ ),
77
+ array( 'wp-jquery-ui-dialog' ),
78
+ '20140819'
79
+ );
80
+
81
+ add_filter( 'mce_external_plugins', array( $this, 'insertPages_handleFilter_mceExternalPlugins' ) );
82
+ add_filter( 'mce_buttons', array( $this, 'insertPages_handleFilter_mceButtons' ) );
83
+
84
+ //load_plugin_textdomain('insert-pages', false, dirname(plugin_basename(__FILE__)).'/languages/');
85
+ }
86
+
87
+ }
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
148
+ ob_end_clean(); // End output buffering
149
+ }
150
+ wp_reset_postdata();
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
+ }
158
+
159
+
160
+ // Filter hook: Add a button to the TinyMCE toolbar for our insert page tool
161
+ function insertPages_handleFilter_mceButtons( $buttons ) {
162
+ array_push( $buttons, 'wpInsertPages_button' ); // add a separator and button to toolbar
163
+ return $buttons;
164
+ }
165
+
166
+ // Filter hook: Load the javascript for our custom toolbar button
167
+ function insertPages_handleFilter_mceExternalPlugins( $plugins ) {
168
+ $plugins['wpInsertPages'] = plugins_url( '/assets/js/wpinsertpages_plugin.js', __FILE__ );
169
+ return $plugins;
170
+ }
171
+
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">
194
+ <label>
195
+ <span class="search-label"><?php _e( 'Search' ); ?></span>
196
+ <input type="search" id="insertpage-search-field" class="insertpage-search-field" autocomplete="off" />
197
+ <span class="spinner"></span>
198
+ </label>
199
+ </div>
200
+ <div id="insertpage-search-results" class="query-results">
201
+ <ul></ul>
202
+ <div class="river-waiting">
203
+ <span class="spinner"></span>
204
+ </div>
205
+ </div>
206
+ <div id="insertpage-most-recent-results" class="query-results">
207
+ <div class="query-notice"><em><?php _e( 'No search term specified. Showing recent items.' ); ?></em></div>
208
+ <ul></ul>
209
+ <div class="river-waiting">
210
+ <span class="spinner"></span>
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>
237
+ </div>
238
+ </div>
239
+ </div>
240
+ <div class="submitbox">
241
+ <div id="wp-insertpage-update">
242
+ <input type="submit" value="<?php esc_attr_e( 'Insert Page' ); ?>" class="button button-primary" id="wp-insertpage-submit" name="wp-insertpage-submit">
243
+ </div>
244
+ <div id="wp-insertpage-cancel">
245
+ <a class="submitdelete deletion" href="#"><?php _e( 'Cancel' ); ?></a>
246
+ </div>
247
+ </div>
248
+ </form>
249
+ </div>
250
+ <?php
251
+ }
252
+
253
+ /** Modified from:
254
+ * Internal linking functions.
255
+ * @package WordPress
256
+ * @subpackage Administration
257
+ * @since 3.1.0
258
+ */
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,
290
+ 'post_status' => 'publish',
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
+
304
+ // Do main query.
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 ) ) ) ),
322
+ 'permalink' => get_permalink( $post->ID ),
323
+ 'slug' => $post->post_name,
324
+ 'info' => $info,
325
+ );
326
+ }
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
+ ?>
readme.txt ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Insert Pages ===
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
9
+
10
+ Insert Pages lets you embed any WordPress content (e.g., pages, posts, custom post types) into other WordPress content using the Shortcode API.
11
+
12
+ == Description ==
13
+
14
+ Insert Pages lets you embed any WordPress content (e.g., pages, posts, custom post types) into other WordPress content using the Shortcode API.
15
+
16
+ The real power of Insert Pages comes when you start creating custom post types, either [programmatically in your theme](http://codex.wordpress.org/Post_Types), or using another plugin like [Custom Post Type UI](http://wordpress.org/plugins/custom-post-type-ui/). You can then abstract away common data types (like videos, quizzes, due dates) into their own custom post types, and then show those pieces of content within your normal pages and posts by Inserting them as a shortcode.
17
+
18
+ Here are two quick example use cases:
19
+
20
+ ### Novice Use Case
21
+ Say you teach a course and you're constantly referring to an assignment due date in your course website. The next semester the due date changes, and you have to go change all of the locations you referred to it. Instead, you'd rather just change the date once! With Insert Pages, you can do the following:
22
+
23
+ 1. Create a custom post type called **Due Date**.
24
+ 1. Create a new *Due Date* called **Assignment 1 Due Date** with **Fri Nov 22, 2013** as its content.
25
+ 1. Edit all the pages where the due date occurs and use the *Insert Pages* toolbar button to insert a reference to the *Due Date* you just created. Be sure to set the *Display* to **Content** so *Fri Nov 22, 2013* shows wherever you insert it. The shortcode you just created should look something like this: `[insert page='assignment-1-due-date' display='content']`
26
+ 1. That's it! Now, when you want to change the due date, just edit the *Assignment 1 Due Date* custom post you created, and it will automatically be updated on all the pages you inserted it on.
27
+
28
+ ### Expert Use Case
29
+ Say your site has a lot of video content, and you want to include video transcripts and video lengths along with the videos wherever you show them. You could just paste the transcripts into the page content under the video, but then you'd have to do this on every page the video showed on. (It's also just a bad idea, architecturally!) With Insert Pages, you can use a custom post type and create a custom theme template to display your videos+transcripts+lengths just the way you want!
30
+
31
+ 1. Create a custom post type called **Video**.
32
+ 1. Use a plugin like [Advanced Custom Fields](http://wordpress.org/plugins/advanced-custom-fields/) to add extra fields to your new *Video* custom post type. Add a **Video URL** field, a **Transcript** field, and a **Video Length** field.
33
+ 1. Create a new *Video* called **My Awesome Video** with the following values in its fields:
34
+ * *Video URL*: **http://www.youtube.com/watch?v=oHg5SJYRHA0**
35
+ * *Transcript*: **We're no strangers to love, You know the rules and so do I...**
36
+ * *Video Length*: **3:34**
37
+ 1. Create a template in your theme so we can display the video content as we want. I won't cover this step here since it's pretty involved, but you can find more help in the [WordPress Codex](http://codex.wordpress.org/Theme_Development#Custom_Page_Templates). Let's assume you created a template called **Video with transcript** (video-with-transcript.php) that shows the youtube video in a [fancybox](http://fancybox.net/), and includes a button that shows the text transcript when a user clicks on it.
38
+ 1. Edit the pages where you want the video to show up and use the *Insert Pages* toolbar button to insert a reference to the *Video* you just created. Be sure to set the *Display* to **Use a custom template**, and select your new template **Video with transcript**. The shortcode you just created should look something like this: `[insert page='my-awesome-video' display='video-with-transcript.php']`
39
+ 1. That's it! Now you can create all sorts of video content and know that it's being tracked cleanly in the database as its own custom post type, and you can place videos all over your site and not worry about lots of duplicate content.
40
+
41
+ The possibilities are endless!
42
+
43
+ == Installation ==
44
+
45
+ 1. Upload "insert-pages" to the "/wp-content/plugins/" directory.
46
+ 1. Activate the plugin through the "Plugins" menu in WordPress.
47
+ 1. Use the toolbar button while editing any page to insert any other page.
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:
54
+
55
+ `[insert page='{slug}|{id}' display='title|link|content|all|{custom-template.php}']`
56
+
57
+ Examples:
58
+
59
+ * `[insert page='your-page-slug' display='link']`
60
+ * `[insert page='your-page-slug' display='your-custom-template.php']`
61
+ * `[insert page='123' display='all']`
62
+
63
+ = Anything I should be careful of? =
64
+
65
+ Just one! The plugin prevents you from embedding a page in itself, but you can totally create a loop that will prevent a page from rendering. Say on page A you embed page B, but on page B you also embed page A. As the plugin tries to render either page, it will keep going down the rabbit hole until your server runs out of memory. Future versions should have a way to prevent this behavior!
66
+
67
+ == Screenshots ==
68
+
69
+ 1. Insert Pages toolbar button.
70
+ 2. Insert Pages browser.
71
+ 3. Insert Pages shortcode example.
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).
78
+
79
+ = 1.3 =
80
+ * Better documentation.
81
+
82
+ = 1.2 =
83
+ * Add retina toolbar icon.
84
+
85
+ = 1.1 =
86
+ * Minor changes to documentation.
87
+
88
+ = 1.0 =
89
+ * Initial release.
90
+
91
+ = 0.5 =
92
+ * Development release.
93
+
94
+ == Upgrade Notice ==
95
+
96
+ = 1.2 =
97
+ Added retina toolbar icon.
98
+
99
+ = 1.0 =
100
+ Upgrade to v1.0 to get the first stable version.
screenshot-1.png ADDED
Binary file
screenshot-2.png ADDED
Binary file
screenshot-3.png ADDED
Binary file