Version Description
- Nested Pages
=
Download this release
Release Info
Developer | kylephillips |
Plugin | Nested Pages |
Version | 1.0 |
Comparing to | |
See all releases |
Version 1.0
- assets/css/fonts/nestedpages.eot +0 -0
- assets/css/fonts/nestedpages.svg +23 -0
- assets/css/fonts/nestedpages.ttf +0 -0
- assets/css/fonts/nestedpages.woff +0 -0
- assets/css/nestedpages.css +1 -0
- assets/images/border.png +0 -0
- assets/images/loading-white.gif +0 -0
- assets/images/loading.gif +0 -0
- assets/js/lib/jquery.mjs.nestedSortable.js +664 -0
- assets/js/lib/jquery.ui.touch-punch.min.js +11 -0
- assets/js/lib/nestedpages.js +578 -0
- assets/js/nestedpages.min.js +1 -0
- assets/screenshot-1.png +0 -0
- assets/screenshot-2.png +0 -0
- assets/screenshot-3.gif +0 -0
- assets/screenshot-4.gif +0 -0
- assets/scss/_alerts.scss +11 -0
- assets/scss/_buttons.scss +51 -0
- assets/scss/_expand-handle.scss +28 -0
- assets/scss/_icons.scss +63 -0
- assets/scss/_mixins.scss +27 -0
- assets/scss/_page-listing.scss +309 -0
- assets/scss/_quick-edit.scss +143 -0
- assets/scss/_toggle-all.scss +29 -0
- assets/scss/_top-tools.scss +10 -0
- assets/scss/_variables.scss +12 -0
- assets/scss/nestedpages.scss +15 -0
- includes/class-nestedpages.php +63 -0
- includes/class-np-activate.php +89 -0
- includes/class-np-dependencies.php +79 -0
- includes/class-np-handler-base.php +108 -0
- includes/class-np-handler-quickedit.php +53 -0
- includes/class-np-handler-sort.php +43 -0
- includes/class-np-handler-syncmenu.php +39 -0
- includes/class-np-navmenu.php +112 -0
- includes/class-np-newpage.php +58 -0
- includes/class-np-pagelisting.php +220 -0
- includes/class-np-pagemeta.php +72 -0
- includes/class-np-postrepository.php +164 -0
- includes/class-np-validation.php +70 -0
- languages/index.php +2 -0
- languages/nestedpages.mo +0 -0
- languages/nestedpages.pot +179 -0
- nestedpages.php +32 -0
- readme.txt +109 -0
- views/pages.php +39 -0
- views/quickedit.php +137 -0
- views/row.php +92 -0
assets/css/fonts/nestedpages.eot
ADDED
Binary file
|
assets/css/fonts/nestedpages.svg
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" standalone="no"?>
|
2 |
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
3 |
+
<svg xmlns="http://www.w3.org/2000/svg">
|
4 |
+
<metadata>Generated by IcoMoon</metadata>
|
5 |
+
<defs>
|
6 |
+
<font id="nestedpages" horiz-adv-x="512">
|
7 |
+
<font-face units-per-em="512" ascent="480" descent="-32" />
|
8 |
+
<missing-glyph horiz-adv-x="512" />
|
9 |
+
<glyph unicode=" " d="" horiz-adv-x="256" />
|
10 |
+
<glyph unicode="" d="M102.4 198.4h230.4v76.8l128-102.4-128-102.4v76.8h-281.6v230.4h51.2v-179.2z" />
|
11 |
+
<glyph unicode="" d="M398.080 129.28l-56.064-52.736-87.552 93.44-93.184-87.808-52.736 55.808 93.184 87.808-87.552 93.184 55.808 52.736 87.808-93.184 93.184 87.552 52.48-55.808-93.184-87.808z" />
|
12 |
+
<glyph unicode="" d="M368.384 339.2l34.304-24.064-137.472-190.72h-34.304l-77.312 102.656 34.304 32 60.16-47.872z" />
|
13 |
+
<glyph unicode="" d="M435.2 300.8v51.2h-358.4v-51.2h358.4zM435.2 198.4v51.2h-358.4v-51.2h358.4zM435.2 96v51.2h-358.4v-51.2h358.4z" />
|
14 |
+
<glyph unicode="" d="M384 275.2l-103.168-153.6-101.632 153.6h204.8z" />
|
15 |
+
<glyph unicode="" d="M204.8 326.4l153.6-103.168-153.6-101.632v204.8z" />
|
16 |
+
<glyph unicode="" d="M32 384h448v-96h-448zM32 256h448v-96h-448zM32 128h448v-96h-448z" />
|
17 |
+
<glyph unicode="" d="M256 448c141.385 0 256-93.125 256-208s-114.615-208-256-208c-13.578 0-26.905 0.867-39.912 2.522-54.989-54.989-120.625-64.85-184.088-66.298v13.458c34.268 16.789 64 47.37 64 82.318 0 4.877-0.379 9.665-1.082 14.348-57.898 38.132-94.918 96.377-94.918 161.652 0 114.875 114.615 208 256 208z" />
|
18 |
+
<glyph unicode="" d="M432 480c44.182 0 80-35.817 80-80 0-18.010-5.955-34.629-16-48l-32-32-112 112 32 32c13.371 10.045 29.989 16 48 16zM32 112l-32-144 144 32 296 296-112 112-296-296zM357.789 298.211l-224-224-27.578 27.578 224 224 27.578-27.578z" />
|
19 |
+
<glyph unicode="" d="M296 256h-8v96c0 52.935-43.065 96-96 96h-64c-52.935 0-96-43.065-96-96v-96h-8c-13.2 0-24-10.8-24-24v-240c0-13.2 10.8-24 24-24h272c13.2 0 24 10.8 24 24v240c0 13.2-10.8 24-24 24zM192 32h-64l13.92 69.6c-8.404 5.766-13.92 15.437-13.92 26.4 0 17.673 14.327 32 32 32s32-14.327 32-32c0-10.963-5.516-20.634-13.92-26.4l13.92-69.6zM224 256h-128v96c0 17.645 14.355 32 32 32h64c17.645 0 32-14.355 32-32v-96z" />
|
20 |
+
<glyph unicode="" d="M400 416h-288c-26.51 0-48-21.49-48-48v-16h384v16c0 26.51-21.49 48-48 48zM316.16 448l7.058-50.5h-134.436l7.057 50.5h120.321zM320 480h-128c-13.2 0-25.495-10.696-27.321-23.769l-9.357-66.962c-1.827-13.073 7.478-23.769 20.678-23.769h160c13.2 0 22.505 10.696 20.679 23.769l-9.357 66.962c-1.827 13.073-14.122 23.769-27.322 23.769v0zM408 320h-304c-17.6 0-30.696-14.341-29.103-31.869l26.206-288.263c1.593-17.527 17.297-31.868 34.897-31.868h240c17.6 0 33.304 14.341 34.897 31.868l26.205 288.263c1.594 17.528-11.502 31.869-29.102 31.869zM192 32h-48l-16 224h64v-224zM288 32h-64v224h64v-224zM368 32h-48v224h64l-16-224z" />
|
21 |
+
<glyph unicode="" d="M256 384c-111.659 0-208.441-65.021-256-160 47.559-94.979 144.341-160 256-160 111.657 0 208.439 65.021 256 160-47.558 94.979-144.343 160-256 160zM382.225 299.148c30.081-19.187 55.571-44.887 74.717-75.148-19.146-30.261-44.637-55.961-74.718-75.149-37.797-24.108-81.445-36.851-126.224-36.851-44.78 0-88.428 12.743-126.225 36.852-30.080 19.186-55.57 44.886-74.717 75.148 19.146 30.262 44.637 55.962 74.717 75.148 1.959 1.25 3.938 2.461 5.929 3.65-4.979-13.664-7.704-28.411-7.704-43.798 0-70.692 57.308-128 128-128s128 57.308 128 128c0 15.387-2.725 30.134-7.704 43.799 1.99-1.189 3.969-2.401 5.929-3.651zM256 275c0-26.51-21.49-48-48-48s-48 21.49-48 48 21.49 48 48 48 48-21.49 48-48z" />
|
22 |
+
<glyph unicode="" d="M419.661 331.792c38.822-27.515 70.685-64.546 92.339-107.792-47.561-94.979-144.343-160-256-160-31.283 0-61.396 5.106-89.589 14.542l38.978 38.978c16.529-3.65 33.486-5.52 50.611-5.52 44.779 0 88.427 12.743 126.223 36.852 30.081 19.188 55.572 44.888 74.718 75.149-18.526 29.283-43.007 54.275-71.825 73.247l34.545 34.544zM256 131c-11.362 0-22.376 1.488-32.864 4.267l156.593 156.592c2.781-10.486 4.271-21.497 4.271-32.859 0-70.692-57.308-128-128-128zM480 480h-26.869l-109.806-109.806c-27.538 8.962-56.877 13.806-87.325 13.806-111.659 0-208.441-65.021-256-160 21.329-42.596 52.564-79.154 90.597-106.534l-90.597-90.597v-26.869h26.869l453.131 453.131v26.869zM208 323c24.022 0 43.923-17.647 47.446-40.685l-54.762-54.762c-23.037 3.524-40.684 23.425-40.684 47.447 0 26.51 21.49 48 48 48zM55.058 224c19.146 30.262 44.637 55.962 74.717 75.148 1.959 1.25 3.938 2.461 5.929 3.65-4.979-13.664-7.704-28.411-7.704-43.798 0-29.262 9.825-56.224 26.349-77.781l-29.275-29.275c-28.036 18.821-51.877 43.386-70.016 72.056z" />
|
23 |
+
</font></defs></svg>
|
assets/css/fonts/nestedpages.ttf
ADDED
Binary file
|
assets/css/fonts/nestedpages.woff
ADDED
Binary file
|
assets/css/nestedpages.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
@font-face{font-family:'nestedpages';src:url('fonts/nestedpages.eot?-cjbqo6');src:url('fonts/nestedpages.eot?#iefix-cjbqo6') format('embedded-opentype'),url('fonts/nestedpages.woff?-cjbqo6') format('woff'),url('fonts/nestedpages.ttf?-cjbqo6') format('truetype'),url('fonts/nestedpages.svg?-cjbqo6#nestedpages') format('svg');font-weight:normal;font-style:normal;}[class^="np-icon-"],[class*=" np-icon-"]{font-family:'nestedpages';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}.np-icon-no:before{content:"\e601";}.np-icon-yes:before{content:"\e602";}.np-icon-menu:before{content:"\e603";}.np-icon-arrow-down:before{content:"\e604";}.np-icon-arrow-right:before{content:"\e605";}.np-icon-sub-menu:before{content:"\e600";}.np-icon-pencil:before{content:"\e608";}.np-icon-bubble:before{content:"\e607";}.np-icon-lock:before{content:"\e609";}.np-icon-remove:before{content:"\e60a";}.np-icon-menu2:before{content:"\e606";}.np-icon-eye:before{content:"\e60b";}.np-icon-eye-blocked:before{content:"\e60c";}.np-btn,.np-toggle-edit{text-decoration:none;color:#555;display:inline-block;background-color:#f7f7f7;border:1px solid #e1e1e1;padding:3px 8px;-webkit-box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0, 0, 0, 0.08);box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0, 0, 0, 0.08);-webkit-transition:all 200ms ease;-o-transition:all 200ms ease;transition:all 200ms ease;}.np-btn:hover,.np-toggle-edit:hover{background-color:#0074a2;color:#ffffff;-webkit-transition:all 200ms ease;-o-transition:all 200ms ease;transition:all 200ms ease;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.08);box-shadow:0 1px 0 rgba(0, 0, 0, 0.08);}.np-btn-trash{background-color:#e14d43;border-color:#e14d43;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.3),0 1px 0 rgba(0, 0, 0, 0.08);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.3),0 1px 0 rgba(0, 0, 0, 0.08);color:#ffffff;}.np-btn-trash:hover{background-color:#ba251e;border-color:#ba251e;}.np-toggle-edit{display:none;float:right;margin-right:10px;}.np-toggle-edit.active{background-color:#0074a2;color:#ffffff;-webkit-box-shadow:none;box-shadow:none;border-color:#0074a2;}@media (max-width: 767px){.np-toggle-edit{display:inline-block;}}.np-quickedit-error{border-left:4px solid #dd3d36;padding:4px 0 4px 8px;margin-bottom:10px;background-color:#f9f9f9;}.nestedpages-toggleall{float:right;margin-top:-30px;}.np-toggle-publish{color:#999999;}.np-toggle-publish.active{color:#333;font-weight:bold;}.np-sync-menu-cont{float:right;margin:-27px 15px 0px 0px;}#nested-loading{display:none;float:right;width:30px;margin:-31px 120px 0 0;}.wppages-top-tools{margin-bottom:20px;padding-top:10px;}.wppages-top-tools a{text-decoration:none;}.wppages-handle-expand{float:left;background-color:#f2f2f2;font-size:18px;width:46px;height:46px;margin-right:5px;text-align:center;border-right:1px solid #e1e1e1;}.wppages-handle-expand div{background-color:#ffffff;border:1px solid #e1e1e1;width:24px;height:24px;line-height:24px;-webkit-border-radius:15px;border-radius:15px;margin-top:9px;cursor:pointer;-webkit-transition:all 200ms ease;-o-transition:all 200ms ease;transition:all 200ms ease;}.wppages-handle-expand div:hover{background-color:#0074a2;border-color:#0074a2;color:#ffffff;-webkit-transition:all 200ms ease;-o-transition:all 200ms ease;transition:all 200ms ease;}.nestedpages{clear:both;-webkit-border-radius:4px;border-radius:4px;}.nestedpages .ui-sortable-placeholder{display:block !important;position:relative;min-height:46px;border:0;border:1px dashed #0074a2 !important;background-color:#effaff;margin:0;}.nestedpages .ui-sortable-helper{opacity:0.8;-webkit-box-shadow:2px 2px 3px 0px rgba(0, 0, 0, 0.5);box-shadow:2px 2px 3px 0px rgba(0, 0, 0, 0.5);}.nestedpages ol{list-style-type:none;clear:both;margin:0;-webkit-box-shadow:0 1px 1px rgba(0, 0, 0, 0.06);box-shadow:0 1px 1px rgba(0, 0, 0, 0.06);border:1px solid #e5e5e5;-webkit-border-radius:3px;border-radius:3px;}.nestedpages ol a{text-decoration:none;}.nestedpages ol .page-link{line-height:26px;}.nestedpages ol .page-link .edit-indicator{margin-left:10px;display:none;}.nestedpages ol .page-link .edit-indicator i{font-size:12px;margin-right:3px;}.nestedpages ol .page-link:hover .edit-indicator{display:inline-block;}.nestedpages ol .locked{color:#333;margin-left:20px;}.nestedpages ol .locked em{font-style:normal;}.nestedpages ol .status{color:#999999;margin:0px 10px;}.nestedpages ol .np-icon-eye-blocked{color:#999999;}.nestedpages ol .nav-status{color:#b3b3b3;}.nestedpages ol .np-hide{display:none;}.nestedpages ol .np-seo-indicator{display:block;float:right;width:12px;height:12px;-webkit-border-radius:8px;border-radius:8px;background-color:#999999;margin:6px 10px 0 0;}.nestedpages ol .np-seo-indicator.good{background-color:#7ad03a;}.nestedpages ol .np-seo-indicator.ok{background-color:#ffba00;}.nestedpages ol .np-seo-indicator.poor{background-color:#ee7c1b;}.nestedpages ol .np-seo-indicator.bad{background-color:#dd3d36;}.nestedpages ol .np-seo-indicator.warn{background-color:maroon;}.nestedpages ol .np-seo-indicator.wrong{background-color:red;}.nestedpages ol li{margin:0;border-top:1px solid #e1e1e1;background-color:#0074a2;}.nestedpages ol li.first{border:0;}.nestedpages ol li:first-child{border:0;}.nestedpages ol li.no-border{border:0;}.nestedpages ol ol{display:none;-webkit-border-radius:0;border-radius:0;list-style-type:none;border:0;-webkit-box-shadow:none;box-shadow:none;border-top:1px solid #e1e1e1;}.nestedpages .child-toggle{float:left;margin:-10px 10px 0 0;width:46px;height:46px;background-color:#f0f0f0;text-align:center;}.nestedpages .child-toggle a{display:inline-block;margin-top:7px;width:28px;height:28px;background-color:#ffffff;border:1px solid #e1e1e1;-webkit-border-radius:20px;border-radius:20px;font-size:20px;line-height:30px;color:#333;-webkit-transition:all 200ms ease;-o-transition:all 200ms ease;transition:all 200ms ease;}.nestedpages .child-toggle a i{line-height:26px;}.nestedpages .child-toggle a:hover{background-color:#0074a2;color:#ffffff;border-color:#0074a2;}.nestedpages .handle{display:inline-block;cursor:move;font-size:20px;color:#b3b3b3;-webkit-transition:all 200ms ease;-o-transition:all 200ms ease;transition:all 200ms ease;position:relative;top:3px;}.nestedpages .handle:hover{-webkit-transition:all 200ms ease;-o-transition:all 200ms ease;transition:all 200ms ease;color:#0074a2;}.nestedpages .np-icon-sub-menu{display:none;color:#999999;position:relative;left:2px;}.nestedpages .handle,.nestedpages .np-icon-sub-menu{width:30px;height:46px;line-height:36px;margin-top:-10px;}.nestedpages li ol .row .np-icon-sub-menu{display:inline-block;}.nestedpages li ol .row .handle{display:none;}.nestedpages li ol .row:hover .np-icon-sub-menu{display:none;}.nestedpages li ol .row:hover .handle{display:inline-block;}.nestedpages .row{background-color:#ffffff;display:block;padding:10px 0px 0px 0px;height:36px;zoom:1;}.nestedpages .row:before,.nestedpages .row:after{content:" ";display:table;}.nestedpages .row:after{clear:both;}.nestedpages .row:hover{background-color:#f0f0f0;}.nestedpages .row.np-updated{background-color:#e9f7df;-webkit-transition:background-color 400ms ease;-o-transition:background-color 400ms ease;transition:background-color 400ms ease;}.nestedpages .row.np-updated-show{background-color:#ffffff;-webkit-transition:background-color 400ms ease;-o-transition:background-color 400ms ease;transition:background-color 400ms ease;}.nestedpages ol li ol .row-inner{padding-left:86px;}.nestedpages ol li ol li ol .row-inner{padding-left:116px;}.nestedpages ol li ol li ol li ol .row-inner{padding-left:156px;}.nestedpages .action-buttons{display:none;float:right;margin:0 10px 0 0;}.nestedpages .action-buttons a{margin-left:5px;}@media (min-width: 768px){.nestedpages .row:hover .action-buttons{display:block;}}@media (max-width: 767px){.nestedpages ol .page-link{line-height:24px;}.nestedpages ol .page-link:hover span{display:none;}.nestedpages ol .locked em{display:none;}.nestedpages .child-toggle{background:transparent;}.nestedpages .row{height:auto;}.nestedpages .action-buttons{display:none;background-color:#0074a2;float:none;margin:0;padding:8px;}.nestedpages .action-buttons a{margin-left:5px;}}.nestedpages .quick-edit{background-color:#ffffff;-webkit-border-radius:0;border-radius:0;}.nestedpages .quick-edit .form-interior{padding:10px;}.nestedpages .quick-edit h3{margin:0 0 8px 0;font-size:14px;}.nestedpages .quick-edit .fields{margin-bottom:10px;background:url('../images/border.png') repeat-y;background-position:center;zoom:1;}.nestedpages .quick-edit .fields:before,.nestedpages .quick-edit .fields:after{content:" ";display:table;}.nestedpages .quick-edit .fields:after{clear:both;}.nestedpages .quick-edit .left{float:left;width:48%;}.nestedpages .quick-edit .right{float:right;width:48%;}.nestedpages .quick-edit label{font-style:oblique;}.nestedpages .quick-edit .buttons{clear:both;zoom:1;background-color:#404040;padding:8px;}.nestedpages .quick-edit .buttons:before,.nestedpages .quick-edit .buttons:after{content:" ";display:table;}.nestedpages .quick-edit .buttons:after{clear:both;}.nestedpages .quick-edit .form-control{clear:both;zoom:1;margin-bottom:5px;}.nestedpages .quick-edit .form-control:before,.nestedpages .quick-edit .form-control:after{content:" ";display:table;}.nestedpages .quick-edit .form-control:after{clear:both;}.nestedpages .quick-edit .form-control input[type='text'],.nestedpages .quick-edit .form-control input[type='password'],.nestedpages .quick-edit .form-control select{float:right;width:75%;}.nestedpages .quick-edit .form-control label{float:left;width:20%;}.nestedpages .quick-edit .comments{float:right;width:75%;margin-bottom:10px;zoom:1;}.nestedpages .quick-edit .comments:before,.nestedpages .quick-edit .comments:after{content:" ";display:table;}.nestedpages .quick-edit .comments:after{clear:both;}.nestedpages .quick-edit .dates{float:right;width:75%;margin-bottom:6px;}.nestedpages .quick-edit .dates select{width:25%;}.nestedpages .quick-edit .dates input{width:12%;}.nestedpages .quick-edit .np-qe-loading{display:none;float:right;width:25px;height:25px;margin:2px 10px 0 0;background:url('../images/loading-white.gif') no-repeat;}.nestedpages .quick-edit .np-toggle-taxonomies{clear:both;float:right;width:71%;text-align:center;}.nestedpages .quick-edit .np-taxonomies{display:none;clear:both;background-color:#f9f9f9;padding:8px;zoom:1;}.nestedpages .quick-edit .np-taxonomies:before,.nestedpages .quick-edit .np-taxonomies:after{content:" ";display:table;}.nestedpages .quick-edit .np-taxonomies:after{clear:both;}.nestedpages .quick-edit .np-taxonomy{float:left;width:30%;margin-right:3.33%;}.nestedpages .quick-edit .np-taxonomy .title{font-weight:bold;margin-bottom:4px;display:block;}.nestedpages .quick-edit .np-taxonomy li{background-color:#ffffff;border:0;}@media (max-width: 767px){.nestedpages .quick-edit .fields{background:transparent;}.nestedpages .quick-edit .left,.nestedpages .quick-edit .right{float:none;width:100%;}.nestedpages .quick-edit .form-control{margin-bottom:10px;}.nestedpages .quick-edit .form-control input[type='text'],.nestedpages .quick-edit .form-control input[type='password'],.nestedpages .quick-edit .form-control select{float:none;width:100%;}.nestedpages .quick-edit .form-control label{display:block;float:none;width:100%;margin-bottom:4px;}.nestedpages .quick-edit .comments{float:none;width:100%;}.nestedpages .quick-edit .dates{float:none;width:100%;margin-bottom:6px;}}
|
assets/images/border.png
ADDED
Binary file
|
assets/images/loading-white.gif
ADDED
Binary file
|
assets/images/loading.gif
ADDED
Binary file
|
assets/js/lib/jquery.mjs.nestedSortable.js
ADDED
@@ -0,0 +1,664 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* jQuery UI Nested Sortable
|
3 |
+
* v 2.0 / 29 oct 2012
|
4 |
+
* http://mjsarfatti.com/sandbox/nestedSortable
|
5 |
+
*
|
6 |
+
* Depends on:
|
7 |
+
* jquery.ui.sortable.js 1.10+
|
8 |
+
*
|
9 |
+
* Copyright (c) 2010-2013 Manuele J Sarfatti
|
10 |
+
* Licensed under the MIT License
|
11 |
+
* http://www.opensource.org/licenses/mit-license.php
|
12 |
+
*/
|
13 |
+
(function( factory ) {
|
14 |
+
if ( typeof define === "function" && define.amd ) {
|
15 |
+
|
16 |
+
// AMD. Register as an anonymous module.
|
17 |
+
define([
|
18 |
+
"jquery",
|
19 |
+
"jquery-ui/sortable"
|
20 |
+
], factory );
|
21 |
+
} else {
|
22 |
+
|
23 |
+
// Browser globals
|
24 |
+
factory( jQuery );
|
25 |
+
}
|
26 |
+
}(function($) {
|
27 |
+
|
28 |
+
function isOverAxis( x, reference, size ) {
|
29 |
+
return ( x > reference ) && ( x < ( reference + size ) );
|
30 |
+
}
|
31 |
+
|
32 |
+
$.widget("mjs.nestedSortable", $.extend({}, $.ui.sortable.prototype, {
|
33 |
+
|
34 |
+
options: {
|
35 |
+
disableParentChange: false,
|
36 |
+
doNotClear: false,
|
37 |
+
expandOnHover: 700,
|
38 |
+
isAllowed: function(placeholder, placeholderParent, originalItem) { return true; },
|
39 |
+
isTree: false,
|
40 |
+
listType: 'ol',
|
41 |
+
maxLevels: 0,
|
42 |
+
protectRoot: false,
|
43 |
+
rootID: null,
|
44 |
+
rtl: false,
|
45 |
+
startCollapsed: false,
|
46 |
+
tabSize: 20,
|
47 |
+
|
48 |
+
branchClass: 'mjs-nestedSortable-branch',
|
49 |
+
collapsedClass: 'mjs-nestedSortable-collapsed',
|
50 |
+
disableNestingClass: 'mjs-nestedSortable-no-nesting',
|
51 |
+
errorClass: 'mjs-nestedSortable-error',
|
52 |
+
expandedClass: 'mjs-nestedSortable-expanded',
|
53 |
+
hoveringClass: 'mjs-nestedSortable-hovering',
|
54 |
+
leafClass: 'mjs-nestedSortable-leaf',
|
55 |
+
disabledClass: 'mjs-nestedSortable-disabled'
|
56 |
+
},
|
57 |
+
|
58 |
+
_create: function() {
|
59 |
+
this.element.data('ui-sortable', this.element.data('mjs-nestedSortable'));
|
60 |
+
|
61 |
+
// mjs - prevent browser from freezing if the HTML is not correct
|
62 |
+
if (!this.element.is(this.options.listType))
|
63 |
+
throw new Error('nestedSortable: Please check that the listType option is set to your actual list type');
|
64 |
+
|
65 |
+
// mjs - force 'intersect' tolerance method if we have a tree with expanding/collapsing functionality
|
66 |
+
if (this.options.isTree && this.options.expandOnHover) {
|
67 |
+
this.options.tolerance = 'intersect';
|
68 |
+
}
|
69 |
+
|
70 |
+
$.ui.sortable.prototype._create.apply(this, arguments);
|
71 |
+
|
72 |
+
// mjs - prepare the tree by applying the right classes (the CSS is responsible for actual hide/show functionality)
|
73 |
+
if (this.options.isTree) {
|
74 |
+
var self = this;
|
75 |
+
$(this.items).each(function() {
|
76 |
+
var $li = this.item;
|
77 |
+
if ($li.children(self.options.listType).length) {
|
78 |
+
$li.addClass(self.options.branchClass);
|
79 |
+
// expand/collapse class only if they have children
|
80 |
+
if ( ! $li.hasClass( self.options.collapsedClass ) && ( ! $li.hasClass( self.options.expandedClass ) ) ) {
|
81 |
+
if (self.options.startCollapsed) $li.addClass(self.options.collapsedClass);
|
82 |
+
else $li.addClass(self.options.expandedClass);
|
83 |
+
}
|
84 |
+
} else {
|
85 |
+
$li.addClass(self.options.leafClass);
|
86 |
+
}
|
87 |
+
});
|
88 |
+
}
|
89 |
+
},
|
90 |
+
|
91 |
+
_destroy: function() {
|
92 |
+
this.element
|
93 |
+
.removeData("mjs-nestedSortable")
|
94 |
+
.removeData("ui-sortable");
|
95 |
+
return $.ui.sortable.prototype._destroy.apply(this, arguments);
|
96 |
+
},
|
97 |
+
|
98 |
+
_mouseDrag: function(event) {
|
99 |
+
var i, item, itemElement, intersection,
|
100 |
+
o = this.options,
|
101 |
+
scrolled = false;
|
102 |
+
|
103 |
+
//Compute the helpers position
|
104 |
+
this.position = this._generatePosition(event);
|
105 |
+
this.positionAbs = this._convertPositionTo("absolute");
|
106 |
+
|
107 |
+
if (!this.lastPositionAbs) {
|
108 |
+
this.lastPositionAbs = this.positionAbs;
|
109 |
+
}
|
110 |
+
|
111 |
+
//Do scrolling
|
112 |
+
if(this.options.scroll) {
|
113 |
+
if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
|
114 |
+
|
115 |
+
if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
|
116 |
+
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
|
117 |
+
} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
|
118 |
+
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
|
119 |
+
}
|
120 |
+
|
121 |
+
if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
|
122 |
+
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
|
123 |
+
} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
|
124 |
+
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
|
125 |
+
}
|
126 |
+
|
127 |
+
} else {
|
128 |
+
|
129 |
+
if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
|
130 |
+
scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
|
131 |
+
} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
|
132 |
+
scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
|
133 |
+
}
|
134 |
+
|
135 |
+
if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
|
136 |
+
scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
|
137 |
+
} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
|
138 |
+
scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
|
139 |
+
}
|
140 |
+
|
141 |
+
}
|
142 |
+
|
143 |
+
if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
|
144 |
+
$.ui.ddmanager.prepareOffsets(this, event);
|
145 |
+
}
|
146 |
+
|
147 |
+
//Regenerate the absolute position used for position checks
|
148 |
+
this.positionAbs = this._convertPositionTo("absolute");
|
149 |
+
|
150 |
+
// mjs - find the top offset before rearrangement,
|
151 |
+
var previousTopOffset = this.placeholder.offset().top;
|
152 |
+
|
153 |
+
//Set the helper position
|
154 |
+
if(!this.options.axis || this.options.axis !== "y") {
|
155 |
+
this.helper[0].style.left = this.position.left+"px";
|
156 |
+
}
|
157 |
+
if(!this.options.axis || this.options.axis !== "x") {
|
158 |
+
this.helper[0].style.top = this.position.top+"px";
|
159 |
+
}
|
160 |
+
|
161 |
+
// mjs - check and reset hovering state at each cycle
|
162 |
+
this.hovering = this.hovering ? this.hovering : null;
|
163 |
+
this.mouseentered = this.mouseentered ? this.mouseentered : false;
|
164 |
+
|
165 |
+
// mjs - let's start caching some variables
|
166 |
+
var parentItem = (this.placeholder[0].parentNode.parentNode &&
|
167 |
+
$(this.placeholder[0].parentNode.parentNode).closest('.ui-sortable').length)
|
168 |
+
? $(this.placeholder[0].parentNode.parentNode)
|
169 |
+
: null,
|
170 |
+
level = this._getLevel(this.placeholder),
|
171 |
+
childLevels = this._getChildLevels(this.helper);
|
172 |
+
|
173 |
+
var newList = document.createElement(o.listType);
|
174 |
+
|
175 |
+
//Rearrange
|
176 |
+
for (i = this.items.length - 1; i >= 0; i--) {
|
177 |
+
|
178 |
+
//Cache variables and intersection, continue if no intersection
|
179 |
+
item = this.items[i];
|
180 |
+
itemElement = item.item[0];
|
181 |
+
intersection = this._intersectsWithPointer(item);
|
182 |
+
if (!intersection) {
|
183 |
+
continue;
|
184 |
+
}
|
185 |
+
|
186 |
+
// Only put the placeholder inside the current Container, skip all
|
187 |
+
// items form other containers. This works because when moving
|
188 |
+
// an item from one container to another the
|
189 |
+
// currentContainer is switched before the placeholder is moved.
|
190 |
+
//
|
191 |
+
// Without this moving items in "sub-sortables" can cause the placeholder to jitter
|
192 |
+
// beetween the outer and inner container.
|
193 |
+
if (item.instance !== this.currentContainer) {
|
194 |
+
continue;
|
195 |
+
}
|
196 |
+
|
197 |
+
// No action if intersected item is disabled
|
198 |
+
// and the element above or below in the direction we're going is also disabled
|
199 |
+
if (itemElement.className.indexOf(o.disabledClass) !== -1) {
|
200 |
+
// Note: intersection hardcoded direction values from jquery.ui.sortable.js:_intersectsWithPointer
|
201 |
+
if (intersection === 2) {
|
202 |
+
// Going down
|
203 |
+
var itemAfter = this.items[i + 1];
|
204 |
+
if (itemAfter && itemAfter.item[0].className.indexOf(o.disabledClass) !== -1){
|
205 |
+
continue;
|
206 |
+
}
|
207 |
+
|
208 |
+
}
|
209 |
+
else if (intersection === 1) {
|
210 |
+
// Going up
|
211 |
+
var itemBefore = this.items[i - 1];
|
212 |
+
if (itemBefore && itemBefore.item[0].className.indexOf(o.disabledClass) !== -1){
|
213 |
+
continue;
|
214 |
+
}
|
215 |
+
}
|
216 |
+
}
|
217 |
+
|
218 |
+
// cannot intersect with itself
|
219 |
+
// no useless actions that have been done before
|
220 |
+
// no action if the item moved is the parent of the item checked
|
221 |
+
if (itemElement !== this.currentItem[0] &&
|
222 |
+
this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
|
223 |
+
!$.contains(this.placeholder[0], itemElement) &&
|
224 |
+
(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
|
225 |
+
) {
|
226 |
+
|
227 |
+
// mjs - we are intersecting an element: trigger the mouseenter event and store this state
|
228 |
+
if (!this.mouseentered) {
|
229 |
+
$(itemElement).mouseenter();
|
230 |
+
this.mouseentered = true;
|
231 |
+
}
|
232 |
+
|
233 |
+
// mjs - if the element has children and they are hidden, show them after a delay (CSS responsible)
|
234 |
+
if (o.isTree && $(itemElement).hasClass(o.collapsedClass) && o.expandOnHover) {
|
235 |
+
if (!this.hovering) {
|
236 |
+
$(itemElement).addClass(o.hoveringClass);
|
237 |
+
var self = this;
|
238 |
+
this.hovering = window.setTimeout(function() {
|
239 |
+
$(itemElement).removeClass(o.collapsedClass).addClass(o.expandedClass);
|
240 |
+
self.refreshPositions();
|
241 |
+
self._trigger("expand", event, self._uiHash());
|
242 |
+
}, o.expandOnHover);
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
this.direction = intersection == 1 ? "down" : "up";
|
247 |
+
|
248 |
+
// mjs - rearrange the elements and reset timeouts and hovering state
|
249 |
+
if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
|
250 |
+
$(itemElement).mouseleave();
|
251 |
+
this.mouseentered = false;
|
252 |
+
$(itemElement).removeClass(o.hoveringClass);
|
253 |
+
this.hovering && window.clearTimeout(this.hovering);
|
254 |
+
this.hovering = null;
|
255 |
+
|
256 |
+
// mjs - do not switch container if it's a root item and 'protectRoot' is true
|
257 |
+
// or if it's not a root item but we are trying to make it root
|
258 |
+
if (o.protectRoot
|
259 |
+
&& ! (this.currentItem[0].parentNode == this.element[0] // it's a root item
|
260 |
+
&& itemElement.parentNode != this.element[0]) // it's intersecting a non-root item
|
261 |
+
) {
|
262 |
+
if (this.currentItem[0].parentNode != this.element[0]
|
263 |
+
&& itemElement.parentNode == this.element[0]
|
264 |
+
) {
|
265 |
+
|
266 |
+
if ( ! $(itemElement).children(o.listType).length) {
|
267 |
+
itemElement.appendChild(newList);
|
268 |
+
o.isTree && $(itemElement).removeClass(o.leafClass).addClass(o.branchClass + ' ' + o.expandedClass);
|
269 |
+
}
|
270 |
+
|
271 |
+
var a = this.direction === "down" ? $(itemElement).prev().children(o.listType) : $(itemElement).children(o.listType);
|
272 |
+
if (a[0] !== undefined) {
|
273 |
+
this._rearrange(event, null, a);
|
274 |
+
}
|
275 |
+
|
276 |
+
} else {
|
277 |
+
this._rearrange(event, item);
|
278 |
+
}
|
279 |
+
} else if ( ! o.protectRoot) {
|
280 |
+
this._rearrange(event, item);
|
281 |
+
}
|
282 |
+
} else {
|
283 |
+
break;
|
284 |
+
}
|
285 |
+
|
286 |
+
// Clear emtpy ul's/ol's
|
287 |
+
this._clearEmpty(itemElement);
|
288 |
+
|
289 |
+
this._trigger("change", event, this._uiHash());
|
290 |
+
break;
|
291 |
+
}
|
292 |
+
}
|
293 |
+
|
294 |
+
// mjs - to find the previous sibling in the list, keep backtracking until we hit a valid list item.
|
295 |
+
var previousItem = this.placeholder[0].previousSibling ? $(this.placeholder[0].previousSibling) : null;
|
296 |
+
if (previousItem != null) {
|
297 |
+
while (previousItem[0].nodeName.toLowerCase() != 'li' || previousItem[0].className.indexOf(o.disabledClass) !== -1 || previousItem[0] == this.currentItem[0] || previousItem[0] == this.helper[0]) {
|
298 |
+
if (previousItem[0].previousSibling) {
|
299 |
+
previousItem = $(previousItem[0].previousSibling);
|
300 |
+
} else {
|
301 |
+
previousItem = null;
|
302 |
+
break;
|
303 |
+
}
|
304 |
+
}
|
305 |
+
}
|
306 |
+
|
307 |
+
// mjs - to find the next sibling in the list, keep stepping forward until we hit a valid list item.
|
308 |
+
var nextItem = this.placeholder[0].nextSibling ? $(this.placeholder[0].nextSibling) : null;
|
309 |
+
if (nextItem != null) {
|
310 |
+
while (nextItem[0].nodeName.toLowerCase() != 'li' || nextItem[0].className.indexOf(o.disabledClass) !== -1 || nextItem[0] == this.currentItem[0] || nextItem[0] == this.helper[0]) {
|
311 |
+
if (nextItem[0].nextSibling) {
|
312 |
+
nextItem = $(nextItem[0].nextSibling);
|
313 |
+
} else {
|
314 |
+
nextItem = null;
|
315 |
+
break;
|
316 |
+
}
|
317 |
+
}
|
318 |
+
}
|
319 |
+
|
320 |
+
this.beyondMaxLevels = 0;
|
321 |
+
|
322 |
+
// mjs - if the item is moved to the left, send it one level up but only if it's at the bottom of the list
|
323 |
+
if (parentItem != null
|
324 |
+
&& nextItem == null
|
325 |
+
&& ! (o.protectRoot && parentItem[0].parentNode == this.element[0])
|
326 |
+
&&
|
327 |
+
(o.rtl && (this.positionAbs.left + this.helper.outerWidth() > parentItem.offset().left + parentItem.outerWidth())
|
328 |
+
|| ! o.rtl && (this.positionAbs.left < parentItem.offset().left))
|
329 |
+
) {
|
330 |
+
|
331 |
+
parentItem.after(this.placeholder[0]);
|
332 |
+
if (o.isTree && parentItem.children(o.listItem).children('li:visible:not(.ui-sortable-helper)').length < 1) {
|
333 |
+
parentItem.removeClass(this.options.branchClass + ' ' + this.options.expandedClass)
|
334 |
+
.addClass(this.options.leafClass);
|
335 |
+
}
|
336 |
+
this._clearEmpty(parentItem[0]);
|
337 |
+
this._trigger("change", event, this._uiHash());
|
338 |
+
}
|
339 |
+
// mjs - if the item is below a sibling and is moved to the right, make it a child of that sibling
|
340 |
+
else if (previousItem != null
|
341 |
+
&& ! previousItem.hasClass(o.disableNestingClass)
|
342 |
+
&&
|
343 |
+
(previousItem.children(o.listType).length && previousItem.children(o.listType).is(':visible')
|
344 |
+
|| ! previousItem.children(o.listType).length)
|
345 |
+
&& ! (o.protectRoot && this.currentItem[0].parentNode == this.element[0])
|
346 |
+
&&
|
347 |
+
(o.rtl && (this.positionAbs.left + this.helper.outerWidth() < previousItem.offset().left + previousItem.outerWidth() - o.tabSize)
|
348 |
+
|| ! o.rtl && (this.positionAbs.left > previousItem.offset().left + o.tabSize))
|
349 |
+
) {
|
350 |
+
|
351 |
+
this._isAllowed(previousItem, level, level+childLevels+1);
|
352 |
+
|
353 |
+
if (!previousItem.children(o.listType).length) {
|
354 |
+
previousItem[0].appendChild(newList);
|
355 |
+
o.isTree && previousItem.removeClass(o.leafClass).addClass(o.branchClass + ' ' + o.expandedClass);
|
356 |
+
}
|
357 |
+
|
358 |
+
// mjs - if this item is being moved from the top, add it to the top of the list.
|
359 |
+
if (previousTopOffset && (previousTopOffset <= previousItem.offset().top)) {
|
360 |
+
previousItem.children(o.listType).prepend(this.placeholder);
|
361 |
+
}
|
362 |
+
// mjs - otherwise, add it to the bottom of the list.
|
363 |
+
else {
|
364 |
+
previousItem.children(o.listType)[0].appendChild(this.placeholder[0]);
|
365 |
+
}
|
366 |
+
|
367 |
+
this._trigger("change", event, this._uiHash());
|
368 |
+
}
|
369 |
+
else {
|
370 |
+
this._isAllowed(parentItem, level, level+childLevels);
|
371 |
+
}
|
372 |
+
|
373 |
+
//Post events to containers
|
374 |
+
this._contactContainers(event);
|
375 |
+
|
376 |
+
//Interconnect with droppables
|
377 |
+
if($.ui.ddmanager) {
|
378 |
+
$.ui.ddmanager.drag(this, event);
|
379 |
+
}
|
380 |
+
|
381 |
+
//Call callbacks
|
382 |
+
this._trigger('sort', event, this._uiHash());
|
383 |
+
|
384 |
+
this.lastPositionAbs = this.positionAbs;
|
385 |
+
return false;
|
386 |
+
|
387 |
+
},
|
388 |
+
|
389 |
+
_mouseStop: function(event, noPropagation) {
|
390 |
+
|
391 |
+
// mjs - if the item is in a position not allowed, send it back
|
392 |
+
if (this.beyondMaxLevels) {
|
393 |
+
|
394 |
+
this.placeholder.removeClass(this.options.errorClass);
|
395 |
+
|
396 |
+
if (this.domPosition.prev) {
|
397 |
+
$(this.domPosition.prev).after(this.placeholder);
|
398 |
+
} else {
|
399 |
+
$(this.domPosition.parent).prepend(this.placeholder);
|
400 |
+
}
|
401 |
+
|
402 |
+
this._trigger("revert", event, this._uiHash());
|
403 |
+
|
404 |
+
}
|
405 |
+
|
406 |
+
|
407 |
+
// mjs - clear the hovering timeout, just to be sure
|
408 |
+
$('.'+this.options.hoveringClass).mouseleave().removeClass(this.options.hoveringClass);
|
409 |
+
this.mouseentered = false;
|
410 |
+
this.hovering && window.clearTimeout(this.hovering);
|
411 |
+
this.hovering = null;
|
412 |
+
|
413 |
+
$.ui.sortable.prototype._mouseStop.apply(this, arguments);
|
414 |
+
|
415 |
+
var pid = $(this.domPosition.parent).parent().attr("id");
|
416 |
+
var sort = this.domPosition.prev ? $(this.domPosition.prev).next().index() : 0;
|
417 |
+
|
418 |
+
if(!(pid == this._uiHash().item.parent().parent().attr("id") &&
|
419 |
+
sort == this._uiHash().item.index())) {
|
420 |
+
this._trigger("relocate", event, this._uiHash());
|
421 |
+
}
|
422 |
+
|
423 |
+
},
|
424 |
+
|
425 |
+
// mjs - this function is slightly modified to make it easier to hover over a collapsed element and have it expand
|
426 |
+
_intersectsWithSides: function(item) {
|
427 |
+
|
428 |
+
var half = this.options.isTree ? .8 : .5;
|
429 |
+
|
430 |
+
var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height*half), item.height),
|
431 |
+
isOverTopHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top - (item.height*half), item.height),
|
432 |
+
isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
|
433 |
+
verticalDirection = this._getDragVerticalDirection(),
|
434 |
+
horizontalDirection = this._getDragHorizontalDirection();
|
435 |
+
|
436 |
+
if (this.floating && horizontalDirection) {
|
437 |
+
return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
|
438 |
+
} else {
|
439 |
+
return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && isOverTopHalf));
|
440 |
+
}
|
441 |
+
|
442 |
+
},
|
443 |
+
|
444 |
+
_contactContainers: function(event) {
|
445 |
+
|
446 |
+
if (this.options.protectRoot && this.currentItem[0].parentNode == this.element[0] ) {
|
447 |
+
return;
|
448 |
+
}
|
449 |
+
|
450 |
+
$.ui.sortable.prototype._contactContainers.apply(this, arguments);
|
451 |
+
|
452 |
+
},
|
453 |
+
|
454 |
+
_clear: function(event, noPropagation) {
|
455 |
+
|
456 |
+
$.ui.sortable.prototype._clear.apply(this, arguments);
|
457 |
+
|
458 |
+
// mjs - clean last empty ul/ol
|
459 |
+
for (var i = this.items.length - 1; i >= 0; i--) {
|
460 |
+
var item = this.items[i].item[0];
|
461 |
+
this._clearEmpty(item);
|
462 |
+
}
|
463 |
+
|
464 |
+
},
|
465 |
+
|
466 |
+
serialize: function(options) {
|
467 |
+
|
468 |
+
var o = $.extend({}, this.options, options),
|
469 |
+
items = this._getItemsAsjQuery(o && o.connected),
|
470 |
+
str = [];
|
471 |
+
|
472 |
+
$(items).each(function() {
|
473 |
+
var res = ($(o.item || this).attr(o.attribute || 'id') || '')
|
474 |
+
.match(o.expression || (/(.+)[-=_](.+)/)),
|
475 |
+
pid = ($(o.item || this).parent(o.listType)
|
476 |
+
.parent(o.items)
|
477 |
+
.attr(o.attribute || 'id') || '')
|
478 |
+
.match(o.expression || (/(.+)[-=_](.+)/));
|
479 |
+
|
480 |
+
if (res) {
|
481 |
+
str.push(((o.key || res[1]) + '[' + (o.key && o.expression ? res[1] : res[2]) + ']')
|
482 |
+
+ '='
|
483 |
+
+ (pid ? (o.key && o.expression ? pid[1] : pid[2]) : o.rootID));
|
484 |
+
}
|
485 |
+
});
|
486 |
+
|
487 |
+
if(!str.length && o.key) {
|
488 |
+
str.push(o.key + '=');
|
489 |
+
}
|
490 |
+
|
491 |
+
return str.join('&');
|
492 |
+
|
493 |
+
},
|
494 |
+
|
495 |
+
toHierarchy: function(options) {
|
496 |
+
|
497 |
+
var o = $.extend({}, this.options, options),
|
498 |
+
sDepth = o.startDepthCount || 0,
|
499 |
+
ret = [];
|
500 |
+
|
501 |
+
$(this.element).children(o.items).each(function () {
|
502 |
+
var level = _recursiveItems(this);
|
503 |
+
ret.push(level);
|
504 |
+
});
|
505 |
+
|
506 |
+
return ret;
|
507 |
+
|
508 |
+
function _recursiveItems(item) {
|
509 |
+
var id = ($(item).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
|
510 |
+
if (id) {
|
511 |
+
var currentItem = {"id" : id[2]};
|
512 |
+
if ($(item).children(o.listType).children(o.items).length > 0) {
|
513 |
+
currentItem.children = [];
|
514 |
+
$(item).children(o.listType).children(o.items).each(function() {
|
515 |
+
var level = _recursiveItems(this);
|
516 |
+
currentItem.children.push(level);
|
517 |
+
});
|
518 |
+
}
|
519 |
+
return currentItem;
|
520 |
+
}
|
521 |
+
}
|
522 |
+
},
|
523 |
+
|
524 |
+
toArray: function(options) {
|
525 |
+
|
526 |
+
var o = $.extend({}, this.options, options),
|
527 |
+
sDepth = o.startDepthCount || 0,
|
528 |
+
ret = [],
|
529 |
+
left = 1;
|
530 |
+
|
531 |
+
if (!o.excludeRoot) {
|
532 |
+
ret.push({
|
533 |
+
"item_id": o.rootID,
|
534 |
+
"parent_id": null,
|
535 |
+
"depth": sDepth,
|
536 |
+
"left": left,
|
537 |
+
"right": ($(o.items, this.element).length + 1) * 2
|
538 |
+
});
|
539 |
+
left++
|
540 |
+
}
|
541 |
+
|
542 |
+
$(this.element).children(o.items).each(function () {
|
543 |
+
left = _recursiveArray(this, sDepth + 1, left);
|
544 |
+
});
|
545 |
+
|
546 |
+
ret = ret.sort(function(a,b){ return (a.left - b.left); });
|
547 |
+
|
548 |
+
return ret;
|
549 |
+
|
550 |
+
function _recursiveArray(item, depth, left) {
|
551 |
+
|
552 |
+
var right = left + 1,
|
553 |
+
id,
|
554 |
+
pid;
|
555 |
+
|
556 |
+
if ($(item).children(o.listType).children(o.items).length > 0) {
|
557 |
+
depth ++;
|
558 |
+
$(item).children(o.listType).children(o.items).each(function () {
|
559 |
+
right = _recursiveArray($(this), depth, right);
|
560 |
+
});
|
561 |
+
depth --;
|
562 |
+
}
|
563 |
+
|
564 |
+
id = ($(item).attr(o.attribute || 'id')).match(o.expression || (/(.+)[-=_](.+)/));
|
565 |
+
|
566 |
+
if (depth === sDepth + 1) {
|
567 |
+
pid = o.rootID;
|
568 |
+
} else {
|
569 |
+
var parentItem = ($(item).parent(o.listType)
|
570 |
+
.parent(o.items)
|
571 |
+
.attr(o.attribute || 'id'))
|
572 |
+
.match(o.expression || (/(.+)[-=_](.+)/));
|
573 |
+
pid = parentItem[2];
|
574 |
+
}
|
575 |
+
|
576 |
+
if (id) {
|
577 |
+
ret.push({"item_id": id[2], "parent_id": pid, "depth": depth, "left": left, "right": right});
|
578 |
+
}
|
579 |
+
|
580 |
+
left = right + 1;
|
581 |
+
return left;
|
582 |
+
}
|
583 |
+
|
584 |
+
},
|
585 |
+
|
586 |
+
_clearEmpty: function(item) {
|
587 |
+
var o = this.options;
|
588 |
+
|
589 |
+
var emptyList = $(item).children(o.listType);
|
590 |
+
|
591 |
+
if (emptyList.length && !emptyList.children().length && !o.doNotClear) {
|
592 |
+
o.isTree && $(item).removeClass(o.branchClass + ' ' + o.expandedClass).addClass(o.leafClass);
|
593 |
+
emptyList.remove();
|
594 |
+
} else if (o.isTree && emptyList.length && emptyList.children().length && emptyList.is(':visible')) {
|
595 |
+
$(item).removeClass(o.leafClass).addClass(o.branchClass + ' ' + o.expandedClass);
|
596 |
+
} else if (o.isTree && emptyList.length && emptyList.children().length && !emptyList.is(':visible')) {
|
597 |
+
$(item).removeClass(o.leafClass).addClass(o.branchClass + ' ' + o.collapsedClass);
|
598 |
+
}
|
599 |
+
|
600 |
+
},
|
601 |
+
|
602 |
+
_getLevel: function(item) {
|
603 |
+
|
604 |
+
var level = 1;
|
605 |
+
|
606 |
+
if (this.options.listType) {
|
607 |
+
var list = item.closest(this.options.listType);
|
608 |
+
while (list && list.length > 0 &&
|
609 |
+
!list.is('.ui-sortable')) {
|
610 |
+
level++;
|
611 |
+
list = list.parent().closest(this.options.listType);
|
612 |
+
}
|
613 |
+
}
|
614 |
+
|
615 |
+
return level;
|
616 |
+
},
|
617 |
+
|
618 |
+
_getChildLevels: function(parent, depth) {
|
619 |
+
var self = this,
|
620 |
+
o = this.options,
|
621 |
+
result = 0;
|
622 |
+
depth = depth || 0;
|
623 |
+
|
624 |
+
$(parent).children(o.listType).children(o.items).each(function (index, child) {
|
625 |
+
result = Math.max(self._getChildLevels(child, depth + 1), result);
|
626 |
+
});
|
627 |
+
|
628 |
+
return depth ? result + 1 : result;
|
629 |
+
},
|
630 |
+
|
631 |
+
_isAllowed: function(parentItem, level, levels) {
|
632 |
+
var o = this.options,
|
633 |
+
maxLevels = this.placeholder.closest('.ui-sortable').nestedSortable('option', 'maxLevels'); // this takes into account the maxLevels set to the recipient list
|
634 |
+
|
635 |
+
// Check if the parent has changed to prevent it, when o.disableParentChange is true
|
636 |
+
var oldParent = this.currentItem.parent().parent();
|
637 |
+
var disabledByParentchange = o.disableParentChange && (
|
638 |
+
parentItem !== null && !oldParent.is(parentItem)//From somewhere to somewhere else, except the root
|
639 |
+
|| parentItem === null && oldParent.is('li') //From somewhere to the root
|
640 |
+
);
|
641 |
+
// mjs - is the root protected?
|
642 |
+
// mjs - are we nesting too deep?
|
643 |
+
if (disabledByParentchange || ! o.isAllowed(this.placeholder, parentItem, this.currentItem)) {
|
644 |
+
this.placeholder.addClass(o.errorClass);
|
645 |
+
if (maxLevels < levels && maxLevels != 0) {
|
646 |
+
this.beyondMaxLevels = levels - maxLevels;
|
647 |
+
} else {
|
648 |
+
this.beyondMaxLevels = 1;
|
649 |
+
}
|
650 |
+
} else {
|
651 |
+
if (maxLevels < levels && maxLevels != 0) {
|
652 |
+
this.placeholder.addClass(o.errorClass);
|
653 |
+
this.beyondMaxLevels = levels - maxLevels;
|
654 |
+
} else {
|
655 |
+
this.placeholder.removeClass(o.errorClass);
|
656 |
+
this.beyondMaxLevels = 0;
|
657 |
+
}
|
658 |
+
}
|
659 |
+
}
|
660 |
+
|
661 |
+
}));
|
662 |
+
|
663 |
+
$.mjs.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.mjs.nestedSortable.prototype.options);
|
664 |
+
}));
|
assets/js/lib/jquery.ui.touch-punch.min.js
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* jQuery UI Touch Punch 0.2.3
|
3 |
+
*
|
4 |
+
* Copyright 2011–2014, Dave Furfero
|
5 |
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
6 |
+
*
|
7 |
+
* Depends:
|
8 |
+
* jquery.ui.widget.js
|
9 |
+
* jquery.ui.mouse.js
|
10 |
+
*/
|
11 |
+
!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);
|
assets/js/lib/nestedpages.js
ADDED
@@ -0,0 +1,578 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* WP Pages Scripts Required by WP Pages Plugin
|
3 |
+
* @author Kyle Phillips
|
4 |
+
*/
|
5 |
+
jQuery(function($){
|
6 |
+
|
7 |
+
/**
|
8 |
+
* ------------------------------------------------------------------------
|
9 |
+
* Sortable and Toggline
|
10 |
+
* ------------------------------------------------------------------------
|
11 |
+
**/
|
12 |
+
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Add the Submenu Toggles (using JS to prevent additional DB Queries)
|
16 |
+
*/
|
17 |
+
$(document).ready(function(){
|
18 |
+
add_remove_submenu_toggles();
|
19 |
+
np_set_borders();
|
20 |
+
});
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Toggle the Submenus
|
24 |
+
*/
|
25 |
+
$(document).on('click', '.child-toggle a', function(e){
|
26 |
+
e.preventDefault();
|
27 |
+
var submenu = $(this).parent('.child-toggle').parent('.row').siblings('ol');
|
28 |
+
$(this).find('i').toggleClass('np-icon-arrow-down').toggleClass('np-icon-arrow-right');
|
29 |
+
$(submenu).toggle();
|
30 |
+
np_set_borders();
|
31 |
+
});
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Toggle all pages (Expand All)
|
35 |
+
*/
|
36 |
+
$(document).on('click', '.nestedpages-toggleall a', function(e){
|
37 |
+
e.preventDefault();
|
38 |
+
if ( $(this).attr('data-toggle') == 'closed' )
|
39 |
+
{
|
40 |
+
$('.nestedpages ol li ol').show();
|
41 |
+
$(this).attr('data-toggle', 'opened');
|
42 |
+
$(this).text(nestedpages.collapse_text);
|
43 |
+
$('.child-toggle i').removeClass('np-icon-arrow-right').addClass('np-icon-arrow-down');
|
44 |
+
revert_quick_edit();
|
45 |
+
np_set_borders();
|
46 |
+
} else
|
47 |
+
{
|
48 |
+
$('.nestedpages ol li ol').hide();
|
49 |
+
$(this).attr('data-toggle', 'closed');
|
50 |
+
$(this).text(nestedpages.expand_text);
|
51 |
+
$('.child-toggle i').removeClass('np-icon-arrow-down').addClass('np-icon-arrow-right');
|
52 |
+
revert_quick_edit();
|
53 |
+
np_set_borders();
|
54 |
+
}
|
55 |
+
});
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Toggle hidden pages
|
59 |
+
*/
|
60 |
+
$(document).on('click', '.np-toggle-hidden', function(e){
|
61 |
+
e.preventDefault();
|
62 |
+
var action = $(this).attr('href');
|
63 |
+
if ( action === 'show' ){
|
64 |
+
$(this).attr('href', 'hide');
|
65 |
+
$(this).text('Show Hidden Pages');
|
66 |
+
$('.np-hide').removeClass('shown').hide();
|
67 |
+
np_set_borders();
|
68 |
+
} else {
|
69 |
+
$(this).attr('href', 'show');
|
70 |
+
$(this).text('Hide Hidden Pages');
|
71 |
+
$('.np-hide').addClass('shown').show();
|
72 |
+
np_set_borders();
|
73 |
+
}
|
74 |
+
});
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Fix :visible :first css limitation when toggling various options
|
78 |
+
*/
|
79 |
+
function np_set_borders()
|
80 |
+
{
|
81 |
+
var lists = $('.nplist');
|
82 |
+
$('.page-row').removeClass('no-border');
|
83 |
+
$.each(lists, function(){
|
84 |
+
$(this).find('.page-row:visible:first').addClass('no-border');
|
85 |
+
});
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Toggle between showing published pages and all
|
90 |
+
*/
|
91 |
+
$(document).on('click', '.np-toggle-publish', function(e){
|
92 |
+
e.preventDefault();
|
93 |
+
var target = $(this).attr('href');
|
94 |
+
$('.np-toggle-publish').removeClass('active');
|
95 |
+
$(this).addClass('active');
|
96 |
+
if ( target == '#published' ){
|
97 |
+
$('.nplist .page-row').hide();
|
98 |
+
$('.nplist .published').show();
|
99 |
+
} else {
|
100 |
+
$('.nplist .page-row').show();
|
101 |
+
}
|
102 |
+
});
|
103 |
+
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Toggle Responsive Action Buttons (Quick edit, add child, etc)
|
107 |
+
*/
|
108 |
+
$(document).on('click', '.np-toggle-edit', function(e){
|
109 |
+
e.preventDefault();
|
110 |
+
var buttons = $(this).siblings('.action-buttons');
|
111 |
+
if ( $(buttons).is(':visible') ){
|
112 |
+
$(this).removeClass('active');
|
113 |
+
$(buttons).hide();
|
114 |
+
} else {
|
115 |
+
$(this).addClass('active');
|
116 |
+
$(buttons).show();
|
117 |
+
}
|
118 |
+
});
|
119 |
+
/**
|
120 |
+
* Remove display block on action buttons when sizing up
|
121 |
+
*/
|
122 |
+
var actiondelay = (function(){
|
123 |
+
var timer = 0;
|
124 |
+
return function(callback, ms){
|
125 |
+
clearTimeout (timer);
|
126 |
+
timer = setTimeout(callback, ms);
|
127 |
+
};
|
128 |
+
})();
|
129 |
+
$(window).resize(function() {
|
130 |
+
actiondelay(function(){
|
131 |
+
$('.action-buttons').removeAttr('style');
|
132 |
+
$('.np-toggle-edit').removeClass('active');
|
133 |
+
}, 500);
|
134 |
+
});
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Make the Menu sortable
|
138 |
+
*/
|
139 |
+
$(document).ready(function(){
|
140 |
+
$('.sortable').not('.no-sort').nestedSortable({
|
141 |
+
items : 'li',
|
142 |
+
toleranceElement: '> .row',
|
143 |
+
handle: '.handle',
|
144 |
+
placeholder: "ui-sortable-placeholder",
|
145 |
+
start: function(e, ui){
|
146 |
+
ui.placeholder.height(ui.item.height());
|
147 |
+
},
|
148 |
+
sort: function(e, ui){
|
149 |
+
update_placeholder_width(ui);
|
150 |
+
},
|
151 |
+
stop: function(e, ui){
|
152 |
+
setTimeout(
|
153 |
+
function(){
|
154 |
+
add_remove_submenu_toggles();
|
155 |
+
np_set_borders();
|
156 |
+
}, 100
|
157 |
+
);
|
158 |
+
submit_sortable_form();
|
159 |
+
},
|
160 |
+
update: function(e, ui){
|
161 |
+
}
|
162 |
+
});
|
163 |
+
});
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Update the width of the placeholder
|
167 |
+
*/
|
168 |
+
function update_placeholder_width(ui)
|
169 |
+
{
|
170 |
+
var parentCount = $(ui.placeholder).parents('ol').length;
|
171 |
+
var listWidth = $('.sortable').width();
|
172 |
+
var offset = ( parentCount * 40 ) - 40;
|
173 |
+
var newWidth = listWidth - offset;
|
174 |
+
$(ui.placeholder).width(newWidth).css('margin-left', offset + 'px');
|
175 |
+
update_list_visibility(ui);
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Make new list items visible
|
180 |
+
*/
|
181 |
+
function update_list_visibility(ui)
|
182 |
+
{
|
183 |
+
var parentList = $(ui.placeholder).parent('ol');
|
184 |
+
if ( !$(parentList).is(':visible') ){
|
185 |
+
$(parentList).show();
|
186 |
+
}
|
187 |
+
}
|
188 |
+
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Add or Remove the submenu toggle after the list has changed
|
192 |
+
*/
|
193 |
+
function add_remove_submenu_toggles()
|
194 |
+
{
|
195 |
+
$('.child-toggle').each(function(i, v){
|
196 |
+
var row = $(this).parent('.row').parent('li');
|
197 |
+
|
198 |
+
if ( $(row).children('ol').length > 0 ){
|
199 |
+
var icon = ( $(row).children('ol:visible').length > 0 ) ? 'np-icon-arrow-down' : 'np-icon-arrow-right';
|
200 |
+
$(this).html('<a href="#"><i class="' + icon + '"></i></a>');
|
201 |
+
} else {
|
202 |
+
$(this).empty();
|
203 |
+
}
|
204 |
+
});
|
205 |
+
}
|
206 |
+
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Submit Sortable Form
|
210 |
+
* @todo add error div, pass message to it and show on error
|
211 |
+
*/
|
212 |
+
function submit_sortable_form()
|
213 |
+
{
|
214 |
+
$('#np-error').hide();
|
215 |
+
$('#nested-loading').show();
|
216 |
+
var syncmenu = ( $('.np-sync-menu').is(':checked') ) ? 'sync' : 'nosync';
|
217 |
+
|
218 |
+
list = $('ol.sortable').nestedSortable('toHierarchy', {startDepthCount: 0});
|
219 |
+
|
220 |
+
$.ajax({
|
221 |
+
url: ajaxurl,
|
222 |
+
type: 'post',
|
223 |
+
datatype: 'json',
|
224 |
+
data: {
|
225 |
+
action : 'npsort',
|
226 |
+
nonce : nestedpages.np_nonce,
|
227 |
+
list : list,
|
228 |
+
syncmenu : syncmenu
|
229 |
+
},
|
230 |
+
success: function(data){
|
231 |
+
if (data.status === 'error'){
|
232 |
+
$('#np-error').text(data.message).show();
|
233 |
+
$('#nested-loading').hide();
|
234 |
+
} else {
|
235 |
+
$('#nested-loading').hide();
|
236 |
+
}
|
237 |
+
}
|
238 |
+
});
|
239 |
+
}
|
240 |
+
|
241 |
+
|
242 |
+
|
243 |
+
|
244 |
+
|
245 |
+
/**
|
246 |
+
* ------------------------------------------------------------------------
|
247 |
+
* Sync Menu Toggle
|
248 |
+
* ------------------------------------------------------------------------
|
249 |
+
**/
|
250 |
+
$('.np-sync-menu').on('change', function(){
|
251 |
+
var setting = ( $(this).is(':checked') ) ? 'sync' : 'nosync';
|
252 |
+
np_updated_sync_menu(setting);
|
253 |
+
});
|
254 |
+
|
255 |
+
function np_updated_sync_menu(setting)
|
256 |
+
{
|
257 |
+
$.ajax({
|
258 |
+
url: ajaxurl,
|
259 |
+
type: 'post',
|
260 |
+
datatype: 'json',
|
261 |
+
data: {
|
262 |
+
action : 'npsyncmenu',
|
263 |
+
nonce : nestedpages.np_nonce,
|
264 |
+
syncmenu : setting
|
265 |
+
},
|
266 |
+
success: function(data){
|
267 |
+
if (data.status === 'error'){
|
268 |
+
alert('There was an error saving the sync setting.')
|
269 |
+
}
|
270 |
+
}
|
271 |
+
});
|
272 |
+
}
|
273 |
+
|
274 |
+
|
275 |
+
|
276 |
+
|
277 |
+
|
278 |
+
|
279 |
+
/**
|
280 |
+
* ------------------------------------------------------------------------
|
281 |
+
* Quick Edit
|
282 |
+
* ------------------------------------------------------------------------
|
283 |
+
**/
|
284 |
+
|
285 |
+
// Show the form
|
286 |
+
$(document).on('click', '.np-quick-edit', function(e){
|
287 |
+
e.preventDefault();
|
288 |
+
revert_quick_edit();
|
289 |
+
set_quick_edit_data($(this));
|
290 |
+
});
|
291 |
+
|
292 |
+
// Cancel the form
|
293 |
+
$(document).on('click', '.np-cancel-quickedit', function(e){
|
294 |
+
var row = $(this).parents('.page-row');
|
295 |
+
revert_quick_edit(row);
|
296 |
+
e.preventDefault();
|
297 |
+
});
|
298 |
+
|
299 |
+
// Submit the form
|
300 |
+
$(document).on('click', '.np-save-quickedit', function(e){
|
301 |
+
e.preventDefault();
|
302 |
+
$('.row').removeClass('np-updated').removeClass('np-updated-show');
|
303 |
+
var form = $(this).parents('form');
|
304 |
+
$(this).attr('disabled', 'disabled');
|
305 |
+
$(form).find('.np-qe-loading').show();
|
306 |
+
submit_np_quickedit(form);
|
307 |
+
});
|
308 |
+
|
309 |
+
// Toggle the Taxonomies
|
310 |
+
$(document).on('click', '.np-toggle-taxonomies', function(e){
|
311 |
+
$(this).parents('form').find('.np-taxonomies').toggle();
|
312 |
+
});
|
313 |
+
|
314 |
+
|
315 |
+
/**
|
316 |
+
* Set Quick Edit data
|
317 |
+
*/
|
318 |
+
function set_quick_edit_data(item)
|
319 |
+
{
|
320 |
+
var data = {
|
321 |
+
id : $(item).attr('data-id'),
|
322 |
+
title : $(item).attr('data-title'),
|
323 |
+
slug : $(item).attr('data-slug'),
|
324 |
+
author : $(item).attr('data-author'),
|
325 |
+
cs : $(item).attr('data-commentstatus'),
|
326 |
+
status : $(item).attr('data-status'),
|
327 |
+
template : $(item).attr('data-template'),
|
328 |
+
month : $(item).attr('data-month'),
|
329 |
+
day : $(item).attr('data-day'),
|
330 |
+
year : $(item).attr('data-year'),
|
331 |
+
hour : $(item).attr('data-hour'),
|
332 |
+
minute : $(item).attr('data-minute'),
|
333 |
+
navstatus : $(item).attr('data-navstatus'),
|
334 |
+
npstatus : $(item).attr('data-np-status'),
|
335 |
+
navtitle : $(item).attr('data-navtitle')
|
336 |
+
};
|
337 |
+
var parent_li = $(item).closest('.row').parent('li');
|
338 |
+
|
339 |
+
// Add Array of Taxonomies to the data object
|
340 |
+
data.taxonomies = [];
|
341 |
+
var classes = $(parent_li).attr('class').split(/\s+/);
|
342 |
+
for ( i = 0; i < classes.length; i++ ){
|
343 |
+
if ( classes[i].substring(0, 3) === 'in-'){
|
344 |
+
data.taxonomies.push(classes[i]);
|
345 |
+
}
|
346 |
+
}
|
347 |
+
|
348 |
+
// Append the form to the list item
|
349 |
+
if ( $(parent_li).children('ol').length > 0 ){
|
350 |
+
var child_ol = $(parent_li).children('ol');
|
351 |
+
var newform = $('.quick-edit-form').clone().insertBefore(child_ol);
|
352 |
+
} else {
|
353 |
+
var newform = $('.quick-edit-form').clone().appendTo(parent_li);
|
354 |
+
}
|
355 |
+
|
356 |
+
var row = $(newform).siblings('.row').hide();
|
357 |
+
populate_quick_edit(newform, data);
|
358 |
+
}
|
359 |
+
|
360 |
+
|
361 |
+
/**
|
362 |
+
* Populate the Quick Edit Form
|
363 |
+
*/
|
364 |
+
function populate_quick_edit(form, data)
|
365 |
+
{
|
366 |
+
$(form).find('.np_id').val(data.id);
|
367 |
+
$(form).find('.np_title').val(data.title);
|
368 |
+
$(form).find('.np_slug').val(data.slug);
|
369 |
+
$(form).find('.np_author select').val(data.author);
|
370 |
+
$(form).find('.np_template').val(data.template);
|
371 |
+
$(form).find('.np_status').val(data.status);
|
372 |
+
$(form).find('.np_nav_title').val(data.navtitle);
|
373 |
+
if ( data.cs === 'open' ) $(form).find('.np_cs').prop('checked', 'checked');
|
374 |
+
|
375 |
+
if ( data.npstatus === 'hide' ){
|
376 |
+
$(form).find('.np_status').prop('checked', 'checked');
|
377 |
+
} else {
|
378 |
+
$(form).find('.np_status').removeAttr('checked');
|
379 |
+
}
|
380 |
+
|
381 |
+
if ( data.navstatus === 'hide' ) {
|
382 |
+
$(form).find('.np_nav_status').prop('checked', 'checked');
|
383 |
+
} else {
|
384 |
+
$(form).find('.np_nav_status').removeAttr('checked');
|
385 |
+
}
|
386 |
+
|
387 |
+
// Date Fields
|
388 |
+
$(form).find('select[name="mm"]').val(data.month);
|
389 |
+
$(form).find('input[name="jj"]').val(data.day);
|
390 |
+
$(form).find('input[name="aa"]').val(data.year);
|
391 |
+
$(form).find('input[name="hh"]').val(data.hour);
|
392 |
+
$(form).find('input[name="mn"]').val(data.minute);
|
393 |
+
|
394 |
+
// Populate Taxonomy Checkboxes
|
395 |
+
if ( data.hasOwnProperty('taxonomies') ){
|
396 |
+
var taxonomies = data.taxonomies;
|
397 |
+
for ( i = 0; i < taxonomies.length; i++ ){
|
398 |
+
var tax = '#' + taxonomies[i];
|
399 |
+
$(form).find(tax).prop('checked', 'checked');
|
400 |
+
}
|
401 |
+
}
|
402 |
+
|
403 |
+
$(form).show();
|
404 |
+
}
|
405 |
+
|
406 |
+
|
407 |
+
/**
|
408 |
+
* Remove the quick edit form and restore the row
|
409 |
+
*/
|
410 |
+
function revert_quick_edit()
|
411 |
+
{
|
412 |
+
$('.np-quickedit-error').hide();
|
413 |
+
$('.sortable .quick-edit').remove();
|
414 |
+
$('.row').show();
|
415 |
+
}
|
416 |
+
|
417 |
+
|
418 |
+
/**
|
419 |
+
* Submit the Quick Edit Form
|
420 |
+
*/
|
421 |
+
function submit_np_quickedit(form)
|
422 |
+
{
|
423 |
+
$('.np-quickedit-error').hide();
|
424 |
+
var syncmenu = ( $('.np-sync-menu').is(':checked') ) ? 'sync' : 'nosync';
|
425 |
+
|
426 |
+
$.ajax({
|
427 |
+
url: ajaxurl,
|
428 |
+
type: 'post',
|
429 |
+
datatype: 'json',
|
430 |
+
data: $(form).serialize() + '&action=npquickedit&nonce=' + nestedpages.np_nonce + '&syncmenu=' + syncmenu,
|
431 |
+
success: function(data){
|
432 |
+
if (data.status === 'error'){
|
433 |
+
np_remove_qe_loading(form);
|
434 |
+
$(form).find('.np-quickedit-error').text(data.message).show();
|
435 |
+
} else {
|
436 |
+
np_remove_qe_loading(form);
|
437 |
+
np_update_qe_data(form, data.post_data);
|
438 |
+
np_qe_update_animate(form);
|
439 |
+
}
|
440 |
+
}
|
441 |
+
});
|
442 |
+
}
|
443 |
+
|
444 |
+
|
445 |
+
/**
|
446 |
+
* Update Row Data after Quick Edit
|
447 |
+
*/
|
448 |
+
function np_update_qe_data(form, data)
|
449 |
+
{
|
450 |
+
var row = $(form).parent('.quick-edit').siblings('.row');
|
451 |
+
$(row).find('.title').text(data.post_title);
|
452 |
+
|
453 |
+
var status = $(row).find('.status');
|
454 |
+
if ( (data._status !== 'publish') && (data._status !== 'future') ){
|
455 |
+
$(status).text('(' + data._status + ')');
|
456 |
+
} else {
|
457 |
+
$(status).text('');
|
458 |
+
}
|
459 |
+
|
460 |
+
// Hide / Show in Nav
|
461 |
+
var nav_status = $(row).find('.nav-status');
|
462 |
+
if ( (data.nav_status == 'hide') ){
|
463 |
+
$(nav_status).text('(Hidden)');
|
464 |
+
} else {
|
465 |
+
$(nav_status).text('');
|
466 |
+
}
|
467 |
+
|
468 |
+
// Hide / Show in Nested Pages
|
469 |
+
var li = $(row).parent('li');
|
470 |
+
if ( (data.np_status == 'hide') ){
|
471 |
+
$(li).addClass('np-hide');
|
472 |
+
$(row).find('.status').after('<i class="np-icon-eye-blocked"></i>');
|
473 |
+
} else {
|
474 |
+
$(li).removeClass('np-hide');
|
475 |
+
$(row).find('.np-icon-eye-blocked').remove();
|
476 |
+
}
|
477 |
+
|
478 |
+
var button = $(row).find('.np-quick-edit');
|
479 |
+
|
480 |
+
$(button).attr('data-id', data.post_id);
|
481 |
+
$(button).attr('data-template', data.page_template);
|
482 |
+
$(button).attr('data-title', data.post_title);
|
483 |
+
$(button).attr('data-slug', data.post_name);
|
484 |
+
$(button).attr('data-commentstatus', data.comment_status);
|
485 |
+
$(button).attr('data-status', data._status);
|
486 |
+
$(button).attr('data-author', data.post_author);
|
487 |
+
$(button).attr('data-navstatus', data.nav_status);
|
488 |
+
$(button).attr('data-np-status', data.np_status);
|
489 |
+
$(button).attr('data-navtitle', data.np_nav_title);
|
490 |
+
|
491 |
+
$(button).attr('data-month', data.mm);
|
492 |
+
$(button).attr('data-day', data.jj);
|
493 |
+
$(button).attr('data-year', data.aa);
|
494 |
+
$(button).attr('data-hour', data.hh);
|
495 |
+
$(button).attr('data-minute', data.mn);
|
496 |
+
|
497 |
+
np_remove_taxonomy_classes(li);
|
498 |
+
np_add_category_classes(li, data);
|
499 |
+
np_add_taxonomy_classes(li, data);
|
500 |
+
|
501 |
+
}
|
502 |
+
|
503 |
+
|
504 |
+
/**
|
505 |
+
* Remove taxonomy classes from the row
|
506 |
+
*/
|
507 |
+
function np_remove_taxonomy_classes(row)
|
508 |
+
{
|
509 |
+
taxonomies = [];
|
510 |
+
var classes = $(row).attr('class').split(/\s+/);
|
511 |
+
for ( i = 0; i < classes.length; i++ ){
|
512 |
+
if ( classes[i].substring(0, 3) === 'in-'){
|
513 |
+
$(row).removeClass(classes[i]);
|
514 |
+
}
|
515 |
+
}
|
516 |
+
}
|
517 |
+
|
518 |
+
|
519 |
+
/**
|
520 |
+
* Add category classes to the row
|
521 |
+
*/
|
522 |
+
function np_add_category_classes(row, data)
|
523 |
+
{
|
524 |
+
if ( data.hasOwnProperty('post_category') ){
|
525 |
+
var cats = data.post_category;
|
526 |
+
for ( i = 0; i < cats.length; i++ ){
|
527 |
+
var taxclass = 'in-category-' + cats[i];
|
528 |
+
$(row).addClass(taxclass);
|
529 |
+
}
|
530 |
+
}
|
531 |
+
}
|
532 |
+
|
533 |
+
|
534 |
+
/**
|
535 |
+
* Add Taxonomy Classes to the row
|
536 |
+
*/
|
537 |
+
function np_add_taxonomy_classes(row, data)
|
538 |
+
{
|
539 |
+
if ( data.hasOwnProperty('tax_input') )
|
540 |
+
{
|
541 |
+
var taxonomies = data.tax_input;
|
542 |
+
$.each(taxonomies, function(tax, terms){
|
543 |
+
for (i = 0; i < terms.length; i++){
|
544 |
+
var taxclass = 'in-' + tax + '-' + terms[i];
|
545 |
+
$(row).addClass(taxclass);
|
546 |
+
}
|
547 |
+
});
|
548 |
+
|
549 |
+
}
|
550 |
+
}
|
551 |
+
|
552 |
+
|
553 |
+
/**
|
554 |
+
* Remove loading state from Quick Edit form
|
555 |
+
*/
|
556 |
+
function np_remove_qe_loading(form)
|
557 |
+
{
|
558 |
+
$(form).find('.np-save-quickedit').removeAttr('disabled');
|
559 |
+
$(form).find('.np-qe-loading').hide();
|
560 |
+
}
|
561 |
+
|
562 |
+
/**
|
563 |
+
* Show quick edit update animation
|
564 |
+
*/
|
565 |
+
function np_qe_update_animate(form)
|
566 |
+
{
|
567 |
+
var row = $(form).parent('.quick-edit').siblings('.row');
|
568 |
+
$(row).addClass('np-updated');
|
569 |
+
$(row).show();
|
570 |
+
$(form).parent('.quick-edit').remove();
|
571 |
+
np_set_borders();
|
572 |
+
setTimeout(function(){
|
573 |
+
$(row).addClass('np-updated-show');
|
574 |
+
}, 1500);
|
575 |
+
}
|
576 |
+
|
577 |
+
|
578 |
+
}); //$
|
assets/js/nestedpages.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery(function(t){function e(){var e=t(".nplist");t(".page-row").removeClass("no-border"),t.each(e,function(){t(this).find(".page-row:visible:first").addClass("no-border")})}function a(e){var a=t(e.placeholder).parents("ol").length,i=t(".sortable").width(),s=40*a-40,o=i-s;t(e.placeholder).width(o).css("margin-left",s+"px"),n(e)}function n(e){var a=t(e.placeholder).parent("ol");t(a).is(":visible")||t(a).show()}function s(){t(".child-toggle").each(function(){var e=t(this).parent(".row").parent("li");if(t(e).children("ol").length>0){var a=t(e).children("ol:visible").length>0?"np-icon-arrow-down":"np-icon-arrow-right";t(this).html('<a href="#"><i class="'+a+'"></i></a>')}else t(this).empty()})}function o(){t("#np-error").hide(),t("#nested-loading").show();var e=t(".np-sync-menu").is(":checked")?"sync":"nosync";list=t("ol.sortable").nestedSortable("toHierarchy",{startDepthCount:0}),t.ajax({url:ajaxurl,type:"post",datatype:"json",data:{action:"npsort",nonce:nestedpages.np_nonce,list:list,syncmenu:e},success:function(e){"error"===e.status?(t("#np-error").text(e.message).show(),t("#nested-loading").hide()):t("#nested-loading").hide()}})}function r(e){t.ajax({url:ajaxurl,type:"post",datatype:"json",data:{action:"npsyncmenu",nonce:nestedpages.np_nonce,syncmenu:e},success:function(t){"error"===t.status&&alert("There was an error saving the sync setting.")}})}function d(e){var a={id:t(e).attr("data-id"),title:t(e).attr("data-title"),slug:t(e).attr("data-slug"),author:t(e).attr("data-author"),cs:t(e).attr("data-commentstatus"),status:t(e).attr("data-status"),template:t(e).attr("data-template"),month:t(e).attr("data-month"),day:t(e).attr("data-day"),year:t(e).attr("data-year"),hour:t(e).attr("data-hour"),minute:t(e).attr("data-minute"),navstatus:t(e).attr("data-navstatus"),npstatus:t(e).attr("data-np-status"),navtitle:t(e).attr("data-navtitle")},n=t(e).closest(".row").parent("li");a.taxonomies=[];var s=t(n).attr("class").split(/\s+/);for(i=0;i<s.length;i++)"in-"===s[i].substring(0,3)&&a.taxonomies.push(s[i]);if(t(n).children("ol").length>0)var o=t(n).children("ol"),r=t(".quick-edit-form").clone().insertBefore(o);else var r=t(".quick-edit-form").clone().appendTo(n);t(r).siblings(".row").hide();l(r,a)}function l(e,a){if(t(e).find(".np_id").val(a.id),t(e).find(".np_title").val(a.title),t(e).find(".np_slug").val(a.slug),t(e).find(".np_author select").val(a.author),t(e).find(".np_template").val(a.template),t(e).find(".np_status").val(a.status),t(e).find(".np_nav_title").val(a.navtitle),"open"===a.cs&&t(e).find(".np_cs").prop("checked","checked"),"hide"===a.npstatus?t(e).find(".np_status").prop("checked","checked"):t(e).find(".np_status").removeAttr("checked"),"hide"===a.navstatus?t(e).find(".np_nav_status").prop("checked","checked"):t(e).find(".np_nav_status").removeAttr("checked"),t(e).find('select[name="mm"]').val(a.month),t(e).find('input[name="jj"]').val(a.day),t(e).find('input[name="aa"]').val(a.year),t(e).find('input[name="hh"]').val(a.hour),t(e).find('input[name="mn"]').val(a.minute),a.hasOwnProperty("taxonomies")){var n=a.taxonomies;for(i=0;i<n.length;i++){var s="#"+n[i];t(e).find(s).prop("checked","checked")}}t(e).show()}function c(){t(".np-quickedit-error").hide(),t(".sortable .quick-edit").remove(),t(".row").show()}function u(e){t(".np-quickedit-error").hide();var a=t(".np-sync-menu").is(":checked")?"sync":"nosync";t.ajax({url:ajaxurl,type:"post",datatype:"json",data:t(e).serialize()+"&action=npquickedit&nonce="+nestedpages.np_nonce+"&syncmenu="+a,success:function(a){"error"===a.status?(g(e),t(e).find(".np-quickedit-error").text(a.message).show()):(g(e),p(e,a.post_data),m(e))}})}function p(e,a){var n=t(e).parent(".quick-edit").siblings(".row");t(n).find(".title").text(a.post_title);var i=t(n).find(".status");t(i).text("publish"!==a._status&&"future"!==a._status?"("+a._status+")":"");var s=t(n).find(".nav-status");t(s).text("hide"==a.nav_status?"(Hidden)":"");var o=t(n).parent("li");"hide"==a.np_status?(t(o).addClass("np-hide"),t(n).find(".status").after('<i class="np-icon-eye-blocked"></i>')):(t(o).removeClass("np-hide"),t(n).find(".np-icon-eye-blocked").remove());var r=t(n).find(".np-quick-edit");t(r).attr("data-id",a.post_id),t(r).attr("data-template",a.page_template),t(r).attr("data-title",a.post_title),t(r).attr("data-slug",a.post_name),t(r).attr("data-commentstatus",a.comment_status),t(r).attr("data-status",a._status),t(r).attr("data-author",a.post_author),t(r).attr("data-navstatus",a.nav_status),t(r).attr("data-np-status",a.np_status),t(r).attr("data-navtitle",a.np_nav_title),t(r).attr("data-month",a.mm),t(r).attr("data-day",a.jj),t(r).attr("data-year",a.aa),t(r).attr("data-hour",a.hh),t(r).attr("data-minute",a.mn),h(o),f(o,a),v(o,a)}function h(e){taxonomies=[];var a=t(e).attr("class").split(/\s+/);for(i=0;i<a.length;i++)"in-"===a[i].substring(0,3)&&t(e).removeClass(a[i])}function f(e,a){if(a.hasOwnProperty("post_category")){var n=a.post_category;for(i=0;i<n.length;i++){var s="in-category-"+n[i];t(e).addClass(s)}}}function v(e,a){if(a.hasOwnProperty("tax_input")){var n=a.tax_input;t.each(n,function(a,n){for(i=0;i<n.length;i++){var s="in-"+a+"-"+n[i];t(e).addClass(s)}})}}function g(e){t(e).find(".np-save-quickedit").removeAttr("disabled"),t(e).find(".np-qe-loading").hide()}function m(a){var n=t(a).parent(".quick-edit").siblings(".row");t(n).addClass("np-updated"),t(n).show(),t(a).parent(".quick-edit").remove(),e(),setTimeout(function(){t(n).addClass("np-updated-show")},1500)}t(document).ready(function(){s(),e()}),t(document).on("click",".child-toggle a",function(a){a.preventDefault();var n=t(this).parent(".child-toggle").parent(".row").siblings("ol");t(this).find("i").toggleClass("np-icon-arrow-down").toggleClass("np-icon-arrow-right"),t(n).toggle(),e()}),t(document).on("click",".nestedpages-toggleall a",function(a){a.preventDefault(),"closed"==t(this).attr("data-toggle")?(t(".nestedpages ol li ol").show(),t(this).attr("data-toggle","opened"),t(this).text(nestedpages.collapse_text),t(".child-toggle i").removeClass("np-icon-arrow-right").addClass("np-icon-arrow-down"),c(),e()):(t(".nestedpages ol li ol").hide(),t(this).attr("data-toggle","closed"),t(this).text(nestedpages.expand_text),t(".child-toggle i").removeClass("np-icon-arrow-down").addClass("np-icon-arrow-right"),c(),e())}),t(document).on("click",".np-toggle-hidden",function(a){a.preventDefault();var n=t(this).attr("href");"show"===n?(t(this).attr("href","hide"),t(this).text("Show Hidden Pages"),t(".np-hide").removeClass("shown").hide(),e()):(t(this).attr("href","show"),t(this).text("Hide Hidden Pages"),t(".np-hide").addClass("shown").show(),e())}),t(document).on("click",".np-toggle-publish",function(e){e.preventDefault();var a=t(this).attr("href");t(".np-toggle-publish").removeClass("active"),t(this).addClass("active"),"#published"==a?(t(".nplist .page-row").hide(),t(".nplist .published").show()):t(".nplist .page-row").show()}),t(document).on("click",".np-toggle-edit",function(e){e.preventDefault();var a=t(this).siblings(".action-buttons");t(a).is(":visible")?(t(this).removeClass("active"),t(a).hide()):(t(this).addClass("active"),t(a).show())});var w=function(){var t=0;return function(e,a){clearTimeout(t),t=setTimeout(e,a)}}();t(window).resize(function(){w(function(){t(".action-buttons").removeAttr("style"),t(".np-toggle-edit").removeClass("active")},500)}),t(document).ready(function(){t(".sortable").not(".no-sort").nestedSortable({items:"li",toleranceElement:"> .row",handle:".handle",placeholder:"ui-sortable-placeholder",start:function(t,e){e.placeholder.height(e.item.height())},sort:function(t,e){a(e)},stop:function(){setTimeout(function(){s(),e()},100),o()},update:function(){}})}),t(".np-sync-menu").on("change",function(){var e=t(this).is(":checked")?"sync":"nosync";r(e)}),t(document).on("click",".np-quick-edit",function(e){e.preventDefault(),c(),d(t(this))}),t(document).on("click",".np-cancel-quickedit",function(e){var a=t(this).parents(".page-row");c(a),e.preventDefault()}),t(document).on("click",".np-save-quickedit",function(e){e.preventDefault(),t(".row").removeClass("np-updated").removeClass("np-updated-show");var a=t(this).parents("form");t(this).attr("disabled","disabled"),t(a).find(".np-qe-loading").show(),u(a)}),t(document).on("click",".np-toggle-taxonomies",function(){t(this).parents("form").find(".np-taxonomies").toggle()})});
|
assets/screenshot-1.png
ADDED
Binary file
|
assets/screenshot-2.png
ADDED
Binary file
|
assets/screenshot-3.gif
ADDED
Binary file
|
assets/screenshot-4.gif
ADDED
Binary file
|
assets/scss/_alerts.scss
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//
|
2 |
+
// Alerts
|
3 |
+
// --------------------------------------------------
|
4 |
+
|
5 |
+
// error in quick edit form
|
6 |
+
.np-quickedit-error {
|
7 |
+
border-left: 4px solid #dd3d36;
|
8 |
+
padding: 4px 0 4px 8px;
|
9 |
+
margin-bottom: 10px;
|
10 |
+
background-color: $gray-lighter;
|
11 |
+
}
|
assets/scss/_buttons.scss
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//
|
2 |
+
// Buttons
|
3 |
+
// --------------------------------------------------
|
4 |
+
.np-btn {
|
5 |
+
text-decoration: none;
|
6 |
+
color: #555;
|
7 |
+
display: inline-block;
|
8 |
+
background-color: #f7f7f7;
|
9 |
+
border: 1px solid $border;
|
10 |
+
padding: 3px 8px;
|
11 |
+
box-shadow: inset 0 1px 0 #fff, 0 1px 0 rgba(0,0,0,.08);
|
12 |
+
transition: all 200ms ease;
|
13 |
+
&:hover {
|
14 |
+
background-color: $blue;
|
15 |
+
color: $white;
|
16 |
+
transition: all 200ms ease;
|
17 |
+
box-shadow: 0 1px 0 rgba(0,0,0,.08);
|
18 |
+
}
|
19 |
+
}
|
20 |
+
|
21 |
+
|
22 |
+
.np-btn-trash {
|
23 |
+
background-color: $red;
|
24 |
+
border-color: $red;
|
25 |
+
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3), 0 1px 0 rgba(0,0,0,.08);
|
26 |
+
color: $white;
|
27 |
+
&:hover {
|
28 |
+
background-color: darken($red, 15%);
|
29 |
+
border-color: darken($red, 15%);
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
// Toggle button for edit buttons (responsive)
|
34 |
+
.np-toggle-edit {
|
35 |
+
display: none;
|
36 |
+
float: right;
|
37 |
+
margin-right: 10px;
|
38 |
+
@extend .np-btn;
|
39 |
+
&.active {
|
40 |
+
background-color: $blue;
|
41 |
+
color: $white;
|
42 |
+
box-shadow: none;
|
43 |
+
border-color: $blue;
|
44 |
+
}
|
45 |
+
}
|
46 |
+
@media (max-width: 767px)
|
47 |
+
{
|
48 |
+
.np-toggle-edit {
|
49 |
+
display: inline-block;
|
50 |
+
}
|
51 |
+
}
|
assets/scss/_expand-handle.scss
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Expand/Contract Button
|
2 |
+
.wppages-handle-expand {
|
3 |
+
float: left;
|
4 |
+
background-color: darken($white, 5%);
|
5 |
+
font-size: 18px;
|
6 |
+
width: 46px;
|
7 |
+
height: 46px;
|
8 |
+
margin-right: 5px;
|
9 |
+
text-align: center;
|
10 |
+
border-right: 1px solid $border;
|
11 |
+
div {
|
12 |
+
background-color: $white;
|
13 |
+
border: 1px solid $border;
|
14 |
+
width: 24px;
|
15 |
+
height: 24px;
|
16 |
+
line-height: 24px;
|
17 |
+
border-radius: 15px;
|
18 |
+
margin-top: 9px;
|
19 |
+
cursor: pointer;
|
20 |
+
transition: all 200ms ease;
|
21 |
+
&:hover {
|
22 |
+
background-color: $blue;
|
23 |
+
border-color: $blue;
|
24 |
+
color: $white;
|
25 |
+
transition: all 200ms ease;
|
26 |
+
}
|
27 |
+
}
|
28 |
+
}
|
assets/scss/_icons.scss
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@font-face {
|
2 |
+
font-family: 'nestedpages';
|
3 |
+
src:url('fonts/nestedpages.eot?-cjbqo6');
|
4 |
+
src:url('fonts/nestedpages.eot?#iefix-cjbqo6') format('embedded-opentype'),
|
5 |
+
url('fonts/nestedpages.woff?-cjbqo6') format('woff'),
|
6 |
+
url('fonts/nestedpages.ttf?-cjbqo6') format('truetype'),
|
7 |
+
url('fonts/nestedpages.svg?-cjbqo6#nestedpages') format('svg');
|
8 |
+
font-weight: normal;
|
9 |
+
font-style: normal;
|
10 |
+
}
|
11 |
+
|
12 |
+
[class^="np-icon-"], [class*=" np-icon-"] {
|
13 |
+
font-family: 'nestedpages';
|
14 |
+
speak: none;
|
15 |
+
font-style: normal;
|
16 |
+
font-weight: normal;
|
17 |
+
font-variant: normal;
|
18 |
+
text-transform: none;
|
19 |
+
line-height: 1;
|
20 |
+
|
21 |
+
/* Better Font Rendering =========== */
|
22 |
+
-webkit-font-smoothing: antialiased;
|
23 |
+
-moz-osx-font-smoothing: grayscale;
|
24 |
+
}
|
25 |
+
.np-icon-no:before {
|
26 |
+
content: "\e601";
|
27 |
+
}
|
28 |
+
.np-icon-yes:before {
|
29 |
+
content: "\e602";
|
30 |
+
}
|
31 |
+
.np-icon-menu:before {
|
32 |
+
content: "\e603";
|
33 |
+
}
|
34 |
+
.np-icon-arrow-down:before {
|
35 |
+
content: "\e604";
|
36 |
+
}
|
37 |
+
.np-icon-arrow-right:before {
|
38 |
+
content: "\e605";
|
39 |
+
}
|
40 |
+
.np-icon-sub-menu:before {
|
41 |
+
content: "\e600";
|
42 |
+
}
|
43 |
+
.np-icon-pencil:before {
|
44 |
+
content: "\e608";
|
45 |
+
}
|
46 |
+
.np-icon-bubble:before {
|
47 |
+
content: "\e607";
|
48 |
+
}
|
49 |
+
.np-icon-lock:before {
|
50 |
+
content: "\e609";
|
51 |
+
}
|
52 |
+
.np-icon-remove:before {
|
53 |
+
content: "\e60a";
|
54 |
+
}
|
55 |
+
.np-icon-menu2:before {
|
56 |
+
content: "\e606";
|
57 |
+
}
|
58 |
+
.np-icon-eye:before {
|
59 |
+
content: "\e60b";
|
60 |
+
}
|
61 |
+
.np-icon-eye-blocked:before {
|
62 |
+
content: "\e60c";
|
63 |
+
}
|
assets/scss/_mixins.scss
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//
|
2 |
+
// Mixins
|
3 |
+
// --------------------------------------------------
|
4 |
+
@mixin clearfix {
|
5 |
+
zoom: 1;
|
6 |
+
&:before,
|
7 |
+
&:after {
|
8 |
+
content: " "; /* 1 */
|
9 |
+
display: table; /* 2 */
|
10 |
+
}
|
11 |
+
&:after {
|
12 |
+
clear: both;
|
13 |
+
}
|
14 |
+
}
|
15 |
+
|
16 |
+
@mixin unstyled {
|
17 |
+
list-style-type: none;
|
18 |
+
margin: 0;
|
19 |
+
padding: 0;
|
20 |
+
}
|
21 |
+
|
22 |
+
// WP Dashboard Styling
|
23 |
+
@mixin wptable {
|
24 |
+
box-shadow: 0 1px 1px rgba(0,0,0,.06);
|
25 |
+
border: 1px solid $border-light;
|
26 |
+
border-radius: 3px;
|
27 |
+
}
|
assets/scss/_page-listing.scss
ADDED
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//
|
2 |
+
// The Page Listing
|
3 |
+
// --------------------------------------------------
|
4 |
+
|
5 |
+
.nestedpages {
|
6 |
+
clear: both;
|
7 |
+
border-radius: 4px;
|
8 |
+
|
9 |
+
// Sortable Placeholder
|
10 |
+
.ui-sortable-placeholder {
|
11 |
+
display: block !important;
|
12 |
+
position: relative;
|
13 |
+
min-height: 46px;
|
14 |
+
border: 0;
|
15 |
+
border: 1px dashed $blue !important;
|
16 |
+
background-color: lighten($blue, 65%);
|
17 |
+
margin: 0;
|
18 |
+
}
|
19 |
+
|
20 |
+
// Sortable Helper
|
21 |
+
.ui-sortable-helper {
|
22 |
+
opacity: 0.8;
|
23 |
+
box-shadow: 2px 2px 3px 0px rgba(0,0,0,.5);
|
24 |
+
}
|
25 |
+
|
26 |
+
|
27 |
+
ol {
|
28 |
+
list-style-type: none;
|
29 |
+
clear: both;
|
30 |
+
margin: 0;
|
31 |
+
@include wptable;
|
32 |
+
|
33 |
+
a {
|
34 |
+
text-decoration: none;
|
35 |
+
}
|
36 |
+
|
37 |
+
|
38 |
+
.page-link {
|
39 |
+
line-height: 26px;
|
40 |
+
.edit-indicator {
|
41 |
+
margin-left: 10px;
|
42 |
+
display: none;
|
43 |
+
i {
|
44 |
+
font-size: 12px;
|
45 |
+
margin-right: 3px;
|
46 |
+
}
|
47 |
+
}
|
48 |
+
&:hover {
|
49 |
+
.edit-indicator {
|
50 |
+
display: inline-block;
|
51 |
+
}
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
// Indicates post is being edited
|
56 |
+
.locked {
|
57 |
+
color: $black;
|
58 |
+
margin-left: 20px;
|
59 |
+
em {
|
60 |
+
font-style: normal;
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
// Indicates status if not published
|
65 |
+
.status {
|
66 |
+
color: darken($white, 40%);
|
67 |
+
margin: 0px 10px;
|
68 |
+
}
|
69 |
+
|
70 |
+
// Indicates page is hidden from nested pages
|
71 |
+
.np-icon-eye-blocked {
|
72 |
+
color: darken($white, 40%);
|
73 |
+
}
|
74 |
+
|
75 |
+
// Indicates hidden from nav is selected
|
76 |
+
.nav-status {
|
77 |
+
color: darken($white, 30%);
|
78 |
+
}
|
79 |
+
|
80 |
+
// Hidden from Nested Pages
|
81 |
+
.np-hide {
|
82 |
+
display: none;
|
83 |
+
}
|
84 |
+
|
85 |
+
// Yoast SEO Indicator
|
86 |
+
// See Yoast's metabox-tabs.css
|
87 |
+
.np-seo-indicator {
|
88 |
+
display: block;
|
89 |
+
float: right;
|
90 |
+
width: 12px;
|
91 |
+
height: 12px;
|
92 |
+
border-radius: 8px;
|
93 |
+
background-color: darken($white, 40%);
|
94 |
+
margin: 6px 10px 0 0;
|
95 |
+
&.good {
|
96 |
+
background-color: #7ad03a;
|
97 |
+
}
|
98 |
+
&.ok {
|
99 |
+
background-color: #ffba00;
|
100 |
+
}
|
101 |
+
&.poor {
|
102 |
+
background-color: #ee7c1b;
|
103 |
+
}
|
104 |
+
&.bad {
|
105 |
+
background-color: #dd3d36;
|
106 |
+
}
|
107 |
+
&.warn {
|
108 |
+
background-color: maroon;
|
109 |
+
}
|
110 |
+
&.wrong {
|
111 |
+
background-color: red;
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
li {
|
116 |
+
margin: 0;
|
117 |
+
border-top: 1px solid $border;
|
118 |
+
background-color: $blue;
|
119 |
+
&.first {
|
120 |
+
border: 0;
|
121 |
+
}
|
122 |
+
&:first-child {
|
123 |
+
border: 0;
|
124 |
+
}
|
125 |
+
&.no-border {
|
126 |
+
border: 0;
|
127 |
+
}
|
128 |
+
} // li
|
129 |
+
|
130 |
+
ol {
|
131 |
+
display: none;
|
132 |
+
border-radius: 0;
|
133 |
+
list-style-type: none;
|
134 |
+
border: 0;
|
135 |
+
box-shadow: none;
|
136 |
+
border-top: 1px solid $border;
|
137 |
+
} // ol 2
|
138 |
+
|
139 |
+
} // ol 1
|
140 |
+
|
141 |
+
// Block that holds the toggle child arrow
|
142 |
+
.child-toggle {
|
143 |
+
float: left;
|
144 |
+
margin: -10px 10px 0 0;
|
145 |
+
width: 46px;
|
146 |
+
height: 46px;
|
147 |
+
background-color: darken($white, 6%);
|
148 |
+
text-align: center;
|
149 |
+
a { // Arrow Toggle
|
150 |
+
display: inline-block;
|
151 |
+
margin-top: 7px;
|
152 |
+
width: 28px;
|
153 |
+
height: 28px;
|
154 |
+
background-color: $white;
|
155 |
+
border: 1px solid $border;
|
156 |
+
border-radius: 20px;
|
157 |
+
font-size: 20px;
|
158 |
+
line-height: 30px;
|
159 |
+
color: $black;
|
160 |
+
transition: all 200ms ease;
|
161 |
+
i {
|
162 |
+
line-height: 26px;
|
163 |
+
}
|
164 |
+
&:hover {
|
165 |
+
background-color: $blue;
|
166 |
+
color: $white;
|
167 |
+
border-color: $blue;
|
168 |
+
}
|
169 |
+
}
|
170 |
+
} // .child-toggle
|
171 |
+
|
172 |
+
|
173 |
+
// Handle for sortable functionality
|
174 |
+
.handle {
|
175 |
+
display: inline-block;
|
176 |
+
cursor: move;
|
177 |
+
font-size: 20px;
|
178 |
+
color: darken($white, 30%);
|
179 |
+
transition: all 200ms ease;
|
180 |
+
position: relative;
|
181 |
+
top: 3px;
|
182 |
+
&:hover {
|
183 |
+
transition: all 200ms ease;
|
184 |
+
color: $blue;
|
185 |
+
}
|
186 |
+
} // .handle
|
187 |
+
|
188 |
+
|
189 |
+
// Submenu Indicator
|
190 |
+
.np-icon-sub-menu {
|
191 |
+
display: none;
|
192 |
+
color: darken($white, 40%);
|
193 |
+
position: relative;
|
194 |
+
left: 2px;
|
195 |
+
}
|
196 |
+
|
197 |
+
|
198 |
+
// Normalize the submenu and handle icons
|
199 |
+
.handle, .np-icon-sub-menu {
|
200 |
+
width: 30px;
|
201 |
+
height: 46px;
|
202 |
+
line-height: 36px;
|
203 |
+
margin-top: -10px;
|
204 |
+
}
|
205 |
+
|
206 |
+
// Hide/show the submenu indicator & handle on hover of the row
|
207 |
+
li ol .row {
|
208 |
+
.np-icon-sub-menu { display: inline-block; }
|
209 |
+
.handle { display: none; }
|
210 |
+
&:hover {
|
211 |
+
.np-icon-sub-menu { display: none; }
|
212 |
+
.handle { display: inline-block; }
|
213 |
+
}
|
214 |
+
}
|
215 |
+
|
216 |
+
|
217 |
+
// Main Row Element
|
218 |
+
.row {
|
219 |
+
background-color: $white;
|
220 |
+
display: block;
|
221 |
+
padding: 10px 0px 0px 0px;
|
222 |
+
height: 36px;
|
223 |
+
@include clearfix;
|
224 |
+
&:hover {
|
225 |
+
background-color: darken($white, 6%);
|
226 |
+
}
|
227 |
+
&.np-updated {
|
228 |
+
background-color: lighten(#7ad03a, 40%);
|
229 |
+
transition: background-color 400ms ease;
|
230 |
+
}
|
231 |
+
&.np-updated-show {
|
232 |
+
background-color: $white;
|
233 |
+
transition: background-color 400ms ease;
|
234 |
+
}
|
235 |
+
} // .row
|
236 |
+
|
237 |
+
|
238 |
+
// Inner row element gets padding to give visual indicator of nested depth
|
239 |
+
ol li ol {
|
240 |
+
.row-inner {
|
241 |
+
padding-left: 86px;
|
242 |
+
}
|
243 |
+
li ol {
|
244 |
+
.row-inner {
|
245 |
+
padding-left: 116px;
|
246 |
+
}
|
247 |
+
li ol {
|
248 |
+
.row-inner {
|
249 |
+
padding-left: 156px;
|
250 |
+
}
|
251 |
+
}
|
252 |
+
}
|
253 |
+
}
|
254 |
+
|
255 |
+
// Action Buttons
|
256 |
+
.action-buttons {
|
257 |
+
display: none;
|
258 |
+
float: right;
|
259 |
+
margin: 0 10px 0 0;
|
260 |
+
a {
|
261 |
+
margin-left: 5px;
|
262 |
+
}
|
263 |
+
}
|
264 |
+
|
265 |
+
|
266 |
+
} // .nestedpages
|
267 |
+
|
268 |
+
@media (min-width: 768px)
|
269 |
+
{
|
270 |
+
.nestedpages .row:hover .action-buttons {
|
271 |
+
display: block;
|
272 |
+
}
|
273 |
+
}
|
274 |
+
|
275 |
+
|
276 |
+
@media (max-width: 767px)
|
277 |
+
{
|
278 |
+
.nestedpages {
|
279 |
+
ol .page-link {
|
280 |
+
line-height: 24px;
|
281 |
+
&:hover span {
|
282 |
+
display: none;
|
283 |
+
}
|
284 |
+
}
|
285 |
+
|
286 |
+
ol .locked em {
|
287 |
+
display: none;
|
288 |
+
}
|
289 |
+
|
290 |
+
.child-toggle {
|
291 |
+
background: transparent;
|
292 |
+
}
|
293 |
+
|
294 |
+
.row {
|
295 |
+
height: auto;
|
296 |
+
}
|
297 |
+
|
298 |
+
.action-buttons {
|
299 |
+
display: none;
|
300 |
+
background-color: $blue;
|
301 |
+
float: none;
|
302 |
+
margin: 0;
|
303 |
+
padding: 8px;
|
304 |
+
a {
|
305 |
+
margin-left: 5px;
|
306 |
+
}
|
307 |
+
}
|
308 |
+
} // .nestedpages
|
309 |
+
} // media query
|
assets/scss/_quick-edit.scss
ADDED
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//
|
2 |
+
// Quick Edit Form
|
3 |
+
// --------------------------------------------------
|
4 |
+
.nestedpages .quick-edit {
|
5 |
+
background-color: $white;
|
6 |
+
border-radius: 0;
|
7 |
+
.form-interior {
|
8 |
+
padding: 10px;
|
9 |
+
}
|
10 |
+
h3 {
|
11 |
+
margin: 0 0 8px 0;
|
12 |
+
font-size: 14px;
|
13 |
+
}
|
14 |
+
.fields {
|
15 |
+
margin-bottom: 10px;
|
16 |
+
background: url('../images/border.png') repeat-y;
|
17 |
+
background-position: center;
|
18 |
+
@include clearfix;
|
19 |
+
}
|
20 |
+
.left {
|
21 |
+
float: left;
|
22 |
+
width: 48%;
|
23 |
+
}
|
24 |
+
.right {
|
25 |
+
float: right;
|
26 |
+
width: 48%;
|
27 |
+
}
|
28 |
+
label {
|
29 |
+
font-style: oblique;
|
30 |
+
}
|
31 |
+
.buttons {
|
32 |
+
clear: both;
|
33 |
+
@include clearfix;
|
34 |
+
background-color: darken($white, 75%);
|
35 |
+
padding: 8px;
|
36 |
+
}
|
37 |
+
.form-control {
|
38 |
+
clear: both;
|
39 |
+
@include clearfix;
|
40 |
+
margin-bottom: 5px;
|
41 |
+
input[type='text'],
|
42 |
+
input[type='password'],
|
43 |
+
select {
|
44 |
+
float: right;
|
45 |
+
width: 75%;
|
46 |
+
}
|
47 |
+
label {
|
48 |
+
float: left;
|
49 |
+
width: 20%;
|
50 |
+
}
|
51 |
+
}
|
52 |
+
.comments {
|
53 |
+
float: right;
|
54 |
+
width: 75%;
|
55 |
+
margin-bottom: 10px;
|
56 |
+
@include clearfix;
|
57 |
+
}
|
58 |
+
.dates {
|
59 |
+
float: right;
|
60 |
+
width: 75%;
|
61 |
+
margin-bottom: 6px;
|
62 |
+
select {
|
63 |
+
width: 25%;
|
64 |
+
}
|
65 |
+
input {
|
66 |
+
width: 12%;
|
67 |
+
}
|
68 |
+
}
|
69 |
+
.np-qe-loading {
|
70 |
+
display: none;
|
71 |
+
float: right;
|
72 |
+
width: 25px;
|
73 |
+
height: 25px;
|
74 |
+
margin: 2px 10px 0 0;
|
75 |
+
background: url('../images/loading-white.gif') no-repeat;
|
76 |
+
}
|
77 |
+
|
78 |
+
// Taxonomies
|
79 |
+
.np-toggle-taxonomies {
|
80 |
+
clear: both;
|
81 |
+
float: right;
|
82 |
+
width: 71%;
|
83 |
+
text-align: center;
|
84 |
+
}
|
85 |
+
.np-taxonomies {
|
86 |
+
display: none;
|
87 |
+
clear: both;
|
88 |
+
background-color: $gray-lighter;
|
89 |
+
padding: 8px;
|
90 |
+
@include clearfix;
|
91 |
+
}
|
92 |
+
.np-taxonomy {
|
93 |
+
float: left;
|
94 |
+
width: 30%;
|
95 |
+
margin-right: 3.33%;
|
96 |
+
.title {
|
97 |
+
font-weight: bold;
|
98 |
+
margin-bottom: 4px;
|
99 |
+
display: block;
|
100 |
+
}
|
101 |
+
li {
|
102 |
+
background-color: $white;
|
103 |
+
border: 0;
|
104 |
+
}
|
105 |
+
} // .np-taxonomy
|
106 |
+
}
|
107 |
+
|
108 |
+
@media (max-width: 767px)
|
109 |
+
{
|
110 |
+
.nestedpages .quick-edit {
|
111 |
+
.fields {
|
112 |
+
background: transparent;
|
113 |
+
}
|
114 |
+
.left, .right {
|
115 |
+
float: none;
|
116 |
+
width: 100%;
|
117 |
+
}
|
118 |
+
.form-control {
|
119 |
+
margin-bottom: 10px;
|
120 |
+
input[type='text'],
|
121 |
+
input[type='password'],
|
122 |
+
select {
|
123 |
+
float: none;
|
124 |
+
width: 100%;
|
125 |
+
}
|
126 |
+
label {
|
127 |
+
display: block;
|
128 |
+
float: none;
|
129 |
+
width: 100%;
|
130 |
+
margin-bottom: 4px;
|
131 |
+
}
|
132 |
+
}
|
133 |
+
.comments {
|
134 |
+
float: none;
|
135 |
+
width: 100%;
|
136 |
+
}
|
137 |
+
.dates {
|
138 |
+
float: none;
|
139 |
+
width: 100%;
|
140 |
+
margin-bottom: 6px;
|
141 |
+
}
|
142 |
+
}
|
143 |
+
}
|
assets/scss/_toggle-all.scss
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//
|
2 |
+
// Toggle Visibility of pages
|
3 |
+
// --------------------------------------------------
|
4 |
+
.nestedpages-toggleall {
|
5 |
+
float: right;
|
6 |
+
margin-top: -30px;
|
7 |
+
}
|
8 |
+
|
9 |
+
// Publish Toggle
|
10 |
+
.np-toggle-publish {
|
11 |
+
color: darken($white, 40%);
|
12 |
+
&.active {
|
13 |
+
color: $black;
|
14 |
+
font-weight: bold;
|
15 |
+
}
|
16 |
+
}
|
17 |
+
|
18 |
+
// Sync Menu
|
19 |
+
.np-sync-menu-cont {
|
20 |
+
float: right;
|
21 |
+
margin: -27px 15px 0px 0px;
|
22 |
+
}
|
23 |
+
|
24 |
+
#nested-loading {
|
25 |
+
display: none;
|
26 |
+
float: right;
|
27 |
+
width: 30px;
|
28 |
+
margin: -31px 120px 0 0;
|
29 |
+
}
|
assets/scss/_top-tools.scss
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//
|
2 |
+
// Links/Tools Above the Page Listing
|
3 |
+
// --------------------------------------------------
|
4 |
+
.wppages-top-tools {
|
5 |
+
margin-bottom: 20px;
|
6 |
+
padding-top: 10px;
|
7 |
+
a {
|
8 |
+
text-decoration: none;
|
9 |
+
}
|
10 |
+
}
|
assets/scss/_variables.scss
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//
|
2 |
+
// Variables
|
3 |
+
// --------------------------------------------------
|
4 |
+
$black: #333;
|
5 |
+
$white: #ffffff;
|
6 |
+
$gray-lighter: #f9f9f9; // WP BG
|
7 |
+
|
8 |
+
$border: #e1e1e1;
|
9 |
+
$border-light: #e5e5e5;
|
10 |
+
|
11 |
+
$blue: #0074a2; // WP Blue
|
12 |
+
$red: #e14d43; // WP red
|
assets/scss/nestedpages.scss
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//
|
2 |
+
// WP Pages Styles
|
3 |
+
// --------------------------------------------------
|
4 |
+
@import "_variables.scss";
|
5 |
+
@import "_mixins.scss";
|
6 |
+
|
7 |
+
@import "_icons.scss";
|
8 |
+
@import "_buttons.scss";
|
9 |
+
@import "_alerts.scss";
|
10 |
+
@import "_toggle-all.scss";
|
11 |
+
|
12 |
+
@import "_top-tools.scss";
|
13 |
+
@import "_expand-handle.scss";
|
14 |
+
@import "_page-listing.scss";
|
15 |
+
@import "_quick-edit.scss";
|
includes/class-nestedpages.php
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Activate and Check Versions
|
3 |
+
require_once('class-np-activate.php');
|
4 |
+
|
5 |
+
// Form Handlers
|
6 |
+
require_once('class-np-handler-sort.php');
|
7 |
+
require_once('class-np-handler-quickedit.php');
|
8 |
+
require_once('class-np-handler-syncmenu.php');
|
9 |
+
|
10 |
+
// Required Classes
|
11 |
+
require_once('class-np-dependencies.php');
|
12 |
+
require_once('class-np-pagelisting.php');
|
13 |
+
require_once('class-np-newpage.php');
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Primary Plugin Class
|
17 |
+
*/
|
18 |
+
class NestedPages {
|
19 |
+
|
20 |
+
|
21 |
+
public function __construct()
|
22 |
+
{
|
23 |
+
$this->init();
|
24 |
+
$this->formActions();
|
25 |
+
add_action('init', array($this, 'addLocalization') );
|
26 |
+
}
|
27 |
+
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Initialize Plugin
|
31 |
+
*/
|
32 |
+
public function init()
|
33 |
+
{
|
34 |
+
new NP_Activate;
|
35 |
+
new NP_Dependencies;
|
36 |
+
new NP_PageListing;
|
37 |
+
new NP_NewPage;
|
38 |
+
}
|
39 |
+
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Set Form Actions & Handlers
|
43 |
+
*/
|
44 |
+
public function formActions()
|
45 |
+
{
|
46 |
+
if ( is_admin() ) {
|
47 |
+
add_action( 'wp_ajax_npsort', 'nestedpages_sort_handler' );
|
48 |
+
add_action( 'wp_ajax_npquickedit', 'nestedpages_quickedit_handler' );
|
49 |
+
add_action( 'wp_ajax_npsyncmenu', 'nestedpages_syncmenu_handler' );
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Localization Domain
|
56 |
+
*/
|
57 |
+
public function addLocalization()
|
58 |
+
{
|
59 |
+
load_plugin_textdomain('nestedpages', false, dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages' );
|
60 |
+
}
|
61 |
+
|
62 |
+
|
63 |
+
}
|
includes/class-np-activate.php
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin Activation
|
4 |
+
*/
|
5 |
+
require_once('class-np-navmenu.php');
|
6 |
+
class NP_Activate {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Plugin Version
|
10 |
+
*/
|
11 |
+
private $version;
|
12 |
+
|
13 |
+
|
14 |
+
public function __construct()
|
15 |
+
{
|
16 |
+
register_activation_hook( dirname( dirname(__FILE__) ) . '/nestedpages.php', array($this, 'install') );
|
17 |
+
$this->version = 1.0;
|
18 |
+
$this->setVersion();
|
19 |
+
$this->addMenu();
|
20 |
+
}
|
21 |
+
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Activation Hook
|
25 |
+
*/
|
26 |
+
public function install()
|
27 |
+
{
|
28 |
+
$this->checkVersions();
|
29 |
+
$this->setOptions();
|
30 |
+
}
|
31 |
+
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Check Wordpress and PHP versions
|
35 |
+
*/
|
36 |
+
private function checkVersions( $wp = '3.9', $php = '5.3.0' ) {
|
37 |
+
global $wp_version;
|
38 |
+
if ( version_compare( PHP_VERSION, $php, '<' ) )
|
39 |
+
$flag = 'PHP';
|
40 |
+
elseif ( version_compare( $wp_version, $wp, '<' ) )
|
41 |
+
$flag = 'WordPress';
|
42 |
+
else
|
43 |
+
return;
|
44 |
+
$version = 'PHP' == $flag ? $php : $wp;
|
45 |
+
deactivate_plugins( basename( __FILE__ ) );
|
46 |
+
|
47 |
+
wp_die('<p><strong>Nested Pages</strong> plugin requires'.$flag.' version '.$version.' or greater.</p>','Plugin Activation Error', array( 'response'=>200, 'back_link'=>TRUE ) );
|
48 |
+
}
|
49 |
+
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Set the Plugin Version
|
53 |
+
*/
|
54 |
+
private function setVersion()
|
55 |
+
{
|
56 |
+
if ( !get_option('nestedpages_version') ){
|
57 |
+
update_option('nestedpages_version', $this->version);
|
58 |
+
}
|
59 |
+
elseif ( get_option('nestedpages_version') < $this->version ){
|
60 |
+
update_option('nestedpages_version', $this->version);
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Add the nav menu
|
67 |
+
*/
|
68 |
+
public function addMenu()
|
69 |
+
{
|
70 |
+
$menu_e = get_term_by('slug', 'nestedpages', 'nav_menu');
|
71 |
+
if ( !$menu_e ){
|
72 |
+
$menu = new NP_NavMenu;
|
73 |
+
$menu->addMenu();
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Set Default Options
|
80 |
+
*/
|
81 |
+
private function setOptions()
|
82 |
+
{
|
83 |
+
if ( !get_option('nestedpages_menusync') ){
|
84 |
+
update_option('nestedpages_menusync', 'sync');
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
|
89 |
+
}
|
includes/class-np-dependencies.php
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin JS & CSS Dependencies
|
4 |
+
*/
|
5 |
+
class NP_Dependencies {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Plugin Directory
|
9 |
+
*/
|
10 |
+
private $plugin_dir;
|
11 |
+
|
12 |
+
public function __construct()
|
13 |
+
{
|
14 |
+
add_action( 'admin_enqueue_scripts', array($this, 'styles') );
|
15 |
+
add_action( 'admin_enqueue_scripts', array($this, 'scripts') );
|
16 |
+
$this->plugin_dir = plugins_url() . '/wp-nested-pages';
|
17 |
+
}
|
18 |
+
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Admin Styles
|
22 |
+
*/
|
23 |
+
public function styles()
|
24 |
+
{
|
25 |
+
wp_enqueue_style(
|
26 |
+
'nestedpages',
|
27 |
+
$this->plugin_dir . '/assets/css/nestedpages.css',
|
28 |
+
array(),
|
29 |
+
'1.0'
|
30 |
+
);
|
31 |
+
}
|
32 |
+
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Admin Scripts required by plugin
|
36 |
+
* Only Loads on the Nested Pages screen
|
37 |
+
*/
|
38 |
+
public function scripts()
|
39 |
+
{
|
40 |
+
$screen = get_current_screen();
|
41 |
+
if ( strpos( $screen->id, 'nestedpages' ) ) :
|
42 |
+
wp_enqueue_script('jquery-ui-core');
|
43 |
+
|
44 |
+
wp_enqueue_script('jquery-ui-sortable');
|
45 |
+
|
46 |
+
wp_enqueue_script(
|
47 |
+
'ui-touch-punch',
|
48 |
+
$this->plugin_dir . '/assets/js/lib/jquery.ui.touch-punch.min.js',
|
49 |
+
array('jquery', 'jquery-ui-sortable'),
|
50 |
+
'1.0'
|
51 |
+
);
|
52 |
+
|
53 |
+
wp_enqueue_script(
|
54 |
+
'nested-sortable',
|
55 |
+
$this->plugin_dir . '/assets/js/lib/jquery.mjs.nestedSortable.js',
|
56 |
+
array('jquery', 'jquery-ui-sortable'),
|
57 |
+
'1.0'
|
58 |
+
);
|
59 |
+
|
60 |
+
wp_enqueue_script(
|
61 |
+
'nestedpages',
|
62 |
+
$this->plugin_dir . '/assets/js/nestedpages.min.js',
|
63 |
+
array('jquery'),
|
64 |
+
'1.0'
|
65 |
+
);
|
66 |
+
|
67 |
+
wp_localize_script(
|
68 |
+
'nestedpages',
|
69 |
+
'nestedpages',
|
70 |
+
array(
|
71 |
+
'np_nonce' => wp_create_nonce( 'nestedpages-nonce' ),
|
72 |
+
'expand_text' => __('Expand Pages', 'nestedpages'),
|
73 |
+
'collapse_text' => __('Collapse Pages', 'nestedpages')
|
74 |
+
)
|
75 |
+
);
|
76 |
+
endif;
|
77 |
+
}
|
78 |
+
|
79 |
+
}
|
includes/class-np-handler-base.php
ADDED
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once('class-np-navmenu.php');
|
4 |
+
require_once('class-np-postrepository.php');
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Base Form Handler Class
|
8 |
+
*/
|
9 |
+
abstract class NP_BaseHandler {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Nonce
|
13 |
+
* @var string
|
14 |
+
*/
|
15 |
+
protected $nonce;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Form Data
|
19 |
+
* @var array
|
20 |
+
*/
|
21 |
+
protected $data;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Post Repo
|
25 |
+
* @var object
|
26 |
+
*/
|
27 |
+
protected $post_repo;
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Response
|
32 |
+
* @var array;
|
33 |
+
*/
|
34 |
+
protected $response;
|
35 |
+
|
36 |
+
public function __construct()
|
37 |
+
{
|
38 |
+
$this->post_repo = new NP_PostRepository;
|
39 |
+
$this->setData();
|
40 |
+
$this->validateNonce();
|
41 |
+
}
|
42 |
+
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Set the Form Data
|
46 |
+
*/
|
47 |
+
protected function setData()
|
48 |
+
{
|
49 |
+
$this->nonce = sanitize_text_field($_POST['nonce']);
|
50 |
+
$data = array();
|
51 |
+
foreach( $_POST as $key => $value ){
|
52 |
+
$data[$key] = $value;
|
53 |
+
}
|
54 |
+
$this->data = $data;
|
55 |
+
}
|
56 |
+
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Validate the Nonce
|
60 |
+
*/
|
61 |
+
protected function validateNonce()
|
62 |
+
{
|
63 |
+
if ( ! wp_verify_nonce( $this->nonce, 'nestedpages-nonce' ) ){
|
64 |
+
$this->response = array( 'status' => 'error', 'message' => __('Incorrect Form Field') );
|
65 |
+
$this->sendResponse();
|
66 |
+
die();
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Sync the Nav Menu
|
73 |
+
*/
|
74 |
+
protected function syncMenu()
|
75 |
+
{
|
76 |
+
if ( $_POST['syncmenu'] == 'sync' ){
|
77 |
+
$menu = new NP_NavMenu;
|
78 |
+
$menu->clearMenu();
|
79 |
+
$menu->sync();
|
80 |
+
update_option('nestedpages_menusync', 'sync');
|
81 |
+
} else {
|
82 |
+
update_option('nestedpages_menusync', 'nosync');
|
83 |
+
}
|
84 |
+
}
|
85 |
+
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Send a Generic Success Message
|
89 |
+
*/
|
90 |
+
protected function sendErrorResponse()
|
91 |
+
{
|
92 |
+
$this->response = array(
|
93 |
+
'status' => 'error',
|
94 |
+
'message' => __('There was an error updating the page.')
|
95 |
+
);
|
96 |
+
$this->sendResponse();
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Return Response
|
102 |
+
*/
|
103 |
+
protected function sendResponse()
|
104 |
+
{
|
105 |
+
return wp_send_json($this->response);
|
106 |
+
}
|
107 |
+
|
108 |
+
}
|
includes/class-np-handler-quickedit.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
function nestedpages_quickedit_handler()
|
4 |
+
{
|
5 |
+
new NP_QuickEdit_Handler;
|
6 |
+
}
|
7 |
+
|
8 |
+
require_once('class-np-handler-base.php');
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Handles processing the quick edit form
|
12 |
+
* @return json response
|
13 |
+
*/
|
14 |
+
class NP_QuickEdit_Handler extends NP_BaseHandler {
|
15 |
+
|
16 |
+
|
17 |
+
public function __construct()
|
18 |
+
{
|
19 |
+
parent::__construct();
|
20 |
+
$this->updatePost();
|
21 |
+
$this->syncMenu();
|
22 |
+
$this->sendResponse();
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Update the Post
|
28 |
+
* @todo update taxonomies
|
29 |
+
*/
|
30 |
+
private function updatePost()
|
31 |
+
{
|
32 |
+
$updated = $this->post_repo->updatePost($this->data);
|
33 |
+
if ( !$updated ) $this->sendErrorResponse();
|
34 |
+
$this->addData();
|
35 |
+
$this->response = array(
|
36 |
+
'status' => 'success',
|
37 |
+
'message' => __('Post successfully updated'),
|
38 |
+
'post_data' => $this->data
|
39 |
+
);
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Add additional data to the response object
|
45 |
+
*/
|
46 |
+
private function addData()
|
47 |
+
{
|
48 |
+
$this->data['nav_status'] = ( isset($this->data['nav_status']) ) ? 'hide' : 'show';
|
49 |
+
$this->data['np_status'] = ( isset($this->data['nested_pages_status']) ) ? 'hide' : 'show';
|
50 |
+
if ( !isset($_POST['comment_status']) ) $this->data['comment_status'] = 'closed';
|
51 |
+
}
|
52 |
+
|
53 |
+
}
|
includes/class-np-handler-sort.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
function nestedpages_sort_handler()
|
4 |
+
{
|
5 |
+
new NP_SortHandler;
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Handles processing sortable pages
|
10 |
+
* updates menu order & page parents
|
11 |
+
* @return json response
|
12 |
+
*/
|
13 |
+
require_once('class-np-handler-base.php');
|
14 |
+
require_once('class-np-navmenu.php');
|
15 |
+
|
16 |
+
class NP_SortHandler extends NP_BaseHandler {
|
17 |
+
|
18 |
+
|
19 |
+
public function __construct()
|
20 |
+
{
|
21 |
+
parent::__construct();
|
22 |
+
$this->updateOrder();
|
23 |
+
$this->syncMenu();
|
24 |
+
$this->sendResponse();
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Update Post Order
|
30 |
+
*/
|
31 |
+
private function updateOrder()
|
32 |
+
{
|
33 |
+
$posts = $this->data['list'];
|
34 |
+
$order = $this->post_repo->updateOrder($posts);
|
35 |
+
if ( $order ){
|
36 |
+
$this->response = array('status' => 'success', 'message' => __('Page order successfully updated.','nestedpages') );
|
37 |
+
} else {
|
38 |
+
$this->response = array('status'=>'error', 'message'=> __('There was an order updating the page order.','nestedpages') );
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
}
|
includes/class-np-handler-syncmenu.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
function nestedpages_syncmenu_handler()
|
4 |
+
{
|
5 |
+
new NP_SyncMenu_Handler;
|
6 |
+
}
|
7 |
+
|
8 |
+
require_once('class-np-handler-base.php');
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Turn on/off menu sync
|
12 |
+
* @return json response
|
13 |
+
*/
|
14 |
+
class NP_SyncMenu_Handler extends NP_BaseHandler {
|
15 |
+
|
16 |
+
public function __construct()
|
17 |
+
{
|
18 |
+
parent::__construct();
|
19 |
+
$this->updateSync();
|
20 |
+
$this->sendResponse();
|
21 |
+
}
|
22 |
+
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Update the sync setting
|
26 |
+
*/
|
27 |
+
private function updateSync()
|
28 |
+
{
|
29 |
+
if ( $this->data['syncmenu'] == 'sync' ){
|
30 |
+
update_option('nestedpages_menusync', 'sync');
|
31 |
+
$this->syncMenu();
|
32 |
+
$this->response = array('status'=>'success', 'message'=> __('Menu sync enabled.'));
|
33 |
+
} else {
|
34 |
+
update_option('nestedpages_menusync', 'nosync');
|
35 |
+
$this->response = array('status'=>'success', 'message'=> __('Menu sync disabled.'));
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
}
|
includes/class-np-navmenu.php
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The generated nav menu that matches the nested pages structure
|
4 |
+
*/
|
5 |
+
class NP_NavMenu {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* The Menu ID
|
9 |
+
*/
|
10 |
+
public $id;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* The Menu Items
|
14 |
+
*/
|
15 |
+
public $items;
|
16 |
+
|
17 |
+
|
18 |
+
public function __construct()
|
19 |
+
{
|
20 |
+
$this->setID();
|
21 |
+
$this->setItems();
|
22 |
+
}
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Add the Nav Menu
|
27 |
+
*/
|
28 |
+
public function addMenu()
|
29 |
+
{
|
30 |
+
$menu = wp_create_nav_menu('nestedpages');
|
31 |
+
$this->id = $menu;
|
32 |
+
}
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Set the Menu ID
|
37 |
+
*/
|
38 |
+
public function setID()
|
39 |
+
{
|
40 |
+
$menu = get_term_by('slug', 'nestedpages', 'nav_menu');
|
41 |
+
if ( $menu ) $this->id = $menu->term_id;
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Set the Menu Items
|
47 |
+
*/
|
48 |
+
public function setItems()
|
49 |
+
{
|
50 |
+
$menu = get_term_by('slug', 'nestedpages', 'nav_menu');
|
51 |
+
if ( $menu ) $this->items = wp_get_nav_menu_items($this->id);
|
52 |
+
}
|
53 |
+
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Create the menu with nested pages (Recursive function)
|
57 |
+
*/
|
58 |
+
public function sync($parent = 0, $menu_parent = 0)
|
59 |
+
{
|
60 |
+
$page_q = new WP_Query(array(
|
61 |
+
'post_type' => 'page',
|
62 |
+
'posts_per_page' => -1,
|
63 |
+
'post_status' => 'publish',
|
64 |
+
'orderby' => 'menu_order',
|
65 |
+
'order' => 'ASC',
|
66 |
+
'post_parent' => $parent
|
67 |
+
));
|
68 |
+
if ( $page_q->have_posts() ) : while ( $page_q->have_posts() ) : $page_q->the_post();
|
69 |
+
|
70 |
+
// Nav Status
|
71 |
+
$ns = get_post_meta( get_the_id(), 'np_nav_status', true);
|
72 |
+
|
73 |
+
// Nested Pages Visibility
|
74 |
+
$np_status = get_post_meta( get_the_id(), 'nested_pages_status', true );
|
75 |
+
|
76 |
+
// Nav Title
|
77 |
+
$nav_title = get_post_meta( get_the_id(), 'np_nav_title', true );
|
78 |
+
$nav_title = ( $nav_title !== "" ) ? $nav_title : get_the_title();
|
79 |
+
|
80 |
+
if ( ($ns == 'show') || ($ns == '') ) {
|
81 |
+
if ( $np_status !== 'hide' ){
|
82 |
+
$menu = wp_update_nav_menu_item($this->id, 0, array(
|
83 |
+
'menu-item-title' => $nav_title,
|
84 |
+
'menu-item-url' => get_the_permalink(),
|
85 |
+
'menu-item-status' => 'publish',
|
86 |
+
'menu-item-type' => 'post_type',
|
87 |
+
'menu-item-object' => 'page',
|
88 |
+
'menu-item-object-id' => get_the_id(),
|
89 |
+
'menu-item-parent-id' => $menu_parent
|
90 |
+
));
|
91 |
+
$this->sync( get_the_id(), $menu );
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
endwhile; endif; wp_reset_postdata();
|
96 |
+
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Clear out the menu
|
102 |
+
*/
|
103 |
+
public function clearMenu()
|
104 |
+
{
|
105 |
+
$menu_items = wp_get_nav_menu_items($this->id);
|
106 |
+
foreach ( $menu_items as $i ){
|
107 |
+
wp_delete_post($i->ID, true);
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
|
112 |
+
}
|
includes/class-np-newpage.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Performs Hooks to check for new page screen
|
4 |
+
* Select appropriate parent page if applicable & shows message
|
5 |
+
*/
|
6 |
+
class NP_NewPage {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Parent Page
|
10 |
+
*/
|
11 |
+
private $parent_page;
|
12 |
+
|
13 |
+
|
14 |
+
public function __construct()
|
15 |
+
{
|
16 |
+
add_action('admin_notices', array($this, 'showNotice'));
|
17 |
+
add_action('admin_head', array($this, 'selectParent'));
|
18 |
+
}
|
19 |
+
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Check if this is a new child page
|
23 |
+
*/
|
24 |
+
private function isChild()
|
25 |
+
{
|
26 |
+
$page = get_current_screen();
|
27 |
+
if ( ($page->id == 'page') && ($page->action == 'add') && (isset($_GET['npparent'])) ){
|
28 |
+
$this->parent_page = (int) sanitize_text_field($_GET['npparent']);
|
29 |
+
return true;
|
30 |
+
} else {
|
31 |
+
return false;
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Show the admin notice
|
38 |
+
*/
|
39 |
+
public function showNotice()
|
40 |
+
{
|
41 |
+
if ( $this->isChild() ) {
|
42 |
+
echo '<div id="message" class="updated"><p>' . __('Adding child page under:') . ' <strong>' . get_the_title($this->parent_page) . '</strong></p></div>';
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Preselect the parent page
|
49 |
+
*/
|
50 |
+
public function selectParent()
|
51 |
+
{
|
52 |
+
if ( $this->isChild() ) {
|
53 |
+
echo '<script>jQuery(document).ready(function(){ jQuery("#parent_id").val("' . $this->parent_page . '"); });</script>';
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
}
|
58 |
+
?>
|
includes/class-np-pagelisting.php
ADDED
@@ -0,0 +1,220 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Primary Listing Class
|
5 |
+
* Initiates Page Listing screen (overwriting default), and displays primary plugin view.
|
6 |
+
*/
|
7 |
+
class NP_PageListing {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Post Type
|
11 |
+
* @var object
|
12 |
+
*/
|
13 |
+
private $post_type;
|
14 |
+
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Hierarchical Taxonomies
|
18 |
+
* @var array
|
19 |
+
*/
|
20 |
+
private $h_taxonomies;
|
21 |
+
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Flat Taxonomies
|
25 |
+
* @var array
|
26 |
+
*/
|
27 |
+
private $f_taxonomies;
|
28 |
+
|
29 |
+
|
30 |
+
public function __construct()
|
31 |
+
{
|
32 |
+
$this->post_type = get_post_type_object('page');
|
33 |
+
add_action( 'admin_menu', array($this, 'adminMenu') );
|
34 |
+
add_action( 'admin_menu', array($this, 'submenu') );
|
35 |
+
}
|
36 |
+
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Add the admin menu item
|
40 |
+
*/
|
41 |
+
public function adminMenu()
|
42 |
+
{
|
43 |
+
if ( current_user_can('edit_pages') ){
|
44 |
+
add_menu_page(
|
45 |
+
$this->post_type->labels->name,
|
46 |
+
$this->post_type->labels->name,
|
47 |
+
'delete_pages',
|
48 |
+
'nestedpages',
|
49 |
+
array( $this, 'pageListing' ),
|
50 |
+
'dashicons-admin-page',
|
51 |
+
20
|
52 |
+
);
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Add Submenu
|
59 |
+
*/
|
60 |
+
public function submenu()
|
61 |
+
{
|
62 |
+
global $submenu;
|
63 |
+
$submenu['nestedpages'][50] = array( __('All Pages','nestedpages'), 'publish_pages', esc_url(admin_url('admin.php?page=nestedpages')) );
|
64 |
+
$submenu['nestedpages'][60] = array( __('Add New','nestedpages'), 'publish_pages', $this->addNewPageLink() );
|
65 |
+
$submenu['nestedpages'][70] = array( __('Default Pages','nestedpages'), 'publish_pages', $this->defaultPagesLink() );
|
66 |
+
}
|
67 |
+
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Add New Page Link
|
71 |
+
* @return string
|
72 |
+
*/
|
73 |
+
private function addNewPageLink()
|
74 |
+
{
|
75 |
+
return esc_url( admin_url('post-new.php?post_type=page') );
|
76 |
+
}
|
77 |
+
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Link to the default WP Pages listing
|
81 |
+
* @return string
|
82 |
+
*/
|
83 |
+
private function defaultPagesLink()
|
84 |
+
{
|
85 |
+
$link = esc_url( admin_url('edit.php?post_type=page') );
|
86 |
+
return $link;
|
87 |
+
}
|
88 |
+
|
89 |
+
|
90 |
+
/**
|
91 |
+
* The Main View
|
92 |
+
* Replaces Default Pages Listing
|
93 |
+
*/
|
94 |
+
public function pageListing()
|
95 |
+
{
|
96 |
+
include( dirname( dirname(__FILE__) ) . '/views/pages.php');
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Set the Taxonomies for Pages
|
102 |
+
*/
|
103 |
+
private function setTaxonomies()
|
104 |
+
{
|
105 |
+
$taxonomy_names = get_object_taxonomies( 'page' );
|
106 |
+
$hierarchical_taxonomies = array();
|
107 |
+
$flat_taxonomies = array();
|
108 |
+
foreach ( $taxonomy_names as $taxonomy_name ) {
|
109 |
+
$taxonomy = get_taxonomy( $taxonomy_name );
|
110 |
+
if ( !$taxonomy->show_ui )
|
111 |
+
continue;
|
112 |
+
|
113 |
+
if ( $taxonomy->hierarchical )
|
114 |
+
$hierarchical_taxonomies[] = $taxonomy;
|
115 |
+
else
|
116 |
+
$flat_taxonomies[] = $taxonomy;
|
117 |
+
}
|
118 |
+
$this->h_taxonomies = $hierarchical_taxonomies;
|
119 |
+
$this->f_taxonomies = $flat_taxonomies;
|
120 |
+
}
|
121 |
+
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Get a Posts Taxonomies
|
125 |
+
*/
|
126 |
+
private function hierarchicalTaxonomies($page_id)
|
127 |
+
{
|
128 |
+
$out = '';
|
129 |
+
if ( count($this->h_taxonomies) > 0 ) {
|
130 |
+
foreach ( $this->h_taxonomies as $taxonomy ){
|
131 |
+
$terms = wp_get_post_terms($page_id, $taxonomy->name);
|
132 |
+
foreach ( $terms as $term ){
|
133 |
+
$out .= 'in-' . $taxonomy->name . '-' . $term->term_id . ' ';
|
134 |
+
}
|
135 |
+
}
|
136 |
+
}
|
137 |
+
if ( $out !== '' ) $out .= ' has-tax ';
|
138 |
+
return $out;
|
139 |
+
}
|
140 |
+
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Loop through all the pages and create the nested / sortable list
|
144 |
+
* Recursive Method, called in page.php view
|
145 |
+
*/
|
146 |
+
private function loopPages($parent_id = 0, $count = 0)
|
147 |
+
{
|
148 |
+
$pages = new WP_Query(array(
|
149 |
+
'post_type' => 'page',
|
150 |
+
'posts_per_page' => -1,
|
151 |
+
'orderby' => 'menu_order',
|
152 |
+
'post_parent' => $parent_id,
|
153 |
+
'order' => 'ASC'
|
154 |
+
));
|
155 |
+
if ( $pages->have_posts() ) :
|
156 |
+
$count++;
|
157 |
+
|
158 |
+
if ( $count == 1 ) {
|
159 |
+
|
160 |
+
$this->setTaxonomies();
|
161 |
+
|
162 |
+
echo ( current_user_can('edit_theme_options') )
|
163 |
+
? '<ol class="sortable nplist">'
|
164 |
+
: '<ol class="sortable no-sort nplist">';
|
165 |
+
} else {
|
166 |
+
echo '<ol class="nplist">';
|
167 |
+
}
|
168 |
+
|
169 |
+
while ( $pages->have_posts() ) : $pages->the_post();
|
170 |
+
|
171 |
+
global $post;
|
172 |
+
|
173 |
+
echo '<li id="menuItem_' . get_the_id() . '" class="page-row';
|
174 |
+
|
175 |
+
// Published?
|
176 |
+
if ( $post->post_status == 'publish' ) echo ' published';
|
177 |
+
|
178 |
+
// Hidden in Nested Pages?
|
179 |
+
$np_status = get_post_meta( get_the_id(), 'nested_pages_status', true );
|
180 |
+
$np_status = ( $np_status == 'hide' ) ? 'hide' : 'show';
|
181 |
+
if ( $np_status == 'hide' ) echo ' np-hide';
|
182 |
+
|
183 |
+
// Taxonomies
|
184 |
+
echo ' ' . $this->hierarchicalTaxonomies( get_the_id() );
|
185 |
+
|
186 |
+
echo '">';
|
187 |
+
$count++;
|
188 |
+
|
189 |
+
$template = get_post_meta(get_the_id(), '_wp_page_template', true);
|
190 |
+
|
191 |
+
// Show Hide in generated nav menu
|
192 |
+
$ns = get_post_meta( get_the_id(), 'np_nav_status', true);
|
193 |
+
$nav_status = ( $ns == 'hide' ) ? 'hide' : 'show';
|
194 |
+
|
195 |
+
// Menu Title
|
196 |
+
$nav_title = get_post_meta(get_the_id(), 'np_nav_title', true);
|
197 |
+
|
198 |
+
// Date Vars
|
199 |
+
$d = get_the_time('d');
|
200 |
+
$month = get_the_time('m');
|
201 |
+
$y = get_the_time('Y');
|
202 |
+
$h = get_the_time('H');
|
203 |
+
$m = get_the_time('i');
|
204 |
+
|
205 |
+
if ( function_exists('wpseo_translate_score') ) {
|
206 |
+
$yoast_score = get_post_meta(get_the_id(), '_yoast_wpseo_linkdex', true);
|
207 |
+
$score = wpseo_translate_score($yoast_score);
|
208 |
+
};
|
209 |
+
|
210 |
+
include( dirname( dirname(__FILE__) ) . '/views/row.php');
|
211 |
+
$this->loopPages(get_the_id(), $count);
|
212 |
+
echo '</li>';
|
213 |
+
|
214 |
+
endwhile; // Loop
|
215 |
+
echo '</ol>';
|
216 |
+
endif; wp_reset_postdata();
|
217 |
+
}
|
218 |
+
|
219 |
+
|
220 |
+
}
|
includes/class-np-pagemeta.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class NP_PageMeta {
|
4 |
+
|
5 |
+
function __construct()
|
6 |
+
{
|
7 |
+
add_action( 'add_meta_boxes', array( $this, 'metaBox' ));
|
8 |
+
add_action( 'save_post', array($this, 'saveMeta' ));
|
9 |
+
}
|
10 |
+
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Register the Meta Box
|
14 |
+
*/
|
15 |
+
public function metaBox()
|
16 |
+
{
|
17 |
+
add_meta_box(
|
18 |
+
'nestedpages',
|
19 |
+
'Nested Pages',
|
20 |
+
array($this, 'metaFields'),
|
21 |
+
'page',
|
22 |
+
'side',
|
23 |
+
'low'
|
24 |
+
);
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Meta Boxes for Output
|
30 |
+
*/
|
31 |
+
public function metaFields($post)
|
32 |
+
{
|
33 |
+
wp_nonce_field( 'nestedpages_meta_box_nonce', 'np_meta_box_nonce' );
|
34 |
+
$np_nav_status = get_post_meta($post->ID, 'np_nav_status', true);
|
35 |
+
$np_nav_title = get_post_meta($post->ID, 'np_nav_title', true);
|
36 |
+
$nested_pages_status = get_post_meta($post->ID, 'nested_pages_status', true);
|
37 |
+
include( dirname( dirname(__FILE__) ) . '/views/page-meta.php');
|
38 |
+
}
|
39 |
+
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Save the custom post meta
|
43 |
+
*/
|
44 |
+
public function saveMeta( $post_id )
|
45 |
+
{
|
46 |
+
if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
|
47 |
+
|
48 |
+
// Verify the nonce & permissions.
|
49 |
+
if( !isset( $_POST['np_meta_box_nonce'] ) || !wp_verify_nonce( $_POST['np_meta_box_nonce'], 'nestedpages_meta_box_nonce' ) ) return;
|
50 |
+
//if( !current_user_can( 'edit_post' ) ) return;
|
51 |
+
|
52 |
+
// Save the Nav Status
|
53 |
+
if( isset( $_POST['np_nav_status'] ) ) {
|
54 |
+
update_post_meta( $post_id, 'np_nav_status', 'hide' );
|
55 |
+
} else {
|
56 |
+
update_post_meta( $post_id, 'np_nav_status', 'show' );
|
57 |
+
}
|
58 |
+
|
59 |
+
// Save the Nav Title
|
60 |
+
if( isset( $_POST['np_nav_title'] ) )
|
61 |
+
update_post_meta( $post_id, 'np_nav_title', esc_attr( $_POST['np_nav_title'] ) );
|
62 |
+
|
63 |
+
// Save the NP Status
|
64 |
+
if ( isset( $_POST['nested_pages_status'] ) ){
|
65 |
+
update_post_meta( $post_id, 'nested_pages_status', 'hide' );
|
66 |
+
} else {
|
67 |
+
update_post_meta( $post_id, 'nested_pages_status', 'show' );
|
68 |
+
}
|
69 |
+
|
70 |
+
}
|
71 |
+
|
72 |
+
}
|
includes/class-np-postrepository.php
ADDED
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once('class-np-validation.php');
|
4 |
+
|
5 |
+
class NP_PostRepository {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Validation Class
|
9 |
+
* @var NP_Validation instance
|
10 |
+
*/
|
11 |
+
protected $validation;
|
12 |
+
|
13 |
+
|
14 |
+
public function __construct()
|
15 |
+
{
|
16 |
+
$this->validation = new NP_Validation;
|
17 |
+
}
|
18 |
+
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Update Order
|
22 |
+
*/
|
23 |
+
public function updateOrder($posts, $parent = 0)
|
24 |
+
{
|
25 |
+
$this->validation->validatePostIDs($posts);
|
26 |
+
foreach( $posts as $key => $post )
|
27 |
+
{
|
28 |
+
wp_update_post(array(
|
29 |
+
'ID' => $post['id'],
|
30 |
+
'menu_order' => $key,
|
31 |
+
'post_parent' => $parent
|
32 |
+
));
|
33 |
+
|
34 |
+
if ( isset($post['children']) ){
|
35 |
+
$this->updateOrder($post['children'], $post['id']);
|
36 |
+
}
|
37 |
+
}
|
38 |
+
return true;
|
39 |
+
}
|
40 |
+
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Update Post
|
44 |
+
*/
|
45 |
+
public function updatePost($data)
|
46 |
+
{
|
47 |
+
$date = $this->validation->validateDate($data);
|
48 |
+
if ( !isset($_POST['comment_status']) ) $data['comment_status'] = 'closed';
|
49 |
+
|
50 |
+
$updated_post = array(
|
51 |
+
'ID' => sanitize_text_field($data['post_id']),
|
52 |
+
'post_title' => sanitize_text_field($data['post_title']),
|
53 |
+
'post_author' => sanitize_text_field($data['post_author']),
|
54 |
+
'post_name' => sanitize_text_field($data['post_name']),
|
55 |
+
'post_date' => $date,
|
56 |
+
'comment_status' => sanitize_text_field($data['comment_status']),
|
57 |
+
'post_status' => sanitize_text_field($data['_status'])
|
58 |
+
);
|
59 |
+
wp_update_post($updated_post);
|
60 |
+
|
61 |
+
$this->updateTemplate($data);
|
62 |
+
$this->updateNavStatus($data);
|
63 |
+
$this->updateNestedPagesStatus($data);
|
64 |
+
$this->updateNavTitle($data);
|
65 |
+
$this->updateCategories($data);
|
66 |
+
$this->updateHierarchicalTaxonomies($data);
|
67 |
+
|
68 |
+
return true;
|
69 |
+
}
|
70 |
+
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Update Page Template
|
74 |
+
*/
|
75 |
+
private function updateTemplate($data)
|
76 |
+
{
|
77 |
+
$template = sanitize_text_field($data['page_template']);
|
78 |
+
update_post_meta(
|
79 |
+
$data['post_id'],
|
80 |
+
'_wp_page_template',
|
81 |
+
$template
|
82 |
+
);
|
83 |
+
}
|
84 |
+
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Update Nav Status (show/hide in nav menu)
|
88 |
+
*/
|
89 |
+
private function updateNavStatus($data)
|
90 |
+
{
|
91 |
+
$status = ( isset($data['nav_status']) ) ? 'hide' : 'show';
|
92 |
+
update_post_meta(
|
93 |
+
$data['post_id'],
|
94 |
+
'np_nav_status',
|
95 |
+
$status
|
96 |
+
);
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Update Nested Pages Visibility (how/hide in Nested Pages interface)
|
102 |
+
*/
|
103 |
+
private function updateNestedPagesStatus($data)
|
104 |
+
{
|
105 |
+
$status = ( isset($data['nested_pages_status']) ) ? 'hide' : 'show';
|
106 |
+
update_post_meta(
|
107 |
+
$data['post_id'],
|
108 |
+
'nested_pages_status',
|
109 |
+
$status
|
110 |
+
);
|
111 |
+
}
|
112 |
+
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Update Nested Pages Menu Title
|
116 |
+
*/
|
117 |
+
private function updateNavTitle($data)
|
118 |
+
{
|
119 |
+
if ( isset($data['np_nav_title']) ){
|
120 |
+
$title = sanitize_text_field($data['np_nav_title']);
|
121 |
+
update_post_meta(
|
122 |
+
$data['post_id'],
|
123 |
+
'np_nav_title',
|
124 |
+
$title
|
125 |
+
);
|
126 |
+
}
|
127 |
+
}
|
128 |
+
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Update Categories
|
132 |
+
*/
|
133 |
+
private function updateCategories($data)
|
134 |
+
{
|
135 |
+
if ( isset($data['post_category']) )
|
136 |
+
{
|
137 |
+
$this->validation->validateIntegerArray($data['post_category']);
|
138 |
+
$cats = array();
|
139 |
+
foreach($data['post_category'] as $cat) {
|
140 |
+
if ( $cat !== 0 ) $cats[] = (int) $cat;
|
141 |
+
}
|
142 |
+
wp_set_post_terms($data['post_id'], $cats, 'category');
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Update Hierarchical Taxonomy Terms
|
149 |
+
*/
|
150 |
+
private function updateHierarchicalTaxonomies($data)
|
151 |
+
{
|
152 |
+
if ( isset($data['tax_input']) ) {
|
153 |
+
foreach ( $data['tax_input'] as $taxonomy => $term_ids ){
|
154 |
+
$this->validation->validateIntegerArray($term_ids);
|
155 |
+
$terms = array();
|
156 |
+
foreach ( $term_ids as $term ){
|
157 |
+
if ( $term !== 0 ) $terms[] = (int) $term;
|
158 |
+
}
|
159 |
+
wp_set_post_terms($data['post_id'], $terms, $taxonomy);
|
160 |
+
}
|
161 |
+
}
|
162 |
+
}
|
163 |
+
|
164 |
+
}
|
includes/class-np-validation.php
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Nested Pages Form Validation
|
5 |
+
*/
|
6 |
+
class NP_Validation {
|
7 |
+
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Validate Post IDs in an array of posts
|
11 |
+
*/
|
12 |
+
public function validatePostIDs($posts)
|
13 |
+
{
|
14 |
+
foreach ($posts as $post)
|
15 |
+
{
|
16 |
+
if ( !is_numeric($post['id']) ){
|
17 |
+
return wp_send_json(array('status'=>'error', 'message'=>'Incorrect Form Field'));
|
18 |
+
}
|
19 |
+
}
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Validate IDs in an array (tax ids)
|
24 |
+
*/
|
25 |
+
public function validateIntegerArray($items)
|
26 |
+
{
|
27 |
+
foreach ( $items as $item )
|
28 |
+
{
|
29 |
+
if ( !is_numeric($item) ){
|
30 |
+
return wp_send_json(array('status'=>'error', 'message'=>'Incorrect Form Field'));
|
31 |
+
}
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Validate Date Input
|
38 |
+
*/
|
39 |
+
public function validateDate($data)
|
40 |
+
{
|
41 |
+
// First validate that it is an actual date
|
42 |
+
if ( !wp_checkdate(
|
43 |
+
intval($data['mm']),
|
44 |
+
intval($data['jj']),
|
45 |
+
intval($data['aa']),
|
46 |
+
$data['aa'] . '-' . $data['mm'] . '-' . $data['jj']
|
47 |
+
)
|
48 |
+
){
|
49 |
+
return wp_send_json(array('status' => 'error', 'message' => __('Please provide a valid date.', 'nestedpages') ));
|
50 |
+
die();
|
51 |
+
}
|
52 |
+
|
53 |
+
// Validate all the fields are there
|
54 |
+
if ( ($data['aa'] !== "")
|
55 |
+
&& ( $data['mm'] !== "" )
|
56 |
+
&& ( $data['jj'] !== "" )
|
57 |
+
&& ( $data['hh'] !== "" )
|
58 |
+
&& ( $data['mm'] !== "" )
|
59 |
+
&& ( $data['ss'] !== "" ) )
|
60 |
+
{
|
61 |
+
$date = strtotime($data['aa'] . '-' . $data['mm'] . '-' . $data['jj'] . ' ' . $data['hh'] . ':' . $data['mm'] . ':' . $data['ss']);
|
62 |
+
return date('Y-m-d H:i:s', $date);
|
63 |
+
} else {
|
64 |
+
return wp_send_json(array('status' => 'error', 'message' => __('Please provide a valid date.', 'nestedpages') ));
|
65 |
+
die();
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
|
70 |
+
}
|
languages/index.php
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//Nothing to see here
|
languages/nestedpages.mo
ADDED
Binary file
|
languages/nestedpages.pot
ADDED
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: Nested Pages\n"
|
4 |
+
"POT-Creation-Date: 2014-10-19 22:04-0500\n"
|
5 |
+
"PO-Revision-Date: 2014-10-19 22:05-0500\n"
|
6 |
+
"Last-Translator: \n"
|
7 |
+
"Language-Team: \n"
|
8 |
+
"Language: es\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"X-Generator: Poedit 1.6.4\n"
|
13 |
+
"X-Poedit-Basepath: ..\n"
|
14 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
15 |
+
"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
|
16 |
+
"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;"
|
17 |
+
"_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
|
18 |
+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
19 |
+
"X-Poedit-SearchPath-0: .\n"
|
20 |
+
|
21 |
+
#: includes/class-np-dependencies.php:72 views/pages.php:9
|
22 |
+
msgid "Expand Pages"
|
23 |
+
msgstr ""
|
24 |
+
|
25 |
+
#: includes/class-np-dependencies.php:73
|
26 |
+
msgid "Collapse Pages"
|
27 |
+
msgstr ""
|
28 |
+
|
29 |
+
#: includes/class-np-handler-base.php:57
|
30 |
+
msgid "Incorrect Form Field"
|
31 |
+
msgstr ""
|
32 |
+
|
33 |
+
#: includes/class-np-handler-quickedit.php:46
|
34 |
+
msgid "Post successfully updated"
|
35 |
+
msgstr ""
|
36 |
+
|
37 |
+
#: includes/class-np-handler-quickedit.php:52
|
38 |
+
msgid "There was an error updating the page."
|
39 |
+
msgstr ""
|
40 |
+
|
41 |
+
#: includes/class-np-handler-sort.php:39
|
42 |
+
msgid "Page order successfully updated."
|
43 |
+
msgstr ""
|
44 |
+
|
45 |
+
#: includes/class-np-handler-sort.php:41
|
46 |
+
msgid "There was an order updating the page order."
|
47 |
+
msgstr ""
|
48 |
+
|
49 |
+
#: includes/class-np-handler-syncmenu.php:33
|
50 |
+
msgid "Menu sync enabled."
|
51 |
+
msgstr ""
|
52 |
+
|
53 |
+
#: includes/class-np-handler-syncmenu.php:36
|
54 |
+
msgid "Menu sync disabled."
|
55 |
+
msgstr ""
|
56 |
+
|
57 |
+
#: includes/class-np-newpage.php:42
|
58 |
+
msgid "Adding child page under:"
|
59 |
+
msgstr ""
|
60 |
+
|
61 |
+
#: includes/class-np-pagelisting.php:49
|
62 |
+
msgid "All Pages"
|
63 |
+
msgstr ""
|
64 |
+
|
65 |
+
#: includes/class-np-pagelisting.php:50
|
66 |
+
msgid "Add New"
|
67 |
+
msgstr ""
|
68 |
+
|
69 |
+
#: includes/class-np-pagelisting.php:51
|
70 |
+
msgid "Default Pages"
|
71 |
+
msgstr ""
|
72 |
+
|
73 |
+
#: includes/class-np-validation.php:36 includes/class-np-validation.php:51
|
74 |
+
msgid "Please provide a valid date."
|
75 |
+
msgstr ""
|
76 |
+
|
77 |
+
#: views/pages.php:15
|
78 |
+
msgid "Sync Menu"
|
79 |
+
msgstr ""
|
80 |
+
|
81 |
+
#: views/pages.php:23
|
82 |
+
msgid "All"
|
83 |
+
msgstr ""
|
84 |
+
|
85 |
+
#: views/pages.php:24 views/quickedit.php:78
|
86 |
+
msgid "Published"
|
87 |
+
msgstr ""
|
88 |
+
|
89 |
+
#: views/pages.php:25
|
90 |
+
msgid "Show Hidden Pages"
|
91 |
+
msgstr ""
|
92 |
+
|
93 |
+
#: views/pages.php:26
|
94 |
+
msgid "Default"
|
95 |
+
msgstr ""
|
96 |
+
|
97 |
+
#: views/quickedit.php:31 views/row.php:81
|
98 |
+
msgid "Quick Edit"
|
99 |
+
msgstr ""
|
100 |
+
|
101 |
+
#: views/quickedit.php:40
|
102 |
+
msgid "Title"
|
103 |
+
msgstr ""
|
104 |
+
|
105 |
+
#: views/quickedit.php:44
|
106 |
+
msgid "Slug"
|
107 |
+
msgstr ""
|
108 |
+
|
109 |
+
#: views/quickedit.php:48
|
110 |
+
msgid "Date"
|
111 |
+
msgstr ""
|
112 |
+
|
113 |
+
#: views/quickedit.php:66
|
114 |
+
msgid "Author"
|
115 |
+
msgstr ""
|
116 |
+
|
117 |
+
#: views/quickedit.php:75
|
118 |
+
msgid "Status"
|
119 |
+
msgstr ""
|
120 |
+
|
121 |
+
#: views/quickedit.php:79
|
122 |
+
msgid "Scheduled"
|
123 |
+
msgstr ""
|
124 |
+
|
125 |
+
#: views/quickedit.php:81
|
126 |
+
msgid "Pending Review"
|
127 |
+
msgstr ""
|
128 |
+
|
129 |
+
#: views/quickedit.php:82
|
130 |
+
msgid "Draft"
|
131 |
+
msgstr ""
|
132 |
+
|
133 |
+
#: views/quickedit.php:90
|
134 |
+
msgid "Template"
|
135 |
+
msgstr ""
|
136 |
+
|
137 |
+
#: views/quickedit.php:92
|
138 |
+
msgid "Default Template"
|
139 |
+
msgstr ""
|
140 |
+
|
141 |
+
#: views/quickedit.php:99
|
142 |
+
msgid "Allow Comments"
|
143 |
+
msgstr ""
|
144 |
+
|
145 |
+
#: views/quickedit.php:104
|
146 |
+
msgid "Menu Title"
|
147 |
+
msgstr ""
|
148 |
+
|
149 |
+
#: views/quickedit.php:110
|
150 |
+
msgid "Hide in Nav Menu"
|
151 |
+
msgstr ""
|
152 |
+
|
153 |
+
#: views/quickedit.php:116
|
154 |
+
msgid "Hide in Nested Pages"
|
155 |
+
msgstr ""
|
156 |
+
|
157 |
+
#: views/quickedit.php:141
|
158 |
+
msgid "Cancel"
|
159 |
+
msgstr ""
|
160 |
+
|
161 |
+
#: views/quickedit.php:144
|
162 |
+
msgid "Update"
|
163 |
+
msgstr ""
|
164 |
+
|
165 |
+
#: views/row.php:42
|
166 |
+
msgid "currently editing"
|
167 |
+
msgstr ""
|
168 |
+
|
169 |
+
#: views/row.php:44
|
170 |
+
msgid "Edit"
|
171 |
+
msgstr ""
|
172 |
+
|
173 |
+
#: views/row.php:61
|
174 |
+
msgid "Add Child"
|
175 |
+
msgstr ""
|
176 |
+
|
177 |
+
#: views/row.php:85
|
178 |
+
msgid "View"
|
179 |
+
msgstr ""
|
nestedpages.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: Nested Pages
|
4 |
+
Plugin URI: http://nestedpages.com
|
5 |
+
Description: Provides an intuitive drag and drop interface for managing pages in the Wordpress admin, while maintaining quick edit functionality.
|
6 |
+
Version: 1.0
|
7 |
+
Author: Kyle Phillips
|
8 |
+
Author URI: https://github.com/kylephillips
|
9 |
+
License: GPLv2 or later.
|
10 |
+
Copyright: Kyle Phillips
|
11 |
+
*/
|
12 |
+
|
13 |
+
/* Copyright 2014 Kyle Phillips (email : support@nestedpages.com)
|
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 |
+
if( !class_exists('NestedPages') ) :
|
30 |
+
require_once('includes/class-nestedpages.php');
|
31 |
+
$nested_pages = new NestedPages;
|
32 |
+
endif;
|
readme.txt
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Nested Pages ===
|
2 |
+
Contributors: kylephillips
|
3 |
+
Donate link: http://nestedpages.com/
|
4 |
+
Tags: pages, admin, nested, tree view, page tree, sort, quick edit
|
5 |
+
Requires at least: 3.8
|
6 |
+
Tested up to: 4.0
|
7 |
+
Stable tag: trunk
|
8 |
+
License: GPLv2 or later
|
9 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
+
|
11 |
+
Nested Pages provides an intuitive drag and drop interface for managing pages in the Wordpress admin, while maintaining quick edit functionality.
|
12 |
+
|
13 |
+
== Description ==
|
14 |
+
|
15 |
+
**Nested Pages offers**
|
16 |
+
|
17 |
+
* A drag and drop interface for managing your pages - simple and intuitive
|
18 |
+
* Quick edit functionality
|
19 |
+
* An expandable, sortable tree view of your site's page structure
|
20 |
+
* A native Wordpress menu, automatically generated to match your Nested Pages screen
|
21 |
+
* A touch-friendly interface
|
22 |
+
|
23 |
+
For more information visit [nestedpages.com](http://nestedpages.com).
|
24 |
+
|
25 |
+
**Nested Pages requires Wordpress version 3.8 or higher, and PHP version 5.4 or higher.**
|
26 |
+
|
27 |
+
== Installation ==
|
28 |
+
|
29 |
+
1. Upload wp-nested-pages to the wp-content/plugins/ directory
|
30 |
+
2. Activate the plugin through the Plugins menu in WordPress
|
31 |
+
3. Click on the Pages Menu item to begin ordering pages. Nested Pages replaces the default Page management screen.
|
32 |
+
4. To access the default the pages screen, select Default Pages located in the Pages submenu, or on the Nested Pages screen
|
33 |
+
|
34 |
+
== Frequently Asked Questions ==
|
35 |
+
|
36 |
+
= Can I use Nested Pages with other post types? =
|
37 |
+
Nested Pages is currently limited to the WordPress “Page” post type.
|
38 |
+
|
39 |
+
= How do I access the WordPress “Pages” screen? =
|
40 |
+
Click the “Default Pages” link in the page subnav, or on the Nested Pages screen.
|
41 |
+
|
42 |
+
= How do I save the order I create? =
|
43 |
+
Page sorting and nesting is saved in the background after changes are made to the structure.
|
44 |
+
|
45 |
+
= How do I edit in bulk? =
|
46 |
+
Bulk quick edits are not currently supported by Nested Pages. To edit in bulk, click on “Default Pages” to use the native interface.
|
47 |
+
|
48 |
+
= What about custom columns? =
|
49 |
+
Custom columns are not currently supported by Nested Pages. To view custom columns, click on “Default Pages” to view the native interface. If you are using WordPress SEO by Yoast, a page analysis indicator is shown.
|
50 |
+
|
51 |
+
= What are those dots in my page rows? =
|
52 |
+
If you have Wordpress SEO by Yoast installed, your page score indicators are shown along with the pages.
|
53 |
+
|
54 |
+
= Does quick edit support taxonomies? =
|
55 |
+
Hierarchical taxonomies are currently supported
|
56 |
+
|
57 |
+
== Screenshots ==
|
58 |
+
|
59 |
+
1. Expandable tree view of your page structure
|
60 |
+
|
61 |
+
2. Retains most quick edit functionality
|
62 |
+
|
63 |
+
3. Sortable page nesting updates in real time
|
64 |
+
|
65 |
+
4. Toggle nested child pages for a clutter-free tree
|
66 |
+
|
67 |
+
== Changelog ==
|
68 |
+
|
69 |
+
= 1.0 =
|
70 |
+
* Nested Pages
|
71 |
+
|
72 |
+
== More Information ==
|
73 |
+
|
74 |
+
= Generated Menu =
|
75 |
+
The generated menu is available for use with the name "nestedpages".
|
76 |
+
|
77 |
+
|
78 |
+
= Toggling the Page Tree =
|
79 |
+
|
80 |
+
To toggle the child pages in and out of view, click the arrow to the left of a parent page. To quickly expand and collapse all pages, click the button in the upper right corner of the Nested Pages Screen.
|
81 |
+
|
82 |
+
|
83 |
+
= Theme Use =
|
84 |
+
|
85 |
+
To order by nested pages ordering in your theme, use the `menu_order` order option in your queries.
|
86 |
+
|
87 |
+
Additionally, the generated menu is available for use, with the name `nestedpages`.
|
88 |
+
|
89 |
+
|
90 |
+
= Hiding Pages from the Tree View =
|
91 |
+
|
92 |
+
To hide a page from the tree view, open the quick edit form, select the option to “Hide in Nested Pages” and click Update to save the change.
|
93 |
+
|
94 |
+
To toggle the page back into view, click the “Show Hidden Pages” link at the top of the screen. The hidden pages are now visible, and can be re-edited to be shown.
|
95 |
+
|
96 |
+
|
97 |
+
= Sorting Pages =
|
98 |
+
|
99 |
+
To sort pages, hover over the page row. A menu icon (three lines) will appear. Click (or tap) this icon and drag to reorder within the menu. To drag a page underneath another, drag the page to the right and underneath the target parent. Visual indication is provided with an indentation. The drag and drop functionality works similarly to WordPress menus.
|
100 |
+
|
101 |
+
= Menu Sync =
|
102 |
+
|
103 |
+
After installing Nested Pages, a new menu will be available with the name `nestedpages`. By default, menu syncing is enabled. To disable the sync, uncheck “Sync Menu” at the top of the Nested Pages screen. Recheck the box to enable it again and to run the sync.
|
104 |
+
|
105 |
+
**Saving Performance:** If your site has a very large number of pages, disabling page sync may help speed up the save time when using Nested Pages.
|
106 |
+
|
107 |
+
**Editing the generated menu:** Any manual changes made to the menu outside of the Nested Pages interface will be overwritten after the synchronization runs.
|
108 |
+
|
109 |
+
**Hiding Pages in the Menu:** To hide a page from the nestedpages menu, click “Quick Edit” on it’s row, select “Hide in Nav Menu”, and click “update”. If menu sync is disabled, enable it now to sync the setting. Hidden pages are marked “(Hidden)”. If a page with child pages is hidden from the menu, all of it’s child pages will also be hidden.
|
views/pages.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="wrap">
|
2 |
+
|
3 |
+
<h2>
|
4 |
+
<?php echo $this->post_type->labels->name; ?>
|
5 |
+
<a href="<?php echo $this->addNewPageLink(); ?>" class="add-new-h2"><?php echo $this->post_type->labels->add_new; ?></a>
|
6 |
+
</h2>
|
7 |
+
|
8 |
+
<ul class="nestedpages-toggleall">
|
9 |
+
<li><a href="#" class="np-btn" data-toggle="closed"><?php _e('Expand Pages'); ?></a></li>
|
10 |
+
</ul>
|
11 |
+
|
12 |
+
<?php if ( current_user_can('edit_theme_options') ) : ?>
|
13 |
+
<div class="np-sync-menu-cont">
|
14 |
+
<label>
|
15 |
+
<input type="checkbox" name="np_sync_menu" class="np-sync-menu" value="sync" <?php if ( get_option('nestedpages_menusync') == 'sync' ) echo 'checked'; ?>/> <?php _e('Sync Menu'); ?>
|
16 |
+
</label>
|
17 |
+
</div>
|
18 |
+
<?php endif; ?>
|
19 |
+
|
20 |
+
<img src="<?php echo plugins_url(); ?>/wp-nested-pages/assets/images/loading.gif" alt="loading" id="nested-loading" />
|
21 |
+
|
22 |
+
<ul class="subsubsub">
|
23 |
+
<li><a href="#all" class="np-toggle-publish active"><?php _e('All'); ?></a> | </li>
|
24 |
+
<li><a href="#published" class="np-toggle-publish"><?php _e('Published'); ?></a> | </li>
|
25 |
+
<li><a href="#show" class="np-toggle-hidden"><?php _e('Show Hidden Pages'); ?></a> | </li>
|
26 |
+
<li><a href="<?php echo $this->defaultPagesLink(); ?>"><?php _e('Default'); ?> <?php echo $this->post_type->labels->name; ?></a></li>
|
27 |
+
</ul>
|
28 |
+
|
29 |
+
<div id="np-error" class="updated error" style="clear:both;display:none;"></div>
|
30 |
+
|
31 |
+
<div class="nestedpages">
|
32 |
+
<?php $this->loopPages(); ?>
|
33 |
+
|
34 |
+
<div class="quick-edit quick-edit-form" style="display:none;">
|
35 |
+
<?php include('quickedit.php'); ?>
|
36 |
+
</div>
|
37 |
+
</div>
|
38 |
+
|
39 |
+
</div><!-- .wrap -->
|
views/quickedit.php
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* See public inline_edit method of WP_Posts_List_Table class
|
4 |
+
*/
|
5 |
+
$post_type_object = get_post_type_object( 'page' );
|
6 |
+
$can_publish = current_user_can( $post_type_object->cap->publish_posts );
|
7 |
+
?>
|
8 |
+
|
9 |
+
<form method="get" action="">
|
10 |
+
<div class="form-interior">
|
11 |
+
<h3><?php _e('Quick Edit', 'nestedpages'); ?></h3>
|
12 |
+
|
13 |
+
<div class="np-quickedit-error" style="clear:both;display:none;"></div>
|
14 |
+
|
15 |
+
<div class="fields">
|
16 |
+
|
17 |
+
<div class="left">
|
18 |
+
|
19 |
+
<div class="form-control">
|
20 |
+
<label><?php _e( 'Title' ); ?></label>
|
21 |
+
<input type="text" name="post_title" class="np_title" value="" />
|
22 |
+
</div>
|
23 |
+
<div class="form-control">
|
24 |
+
<label><?php _e( 'Slug' ); ?></label>
|
25 |
+
<input type="text" name="post_name" class="np_slug" value="" />
|
26 |
+
</div>
|
27 |
+
<div>
|
28 |
+
<label><?php _e( 'Date' ); ?></label>
|
29 |
+
<div class="dates"><?php touch_time( 1, 1, 0, 1 ); ?></div>
|
30 |
+
</div>
|
31 |
+
|
32 |
+
<?php
|
33 |
+
$authors_dropdown = '';
|
34 |
+
if ( is_super_admin() || current_user_can( $post_type_object->cap->edit_others_posts ) ) :
|
35 |
+
$users_opt = array(
|
36 |
+
'hide_if_only_one_author' => false,
|
37 |
+
'who' => 'authors',
|
38 |
+
'name' => 'post_author',
|
39 |
+
'id' => 'post_author',
|
40 |
+
'class'=> 'authors',
|
41 |
+
'multi' => 1,
|
42 |
+
'echo' => 0
|
43 |
+
);
|
44 |
+
|
45 |
+
if ( $authors = wp_dropdown_users( $users_opt ) ) :
|
46 |
+
$authors_dropdown = '<div class="form-control np_author"><label>' . __( 'Author' ) . '</label>';
|
47 |
+
$authors_dropdown .= $authors;
|
48 |
+
$authors_dropdown .= '</div>';
|
49 |
+
endif;
|
50 |
+
echo $authors_dropdown;
|
51 |
+
endif;
|
52 |
+
?>
|
53 |
+
|
54 |
+
<div class="form-control">
|
55 |
+
<label><?php _e( 'Status' ); ?></label>
|
56 |
+
<select name="_status" class="np_status">
|
57 |
+
<?php if ( $can_publish ) : ?>
|
58 |
+
<option value="publish"><?php _e( 'Published' ); ?></option>
|
59 |
+
<option value="future"><?php _e( 'Scheduled' ); ?></option>
|
60 |
+
<?php endif; ?>
|
61 |
+
<option value="pending"><?php _e( 'Pending Review' ); ?></option>
|
62 |
+
<option value="draft"><?php _e( 'Draft' ); ?></option>
|
63 |
+
</select>
|
64 |
+
</div>
|
65 |
+
|
66 |
+
</div><!-- .left -->
|
67 |
+
|
68 |
+
<div class="right">
|
69 |
+
<div class="form-control">
|
70 |
+
<label><?php _e( 'Template' ); ?></label>
|
71 |
+
<select name="page_template" class="np_template">
|
72 |
+
<option value="default"><?php _e( 'Default Template' ); ?></option>
|
73 |
+
<?php page_template_dropdown() ?>
|
74 |
+
</select>
|
75 |
+
</div>
|
76 |
+
<div class="comments">
|
77 |
+
<label>
|
78 |
+
<input type="checkbox" name="comment_status" class="np_cs" value="open" />
|
79 |
+
<span class="checkbox-title"><?php _e( 'Allow Comments' ); ?></span>
|
80 |
+
</label>
|
81 |
+
</div>
|
82 |
+
<?php if ( current_user_can('edit_theme_options') ) : ?>
|
83 |
+
<div class="form-control">
|
84 |
+
<label><?php _e( 'Menu Title' ); ?></label>
|
85 |
+
<input type="text" name="np_nav_title" class="np_nav_title" value="" />
|
86 |
+
</div>
|
87 |
+
<div class="comments">
|
88 |
+
<label>
|
89 |
+
<input type="checkbox" name="nav_status" class="np_nav_status" value="hide" />
|
90 |
+
<span class="checkbox-title"><?php _e( 'Hide in Nav Menu' ); ?></span>
|
91 |
+
</label>
|
92 |
+
</div>
|
93 |
+
<div class="comments">
|
94 |
+
<label>
|
95 |
+
<input type="checkbox" name="nested_pages_status" class="np_status" value="hide" />
|
96 |
+
<span class="checkbox-title"><?php _e( 'Hide in Nested Pages' ); ?></span>
|
97 |
+
</label>
|
98 |
+
</div>
|
99 |
+
<?php endif; // Edit theme options?>
|
100 |
+
|
101 |
+
<?php if ( !empty($this->h_taxonomies) ) : ?>
|
102 |
+
<div class="form-control">
|
103 |
+
<a href="#" class="np-btn np-toggle-taxonomies"><?php _e('Edit Taxonomies'); ?></a>
|
104 |
+
</div>
|
105 |
+
<?php endif; ?>
|
106 |
+
|
107 |
+
</div><!-- .right -->
|
108 |
+
|
109 |
+
<?php if ( !empty($this->h_taxonomies) ) : ?>
|
110 |
+
<div class="np-taxonomies">
|
111 |
+
<?php foreach ( $this->h_taxonomies as $taxonomy ) : ?>
|
112 |
+
<div class="np-taxonomy">
|
113 |
+
<span class="title"><?php echo esc_html( $taxonomy->labels->name ) ?></span>
|
114 |
+
<input type="hidden" name="<?php echo ( $taxonomy->name == 'category' ) ? 'post_category[]' : 'tax_input[' . esc_attr( $taxonomy->name ) . '][]'; ?>" value="0" />
|
115 |
+
<ul class="cat-checklist <?php echo esc_attr( $taxonomy->name )?>-checklist">
|
116 |
+
<?php wp_terms_checklist( null, array( 'taxonomy' => $taxonomy->name ) ) ?>
|
117 |
+
</ul>
|
118 |
+
</div><!-- .np-taxonomy -->
|
119 |
+
<?php endforeach; ?>
|
120 |
+
</div><!-- .taxonomies -->
|
121 |
+
<?php endif; // if taxonomies ?>
|
122 |
+
|
123 |
+
</div><!-- .fields -->
|
124 |
+
|
125 |
+
</div><!-- .form-interior -->
|
126 |
+
|
127 |
+
<div class="buttons">
|
128 |
+
<input type="hidden" name="post_id" class="np_id" value="<?php echo get_the_id(); ?>">
|
129 |
+
<a accesskey="c" href="#inline-edit" class="button-secondary alignleft np-cancel-quickedit">
|
130 |
+
<?php _e( 'Cancel' ); ?>
|
131 |
+
</a>
|
132 |
+
<a accesskey="s" href="#inline-edit" class="button-primary np-save-quickedit alignright">
|
133 |
+
<?php _e( 'Update' ); ?>
|
134 |
+
</a>
|
135 |
+
<span class="np-qe-loading"></span>
|
136 |
+
</div>
|
137 |
+
</form>
|
views/row.php
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Row represents a single page
|
4 |
+
*/
|
5 |
+
?>
|
6 |
+
<div class="row">
|
7 |
+
<div class="child-toggle"></div>
|
8 |
+
<div class="row-inner">
|
9 |
+
<i class="np-icon-sub-menu"></i>
|
10 |
+
<?php if ( current_user_can('edit_theme_options') ) : ?>
|
11 |
+
<i class="handle np-icon-menu"></i>
|
12 |
+
<?php endif; ?>
|
13 |
+
<a href="<?php echo get_edit_post_link(); ?>" class="page-link page-title">
|
14 |
+
<span class="title"><?php the_title(); ?></span>
|
15 |
+
<?php
|
16 |
+
|
17 |
+
if ( function_exists('wpseo_translate_score') ){
|
18 |
+
echo '<span class="np-seo-indicator ' . $score . '"></span>';
|
19 |
+
}
|
20 |
+
|
21 |
+
// Post Status
|
22 |
+
if ( $post->post_status !== 'publish' ){
|
23 |
+
echo '<span class="status">(' . $post->post_status . ')</span>';
|
24 |
+
} else {
|
25 |
+
echo '<span class="status"></span>';
|
26 |
+
}
|
27 |
+
|
28 |
+
// Nested Pages Status
|
29 |
+
if ( $np_status == 'hide' )
|
30 |
+
echo '<i class="np-icon-eye-blocked"></i>';
|
31 |
+
|
32 |
+
// Nav Status
|
33 |
+
if ( $nav_status == 'hide' ){
|
34 |
+
echo '<span class="nav-status">(Hidden)</span>';
|
35 |
+
} else {
|
36 |
+
echo '<span class="nav-status"></span>';
|
37 |
+
}
|
38 |
+
|
39 |
+
// Post Lock
|
40 |
+
if ( $user = wp_check_post_lock(get_the_id()) ){
|
41 |
+
$u = get_userdata($user);
|
42 |
+
echo '<span class="locked"><i class="np-icon-lock"></i><em> ' . $u->display_name . ' ' . __('currently editing', 'nestedpages') . '</em></span>';
|
43 |
+
} else {
|
44 |
+
echo '<span class="edit-indicator"><i class="np-icon-pencil"></i>' . __('Edit', 'nestedpages') . '</span>';
|
45 |
+
}
|
46 |
+
?>
|
47 |
+
</a>
|
48 |
+
|
49 |
+
<a href="#" class="np-toggle-edit"><i class="np-icon-pencil"></i></a>
|
50 |
+
|
51 |
+
<div class="action-buttons">
|
52 |
+
|
53 |
+
<?php if ( $post->comment_status == 'open' ) : $comments = wp_count_comments(get_the_id()); $cs = 'open' ?>
|
54 |
+
|
55 |
+
<a href="<?php echo admin_url( 'edit-comments.php?p=' . get_the_id() ); ?>" class="np-btn">
|
56 |
+
<i class="np-icon-bubble"></i> <?php echo $comments->total_comments; ?>
|
57 |
+
</a>
|
58 |
+
|
59 |
+
<?php else : $cs = 'closed'; endif; ?>
|
60 |
+
|
61 |
+
<a href="<?php echo $this->addNewPageLink(); ?>&npparent=<?php echo get_the_id(); ?>" class="np-btn"><?php _e('Add Child', 'nestedpages'); ?></a>
|
62 |
+
|
63 |
+
<?php if ( !$user = wp_check_post_lock(get_the_id()) ) : ?>
|
64 |
+
<a href="#"
|
65 |
+
class="np-btn np-quick-edit"
|
66 |
+
data-id="<?php echo get_the_id(); ?>"
|
67 |
+
data-template="<?php echo $template; ?>"
|
68 |
+
data-title="<?php the_title(); ?>"
|
69 |
+
data-slug="<?php echo $post->post_name; ?>"
|
70 |
+
data-commentstatus="<?php echo $cs; ?>"
|
71 |
+
data-status="<?php echo get_post_status(); ?>"
|
72 |
+
data-np-status="<?php echo $np_status; ?>"
|
73 |
+
data-navstatus="<?php echo $nav_status; ?>"
|
74 |
+
data-navtitle="<?php echo $nav_title; ?>"
|
75 |
+
data-author="<?php echo $post->post_author; ?>"
|
76 |
+
data-month="<?php echo $month; ?>"
|
77 |
+
data-day="<?php echo $d; ?>"
|
78 |
+
data-year="<?php echo $y; ?>"
|
79 |
+
data-hour="<?php echo $h; ?>"
|
80 |
+
data-minute="<?php echo $m; ?>">
|
81 |
+
<?php _e('Quick Edit', 'nestedpages'); ?>
|
82 |
+
</a>
|
83 |
+
<?php endif; ?>
|
84 |
+
|
85 |
+
<a href="<?php echo get_the_permalink(); ?>" class="np-btn"><?php _e('View', 'nestedpages'); ?></a>
|
86 |
+
<!--
|
87 |
+
<a href="#" class="np-btn np-btn-trash">
|
88 |
+
<i class="np-icon-remove"></i>
|
89 |
+
</a> -->
|
90 |
+
</div><!-- .action-buttons -->
|
91 |
+
</div><!-- .row-inner -->
|
92 |
+
</div><!-- .row -->
|