Version Description
- Feature: Import recipe from text
- Feature: Add nofollow links in summary and instructions
- Feature: Import recipes from Meal Planner Pro
- Feature: Import recipes from BigOven
- Improvement: Setting to disable comment ratings
- Improvement: Recognize unicode fractions when importing ingredients
- Improvement: Import nutrition facts from WP Ultimate Recipe
- Fix: Only show nutritional metadata if present
- Fix: Consistent behaviour for automatic time calculations
Download this release
Release Info
Developer | BrechtVds |
Plugin | WP Recipe Maker |
Version | 1.7.0 |
Comparing to | |
See all releases |
Code changes from version 1.6.0 to 1.7.0
- assets/css/admin/modal.min.css +1 -1
- assets/css/admin/modal.scss +1 -0
- assets/css/admin/modal/_container.scss +15 -0
- assets/css/admin/modal/_form.scss +2 -1
- assets/css/admin/modal/_import-text.scss +36 -0
- assets/css/public/_template_reset.scss +10 -0
- assets/css/public/public.min.css +1 -1
- assets/css/public/public.scss +1 -0
- assets/js/admin/import-text.js +249 -0
- assets/js/admin/modal.js +2 -0
- assets/js/admin/recipe-form.js +66 -37
- assets/js/admin/rich-editor.js +579 -4
- includes/admin/class-wprm-recipe-parser.php +63 -3
- includes/admin/import/class-wprm-import-bigoven.php +291 -0
- includes/admin/import/class-wprm-import-mealplannerpro.php +396 -0
- includes/admin/import/class-wprm-import-wpultimaterecipe.php +25 -1
- includes/admin/modal/class-wprm-modal.php +11 -0
- includes/class-wp-recipe-maker.php +9 -3
- includes/public/class-wprm-fallback-recipe.php +33 -0
- includes/public/class-wprm-metadata.php +1 -1
- includes/public/class-wprm-print.php +3 -0
- includes/public/class-wprm-settings.php +50 -11
- includes/public/class-wprm-shortcode.php +35 -1
- includes/public/class-wprm-template-manager.php +62 -16
- readme.txt +22 -0
- templates/admin/menu/addons.php +4 -0
- templates/admin/menu/faq/whats_new.php +13 -0
- templates/admin/modal/modal.php +3 -0
- templates/admin/modal/tabs/import-text.php +74 -0
- templates/admin/modal/tabs/recipe-details.php +16 -5
- templates/admin/modal/tabs/recipe-ingredients-instructions.php +4 -0
- templates/admin/settings.php +1 -0
- templates/admin/settings/features.php +68 -0
- templates/recipe/clean-print-with-image/clean-print-with-image.min.css +1 -1
- templates/recipe/clean-print-with-image/clean-print-with-image.scss +1 -0
- templates/recipe/clean-print/clean-print.min.css +1 -1
- templates/recipe/clean-print/clean-print.scss +1 -0
- templates/recipe/simple/simple.min.css +1 -1
- templates/recipe/simple/simple.scss +1 -0
- vendor/texthighlighter/TextHighlighter.min.js +40 -0
- wp-recipe-maker.php +1 -1
assets/css/admin/modal.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.wprm-frame-title .dashicons,.wprm-frame.hide-router .wprm-frame-router,.wprm-modal-container{display:none}.select2_wprm-container{z-index:100075}.select2_wprm-container.select2_wprm-container--focus .select2_wprm-selection{border-color:#5b9dd9}.select2_wprm-container li{margin:0}.select2_wprm-container .select2_wprm-selection{border-color:#ddd}.medium-editor-toolbar{z-index:100080}.medium-editor-element{border:1px solid #ddd;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.07);box-shadow:inset 0 1px 2px rgba(0,0,0,.07);min-height:68px;padding:3px 5px}.medium-editor-element:focus{border-color:#5b9dd9;-webkit-box-shadow:0 0 2px rgba(30,140,190,.8);box-shadow:0 0 2px rgba(30,140,190,.8)}.medium-editor-element:after{font-style:normal;color:#999;opacity:.5;font-size:14px;line-height:28px}.medium-editor-element p:first-child{margin-top:0}.medium-editor-element p:last-child{margin-bottom:0}.wprm-modal-hint{max-width:400px;margin-bottom:20px}.wprm-modal-hint .wprm-modal-hint-header{font-weight:700;font-variant:small-caps}.wprm-modal-hint .wprm-modal-hint-text{font-style:italic}.wprm-modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;min-height:360px;background:#000;opacity:.7;z-index:100000}.wprm-modal{position:fixed;top:30px;left:30px;right:30px;bottom:30px;z-index:100050}.wprm-modal *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.wprm-modal-close{position:absolute;top:0;right:0;width:50px;height:50px;padding:0;z-index:1000;-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out}.wprm-modal-close .wprm-modal-icon:before{content:"\f158";font:400 20px/1 dashicons;speak:none;vertical-align:middle;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#666}.wprm-modal-content{position:absolute;top:0;left:0;right:0;bottom:0;overflow:auto;min-height:300px;-webkit-box-shadow:0 5px 15px rgba(0,0,0,.7);box-shadow:0 5px 15px rgba(0,0,0,.7);background:#fcfcfc;-webkit-font-smoothing:subpixel-antialiased}.wprm-modal-content ::-webkit-input-placeholder{color:#999;opacity:.5}.wprm-modal-content :-moz-placeholder{color:#999;opacity:.5}.wprm-modal-content ::-moz-placeholder{color:#999;opacity:.5}.wprm-modal-content :-ms-input-placeholder{color:#999;opacity:.5}.wprm-frame{overflow:hidden;right:0}.wprm-frame,.wprm-frame-menu{position:absolute;left:0;bottom:0;top:0}.wprm-frame-menu{width:200px;z-index:150}.wprm-frame-title{top:0;height:50px}.wprm-frame-router,.wprm-frame-title{z-index:200;left:200px;position:absolute;right:0}.wprm-menu-item{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.wprm-menu{position:absolute;left:0;margin:0;padding:10px 0;border-right-width:1px;border-right-style:solid;border-right-color:#ccc;user-select:none}.wprm-menu,.wprm-sidebar{top:0;bottom:0;background:#f3f3f3;right:0}.wprm-menu .active,.wprm-menu .active:hover{color:#23282d;font-weight:700}.wprm-menu>a{display:block;position:relative;padding:8px 20px;margin:0;color:#0073aa}.wprm-frame .hidden,.wprm-frame-content-tab:not(.active),.wprm-router:not(.active){display:none}.wprm-menu>a,.wprm-router>a{line-height:18px;font-size:14px;text-decoration:none}.wprm-frame a{border-bottom:none;color:#0073aa}.wprm-menu .separator{height:0;margin:12px 20px;padding:0;border-top:1px solid #ddd}.wprm-frame-title h1{padding:0 16px;font-size:22px;line-height:50px;margin:0}.wprm-frame-router{top:50px;height:36px}.wprm-router{position:relative;padding:0 6px;margin:0;clear:both;user-select:none}.wprm-router>a{position:relative;float:left;padding:8px 10px 9px;margin:0;height:18px}.wprm-router a{-webkit-transition:none;transition:none}.wprm-router>a:last-child{border-right:0}.wprm-router .active,.wprm-router>a.active:last-child{margin:-1px -1px 0;background:#fff;border:1px solid #ddd;border-bottom:none}.wprm-router .active,.wprm-router .active:hover{color:#32373c}.wprm-frame-content{position:absolute;top:84px;left:200px;right:0;bottom:61px;height:auto;width:auto;margin:0;overflow:auto;background:#fff;border-top:1px solid #ddd;border-bottom:1px solid #ddd}.wprm-frame-toolbar,.wprm-toolbar{position:absolute;right:0;z-index:100;height:60px}.wprm-frame-content-tab{margin:20px}.wprm-frame-toolbar{left:200px;bottom:0}.wprm-toolbar{top:0;left:0;padding:0 16px;border:0 solid #ddd;overflow:hidden}.wprm-modal-content .wprm-toolbar-primary.search-form{width:33%}.wprm-toolbar-primary{float:right;height:100%}.wprm-modal-content .wprm-toolbar-primary .wprm-button{float:right}.wprm-toolbar-primary>.wprm-button,.wprm-toolbar-primary>.wprm-button-group{margin-left:10px;float:left;margin-top:15px}@media only screen and (max-width:900px){.wprm-frame:not(.hide-menu) .wprm-frame-title .dashicons{display:inline-block;line-height:50px}.wprm-frame:not(.hide-menu) .wprm-frame-menu{position:static;width:0}.wprm-frame:not(.hide-menu) .wprm-frame-content,.wprm-frame:not(.hide-menu) .wprm-frame-router,.wprm-frame:not(.hide-menu) .wprm-frame-title,.wprm-frame:not(.hide-menu) .wprm-frame-toolbar,.wprm-frame:not(.hide-menu) .wprm-menu.visible{left:0}.wprm-frame:not(.hide-menu) .wprm-menu{width:auto;max-width:80%;overflow:auto;z-index:2000;top:50px;left:-300px;right:auto;bottom:auto;padding:5px 0;border:1px solid #ccc}.wprm-frame:not(.hide-menu) .wprm-menu>a.active{display:none}.wprm-frame:not(.hide-menu) .wprm-menu>a{padding:12px 16px;font-size:16px}.wprm-frame:not(.hide-menu) .wprm-menu .separator{margin:5px 10px}.wprm-frame:not(.hide-menu) .wprm-frame-title h1{color:#0073aa;line-height:3;font-size:18px;float:left;cursor:pointer}}@media only screen and (max-width:640px),screen and (max-height:400px){.wprm-modal{position:fixed;top:0;left:0;right:0;bottom:0}.wprm-modal .wprm-frame-title{height:40px}}@media only screen and (max-width:480px){.wprm-frame:not(.hide-menu) .wprm-frame-title .dashicons{line-height:40px}.wprm-frame-router,.wprm-frame:not(.hide-menu) .wprm-menu{top:40px}.wprm-frame:not(.hide-menu) .wprm-frame-title h1,.wprm-modal .wprm-frame-title h1{font-size:18px;line-height:40px}.wprm-frame-content{top:74px}}.wprm-recipe-form{max-width:600px}.wprm-recipe-form .wprm-recipe-form-container{margin-bottom:15px;vertical-align:top}.wprm-recipe-form .wprm-recipe-form-container-halfs{display:inline-block;width:50%}.wprm-recipe-form .wprm-recipe-form-container-thirds{display:inline-block;width:33.3%}.wprm-recipe-form label{display:block;font-weight:700;margin-bottom:5px}.wprm-recipe-form input{margin:0;width:100%;max-width:120px;height:34px;line-height:34px}.wprm-recipe-form input[type=number]{max-width:50px}.wprm-recipe-form input.select2_wprm-search__field{height:18px;line-height:18px}.wprm-recipe-form select{width:100%}.wprm-recipe-form textarea{width:100%;resize:vertical}.wprm-recipe-details-form input#wprm-recipe-name{max-width:450px}.wprm-recipe-details-form input#wprm-recipe-author-name{max-width:none}.wprm-recipe-details-form input#wprm-recipe-calories{max-width:70px}.wprm-recipe-details-form .wprm-recipe-image-preview{float:right;max-width:100px}.wprm-recipe-details-form .wprm-recipe-image-preview img{max-width:100%;height:auto}.wprm-recipe-details-form .wprm-recipe-summary-container{clear:both}@media only screen and (max-width:480px){.wprm-recipe-form .wprm-recipe-form-container-halfs,.wprm-recipe-form .wprm-recipe-form-container-thirds{display:block;width:100%}.wprm-recipe-details-form .wprm-recipe-image-preview{float:none;margin:10px auto}}.wprm-recipe-ingredients-form,.wprm-recipe-instructions-form{max-width:750px;margin-bottom:15px}.wprm-recipe-ingredients-form input,.wprm-recipe-instructions-form input{margin:0;width:100%;height:34px;line-height:34px}.wprm-recipe-ingredients-form textarea,.wprm-recipe-instructions-form textarea{width:100%;resize:vertical}.wprm-recipe-ingredients-form ::-webkit-input-placeholder,.wprm-recipe-instructions-form ::-webkit-input-placeholder{color:#999;opacity:.5}.wprm-recipe-ingredients-form :-moz-placeholder,.wprm-recipe-instructions-form :-moz-placeholder{color:#999;opacity:.5}.wprm-recipe-ingredients-form ::-moz-placeholder,.wprm-recipe-instructions-form ::-moz-placeholder{color:#999;opacity:.5}.wprm-recipe-ingredients-form :-ms-input-placeholder,.wprm-recipe-instructions-form :-ms-input-placeholder{color:#999;opacity:.5}.wprm-recipe-ingredients-form table,.wprm-recipe-instructions-form table{width:100%}.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th,.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th{text-align:left}.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th:nth-child(1),.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th:nth-child(6),.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th:nth-child(1),.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th:nth-child(6){width:5%;text-align:center}.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th:nth-child(2),.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th:nth-child(2){width:10%}.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th:nth-child(3),.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th:nth-child(3){width:15%}.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th:nth-child(4),.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th:nth-child(4){width:40%}.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th:nth-child(5),.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th:nth-child(5){width:25%}.wprm-recipe-ingredients-form table.wprm-recipe-instructions-container th,.wprm-recipe-instructions-form table.wprm-recipe-instructions-container th{text-align:left}.wprm-recipe-ingredients-form table.wprm-recipe-instructions-container th:nth-child(1),.wprm-recipe-ingredients-form table.wprm-recipe-instructions-container th:nth-child(4),.wprm-recipe-instructions-form table.wprm-recipe-instructions-container th:nth-child(1),.wprm-recipe-instructions-form table.wprm-recipe-instructions-container th:nth-child(4){width:5%;text-align:center}.wprm-recipe-ingredients-form table.wprm-recipe-instructions-container th:nth-child(2),.wprm-recipe-instructions-form table.wprm-recipe-instructions-container th:nth-child(2){width:65%}.wprm-recipe-ingredients-form table.wprm-recipe-instructions-container th:nth-child(3),.wprm-recipe-instructions-form table.wprm-recipe-instructions-container th:nth-child(3){width:25%}.wprm-recipe-ingredients-form table .wprm-recipe-ingredients-placeholder,.wprm-recipe-ingredients-form table .wprm-recipe-instructions-placeholder,.wprm-recipe-instructions-form table .wprm-recipe-ingredients-placeholder,.wprm-recipe-instructions-form table .wprm-recipe-instructions-placeholder{display:none}.wprm-recipe-ingredients-form table td,.wprm-recipe-instructions-form table td{text-align:left;vertical-align:top}.wprm-recipe-ingredients-form table td:first-child,.wprm-recipe-ingredients-form table td:last-child,.wprm-recipe-instructions-form table td:first-child,.wprm-recipe-instructions-form table td:last-child{text-align:center;vertical-align:middle}.wprm-recipe-ingredients-form .ui-sortable-helper,.wprm-recipe-instructions-form .ui-sortable-helper{display:table}.wprm-recipe-ingredients-form .ui-sortable-helper .wprm-recipe-instruction-text,.wprm-recipe-instructions-form .ui-sortable-helper .wprm-recipe-instruction-text{min-width:200px}.wprm-recipe-ingredients-form .wprm-recipe-ingredients-instructions-sort,.wprm-recipe-instructions-form .wprm-recipe-ingredients-instructions-sort{cursor:move}.wprm-recipe-ingredients-form .wprm-recipe-ingredients-instructions-delete,.wprm-recipe-instructions-form .wprm-recipe-ingredients-instructions-delete{cursor:pointer}.wprm-recipe-ingredients-form .wprm-recipe-ingredients-instructions-delete,.wprm-recipe-ingredients-form .wprm-recipe-ingredients-instructions-sort,.wprm-recipe-instructions-form .wprm-recipe-ingredients-instructions-delete,.wprm-recipe-instructions-form .wprm-recipe-ingredients-instructions-sort{color:#999;opacity:.5}.wprm-recipe-ingredients-form .wprm-recipe-ingredients-instructions-delete:hover,.wprm-recipe-ingredients-form .wprm-recipe-ingredients-instructions-sort:hover,.wprm-recipe-instructions-form .wprm-recipe-ingredients-instructions-delete:hover,.wprm-recipe-instructions-form .wprm-recipe-ingredients-instructions-sort:hover{color:#444;opacity:1}.wprm-recipe-ingredients-form .wprm-recipe-ingredients-actions,.wprm-recipe-ingredients-form .wprm-recipe-instructions-actions,.wprm-recipe-instructions-form .wprm-recipe-ingredients-actions,.wprm-recipe-instructions-form .wprm-recipe-instructions-actions{margin:10px}.wprm-recipe-ingredients-form .wprm-recipe-image-preview,.wprm-recipe-instructions-form .wprm-recipe-image-preview{max-width:75px}.wprm-recipe-ingredients-form .wprm-recipe-image-preview img,.wprm-recipe-instructions-form .wprm-recipe-image-preview img{max-width:100%;height:auto}.wprm-shortcode-builder .wprm-shortcode-builder-container{margin-bottom:15px;vertical-align:top}.wprm-shortcode-builder .wprm-shortcode-builder-container-halfs{display:inline-block;width:50%}.wprm-shortcode-builder .wprm-shortcode-builder-container-thirds{display:inline-block;width:33.3%}.wprm-shortcode-builder label{display:block;font-weight:700;margin-bottom:5px}.wprm-shortcode-builder .wprm-shortcode-builder-helper{margin-left:5px;font-size:.8em;font-style:italic}.wprm-shortcode-builder input{margin:0;width:100%;max-width:250px;height:34px;line-height:34px}.wprm-shortcode-builder input.select2_wprm-search__field{height:18px;line-height:18px}.wprm-shortcode-builder select{width:250px}
|
1 |
+
.wprm-frame-title .dashicons,.wprm-frame.hide-router .wprm-frame-router,.wprm-modal-container{display:none}.wprm-easyrecipe-warning{display:none;border:1px solid #8b0000;background-color:rgba(255,0,0,.15);padding:10px 10px 0;margin-bottom:10px}.select2_wprm-container{z-index:100075}.select2_wprm-container.select2_wprm-container--focus .select2_wprm-selection{border-color:#5b9dd9}.select2_wprm-container li{margin:0}.select2_wprm-container .select2_wprm-selection{border-color:#ddd}.medium-editor-toolbar{z-index:100080}.medium-editor-element{border:1px solid #ddd;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.07);box-shadow:inset 0 1px 2px rgba(0,0,0,.07);min-height:68px;padding:3px 5px}.medium-editor-element:focus{border-color:#5b9dd9;-webkit-box-shadow:0 0 2px rgba(30,140,190,.8);box-shadow:0 0 2px rgba(30,140,190,.8)}.medium-editor-element:after{font-style:normal;color:#999;opacity:.5;font-size:14px;line-height:28px}.medium-editor-element p:first-child{margin-top:0}.medium-editor-element p:last-child{margin-bottom:0}.wprm-modal-hint{max-width:400px;margin-bottom:20px}.wprm-modal-hint .wprm-modal-hint-header{font-weight:700;font-variant:small-caps}.wprm-modal-hint .wprm-modal-hint-text{font-style:italic}.wprm-modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;min-height:360px;background:#000;opacity:.7;z-index:100000}.wprm-modal{position:fixed;top:30px;left:30px;right:30px;bottom:30px;z-index:100050}.wprm-modal *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.wprm-modal-close{position:absolute;top:0;right:0;width:50px;height:50px;padding:0;z-index:1000;-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out}.wprm-modal-close .wprm-modal-icon:before{content:"\f158";font:400 20px/1 dashicons;speak:none;vertical-align:middle;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#666}.wprm-modal-content{position:absolute;top:0;left:0;right:0;bottom:0;overflow:auto;min-height:300px;-webkit-box-shadow:0 5px 15px rgba(0,0,0,.7);box-shadow:0 5px 15px rgba(0,0,0,.7);background:#fcfcfc;-webkit-font-smoothing:subpixel-antialiased}.wprm-modal-content ::-webkit-input-placeholder{color:#999;opacity:.5}.wprm-modal-content :-moz-placeholder{color:#999;opacity:.5}.wprm-modal-content ::-moz-placeholder{color:#999;opacity:.5}.wprm-modal-content :-ms-input-placeholder{color:#999;opacity:.5}.wprm-frame{overflow:hidden;right:0}.wprm-frame,.wprm-frame-menu{position:absolute;left:0;bottom:0;top:0}.wprm-frame-menu{width:200px;z-index:150}.wprm-frame-title{top:0;height:50px}.wprm-frame-router,.wprm-frame-title{z-index:200;left:200px;position:absolute;right:0}.wprm-menu-item{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.wprm-menu{position:absolute;left:0;margin:0;padding:10px 0;border-right-width:1px;border-right-style:solid;border-right-color:#ccc;user-select:none}.wprm-menu-hidden{padding:5px 5px 0 10px;font-style:italic}.wprm-menu,.wprm-sidebar{top:0;bottom:0;background:#f3f3f3;right:0}.wprm-menu .active,.wprm-menu .active:hover{color:#23282d;font-weight:700}.wprm-menu>a{display:block;position:relative;padding:8px 20px;margin:0;color:#0073aa}.wprm-frame .hidden,.wprm-frame-content-tab:not(.active),.wprm-router:not(.active){display:none}.wprm-menu>a,.wprm-router>a{line-height:18px;font-size:14px;text-decoration:none}.wprm-frame a{border-bottom:none;color:#0073aa}.wprm-menu .separator{height:0;margin:12px 20px;padding:0;border-top:1px solid #ddd}.wprm-frame-title h1{padding:0 16px;font-size:22px;line-height:50px;margin:0}.wprm-frame-router{top:50px;height:36px}.wprm-router{position:relative;padding:0 6px;margin:0;clear:both;user-select:none}.wprm-router>a{position:relative;float:left;padding:8px 10px 9px;margin:0;height:18px}.wprm-router a{-webkit-transition:none;transition:none}.wprm-router>a:last-child{border-right:0}.wprm-router .active,.wprm-router>a.active:last-child{margin:-1px -1px 0;background:#fff;border:1px solid #ddd;border-bottom:none}.wprm-router .active,.wprm-router .active:hover{color:#32373c}.wprm-frame-content{position:absolute;top:84px;left:200px;right:0;bottom:61px;height:auto;width:auto;margin:0;overflow:auto;background:#fff;border-top:1px solid #ddd;border-bottom:1px solid #ddd}.wprm-frame-toolbar,.wprm-toolbar{position:absolute;right:0;z-index:100;height:60px}.wprm-frame-content-tab{margin:20px}.wprm-frame-toolbar{left:200px;bottom:0}.wprm-toolbar{top:0;left:0;padding:0 16px;border:0 solid #ddd;overflow:hidden}.wprm-modal-content .wprm-toolbar-primary.search-form{width:33%}.wprm-toolbar-primary{float:right;height:100%}.wprm-modal-content .wprm-toolbar-primary .wprm-button{float:right}.wprm-toolbar-primary>.wprm-button,.wprm-toolbar-primary>.wprm-button-group{margin-left:10px;float:left;margin-top:15px}@media only screen and (max-width:900px){.wprm-frame:not(.hide-menu) .wprm-frame-title .dashicons{display:inline-block;line-height:50px}.wprm-frame:not(.hide-menu) .wprm-frame-menu{position:static;width:0}.wprm-frame:not(.hide-menu) .wprm-frame-content,.wprm-frame:not(.hide-menu) .wprm-frame-router,.wprm-frame:not(.hide-menu) .wprm-frame-title,.wprm-frame:not(.hide-menu) .wprm-frame-toolbar,.wprm-frame:not(.hide-menu) .wprm-menu.visible{left:0}.wprm-frame:not(.hide-menu) .wprm-menu{width:auto;max-width:80%;overflow:auto;z-index:2000;top:50px;left:-300px;right:auto;bottom:auto;padding:5px 0;border:1px solid #ccc}.wprm-frame:not(.hide-menu) .wprm-menu>a.active{display:none}.wprm-frame:not(.hide-menu) .wprm-menu>a{padding:12px 16px;font-size:16px}.wprm-frame:not(.hide-menu) .wprm-menu .separator{margin:5px 10px}.wprm-frame:not(.hide-menu) .wprm-frame-title h1{color:#0073aa;line-height:3;font-size:18px;float:left;cursor:pointer}}@media only screen and (max-width:640px),screen and (max-height:400px){.wprm-modal{position:fixed;top:0;left:0;right:0;bottom:0}.wprm-modal .wprm-frame-title{height:40px}}@media only screen and (max-width:480px){.wprm-frame:not(.hide-menu) .wprm-frame-title .dashicons{line-height:40px}.wprm-frame-router,.wprm-frame:not(.hide-menu) .wprm-menu{top:40px}.wprm-frame:not(.hide-menu) .wprm-frame-title h1,.wprm-modal .wprm-frame-title h1{font-size:18px;line-height:40px}.wprm-frame-content{top:74px}}.wprm-recipe-form{max-width:600px}.wprm-recipe-form .wprm-recipe-form-container{margin-bottom:15px;vertical-align:top}.wprm-recipe-form .wprm-recipe-form-container-halfs{display:inline-block;width:50%}.wprm-recipe-form .wprm-recipe-form-container-thirds{display:inline-block;width:33.3%}.wprm-recipe-form label{display:block;font-weight:700;margin-bottom:5px}.wprm-recipe-form input[type=text],.wprm-recipe-form input[type=number]{margin:0;width:100%;max-width:120px;height:34px;line-height:34px}.wprm-recipe-form input[type=text][type=number],.wprm-recipe-form input[type=number][type=number]{max-width:50px}.wprm-recipe-form input[type=text].select2_wprm-search__field,.wprm-recipe-form input[type=number].select2_wprm-search__field{height:18px;line-height:18px}.wprm-recipe-form select{width:100%}.wprm-recipe-form textarea{width:100%;resize:vertical}@media only screen and (max-width:480px){.wprm-recipe-form .wprm-recipe-form-container-halfs,.wprm-recipe-form .wprm-recipe-form-container-thirds{display:block;width:100%}}.wprm-recipe-import-text-form .import-text-buttons{margin-bottom:10px}.wprm-recipe-import-text-form .import-text-step{display:none}.wprm-recipe-import-text-form .import-text-step#import-text-step-input{display:block}.wprm-recipe-import-text-form #import-text-highlight-sandbox,.wprm-recipe-import-text-form .import-text-input{margin-top:10px}.wprm-recipe-import-text-form #import-text-ingredient-groups label,.wprm-recipe-import-text-form #import-text-instruction-groups label{display:inline;font-weight:400}.wprm-recipe-import-text-form #import-text-highlight-sandbox{display:none;max-height:400px;overflow:scroll;padding:10px;border:1px dashed #999}.wprm-recipe-details-form input#wprm-recipe-name{max-width:450px}.wprm-recipe-details-form input#wprm-recipe-author-name{max-width:none}.wprm-recipe-details-form input#wprm-recipe-calories{max-width:70px}.wprm-recipe-details-form .wprm-recipe-image-preview{float:right;max-width:100px}.wprm-recipe-details-form .wprm-recipe-image-preview img{max-width:100%;height:auto}.wprm-recipe-details-form .wprm-recipe-summary-container{clear:both}@media only screen and (max-width:480px){.wprm-recipe-details-form .wprm-recipe-image-preview{float:none;margin:10px auto}}.wprm-recipe-ingredients-form,.wprm-recipe-instructions-form{max-width:750px;margin-bottom:15px}.wprm-recipe-ingredients-form input,.wprm-recipe-instructions-form input{margin:0;width:100%;height:34px;line-height:34px}.wprm-recipe-ingredients-form textarea,.wprm-recipe-instructions-form textarea{width:100%;resize:vertical}.wprm-recipe-ingredients-form ::-webkit-input-placeholder,.wprm-recipe-instructions-form ::-webkit-input-placeholder{color:#999;opacity:.5}.wprm-recipe-ingredients-form :-moz-placeholder,.wprm-recipe-instructions-form :-moz-placeholder{color:#999;opacity:.5}.wprm-recipe-ingredients-form ::-moz-placeholder,.wprm-recipe-instructions-form ::-moz-placeholder{color:#999;opacity:.5}.wprm-recipe-ingredients-form :-ms-input-placeholder,.wprm-recipe-instructions-form :-ms-input-placeholder{color:#999;opacity:.5}.wprm-recipe-ingredients-form table,.wprm-recipe-instructions-form table{width:100%}.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th,.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th{text-align:left}.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th:nth-child(1),.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th:nth-child(6),.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th:nth-child(1),.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th:nth-child(6){width:5%;text-align:center}.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th:nth-child(2),.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th:nth-child(2){width:10%}.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th:nth-child(3),.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th:nth-child(3){width:15%}.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th:nth-child(4),.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th:nth-child(4){width:40%}.wprm-recipe-ingredients-form table.wprm-recipe-ingredients-container th:nth-child(5),.wprm-recipe-instructions-form table.wprm-recipe-ingredients-container th:nth-child(5){width:25%}.wprm-recipe-ingredients-form table.wprm-recipe-instructions-container th,.wprm-recipe-instructions-form table.wprm-recipe-instructions-container th{text-align:left}.wprm-recipe-ingredients-form table.wprm-recipe-instructions-container th:nth-child(1),.wprm-recipe-ingredients-form table.wprm-recipe-instructions-container th:nth-child(4),.wprm-recipe-instructions-form table.wprm-recipe-instructions-container th:nth-child(1),.wprm-recipe-instructions-form table.wprm-recipe-instructions-container th:nth-child(4){width:5%;text-align:center}.wprm-recipe-ingredients-form table.wprm-recipe-instructions-container th:nth-child(2),.wprm-recipe-instructions-form table.wprm-recipe-instructions-container th:nth-child(2){width:65%}.wprm-recipe-ingredients-form table.wprm-recipe-instructions-container th:nth-child(3),.wprm-recipe-instructions-form table.wprm-recipe-instructions-container th:nth-child(3){width:25%}.wprm-recipe-ingredients-form table .wprm-recipe-ingredients-placeholder,.wprm-recipe-ingredients-form table .wprm-recipe-instructions-placeholder,.wprm-recipe-instructions-form table .wprm-recipe-ingredients-placeholder,.wprm-recipe-instructions-form table .wprm-recipe-instructions-placeholder{display:none}.wprm-recipe-ingredients-form table td,.wprm-recipe-instructions-form table td{text-align:left;vertical-align:top}.wprm-recipe-ingredients-form table td:first-child,.wprm-recipe-ingredients-form table td:last-child,.wprm-recipe-instructions-form table td:first-child,.wprm-recipe-instructions-form table td:last-child{text-align:center;vertical-align:middle}.wprm-recipe-ingredients-form .ui-sortable-helper,.wprm-recipe-instructions-form .ui-sortable-helper{display:table}.wprm-recipe-ingredients-form .ui-sortable-helper .wprm-recipe-instruction-text,.wprm-recipe-instructions-form .ui-sortable-helper .wprm-recipe-instruction-text{min-width:200px}.wprm-recipe-ingredients-form .wprm-recipe-ingredients-instructions-sort,.wprm-recipe-instructions-form .wprm-recipe-ingredients-instructions-sort{cursor:move}.wprm-recipe-ingredients-form .wprm-recipe-ingredients-instructions-delete,.wprm-recipe-instructions-form .wprm-recipe-ingredients-instructions-delete{cursor:pointer}.wprm-recipe-ingredients-form .wprm-recipe-ingredients-instructions-delete,.wprm-recipe-ingredients-form .wprm-recipe-ingredients-instructions-sort,.wprm-recipe-instructions-form .wprm-recipe-ingredients-instructions-delete,.wprm-recipe-instructions-form .wprm-recipe-ingredients-instructions-sort{color:#999;opacity:.5}.wprm-recipe-ingredients-form .wprm-recipe-ingredients-instructions-delete:hover,.wprm-recipe-ingredients-form .wprm-recipe-ingredients-instructions-sort:hover,.wprm-recipe-instructions-form .wprm-recipe-ingredients-instructions-delete:hover,.wprm-recipe-instructions-form .wprm-recipe-ingredients-instructions-sort:hover{color:#444;opacity:1}.wprm-recipe-ingredients-form .wprm-recipe-ingredients-actions,.wprm-recipe-ingredients-form .wprm-recipe-instructions-actions,.wprm-recipe-instructions-form .wprm-recipe-ingredients-actions,.wprm-recipe-instructions-form .wprm-recipe-instructions-actions{margin:10px}.wprm-recipe-ingredients-form .wprm-recipe-image-preview,.wprm-recipe-instructions-form .wprm-recipe-image-preview{max-width:75px}.wprm-recipe-ingredients-form .wprm-recipe-image-preview img,.wprm-recipe-instructions-form .wprm-recipe-image-preview img{max-width:100%;height:auto}.wprm-shortcode-builder .wprm-shortcode-builder-container{margin-bottom:15px;vertical-align:top}.wprm-shortcode-builder .wprm-shortcode-builder-container-halfs{display:inline-block;width:50%}.wprm-shortcode-builder .wprm-shortcode-builder-container-thirds{display:inline-block;width:33.3%}.wprm-shortcode-builder label{display:block;font-weight:700;margin-bottom:5px}.wprm-shortcode-builder .wprm-shortcode-builder-helper{margin-left:5px;font-size:.8em;font-style:italic}.wprm-shortcode-builder input{margin:0;width:100%;max-width:250px;height:34px;line-height:34px}.wprm-shortcode-builder input.select2_wprm-search__field{height:18px;line-height:18px}.wprm-shortcode-builder select{width:250px}
|
assets/css/admin/modal.scss
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
@import "modal/container";
|
2 |
@import "modal/form";
|
|
|
3 |
@import "modal/recipe-details";
|
4 |
@import "modal/recipe-ingredients";
|
5 |
@import "modal/shortcode-builder";
|
1 |
@import "modal/container";
|
2 |
@import "modal/form";
|
3 |
+
@import "modal/import-text";
|
4 |
@import "modal/recipe-details";
|
5 |
@import "modal/recipe-ingredients";
|
6 |
@import "modal/shortcode-builder";
|
assets/css/admin/modal/_container.scss
CHANGED
@@ -1,5 +1,14 @@
|
|
1 |
// main: ../modal.scss
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
.select2_wprm-container {
|
4 |
z-index: 100075;
|
5 |
|
@@ -63,6 +72,7 @@
|
|
63 |
font-style: italic;
|
64 |
}
|
65 |
}
|
|
|
66 |
/* Media Modal Replication */
|
67 |
.wprm-modal-container {
|
68 |
display: none;
|
@@ -204,6 +214,11 @@
|
|
204 |
user-select: none;
|
205 |
}
|
206 |
|
|
|
|
|
|
|
|
|
|
|
207 |
.wprm-menu,
|
208 |
.wprm-sidebar {
|
209 |
top: 0;
|
1 |
// main: ../modal.scss
|
2 |
|
3 |
+
.wprm-easyrecipe-warning {
|
4 |
+
display: none;
|
5 |
+
border: 1px solid darkred;
|
6 |
+
background-color: rgba(255,0,0,0.15);
|
7 |
+
padding: 10px;
|
8 |
+
padding-bottom: 0;
|
9 |
+
margin-bottom: 10px;
|
10 |
+
}
|
11 |
+
|
12 |
.select2_wprm-container {
|
13 |
z-index: 100075;
|
14 |
|
72 |
font-style: italic;
|
73 |
}
|
74 |
}
|
75 |
+
|
76 |
/* Media Modal Replication */
|
77 |
.wprm-modal-container {
|
78 |
display: none;
|
214 |
user-select: none;
|
215 |
}
|
216 |
|
217 |
+
.wprm-menu-hidden {
|
218 |
+
padding: 5px 5px 0 10px;
|
219 |
+
font-style: italic;
|
220 |
+
}
|
221 |
+
|
222 |
.wprm-menu,
|
223 |
.wprm-sidebar {
|
224 |
top: 0;
|
assets/css/admin/modal/_form.scss
CHANGED
@@ -23,7 +23,8 @@
|
|
23 |
margin-bottom: 5px;
|
24 |
}
|
25 |
|
26 |
-
input
|
|
|
27 |
margin: 0;
|
28 |
width: 100%;
|
29 |
max-width: 120px;
|
23 |
margin-bottom: 5px;
|
24 |
}
|
25 |
|
26 |
+
input[type="text"],
|
27 |
+
input[type="number"] {
|
28 |
margin: 0;
|
29 |
width: 100%;
|
30 |
max-width: 120px;
|
assets/css/admin/modal/_import-text.scss
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// main: ../modal.scss
|
2 |
+
|
3 |
+
.wprm-recipe-import-text-form {
|
4 |
+
.import-text-buttons {
|
5 |
+
margin-bottom: 10px;
|
6 |
+
}
|
7 |
+
|
8 |
+
.import-text-step {
|
9 |
+
display: none;
|
10 |
+
|
11 |
+
&#import-text-step-input {
|
12 |
+
display: block;
|
13 |
+
}
|
14 |
+
}
|
15 |
+
|
16 |
+
.import-text-input,
|
17 |
+
#import-text-highlight-sandbox {
|
18 |
+
margin-top: 10px;
|
19 |
+
}
|
20 |
+
|
21 |
+
#import-text-ingredient-groups,
|
22 |
+
#import-text-instruction-groups {
|
23 |
+
label {
|
24 |
+
display: inline;
|
25 |
+
font-weight: normal;
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
#import-text-highlight-sandbox {
|
30 |
+
display: none;
|
31 |
+
max-height: 400px;
|
32 |
+
overflow: scroll;
|
33 |
+
padding: 10px;
|
34 |
+
border: 1px dashed #999;
|
35 |
+
}
|
36 |
+
}
|
assets/css/public/_template_reset.scss
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// main: public.scss
|
2 |
+
.wprm-recipe {
|
3 |
+
p, li {
|
4 |
+
font-size: 1em;
|
5 |
+
}
|
6 |
+
|
7 |
+
li:before {
|
8 |
+
display: none;
|
9 |
+
}
|
10 |
+
}
|
assets/css/public/public.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.comment-form-wprm-rating{display:none}.comment-form-wprm-rating .wprm-rating-star{cursor:pointer}.wprm-rating-star svg{vertical-align:middle;width:16px;height:16px;margin:0}.wprm-rating-star.rated svg polygon{fill:#000}
|
1 |
+
.comment-form-wprm-rating,.wprm-recipe li:before{display:none}.comment-form-wprm-rating .wprm-rating-star{cursor:pointer}.wprm-rating-star svg{vertical-align:middle;width:16px;height:16px;margin:0}.wprm-rating-star.rated svg polygon{fill:#000}.wprm-recipe li,.wprm-recipe p{font-size:1em}
|
assets/css/public/public.scss
CHANGED
@@ -1 +1,2 @@
|
|
1 |
@import "comments";
|
|
1 |
@import "comments";
|
2 |
+
@import "template_reset";
|
assets/js/admin/import-text.js
ADDED
@@ -0,0 +1,249 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var wprm_admin = wprm_admin || {};
|
2 |
+
|
3 |
+
wprm_admin.text_import_step = '';
|
4 |
+
wprm_admin.text_import_highlighter;
|
5 |
+
wprm_admin.text_import = {};
|
6 |
+
|
7 |
+
wprm_admin.start_text_import = function() {
|
8 |
+
jQuery('.wprm-button-import-text-reset').removeAttr('disabled');
|
9 |
+
jQuery('.wprm-button-import-text-clear').removeAttr('disabled');
|
10 |
+
jQuery('.wprm-button-import-text-next').removeAttr('disabled');
|
11 |
+
|
12 |
+
wprm_admin.text_import_step = 'input';
|
13 |
+
jQuery('#import-text-highlight-sandbox').textHighlighter();
|
14 |
+
wprm_admin.text_import_highlighter = jQuery('#import-text-highlight-sandbox').getHighlighter()
|
15 |
+
};
|
16 |
+
|
17 |
+
wprm_admin.btn_text_import_reset = function() {
|
18 |
+
wprm_admin.btn_text_import_clear(true);
|
19 |
+
jQuery('#import-text-highlight-sandbox').text('');
|
20 |
+
wprm_admin.text_import = {};
|
21 |
+
|
22 |
+
jQuery('.wprm-button-import-text-reset').attr('disabled', 'disabled');
|
23 |
+
jQuery('.wprm-button-import-text-clear').attr('disabled', 'disabled');
|
24 |
+
jQuery('.wprm-button-import-text-next').attr('disabled', 'disabled');
|
25 |
+
|
26 |
+
jQuery('.import-text-step').hide();
|
27 |
+
jQuery('#import-text-step-input').show();
|
28 |
+
jQuery('#import-text-highlight-sandbox').hide();
|
29 |
+
};
|
30 |
+
|
31 |
+
wprm_admin.btn_text_import_clear = function(all) {
|
32 |
+
if(all || wprm_admin.text_import_step == 'input') {
|
33 |
+
jQuery('#import-text-input-recipe').val('');
|
34 |
+
}
|
35 |
+
|
36 |
+
if(all || wprm_admin.text_import_step == 'ingredient-groups') {
|
37 |
+
jQuery('#import-text-ingredient-groups').find('input').attr('checked', false);
|
38 |
+
}
|
39 |
+
|
40 |
+
if(all || wprm_admin.text_import_step == 'instruction-groups') {
|
41 |
+
jQuery('#import-text-instruction-groups').find('input').attr('checked', false);
|
42 |
+
}
|
43 |
+
|
44 |
+
wprm_admin.text_import_highlighter.removeHighlights();
|
45 |
+
};
|
46 |
+
|
47 |
+
wprm_admin.btn_text_import_next = function() {
|
48 |
+
if(wprm_admin.text_import_step == 'input') {
|
49 |
+
wprm_admin.text_import.raw = jQuery('#import-text-input-recipe').val();
|
50 |
+
jQuery('#import-text-highlight-sandbox').html(wprm_admin.text_import.raw.replace(/\r?\n/g,'<br/>')).show();
|
51 |
+
|
52 |
+
wprm_admin.text_import_step = 'name';
|
53 |
+
} else if(wprm_admin.text_import_step == 'name') {
|
54 |
+
wprm_admin.text_import.name = wprm_admin.get_highlighted_text();
|
55 |
+
|
56 |
+
wprm_admin.text_import_step = 'summary';
|
57 |
+
} else if(wprm_admin.text_import_step == 'summary') {
|
58 |
+
wprm_admin.text_import.summary = wprm_admin.get_highlighted_text();
|
59 |
+
|
60 |
+
jQuery('#import-text-highlight-sandbox').show();
|
61 |
+
|
62 |
+
wprm_admin.text_import_step = 'ingredients';
|
63 |
+
} else if(wprm_admin.text_import_step == 'ingredients') {
|
64 |
+
var ingredients = wprm_admin.text_import_highlighter.getHighlights();
|
65 |
+
wprm_admin.text_import.ingredients_raw = ingredients;
|
66 |
+
|
67 |
+
jQuery('#import-text-ingredient-groups').html('');
|
68 |
+
for(var i = 0, l = ingredients.length; i<l; i++) {
|
69 |
+
var text = jQuery(ingredients[i]).text().trim();
|
70 |
+
text = text.replace(/\d\.\s+|[a-z]\)\s+|•\s+|[A-Z]\.\s+|[IVX]+\.\s+/g, "");
|
71 |
+
var ingredient = '<div class="import-text-ingredient"><input type="checkbox" id="ingredient-' + i + '"> ' + '<label for="ingredient-' + i + '">' + text + '</label></div>';
|
72 |
+
jQuery('#import-text-ingredient-groups').append(ingredient);
|
73 |
+
}
|
74 |
+
|
75 |
+
if(ingredients.length == 0) {
|
76 |
+
jQuery('#import-text-highlight-sandbox').show();
|
77 |
+
wprm_admin.text_import.ingredients = [];
|
78 |
+
wprm_admin.text_import_step = 'instructions';
|
79 |
+
} else {
|
80 |
+
jQuery('#import-text-highlight-sandbox').hide();
|
81 |
+
wprm_admin.text_import_step = 'ingredient-groups';
|
82 |
+
}
|
83 |
+
} else if(wprm_admin.text_import_step == 'ingredient-groups') {
|
84 |
+
var ingredients = [],
|
85 |
+
ingredient_group = {
|
86 |
+
name: '',
|
87 |
+
ingredients: []
|
88 |
+
};
|
89 |
+
|
90 |
+
jQuery('#import-text-ingredient-groups').find('.import-text-ingredient').each(function() {
|
91 |
+
var is_ingredient_group = jQuery(this).find('input').is(':checked'),
|
92 |
+
ingredient = jQuery(this).find('label').text();
|
93 |
+
|
94 |
+
if(is_ingredient_group) {
|
95 |
+
ingredients.push(ingredient_group);
|
96 |
+
|
97 |
+
ingredient_group = {
|
98 |
+
name: ingredient,
|
99 |
+
ingredients: []
|
100 |
+
}
|
101 |
+
} else {
|
102 |
+
ingredient_group.ingredients.push({raw: ingredient});
|
103 |
+
}
|
104 |
+
});
|
105 |
+
ingredients.push(ingredient_group);
|
106 |
+
|
107 |
+
wprm_admin.text_import.ingredients = [];
|
108 |
+
|
109 |
+
// Parse ingredients
|
110 |
+
var data = {
|
111 |
+
action: 'wprm_parse_ingredients',
|
112 |
+
security: wprm_modal.nonce,
|
113 |
+
ingredients: ingredients
|
114 |
+
};
|
115 |
+
|
116 |
+
jQuery.post(wprm_modal.ajax_url, data, function(out) {
|
117 |
+
if (out.success) {
|
118 |
+
wprm_admin.text_import.ingredients = out.data.ingredients;
|
119 |
+
}
|
120 |
+
}, 'json');
|
121 |
+
|
122 |
+
jQuery('#import-text-highlight-sandbox').show();
|
123 |
+
|
124 |
+
wprm_admin.text_import_step = 'instructions';
|
125 |
+
} else if(wprm_admin.text_import_step == 'instructions') {
|
126 |
+
var instructions = wprm_admin.text_import_highlighter.getHighlights();
|
127 |
+
wprm_admin.text_import.instructions_raw = instructions;
|
128 |
+
|
129 |
+
jQuery('#import-text-instruction-groups').html('');
|
130 |
+
for(var i = 0, l = instructions.length; i<l; i++) {
|
131 |
+
var text = jQuery(instructions[i]).text().trim();
|
132 |
+
text = text.replace(/\d\.\s+|[a-z]\)\s+|•\s+|[A-Z]\.\s+|[IVX]+\.\s+/g, "");
|
133 |
+
var instruction = '<div class="import-text-instruction"><input type="checkbox" id="instruction-' + i + '"> ' + '<label for="instruction-' + i + '">' + text + '</label></div>';
|
134 |
+
jQuery('#import-text-instruction-groups').append(instruction);
|
135 |
+
}
|
136 |
+
|
137 |
+
if(instructions.length == 0) {
|
138 |
+
jQuery('#import-text-highlight-sandbox').show();
|
139 |
+
wprm_admin.text_import.instructions = [];
|
140 |
+
wprm_admin.text_import_step = 'notes';
|
141 |
+
} else {
|
142 |
+
jQuery('#import-text-highlight-sandbox').hide();
|
143 |
+
wprm_admin.text_import_step = 'instruction-groups';
|
144 |
+
}
|
145 |
+
} else if(wprm_admin.text_import_step == 'instruction-groups') {
|
146 |
+
var instructions = [],
|
147 |
+
instruction_group = {
|
148 |
+
name: '',
|
149 |
+
instructions: []
|
150 |
+
};
|
151 |
+
|
152 |
+
jQuery('#import-text-instruction-groups').find('.import-text-instruction').each(function() {
|
153 |
+
var is_instruction_group = jQuery(this).find('input').is(':checked'),
|
154 |
+
instruction = jQuery(this).find('label').text();
|
155 |
+
|
156 |
+
if(is_instruction_group) {
|
157 |
+
instructions.push(instruction_group);
|
158 |
+
|
159 |
+
instruction_group = {
|
160 |
+
name: instruction,
|
161 |
+
instructions: []
|
162 |
+
}
|
163 |
+
} else {
|
164 |
+
instruction_group.instructions.push({text: instruction});
|
165 |
+
}
|
166 |
+
});
|
167 |
+
instructions.push(instruction_group);
|
168 |
+
|
169 |
+
wprm_admin.text_import.instructions = instructions;
|
170 |
+
|
171 |
+
jQuery('#import-text-highlight-sandbox').show();
|
172 |
+
|
173 |
+
wprm_admin.text_import_step = 'notes';
|
174 |
+
} else if(wprm_admin.text_import_step == 'notes') {
|
175 |
+
wprm_admin.text_import.notes = wprm_admin.get_highlighted_text();
|
176 |
+
|
177 |
+
jQuery('#import-text-highlight-sandbox').hide();
|
178 |
+
jQuery('.wprm-button-import-text-clear').attr('disabled', 'disabled');
|
179 |
+
jQuery('.wprm-button-import-text-next').attr('disabled', 'disabled');
|
180 |
+
|
181 |
+
wprm_admin.import_recipe();
|
182 |
+
wprm_admin.text_import_step = 'finished';
|
183 |
+
}
|
184 |
+
|
185 |
+
jQuery('.import-text-step').hide();
|
186 |
+
jQuery('#import-text-step-' + wprm_admin.text_import_step).show();
|
187 |
+
wprm_admin.text_import_highlighter.removeHighlights();
|
188 |
+
};
|
189 |
+
|
190 |
+
wprm_admin.get_highlighted_text = function() {
|
191 |
+
var highlight_parts = wprm_admin.text_import_highlighter.getHighlights();
|
192 |
+
var highlight = '';
|
193 |
+
|
194 |
+
for(var i = 0, l = highlight_parts.length; i<l; i++) {
|
195 |
+
if(i > 0) {
|
196 |
+
highlight += ' ';
|
197 |
+
}
|
198 |
+
highlight += jQuery(highlight_parts[i]).text().trim();
|
199 |
+
}
|
200 |
+
|
201 |
+
return highlight;
|
202 |
+
};
|
203 |
+
|
204 |
+
wprm_admin.import_recipe = function() {
|
205 |
+
if(wprm_admin.text_import.name) {
|
206 |
+
jQuery('#wprm-recipe-name').val(wprm_admin.text_import.name);
|
207 |
+
}
|
208 |
+
|
209 |
+
if(wprm_admin.text_import.summary) {
|
210 |
+
wprm_admin.rich_editor.setContent(wprm_admin.text_import.summary);
|
211 |
+
}
|
212 |
+
|
213 |
+
if(wprm_admin.text_import.notes) {
|
214 |
+
if (typeof tinyMCE !== 'undefined' && tinyMCE.get('wprm_recipe_notes') && !tinyMCE.get('wprm_recipe_notes').isHidden()) {
|
215 |
+
tinyMCE.get('wprm_recipe_notes').focus(true);
|
216 |
+
tinyMCE.activeEditor.setContent(wprm_admin.text_import.notes);
|
217 |
+
} else {
|
218 |
+
jQuery('#wprm_recipe_notes').val(wprm_admin.text_import.notes);
|
219 |
+
}
|
220 |
+
}
|
221 |
+
|
222 |
+
if(wprm_admin.text_import.instructions.length > 0) {
|
223 |
+
wprm_admin.set_recipe_instruction_fields(wprm_admin.text_import.instructions);
|
224 |
+
}
|
225 |
+
|
226 |
+
if(wprm_admin.text_import.ingredients.length > 0) {
|
227 |
+
wprm_admin.set_recipe_ingredient_fields(wprm_admin.text_import.ingredients);
|
228 |
+
}
|
229 |
+
};
|
230 |
+
|
231 |
+
jQuery(document).ready(function($) {
|
232 |
+
jQuery('#import-text-input-recipe').on('keydown change', function() {
|
233 |
+
wprm_admin.start_text_import();
|
234 |
+
});
|
235 |
+
|
236 |
+
jQuery('.wprm-button-import-text-reset').on('click', function() {
|
237 |
+
if(confirm(wprm_modal.text.import_text_reset)) {
|
238 |
+
wprm_admin.btn_text_import_reset();
|
239 |
+
}
|
240 |
+
});
|
241 |
+
|
242 |
+
jQuery('.wprm-button-import-text-clear').on('click', function() {
|
243 |
+
wprm_admin.btn_text_import_clear(false);
|
244 |
+
});
|
245 |
+
|
246 |
+
jQuery('.wprm-button-import-text-next').on('click', function() {
|
247 |
+
wprm_admin.btn_text_import_next();
|
248 |
+
});
|
249 |
+
});
|
assets/js/admin/modal.js
CHANGED
@@ -4,6 +4,7 @@ wprm_admin.active_editor_id = false;
|
|
4 |
|
5 |
wprm_admin.disable_menu = function() {
|
6 |
jQuery('.wprm-frame-menu').find('.wprm-menu-item').hide();
|
|
|
7 |
};
|
8 |
|
9 |
wprm_admin.open_modal = function(editor_id, args) {
|
@@ -14,6 +15,7 @@ wprm_admin.open_modal = function(editor_id, args) {
|
|
14 |
|
15 |
// Enable menu items
|
16 |
jQuery('.wprm-menu-item').show();
|
|
|
17 |
|
18 |
wprm_admin.active_editor_id = editor_id;
|
19 |
jQuery('.wprm-modal-container').show();
|
4 |
|
5 |
wprm_admin.disable_menu = function() {
|
6 |
jQuery('.wprm-frame-menu').find('.wprm-menu-item').hide();
|
7 |
+
jQuery('.wprm-menu-hidden').show();
|
8 |
};
|
9 |
|
10 |
wprm_admin.open_modal = function(editor_id, args) {
|
15 |
|
16 |
// Enable menu items
|
17 |
jQuery('.wprm-menu-item').show();
|
18 |
+
jQuery('.wprm-menu-hidden').hide();
|
19 |
|
20 |
wprm_admin.active_editor_id = editor_id;
|
21 |
jQuery('.wprm-modal-container').show();
|
assets/js/admin/recipe-form.js
CHANGED
@@ -54,6 +54,10 @@ wprm_admin.clear_recipe_fields = function() {
|
|
54 |
jQuery('#wprm-recipe-cook-time').val('');
|
55 |
jQuery('#wprm-recipe-total-time').val('');
|
56 |
|
|
|
|
|
|
|
|
|
57 |
jQuery('.wprm-recipe-tags').val(null).trigger('change');
|
58 |
|
59 |
// Ingredients & Instructions
|
@@ -66,7 +70,14 @@ wprm_admin.clear_recipe_fields = function() {
|
|
66 |
// Recipe Notes
|
67 |
if (typeof tinyMCE !== 'undefined' && tinyMCE.get('wprm_recipe_notes') && !tinyMCE.get('wprm_recipe_notes').isHidden()) {
|
68 |
tinyMCE.get('wprm_recipe_notes').focus(true);
|
69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
} else {
|
71 |
jQuery('#wprm_recipe_notes').val('');
|
72 |
}
|
@@ -97,49 +108,66 @@ wprm_admin.set_recipe_fields = function(recipe) {
|
|
97 |
jQuery('#wprm-recipe-cook-time').val(cook_time);
|
98 |
jQuery('#wprm-recipe-total-time').val(total_time);
|
99 |
|
|
|
|
|
|
|
|
|
100 |
wprm_admin.set_recipe_tags(recipe, 'course');
|
101 |
wprm_admin.set_recipe_tags(recipe, 'cuisine');
|
102 |
|
103 |
// Ingredients & Instructions
|
104 |
-
|
105 |
-
|
106 |
-
});
|
107 |
|
108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
|
110 |
-
|
111 |
-
|
|
|
|
|
112 |
|
113 |
-
|
114 |
-
wprm_admin.add_ingredient_group(group.name);
|
115 |
-
}
|
116 |
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
}
|
|
|
|
|
122 |
|
123 |
-
|
124 |
-
|
|
|
|
|
125 |
|
126 |
-
|
127 |
-
wprm_admin.add_instruction_group(group.name);
|
128 |
-
}
|
129 |
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
|
|
134 |
}
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
tinyMCE.activeEditor.setContent(recipe.notes);
|
140 |
-
} else {
|
141 |
-
jQuery('#wprm_recipe_notes').val(recipe.notes);
|
142 |
}
|
|
|
143 |
};
|
144 |
|
145 |
wprm_admin.set_recipe_tags = function(recipe, tag) {
|
@@ -179,18 +207,19 @@ wprm_admin.select_media_image = function(container) {
|
|
179 |
frame.open();
|
180 |
};
|
181 |
wprm_admin.set_media_image = function(container, image_id, image_url) {
|
182 |
-
|
183 |
-
|
|
|
184 |
|
185 |
-
|
186 |
-
|
187 |
};
|
188 |
wprm_admin.remove_media_image = function(container) {
|
189 |
-
|
190 |
-
|
191 |
|
192 |
-
|
193 |
-
|
194 |
};
|
195 |
|
196 |
wprm_admin.start_loader = function(button) {
|
54 |
jQuery('#wprm-recipe-cook-time').val('');
|
55 |
jQuery('#wprm-recipe-total-time').val('');
|
56 |
|
57 |
+
wprm_admin.prep_time_set = false;
|
58 |
+
wprm_admin.cook_time_set = false;
|
59 |
+
wprm_admin.total_time_set = false;
|
60 |
+
|
61 |
jQuery('.wprm-recipe-tags').val(null).trigger('change');
|
62 |
|
63 |
// Ingredients & Instructions
|
70 |
// Recipe Notes
|
71 |
if (typeof tinyMCE !== 'undefined' && tinyMCE.get('wprm_recipe_notes') && !tinyMCE.get('wprm_recipe_notes').isHidden()) {
|
72 |
tinyMCE.get('wprm_recipe_notes').focus(true);
|
73 |
+
|
74 |
+
// Check for error caused by EasyRecipe.
|
75 |
+
jQuery('.wprm-easyrecipe-warning').hide();
|
76 |
+
try {
|
77 |
+
tinyMCE.activeEditor.setContent('');
|
78 |
+
} catch(err) {
|
79 |
+
jQuery('.wprm-easyrecipe-warning').show();
|
80 |
+
}
|
81 |
} else {
|
82 |
jQuery('#wprm_recipe_notes').val('');
|
83 |
}
|
108 |
jQuery('#wprm-recipe-cook-time').val(cook_time);
|
109 |
jQuery('#wprm-recipe-total-time').val(total_time);
|
110 |
|
111 |
+
if (prep_time) wprm_admin.prep_time_set = true;
|
112 |
+
if (cook_time) wprm_admin.cook_time_set = true;
|
113 |
+
if (total_time) wprm_admin.total_time_set = true;
|
114 |
+
|
115 |
wprm_admin.set_recipe_tags(recipe, 'course');
|
116 |
wprm_admin.set_recipe_tags(recipe, 'cuisine');
|
117 |
|
118 |
// Ingredients & Instructions
|
119 |
+
wprm_admin.set_recipe_ingredient_fields(recipe.ingredients);
|
120 |
+
wprm_admin.set_recipe_instruction_fields(recipe.instructions);
|
|
|
121 |
|
122 |
+
// Recipe Notes
|
123 |
+
if (typeof tinyMCE !== 'undefined' && tinyMCE.get('wprm_recipe_notes') && !tinyMCE.get('wprm_recipe_notes').isHidden()) {
|
124 |
+
tinyMCE.get('wprm_recipe_notes').focus(true);
|
125 |
+
tinyMCE.activeEditor.setContent(recipe.notes);
|
126 |
+
} else {
|
127 |
+
jQuery('#wprm_recipe_notes').val(recipe.notes);
|
128 |
+
}
|
129 |
+
};
|
130 |
|
131 |
+
wprm_admin.set_recipe_ingredient_fields = function(ingredients) {
|
132 |
+
jQuery('.wprm-recipe-ingredients .wprm-recipe-ingredients-instructions-delete').each(function() {
|
133 |
+
jQuery(this).click();
|
134 |
+
});
|
135 |
|
136 |
+
var i, l, group, j, m;
|
|
|
|
|
137 |
|
138 |
+
for (i = 0, l = ingredients.length; i < l; i++) {
|
139 |
+
group = ingredients[i];
|
140 |
+
|
141 |
+
if (i > 0 || group.name !== '') {
|
142 |
+
wprm_admin.add_ingredient_group(group.name);
|
143 |
+
}
|
144 |
+
|
145 |
+
for (j = 0, m = group.ingredients.length; j < m; j++) {
|
146 |
+
var ingredient = group.ingredients[j];
|
147 |
+
wprm_admin.add_ingredient(ingredient.amount, ingredient.unit, ingredient.name, ingredient.notes);
|
148 |
}
|
149 |
+
}
|
150 |
+
};
|
151 |
|
152 |
+
wprm_admin.set_recipe_instruction_fields = function(instructions) {
|
153 |
+
jQuery('.wprm-recipe-instructions .wprm-recipe-ingredients-instructions-delete').each(function() {
|
154 |
+
jQuery(this).click();
|
155 |
+
});
|
156 |
|
157 |
+
var i, l, group, j, m;
|
|
|
|
|
158 |
|
159 |
+
for (i = 0, l = instructions.length; i < l; i++) {
|
160 |
+
group = instructions[i];
|
161 |
+
|
162 |
+
if (i > 0 || group.name !== '') {
|
163 |
+
wprm_admin.add_instruction_group(group.name);
|
164 |
}
|
165 |
|
166 |
+
for (j = 0, m = group.instructions.length; j < m; j++) {
|
167 |
+
var instruction = group.instructions[j];
|
168 |
+
wprm_admin.add_instruction(instruction.text, instruction.image);
|
|
|
|
|
|
|
169 |
}
|
170 |
+
}
|
171 |
};
|
172 |
|
173 |
wprm_admin.set_recipe_tags = function(recipe, tag) {
|
207 |
frame.open();
|
208 |
};
|
209 |
wprm_admin.set_media_image = function(container, image_id, image_url) {
|
210 |
+
container.find('.wprm-recipe-image-preview').html('');
|
211 |
+
container.find('.wprm-recipe-image-preview').append('<img src="' + image_url + '" />');
|
212 |
+
container.find('input').val(image_id);
|
213 |
|
214 |
+
container.find('.wprm-recipe-image-add').addClass('hidden');
|
215 |
+
container.find('.wprm-recipe-image-remove').removeClass('hidden');
|
216 |
};
|
217 |
wprm_admin.remove_media_image = function(container) {
|
218 |
+
container.find('.wprm-recipe-image-preview').html('');
|
219 |
+
container.find('input').val('');
|
220 |
|
221 |
+
container.find('.wprm-recipe-image-add').removeClass('hidden');
|
222 |
+
container.find('.wprm-recipe-image-remove').addClass('hidden');
|
223 |
};
|
224 |
|
225 |
wprm_admin.start_loader = function(button) {
|
assets/js/admin/rich-editor.js
CHANGED
@@ -9,17 +9,18 @@ wprm_admin.init_rich_editor = function() {
|
|
9 |
autoLink: true,
|
10 |
imageDragging: false,
|
11 |
toolbar: {
|
12 |
-
buttons: ['bold', 'italic', 'underline'
|
13 |
-
name: 'anchor',
|
14 |
-
contentDefault: '<span class="dashicons dashicons-admin-links"></span>'
|
15 |
-
}]
|
16 |
},
|
17 |
extensions: {}
|
18 |
};
|
19 |
|
|
|
|
|
|
|
20 |
if(wprm_modal.addons.premium) {
|
21 |
args.toolbar.buttons.push('adjustable_servings');
|
22 |
args.toolbar.buttons.push('timer');
|
|
|
23 |
args.extensions.adjustable_servings = new wprm_admin.rich_editor_adjustable_servings();
|
24 |
args.extensions.timer = new wprm_admin.rich_editor_timer();
|
25 |
}
|
@@ -90,4 +91,578 @@ wprm_admin.rich_editor_timer = MediumEditor.Extension.extend({
|
|
90 |
range.insertNode(text);
|
91 |
rangy.getSelection().setSingleRange(original_range);
|
92 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
});
|
9 |
autoLink: true,
|
10 |
imageDragging: false,
|
11 |
toolbar: {
|
12 |
+
buttons: ['bold', 'italic', 'underline']
|
|
|
|
|
|
|
13 |
},
|
14 |
extensions: {}
|
15 |
};
|
16 |
|
17 |
+
args.toolbar.buttons.push('links');
|
18 |
+
args.extensions.links = new wprm_admin.rich_editor_links();
|
19 |
+
|
20 |
if(wprm_modal.addons.premium) {
|
21 |
args.toolbar.buttons.push('adjustable_servings');
|
22 |
args.toolbar.buttons.push('timer');
|
23 |
+
|
24 |
args.extensions.adjustable_servings = new wprm_admin.rich_editor_adjustable_servings();
|
25 |
args.extensions.timer = new wprm_admin.rich_editor_timer();
|
26 |
}
|
91 |
range.insertNode(text);
|
92 |
rangy.getSelection().setSingleRange(original_range);
|
93 |
}
|
94 |
+
});
|
95 |
+
|
96 |
+
// Source: medium-editor.js
|
97 |
+
MediumEditor.prototype.createLink = function (opts) {
|
98 |
+
console.log(opts);
|
99 |
+
var currentEditor = MediumEditor.selection.getSelectionElement(this.options.contentWindow),
|
100 |
+
customEvent = {},
|
101 |
+
targetUrl;
|
102 |
+
|
103 |
+
// Make sure the selection is within an element this editor is tracking
|
104 |
+
if (this.elements.indexOf(currentEditor) === -1) {
|
105 |
+
return;
|
106 |
+
}
|
107 |
+
|
108 |
+
try {
|
109 |
+
this.events.disableCustomEvent('editableInput');
|
110 |
+
// TODO: Deprecate support for opts.url in 6.0.0
|
111 |
+
if (opts.url) {
|
112 |
+
MediumEditor.util.deprecated('.url option for createLink', '.value', '6.0.0');
|
113 |
+
}
|
114 |
+
targetUrl = opts.url || opts.value;
|
115 |
+
if (targetUrl && targetUrl.trim().length > 0) {
|
116 |
+
var currentSelection = this.options.contentWindow.getSelection();
|
117 |
+
if (currentSelection) {
|
118 |
+
var currRange = currentSelection.getRangeAt(0),
|
119 |
+
commonAncestorContainer = currRange.commonAncestorContainer,
|
120 |
+
exportedSelection,
|
121 |
+
startContainerParentElement,
|
122 |
+
endContainerParentElement,
|
123 |
+
textNodes;
|
124 |
+
|
125 |
+
// If the selection is contained within a single text node
|
126 |
+
// and the selection starts at the beginning of the text node,
|
127 |
+
// MSIE still says the startContainer is the parent of the text node.
|
128 |
+
// If the selection is contained within a single text node, we
|
129 |
+
// want to just use the default browser 'createLink', so we need
|
130 |
+
// to account for this case and adjust the commonAncestorContainer accordingly
|
131 |
+
if (currRange.endContainer.nodeType === 3 &&
|
132 |
+
currRange.startContainer.nodeType !== 3 &&
|
133 |
+
currRange.startOffset === 0 &&
|
134 |
+
currRange.startContainer.firstChild === currRange.endContainer) {
|
135 |
+
commonAncestorContainer = currRange.endContainer;
|
136 |
+
}
|
137 |
+
|
138 |
+
startContainerParentElement = MediumEditor.util.getClosestBlockContainer(currRange.startContainer);
|
139 |
+
endContainerParentElement = MediumEditor.util.getClosestBlockContainer(currRange.endContainer);
|
140 |
+
|
141 |
+
// If the selection is not contained within a single text node
|
142 |
+
// but the selection is contained within the same block element
|
143 |
+
// we want to make sure we create a single link, and not multiple links
|
144 |
+
// which can happen with the built in browser functionality
|
145 |
+
if (commonAncestorContainer.nodeType !== 3 && commonAncestorContainer.textContent.length !== 0 && startContainerParentElement === endContainerParentElement) {
|
146 |
+
var parentElement = (startContainerParentElement || currentEditor),
|
147 |
+
fragment = this.options.ownerDocument.createDocumentFragment();
|
148 |
+
|
149 |
+
// since we are going to create a link from an extracted text,
|
150 |
+
// be sure that if we are updating a link, we won't let an empty link behind (see #754)
|
151 |
+
// (Workaroung for Chrome)
|
152 |
+
this.execAction('unlink');
|
153 |
+
|
154 |
+
exportedSelection = this.exportSelection();
|
155 |
+
fragment.appendChild(parentElement.cloneNode(true));
|
156 |
+
|
157 |
+
if (currentEditor === parentElement) {
|
158 |
+
// We have to avoid the editor itself being wiped out when it's the only block element,
|
159 |
+
// as our reference inside this.elements gets detached from the page when insertHTML runs.
|
160 |
+
// If we just use [parentElement, 0] and [parentElement, parentElement.childNodes.length]
|
161 |
+
// as the range boundaries, this happens whenever parentElement === currentEditor.
|
162 |
+
// The tradeoff to this workaround is that a orphaned tag can sometimes be left behind at
|
163 |
+
// the end of the editor's content.
|
164 |
+
// In Gecko:
|
165 |
+
// as an empty <strong></strong> if parentElement.lastChild is a <strong> tag.
|
166 |
+
// In WebKit:
|
167 |
+
// an invented <br /> tag at the end in the same situation
|
168 |
+
MediumEditor.selection.select(
|
169 |
+
this.options.ownerDocument,
|
170 |
+
parentElement.firstChild,
|
171 |
+
0,
|
172 |
+
parentElement.lastChild,
|
173 |
+
parentElement.lastChild.nodeType === 3 ?
|
174 |
+
parentElement.lastChild.nodeValue.length : parentElement.lastChild.childNodes.length
|
175 |
+
);
|
176 |
+
} else {
|
177 |
+
MediumEditor.selection.select(
|
178 |
+
this.options.ownerDocument,
|
179 |
+
parentElement,
|
180 |
+
0,
|
181 |
+
parentElement,
|
182 |
+
parentElement.childNodes.length
|
183 |
+
);
|
184 |
+
}
|
185 |
+
|
186 |
+
var modifiedExportedSelection = this.exportSelection();
|
187 |
+
|
188 |
+
textNodes = MediumEditor.util.findOrCreateMatchingTextNodes(
|
189 |
+
this.options.ownerDocument,
|
190 |
+
fragment,
|
191 |
+
{
|
192 |
+
start: exportedSelection.start - modifiedExportedSelection.start,
|
193 |
+
end: exportedSelection.end - modifiedExportedSelection.start,
|
194 |
+
editableElementIndex: exportedSelection.editableElementIndex
|
195 |
+
}
|
196 |
+
);
|
197 |
+
// If textNodes are not present, when changing link on images
|
198 |
+
// ex: <a><img src="http://image.test.com"></a>, change fragment to currRange.startContainer
|
199 |
+
// and set textNodes array to [imageElement, imageElement]
|
200 |
+
if (textNodes.length === 0) {
|
201 |
+
fragment = this.options.ownerDocument.createDocumentFragment();
|
202 |
+
fragment.appendChild(commonAncestorContainer.cloneNode(true));
|
203 |
+
textNodes = [fragment.firstChild.firstChild, fragment.firstChild.lastChild];
|
204 |
+
}
|
205 |
+
|
206 |
+
// Creates the link in the document fragment
|
207 |
+
MediumEditor.util.createLink(this.options.ownerDocument, textNodes, targetUrl.trim());
|
208 |
+
|
209 |
+
// Chrome trims the leading whitespaces when inserting HTML, which messes up restoring the selection.
|
210 |
+
var leadingWhitespacesCount = (fragment.firstChild.innerHTML.match(/^\s+/) || [''])[0].length;
|
211 |
+
|
212 |
+
// Now move the created link back into the original document in a way to preserve undo/redo history
|
213 |
+
MediumEditor.util.insertHTMLCommand(this.options.ownerDocument, fragment.firstChild.innerHTML.replace(/^\s+/, ''));
|
214 |
+
exportedSelection.start -= leadingWhitespacesCount;
|
215 |
+
exportedSelection.end -= leadingWhitespacesCount;
|
216 |
+
|
217 |
+
this.importSelection(exportedSelection);
|
218 |
+
} else {
|
219 |
+
this.options.ownerDocument.execCommand('createLink', false, targetUrl);
|
220 |
+
}
|
221 |
+
|
222 |
+
if (this.options.targetBlank || opts.target === '_blank') {
|
223 |
+
MediumEditor.util.setTargetBlank(MediumEditor.selection.getSelectionStart(this.options.ownerDocument), targetUrl);
|
224 |
+
} else {
|
225 |
+
MediumEditor.util.removeTargetBlank(MediumEditor.selection.getSelectionStart(this.options.ownerDocument), targetUrl);
|
226 |
+
}
|
227 |
+
|
228 |
+
if (opts.rel === 'nofollow') {
|
229 |
+
MediumEditor.util.setNofollow(MediumEditor.selection.getSelectionStart(this.options.ownerDocument), targetUrl);
|
230 |
+
} else {
|
231 |
+
MediumEditor.util.removeNofollow(MediumEditor.selection.getSelectionStart(this.options.ownerDocument), targetUrl);
|
232 |
+
}
|
233 |
+
|
234 |
+
if (opts.buttonClass) {
|
235 |
+
MediumEditor.util.addClassToAnchors(MediumEditor.selection.getSelectionStart(this.options.ownerDocument), opts.buttonClass);
|
236 |
+
}
|
237 |
+
}
|
238 |
+
}
|
239 |
+
// Fire input event for backwards compatibility if anyone was listening directly to the DOM input event
|
240 |
+
if (this.options.targetBlank || opts.target === '_blank' || opts.rel === 'nofollow' || opts.buttonClass) {
|
241 |
+
customEvent = this.options.ownerDocument.createEvent('HTMLEvents');
|
242 |
+
customEvent.initEvent('input', true, true, this.options.contentWindow);
|
243 |
+
for (var i = 0, len = this.elements.length; i < len; i += 1) {
|
244 |
+
this.elements[i].dispatchEvent(customEvent);
|
245 |
+
}
|
246 |
+
}
|
247 |
+
} finally {
|
248 |
+
this.events.enableCustomEvent('editableInput');
|
249 |
+
}
|
250 |
+
// Fire our custom editableInput event
|
251 |
+
this.events.triggerCustomEvent('editableInput', customEvent, currentEditor);
|
252 |
+
};
|
253 |
+
|
254 |
+
MediumEditor.util.setNofollow = function (el, anchorUrl) {
|
255 |
+
var i, url = anchorUrl || false;
|
256 |
+
if (el.nodeName.toLowerCase() === 'a') {
|
257 |
+
el.rel = 'nofollow';
|
258 |
+
} else {
|
259 |
+
el = el.getElementsByTagName('a');
|
260 |
+
|
261 |
+
for (i = 0; i < el.length; i += 1) {
|
262 |
+
if (false === url || url === el[i].attributes.href.value) {
|
263 |
+
el[i].rel = 'nofollow';
|
264 |
+
}
|
265 |
+
}
|
266 |
+
}
|
267 |
+
};
|
268 |
+
|
269 |
+
MediumEditor.util.removeNofollow = function (el, anchorUrl) {
|
270 |
+
var i;
|
271 |
+
if (el.nodeName.toLowerCase() === 'a') {
|
272 |
+
el.removeAttribute('rel');
|
273 |
+
} else {
|
274 |
+
el = el.getElementsByTagName('a');
|
275 |
+
|
276 |
+
for (i = 0; i < el.length; i += 1) {
|
277 |
+
if (anchorUrl === el[i].attributes.href.value) {
|
278 |
+
el[i].removeAttribute('rel');
|
279 |
+
}
|
280 |
+
}
|
281 |
+
}
|
282 |
+
};
|
283 |
+
|
284 |
+
wprm_admin.rich_editor_links = MediumEditor.extensions.form.extend({
|
285 |
+
/* Anchor Form Options */
|
286 |
+
|
287 |
+
/* customClassOption: [string] (previously options.anchorButton + options.anchorButtonClass)
|
288 |
+
* Custom class name the user can optionally have added to their created links (ie 'button').
|
289 |
+
* If passed as a non-empty string, a checkbox will be displayed allowing the user to choose
|
290 |
+
* whether to have the class added to the created link or not.
|
291 |
+
*/
|
292 |
+
customClassOption: null,
|
293 |
+
|
294 |
+
/* customClassOptionText: [string]
|
295 |
+
* text to be shown in the checkbox when the __customClassOption__ is being used.
|
296 |
+
*/
|
297 |
+
customClassOptionText: 'Button',
|
298 |
+
|
299 |
+
/* linkValidation: [boolean] (previously options.checkLinkFormat)
|
300 |
+
* enables/disables check for common URL protocols on anchor links.
|
301 |
+
*/
|
302 |
+
linkValidation: false,
|
303 |
+
|
304 |
+
/* placeholderText: [string] (previously options.anchorInputPlaceholder)
|
305 |
+
* text to be shown as placeholder of the anchor input.
|
306 |
+
*/
|
307 |
+
placeholderText: 'Paste or type a link',
|
308 |
+
|
309 |
+
/* targetCheckbox: [boolean] (previously options.anchorTarget)
|
310 |
+
* enables/disables displaying a "Open in new window" checkbox, which when checked
|
311 |
+
* changes the `target` attribute of the created link.
|
312 |
+
*/
|
313 |
+
targetCheckbox: true,
|
314 |
+
|
315 |
+
/* targetCheckboxText: [string] (previously options.anchorInputCheckboxLabel)
|
316 |
+
* text to be shown in the checkbox enabled via the __targetCheckbox__ option.
|
317 |
+
*/
|
318 |
+
targetCheckboxText: 'Open in new tab',
|
319 |
+
|
320 |
+
nofollowCheckbox: true,
|
321 |
+
nofollowCheckboxText: 'Use nofollow',
|
322 |
+
|
323 |
+
// Options for the Button base class
|
324 |
+
name: 'links',
|
325 |
+
action: 'createLink',
|
326 |
+
aria: 'link',
|
327 |
+
tagNames: ['a'],
|
328 |
+
contentDefault: '<span class="dashicons dashicons-admin-links"></span>',
|
329 |
+
contentFA: '<i class="fa fa-link"></i>',
|
330 |
+
|
331 |
+
init: function () {
|
332 |
+
MediumEditor.extensions.form.prototype.init.apply(this, arguments);
|
333 |
+
|
334 |
+
this.subscribe('editableKeydown', this.handleKeydown.bind(this));
|
335 |
+
},
|
336 |
+
|
337 |
+
// Called when the button the toolbar is clicked
|
338 |
+
// Overrides ButtonExtension.handleClick
|
339 |
+
handleClick: function (event) {
|
340 |
+
event.preventDefault();
|
341 |
+
event.stopPropagation();
|
342 |
+
|
343 |
+
var range = MediumEditor.selection.getSelectionRange(this.document);
|
344 |
+
|
345 |
+
if (range.startContainer.nodeName.toLowerCase() === 'a' ||
|
346 |
+
range.endContainer.nodeName.toLowerCase() === 'a' ||
|
347 |
+
MediumEditor.util.getClosestTag(MediumEditor.selection.getSelectedParentElement(range), 'a')) {
|
348 |
+
return this.execAction('unlink');
|
349 |
+
}
|
350 |
+
|
351 |
+
if (!this.isDisplayed()) {
|
352 |
+
this.showForm();
|
353 |
+
}
|
354 |
+
|
355 |
+
return false;
|
356 |
+
},
|
357 |
+
|
358 |
+
// Called when user hits the defined shortcut (CTRL / COMMAND + K)
|
359 |
+
handleKeydown: function (event) {
|
360 |
+
if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.K) && MediumEditor.util.isMetaCtrlKey(event) && !event.shiftKey) {
|
361 |
+
this.handleClick(event);
|
362 |
+
}
|
363 |
+
},
|
364 |
+
|
365 |
+
// Called by medium-editor to append form to the toolbar
|
366 |
+
getForm: function () {
|
367 |
+
if (!this.form) {
|
368 |
+
this.form = this.createForm();
|
369 |
+
}
|
370 |
+
return this.form;
|
371 |
+
},
|
372 |
+
|
373 |
+
getTemplate: function () {
|
374 |
+
var template = [
|
375 |
+
'<input type="text" class="medium-editor-toolbar-input" placeholder="', this.placeholderText, '" style="padding-left: 25px; width: 265px;">'
|
376 |
+
];
|
377 |
+
|
378 |
+
template.push(
|
379 |
+
'<a href="#" class="medium-editor-toolbar-save">',
|
380 |
+
this.getEditorOption('buttonLabels') === 'fontawesome' ? '<i class="fa fa-check"></i>' : this.formSaveLabel,
|
381 |
+
'</a>'
|
382 |
+
);
|
383 |
+
|
384 |
+
template.push('<a href="#" class="medium-editor-toolbar-close">',
|
385 |
+
this.getEditorOption('buttonLabels') === 'fontawesome' ? '<i class="fa fa-times"></i>' : this.formCloseLabel,
|
386 |
+
'</a>');
|
387 |
+
|
388 |
+
// both of these options are slightly moot with the ability to
|
389 |
+
// override the various form buildup/serialize functions.
|
390 |
+
|
391 |
+
if (this.targetCheckbox) {
|
392 |
+
// fixme: ideally, this targetCheckboxText would be a formLabel too,
|
393 |
+
// figure out how to deprecate? also consider `fa-` icon default implcations.
|
394 |
+
template.push(
|
395 |
+
'<div class="medium-editor-toolbar-form-row" style="padding-left: 20px;">',
|
396 |
+
'<input type="checkbox" class="medium-editor-toolbar-anchor-target">',
|
397 |
+
'<label>',
|
398 |
+
this.targetCheckboxText,
|
399 |
+
'</label>',
|
400 |
+
'</div>'
|
401 |
+
);
|
402 |
+
}
|
403 |
+
|
404 |
+
if (this.nofollowCheckbox) {
|
405 |
+
template.push(
|
406 |
+
'<div class="medium-editor-toolbar-form-row" style="padding-left: 20px;">',
|
407 |
+
'<input type="checkbox" class="medium-editor-toolbar-anchor-nofollow">',
|
408 |
+
'<label>',
|
409 |
+
this.nofollowCheckboxText,
|
410 |
+
'</label>',
|
411 |
+
'</div>'
|
412 |
+
);
|
413 |
+
}
|
414 |
+
|
415 |
+
if (this.customClassOption) {
|
416 |
+
// fixme: expose this `Button` text as a formLabel property, too
|
417 |
+
// and provide similar access to a `fa-` icon default.
|
418 |
+
template.push(
|
419 |
+
'<div class="medium-editor-toolbar-form-row">',
|
420 |
+
'<input type="checkbox" class="medium-editor-toolbar-anchor-button">',
|
421 |
+
'<label>',
|
422 |
+
this.customClassOptionText,
|
423 |
+
'</label>',
|
424 |
+
'</div>'
|
425 |
+
);
|
426 |
+
}
|
427 |
+
|
428 |
+
return template.join('');
|
429 |
+
|
430 |
+
},
|
431 |
+
|
432 |
+
// Used by medium-editor when the default toolbar is to be displayed
|
433 |
+
isDisplayed: function () {
|
434 |
+
return MediumEditor.extensions.form.prototype.isDisplayed.apply(this);
|
435 |
+
},
|
436 |
+
|
437 |
+
hideForm: function () {
|
438 |
+
MediumEditor.extensions.form.prototype.hideForm.apply(this);
|
439 |
+
this.getInput().value = '';
|
440 |
+
},
|
441 |
+
|
442 |
+
showForm: function (opts) {
|
443 |
+
var input = this.getInput(),
|
444 |
+
targetCheckbox = this.getAnchorTargetCheckbox(),
|
445 |
+
nofollowCheckbox = this.getAnchorNofollowCheckbox(),
|
446 |
+
buttonCheckbox = this.getAnchorButtonCheckbox();
|
447 |
+
|
448 |
+
opts = opts || { value: '' };
|
449 |
+
// TODO: This is for backwards compatability
|
450 |
+
// We don't need to support the 'string' argument in 6.0.0
|
451 |
+
if (typeof opts === 'string') {
|
452 |
+
opts = {
|
453 |
+
value: opts
|
454 |
+
};
|
455 |
+
}
|
456 |
+
|
457 |
+
this.base.saveSelection();
|
458 |
+
this.hideToolbarDefaultActions();
|
459 |
+
MediumEditor.extensions.form.prototype.showForm.apply(this);
|
460 |
+
this.setToolbarPosition();
|
461 |
+
|
462 |
+
input.value = opts.value;
|
463 |
+
input.focus();
|
464 |
+
|
465 |
+
// If we have a target checkbox, we want it to be checked/unchecked
|
466 |
+
// based on whether the existing link has target=_blank
|
467 |
+
if (targetCheckbox) {
|
468 |
+
targetCheckbox.checked = opts.target === '_blank';
|
469 |
+
}
|
470 |
+
|
471 |
+
if (nofollowCheckbox) {
|
472 |
+
nofollowCheckbox.checked = opts.rel === 'nofollow';
|
473 |
+
}
|
474 |
+
|
475 |
+
// If we have a custom class checkbox, we want it to be checked/unchecked
|
476 |
+
// based on whether an existing link already has the class
|
477 |
+
if (buttonCheckbox) {
|
478 |
+
var classList = opts.buttonClass ? opts.buttonClass.split(' ') : [];
|
479 |
+
buttonCheckbox.checked = (classList.indexOf(this.customClassOption) !== -1);
|
480 |
+
}
|
481 |
+
},
|
482 |
+
|
483 |
+
// Called by core when tearing down medium-editor (destroy)
|
484 |
+
destroy: function () {
|
485 |
+
if (!this.form) {
|
486 |
+
return false;
|
487 |
+
}
|
488 |
+
|
489 |
+
if (this.form.parentNode) {
|
490 |
+
this.form.parentNode.removeChild(this.form);
|
491 |
+
}
|
492 |
+
|
493 |
+
delete this.form;
|
494 |
+
},
|
495 |
+
|
496 |
+
// core methods
|
497 |
+
|
498 |
+
getFormOpts: function () {
|
499 |
+
// no notion of private functions? wanted `_getFormOpts`
|
500 |
+
var targetCheckbox = this.getAnchorTargetCheckbox(),
|
501 |
+
nofollowCheckbox = this.getAnchorNofollowCheckbox(),
|
502 |
+
buttonCheckbox = this.getAnchorButtonCheckbox(),
|
503 |
+
opts = {
|
504 |
+
value: this.getInput().value.trim()
|
505 |
+
};
|
506 |
+
|
507 |
+
if (this.linkValidation) {
|
508 |
+
opts.value = this.checkLinkFormat(opts.value);
|
509 |
+
}
|
510 |
+
|
511 |
+
opts.target = '_self';
|
512 |
+
if (targetCheckbox && targetCheckbox.checked) {
|
513 |
+
opts.target = '_blank';
|
514 |
+
}
|
515 |
+
|
516 |
+
opts.rel = '';
|
517 |
+
if (nofollowCheckbox && nofollowCheckbox.checked) {
|
518 |
+
opts.rel = 'nofollow';
|
519 |
+
}
|
520 |
+
|
521 |
+
if (buttonCheckbox && buttonCheckbox.checked) {
|
522 |
+
opts.buttonClass = this.customClassOption;
|
523 |
+
}
|
524 |
+
|
525 |
+
return opts;
|
526 |
+
},
|
527 |
+
|
528 |
+
doFormSave: function () {
|
529 |
+
var opts = this.getFormOpts();
|
530 |
+
this.completeFormSave(opts);
|
531 |
+
},
|
532 |
+
|
533 |
+
completeFormSave: function (opts) {
|
534 |
+
this.base.restoreSelection();
|
535 |
+
this.execAction(this.action, opts);
|
536 |
+
this.base.checkSelection();
|
537 |
+
},
|
538 |
+
|
539 |
+
ensureEncodedUri: function (str) {
|
540 |
+
return str === decodeURI(str) ? encodeURI(str) : str;
|
541 |
+
},
|
542 |
+
|
543 |
+
ensureEncodedUriComponent: function (str) {
|
544 |
+
return str === decodeURIComponent(str) ? encodeURIComponent(str) : str;
|
545 |
+
},
|
546 |
+
|
547 |
+
ensureEncodedParam: function (param) {
|
548 |
+
var split = param.split('='),
|
549 |
+
key = split[0],
|
550 |
+
val = split[1];
|
551 |
+
|
552 |
+
return key + (val === undefined ? '' : '=' + this.ensureEncodedUriComponent(val));
|
553 |
+
},
|
554 |
+
|
555 |
+
ensureEncodedQuery: function (queryString) {
|
556 |
+
return queryString.split('&').map(this.ensureEncodedParam.bind(this)).join('&');
|
557 |
+
},
|
558 |
+
|
559 |
+
checkLinkFormat: function (value) {
|
560 |
+
// Matches any alphabetical characters followed by ://
|
561 |
+
// Matches protocol relative "//"
|
562 |
+
// Matches common external protocols "mailto:" "tel:" "maps:"
|
563 |
+
// Matches relative hash link, begins with "#"
|
564 |
+
var urlSchemeRegex = /^([a-z]+:)?\/\/|^(mailto|tel|maps):|^\#/i,
|
565 |
+
// telRegex is a regex for checking if the string is a telephone number
|
566 |
+
telRegex = /^\+?\s?\(?(?:\d\s?\-?\)?){3,20}$/,
|
567 |
+
split = value.split('?'),
|
568 |
+
path = split[0],
|
569 |
+
query = split[1];
|
570 |
+
|
571 |
+
if (telRegex.test(value)) {
|
572 |
+
return 'tel:' + value;
|
573 |
+
} else {
|
574 |
+
// Check for URL scheme and default to http:// if none found
|
575 |
+
return (urlSchemeRegex.test(value) ? '' : 'http://') +
|
576 |
+
// Ensure path is encoded
|
577 |
+
this.ensureEncodedUri(path) +
|
578 |
+
// Ensure query is encoded
|
579 |
+
(query === undefined ? '' : '?' + this.ensureEncodedQuery(query));
|
580 |
+
}
|
581 |
+
},
|
582 |
+
|
583 |
+
doFormCancel: function () {
|
584 |
+
this.base.restoreSelection();
|
585 |
+
this.base.checkSelection();
|
586 |
+
},
|
587 |
+
|
588 |
+
// form creation and event handling
|
589 |
+
attachFormEvents: function (form) {
|
590 |
+
var close = form.querySelector('.medium-editor-toolbar-close'),
|
591 |
+
save = form.querySelector('.medium-editor-toolbar-save'),
|
592 |
+
input = form.querySelector('.medium-editor-toolbar-input');
|
593 |
+
|
594 |
+
// Handle clicks on the form itself
|
595 |
+
this.on(form, 'click', this.handleFormClick.bind(this));
|
596 |
+
|
597 |
+
// Handle typing in the textbox
|
598 |
+
this.on(input, 'keyup', this.handleTextboxKeyup.bind(this));
|
599 |
+
|
600 |
+
// Handle close button clicks
|
601 |
+
this.on(close, 'click', this.handleCloseClick.bind(this));
|
602 |
+
|
603 |
+
// Handle save button clicks (capture)
|
604 |
+
this.on(save, 'click', this.handleSaveClick.bind(this), true);
|
605 |
+
|
606 |
+
},
|
607 |
+
|
608 |
+
createForm: function () {
|
609 |
+
var doc = this.document,
|
610 |
+
form = doc.createElement('div');
|
611 |
+
|
612 |
+
// Anchor Form (div)
|
613 |
+
form.className = 'medium-editor-toolbar-form';
|
614 |
+
form.id = 'medium-editor-toolbar-form-anchor-' + this.getEditorId();
|
615 |
+
form.innerHTML = this.getTemplate();
|
616 |
+
this.attachFormEvents(form);
|
617 |
+
|
618 |
+
return form;
|
619 |
+
},
|
620 |
+
|
621 |
+
getInput: function () {
|
622 |
+
return this.getForm().querySelector('input.medium-editor-toolbar-input');
|
623 |
+
},
|
624 |
+
|
625 |
+
getAnchorTargetCheckbox: function () {
|
626 |
+
return this.getForm().querySelector('.medium-editor-toolbar-anchor-target');
|
627 |
+
},
|
628 |
+
|
629 |
+
getAnchorNofollowCheckbox: function () {
|
630 |
+
return this.getForm().querySelector('.medium-editor-toolbar-anchor-nofollow');
|
631 |
+
},
|
632 |
+
|
633 |
+
getAnchorButtonCheckbox: function () {
|
634 |
+
return this.getForm().querySelector('.medium-editor-toolbar-anchor-button');
|
635 |
+
},
|
636 |
+
|
637 |
+
handleTextboxKeyup: function (event) {
|
638 |
+
// For ENTER -> create the anchor
|
639 |
+
if (event.keyCode === MediumEditor.util.keyCode.ENTER) {
|
640 |
+
event.preventDefault();
|
641 |
+
this.doFormSave();
|
642 |
+
return;
|
643 |
+
}
|
644 |
+
|
645 |
+
// For ESCAPE -> close the form
|
646 |
+
if (event.keyCode === MediumEditor.util.keyCode.ESCAPE) {
|
647 |
+
event.preventDefault();
|
648 |
+
this.doFormCancel();
|
649 |
+
}
|
650 |
+
},
|
651 |
+
|
652 |
+
handleFormClick: function (event) {
|
653 |
+
// make sure not to hide form when clicking inside the form
|
654 |
+
event.stopPropagation();
|
655 |
+
},
|
656 |
+
|
657 |
+
handleSaveClick: function (event) {
|
658 |
+
// Clicking Save -> create the anchor
|
659 |
+
event.preventDefault();
|
660 |
+
this.doFormSave();
|
661 |
+
},
|
662 |
+
|
663 |
+
handleCloseClick: function (event) {
|
664 |
+
// Click Close -> close the form
|
665 |
+
event.preventDefault();
|
666 |
+
this.doFormCancel();
|
667 |
+
}
|
668 |
});
|
includes/admin/class-wprm-recipe-parser.php
CHANGED
@@ -20,16 +20,74 @@
|
|
20 |
class WPRM_Recipe_Parser {
|
21 |
|
22 |
/**
|
23 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
*
|
25 |
* @since 1.0.0
|
26 |
-
* @param
|
27 |
*/
|
28 |
public static function parse_ingredient( $raw ) {
|
29 |
// Amount.
|
30 |
$amount = '';
|
31 |
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
if ( isset( $match[0] ) ) {
|
34 |
$amount = trim( $match[1] );
|
35 |
$raw = trim( $match[2] );
|
@@ -186,3 +244,5 @@ class WPRM_Recipe_Parser {
|
|
186 |
return array_map( 'sanitize_text_field', $units );
|
187 |
}
|
188 |
}
|
|
|
|
20 |
class WPRM_Recipe_Parser {
|
21 |
|
22 |
/**
|
23 |
+
* Register actions and filters.
|
24 |
+
*
|
25 |
+
* @since 1.7.0
|
26 |
+
*/
|
27 |
+
public static function init() {
|
28 |
+
add_action( 'wp_ajax_wprm_parse_ingredients', array( __CLASS__, 'ajax_parse_ingredients' ) );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Parse ingredients submitted through AJAX.
|
33 |
+
*
|
34 |
+
* @since 1.7.0
|
35 |
+
*/
|
36 |
+
public static function ajax_parse_ingredients() {
|
37 |
+
if ( check_ajax_referer( 'wprm', 'security', false ) ) {
|
38 |
+
$ingredients = isset( $_POST['ingredients'] ) ? wp_unslash( $_POST['ingredients'] ) : array(); // Input var okay.
|
39 |
+
$parsed_ingredients = array();
|
40 |
+
$parsed_ingredient_group = array();
|
41 |
+
|
42 |
+
foreach ( $ingredients as $ingredient_or_group ) {
|
43 |
+
if ( isset( $ingredient_or_group['raw'] ) ) {
|
44 |
+
$parsed_ingredients[] = self::parse_ingredient( $ingredient_or_group['raw'] );
|
45 |
+
} elseif ( isset( $ingredient_or_group['ingredients'] ) ) {
|
46 |
+
$parsed_group_ingredients = array();
|
47 |
+
|
48 |
+
foreach ( $ingredient_or_group['ingredients'] as $ingredient ) {
|
49 |
+
$parsed_group_ingredients[] = self::parse_ingredient( $ingredient['raw'] );
|
50 |
+
}
|
51 |
+
$parsed_ingredients[] = array(
|
52 |
+
'name' => $ingredient_or_group['name'],
|
53 |
+
'ingredients' => $parsed_group_ingredients,
|
54 |
+
);
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
wp_send_json_success( array(
|
59 |
+
'ingredients' => $parsed_ingredients,
|
60 |
+
) );
|
61 |
+
}
|
62 |
+
|
63 |
+
wp_die();
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Parse text to ingredient fields.
|
68 |
*
|
69 |
* @since 1.0.0
|
70 |
+
* @param mixed $raw Text to parse into an ingredient.
|
71 |
*/
|
72 |
public static function parse_ingredient( $raw ) {
|
73 |
// Amount.
|
74 |
$amount = '';
|
75 |
|
76 |
+
$unicode_map = array(
|
77 |
+
'00BC' => ' 1/4', '00BD' => ' 1/2', '00BE' => ' 3/4', '2150' => ' 1/7',
|
78 |
+
'2151' => ' 1/9', '2152' => ' 1/10', '2153' => ' 1/3', '2154' => ' 2/3',
|
79 |
+
'2155' => ' 1/5', '2156' => ' 2/5', '2157' => ' 3/5', '2158' => ' 4/5',
|
80 |
+
'2159' => ' 1/6', '215A' => ' 5/6', '215B' => ' 1/8', '215C' => ' 3/8',
|
81 |
+
'215D' => ' 5/8', '215E' => ' 7/8'
|
82 |
+
);
|
83 |
+
|
84 |
+
$unicode_regex = '';
|
85 |
+
foreach ( $unicode_map as $unicode => $normal ) {
|
86 |
+
$unicode_regex .= '\x{' . $unicode . '}';
|
87 |
+
}
|
88 |
+
$amount_regex = '/^\s*([\d' . $unicode_regex . '][\s\/\-\d.,' . $unicode_regex . ']*)(.*)/u';
|
89 |
+
|
90 |
+
preg_match( $amount_regex, $raw, $match );
|
91 |
if ( isset( $match[0] ) ) {
|
92 |
$amount = trim( $match[1] );
|
93 |
$raw = trim( $match[2] );
|
244 |
return array_map( 'sanitize_text_field', $units );
|
245 |
}
|
246 |
}
|
247 |
+
|
248 |
+
WPRM_Recipe_Parser::init();
|
includes/admin/import/class-wprm-import-bigoven.php
ADDED
@@ -0,0 +1,291 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Responsible for importing BigOven recipes.
|
4 |
+
*
|
5 |
+
* @link http://bootstrapped.ventures
|
6 |
+
* @since 1.7.0
|
7 |
+
*
|
8 |
+
* @package WP_Recipe_Maker
|
9 |
+
* @subpackage WP_Recipe_Maker/includes/admin/import
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Responsible for importing BigOven recipes.
|
14 |
+
*
|
15 |
+
* @since 1.7.0
|
16 |
+
* @package WP_Recipe_Maker
|
17 |
+
* @subpackage WP_Recipe_Maker/includes/admin/import
|
18 |
+
* @author Brecht Vandersmissen <brecht@bootstrapped.ventures>
|
19 |
+
*/
|
20 |
+
class WPRM_Import_Bigoven extends WPRM_Import {
|
21 |
+
/**
|
22 |
+
* Get the UID of this import source.
|
23 |
+
*
|
24 |
+
* @since 1.7.0
|
25 |
+
*/
|
26 |
+
public function get_uid() {
|
27 |
+
return 'bigoven';
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Get the name of this import source.
|
32 |
+
*
|
33 |
+
* @since 1.7.0
|
34 |
+
*/
|
35 |
+
public function get_name() {
|
36 |
+
return 'BigOven';
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Get HTML for the import settings.
|
41 |
+
*
|
42 |
+
* @since 1.7.0
|
43 |
+
*/
|
44 |
+
public function get_settings_html() {
|
45 |
+
return '';
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Get a list of recipes that are available to import.
|
50 |
+
*
|
51 |
+
* @since 1.7.0
|
52 |
+
*/
|
53 |
+
public function get_recipes() {
|
54 |
+
$recipes = array();
|
55 |
+
|
56 |
+
// Loop through all posts.
|
57 |
+
$limit = 100;
|
58 |
+
$offset = 0;
|
59 |
+
|
60 |
+
while ( true ) {
|
61 |
+
$args = array(
|
62 |
+
'post_type' => 'bo-recipe',
|
63 |
+
'post_status' => 'any',
|
64 |
+
'orderby' => 'date',
|
65 |
+
'order' => 'DESC',
|
66 |
+
'posts_per_page' => $limit,
|
67 |
+
'offset' => $offset,
|
68 |
+
);
|
69 |
+
|
70 |
+
$query = new WP_Query( $args );
|
71 |
+
|
72 |
+
if ( ! $query->have_posts() ) {
|
73 |
+
break;
|
74 |
+
}
|
75 |
+
|
76 |
+
$posts = $query->posts;
|
77 |
+
|
78 |
+
foreach ( $posts as $post ) {
|
79 |
+
$recipes[ $post->ID ] = array(
|
80 |
+
'name' => $post->post_title,
|
81 |
+
'url' => get_edit_post_link( $post->ID ),
|
82 |
+
);
|
83 |
+
|
84 |
+
wp_cache_delete( $post->ID, 'posts' );
|
85 |
+
wp_cache_delete( $post->ID, 'post_meta' );
|
86 |
+
}
|
87 |
+
|
88 |
+
$offset += $limit;
|
89 |
+
wp_cache_flush();
|
90 |
+
}
|
91 |
+
|
92 |
+
return $recipes;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Get recipe with the specified ID in the import format.
|
97 |
+
*
|
98 |
+
* @since 1.7.0
|
99 |
+
* @param mixed $id ID of the recipe we want to import.
|
100 |
+
* @param array $post_data POST data passed along when submitting the form.
|
101 |
+
*/
|
102 |
+
public function get_recipe( $id, $post_data ) {
|
103 |
+
$recipe = array(
|
104 |
+
'import_id' => $id,
|
105 |
+
'import_backup' => array(
|
106 |
+
'bo_recipe_id' => $id,
|
107 |
+
),
|
108 |
+
);
|
109 |
+
|
110 |
+
$post = get_post( $id );
|
111 |
+
$bo_recipe = get_post_meta( $id, 'clc-recipe-attributes', true );
|
112 |
+
|
113 |
+
// Featured Image.
|
114 |
+
$recipe['image_id'] = get_post_thumbnail_id( $id );
|
115 |
+
|
116 |
+
// Simple Matching.
|
117 |
+
$recipe['name'] = $post->post_title;
|
118 |
+
$recipe['summary'] = $post->post_content;
|
119 |
+
|
120 |
+
// Servings.
|
121 |
+
$match = preg_match( '/^\s*\d+/', $bo_recipe['yield'], $servings_array );
|
122 |
+
if ( 1 === $match ) {
|
123 |
+
$servings = str_replace( ' ','', $servings_array[0] );
|
124 |
+
} else {
|
125 |
+
$servings = '';
|
126 |
+
}
|
127 |
+
|
128 |
+
$servings_unit = preg_replace( '/^\s*\d+\s*/', '', $bo_recipe['yield'] );
|
129 |
+
|
130 |
+
$recipe['servings'] = $servings;
|
131 |
+
$recipe['servings_unit'] = $servings_unit;
|
132 |
+
|
133 |
+
// Recipe Times.
|
134 |
+
$recipe['prep_time'] = $bo_recipe['time-preparation'] ? $this->time_to_minutes( $bo_recipe['time-preparation'] ) : 0;
|
135 |
+
$recipe['cook_time'] = $bo_recipe['time-cook'] ? $this->time_to_minutes( $bo_recipe['time-cook'] ) : 0;
|
136 |
+
$recipe['total_time'] = $bo_recipe['time-total'] ? $this->time_to_minutes( $bo_recipe['time-total'] ) : 0;
|
137 |
+
|
138 |
+
// Ingredients.
|
139 |
+
$ingredients = array();
|
140 |
+
$group = array(
|
141 |
+
'ingredients' => array(),
|
142 |
+
'name' => '',
|
143 |
+
);
|
144 |
+
|
145 |
+
$bo_ingredients = preg_split( '/$\R?^/m', $bo_recipe['ingredients'] );
|
146 |
+
|
147 |
+
foreach ( $bo_ingredients as $bo_ingredient ) {
|
148 |
+
$bo_ingredient = $this->derichify( $bo_ingredient );
|
149 |
+
|
150 |
+
if ( '!' === substr( $bo_ingredient, 0, 1 ) ) {
|
151 |
+
$ingredients[] = $group;
|
152 |
+
$group = array(
|
153 |
+
'ingredients' => array(),
|
154 |
+
'name' => substr( $bo_ingredient, 1 ),
|
155 |
+
);
|
156 |
+
} else {
|
157 |
+
$group['ingredients'][] = array(
|
158 |
+
'raw' => $bo_ingredient,
|
159 |
+
);
|
160 |
+
}
|
161 |
+
}
|
162 |
+
$ingredients[] = $group;
|
163 |
+
$recipe['ingredients'] = $ingredients;
|
164 |
+
|
165 |
+
// Instructions.
|
166 |
+
$instructions = array();
|
167 |
+
$group = array(
|
168 |
+
'instructions' => array(),
|
169 |
+
'name' => '',
|
170 |
+
);
|
171 |
+
|
172 |
+
$bo_instructions = preg_split( '/$\R?^/m', $bo_recipe['instructions'] );
|
173 |
+
|
174 |
+
foreach ( $bo_instructions as $bo_instruction ) {
|
175 |
+
if ( '!' === substr( $bo_instruction, 0, 1 ) ) {
|
176 |
+
$instructions[] = $group;
|
177 |
+
$group = array(
|
178 |
+
'instructions' => array(),
|
179 |
+
'name' => $this->derichify( substr( $bo_instruction, 1 ) ),
|
180 |
+
);
|
181 |
+
} else {
|
182 |
+
$group['instructions'][] = array(
|
183 |
+
'text' => $this->richify( $bo_instruction ),
|
184 |
+
);
|
185 |
+
}
|
186 |
+
}
|
187 |
+
$instructions[] = $group;
|
188 |
+
$recipe['instructions'] = $instructions;
|
189 |
+
|
190 |
+
// Nutrition Facts.
|
191 |
+
$recipe['nutrition'] = array();
|
192 |
+
|
193 |
+
$recipe['nutrition']['serving_size'] = $bo_recipe['serving-size'];
|
194 |
+
$recipe['nutrition']['calories'] = $bo_recipe['nutrition-calories'];
|
195 |
+
$recipe['nutrition']['fat'] = $bo_recipe['nutrition-fat'];
|
196 |
+
$recipe['nutrition']['carbohydrates'] = $bo_recipe['nutrition-carbohydrates'];
|
197 |
+
$recipe['nutrition']['protein'] = $bo_recipe['nutrition-protein'];
|
198 |
+
|
199 |
+
return $recipe;
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Replace the original recipe with the newly imported WPRM one.
|
204 |
+
*
|
205 |
+
* @since 1.7.0
|
206 |
+
* @param mixed $id ID of the recipe we want replace.
|
207 |
+
* @param mixed $wprm_id ID of the WPRM recipe to replace with.
|
208 |
+
* @param array $post_data POST data passed along when submitting the form.
|
209 |
+
*/
|
210 |
+
public function replace_recipe( $id, $wprm_id, $post_data ) {
|
211 |
+
// We don't know which posts use this recipe so we rely on the fallback shortcode.
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Richify text by adding links and styling.
|
216 |
+
*
|
217 |
+
* @since 1.7.0
|
218 |
+
* @param mixed $text Text to richify.
|
219 |
+
*/
|
220 |
+
private function richify( $text ) {
|
221 |
+
$output = $text;
|
222 |
+
|
223 |
+
$link_ptr = '#\[(.*?)\]\((.*?)\)#';
|
224 |
+
preg_match_all(
|
225 |
+
$link_ptr,
|
226 |
+
$text,
|
227 |
+
$matches
|
228 |
+
);
|
229 |
+
|
230 |
+
if ( isset( $matches[0] ) ) {
|
231 |
+
$orig = $matches[0];
|
232 |
+
$substitution = preg_replace(
|
233 |
+
$link_ptr,
|
234 |
+
'<a href="\\2">\\1</a>',
|
235 |
+
str_replace( '"', '', $orig )
|
236 |
+
);
|
237 |
+
$output = str_replace( $orig, $substitution, $text );
|
238 |
+
}
|
239 |
+
|
240 |
+
$output = preg_replace( '#\*\*(.*?)\*\*#s', '<strong>\1</strong>', $output );
|
241 |
+
$output = preg_replace( '#\*(.*?)\*#s', '<em>\1</em>', $output );
|
242 |
+
return $output;
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Derichify text by removing links and styling.
|
247 |
+
*
|
248 |
+
* @since 1.7.0
|
249 |
+
* @param mixed $text Text to derichify.
|
250 |
+
*/
|
251 |
+
private function derichify( $text ) {
|
252 |
+
$output = $text;
|
253 |
+
|
254 |
+
$link_ptr = '#\[(.*?)\]\((.*?)\)#';
|
255 |
+
preg_match_all(
|
256 |
+
$link_ptr,
|
257 |
+
$text,
|
258 |
+
$matches
|
259 |
+
);
|
260 |
+
|
261 |
+
if ( isset( $matches[0] ) ) {
|
262 |
+
$orig = $matches[0];
|
263 |
+
$substitution = preg_replace(
|
264 |
+
$link_ptr,
|
265 |
+
'\\1',
|
266 |
+
str_replace( '"', '', $orig )
|
267 |
+
);
|
268 |
+
$output = str_replace( $orig, $substitution, $text );
|
269 |
+
}
|
270 |
+
|
271 |
+
$output = preg_replace( '#\*\*(.*?)\*\*#s', '\1', $output );
|
272 |
+
$output = preg_replace( '#\*(.*?)\*#s', '\1', $output );
|
273 |
+
return $output;
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Convert time field to minutes.
|
278 |
+
*
|
279 |
+
* @since 1.7.0
|
280 |
+
* @param mixed $time_string Time to convert.
|
281 |
+
*/
|
282 |
+
private function time_to_minutes( $time_string ) {
|
283 |
+
$time = strtotime( $time_string, 0 );
|
284 |
+
|
285 |
+
if ( $time ) {
|
286 |
+
return intval( ceil( $time / 60 ) );
|
287 |
+
} else {
|
288 |
+
return 0;
|
289 |
+
}
|
290 |
+
}
|
291 |
+
}
|
includes/admin/import/class-wprm-import-mealplannerpro.php
ADDED
@@ -0,0 +1,396 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Responsible for importing Meal Planner Pro recipes.
|
4 |
+
*
|
5 |
+
* @link http://bootstrapped.ventures
|
6 |
+
* @since 1.7.0
|
7 |
+
*
|
8 |
+
* @package WP_Recipe_Maker
|
9 |
+
* @subpackage WP_Recipe_Maker/includes/admin/import
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Responsible for importing Meal Planner Pro recipes.
|
14 |
+
*
|
15 |
+
* @since 1.7.0
|
16 |
+
* @package WP_Recipe_Maker
|
17 |
+
* @subpackage WP_Recipe_Maker/includes/admin/import
|
18 |
+
* @author Brecht Vandersmissen <brecht@bootstrapped.ventures>
|
19 |
+
*/
|
20 |
+
class WPRM_Import_Mealplannerpro extends WPRM_Import {
|
21 |
+
/**
|
22 |
+
* Get the UID of this import source.
|
23 |
+
*
|
24 |
+
* @since 1.7.0
|
25 |
+
*/
|
26 |
+
public function get_uid() {
|
27 |
+
return 'mealplannerpro';
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Get the name of this import source.
|
32 |
+
*
|
33 |
+
* @since 1.7.0
|
34 |
+
*/
|
35 |
+
public function get_name() {
|
36 |
+
return 'Meal Planner Pro';
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Get HTML for the import settings.
|
41 |
+
*
|
42 |
+
* @since 1.7.0
|
43 |
+
*/
|
44 |
+
public function get_settings_html() {
|
45 |
+
return '';
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Get a list of recipes that are available to import.
|
50 |
+
*
|
51 |
+
* @since 1.7.0
|
52 |
+
*/
|
53 |
+
public function get_recipes() {
|
54 |
+
$recipes = array();
|
55 |
+
|
56 |
+
global $wpdb;
|
57 |
+
$mpp_recipes = $wpdb->get_results( 'SELECT recipe_id, post_id, server_recipe_id, recipe_title FROM ' . $wpdb->prefix . 'mpprecipe_recipes' );
|
58 |
+
|
59 |
+
foreach ( $mpp_recipes as $mpp_recipe ) {
|
60 |
+
if ( 'wprm-' !== substr( $mpp_recipe->server_recipe_id, 0, 5 ) ) {
|
61 |
+
$recipes[ $mpp_recipe->recipe_id ] = array(
|
62 |
+
'name' => $mpp_recipe->recipe_title,
|
63 |
+
'url' => get_edit_post_link( $mpp_recipe->post_id ),
|
64 |
+
);
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
return $recipes;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Get recipe with the specified ID in the import format.
|
73 |
+
*
|
74 |
+
* @since 1.7.0
|
75 |
+
* @param mixed $id ID of the recipe we want to import.
|
76 |
+
* @param array $post_data POST data passed along when submitting the form.
|
77 |
+
*/
|
78 |
+
public function get_recipe( $id, $post_data ) {
|
79 |
+
$recipe = array(
|
80 |
+
'import_id' => 0, // Set to 0 because we need to create a new recipe post.
|
81 |
+
'import_backup' => array(
|
82 |
+
'mpp_recipe_id' => $id,
|
83 |
+
),
|
84 |
+
);
|
85 |
+
|
86 |
+
global $wpdb;
|
87 |
+
$mpp_recipe = $wpdb->get_row( 'SELECT * FROM ' . $wpdb->prefix . 'mpprecipe_recipes WHERE recipe_id=' . $id );
|
88 |
+
$post_id = $mpp_recipe->post_id;
|
89 |
+
|
90 |
+
// Featured Image.
|
91 |
+
if ( $mpp_recipe->recipe_image ) {
|
92 |
+
$image_id = $this->get_or_upload_attachment( $post_id, $mpp_recipe->recipe_image );
|
93 |
+
|
94 |
+
if ( $image_id ) {
|
95 |
+
$recipe['image_id'] = $image_id;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
// Simple Matching.
|
100 |
+
$recipe['name'] = $mpp_recipe->recipe_title;
|
101 |
+
$recipe['summary'] = $this->richify( $mpp_recipe->summary );
|
102 |
+
$recipe['notes'] = $this->richify( $mpp_recipe->notes );
|
103 |
+
|
104 |
+
// Author.
|
105 |
+
$recipe['author_name'] = $mpp_recipe->author;
|
106 |
+
if ( '' !== trim( $recipe['author_name'] ) ) {
|
107 |
+
$recipe['author_display'] = 'custom';
|
108 |
+
}
|
109 |
+
|
110 |
+
// Servings.
|
111 |
+
$match = preg_match( '/^\s*\d+/', $mpp_recipe->yield, $servings_array );
|
112 |
+
if ( 1 === $match ) {
|
113 |
+
$servings = str_replace( ' ','', $servings_array[0] );
|
114 |
+
} else {
|
115 |
+
$servings = '';
|
116 |
+
}
|
117 |
+
|
118 |
+
$servings_unit = preg_replace( '/^\s*\d+\s*/', '', $mpp_recipe->yield );
|
119 |
+
|
120 |
+
$recipe['servings'] = $servings;
|
121 |
+
$recipe['servings_unit'] = $servings_unit;
|
122 |
+
|
123 |
+
// Recipe Times.
|
124 |
+
$recipe['prep_time'] = $mpp_recipe->prep_time ? $this->time_to_minutes( $mpp_recipe->prep_time ) : 0;
|
125 |
+
$recipe['cook_time'] = $mpp_recipe->cook_time ? $this->time_to_minutes( $mpp_recipe->cook_time ) : 0;
|
126 |
+
$recipe['total_time'] = $mpp_recipe->total_time ? $this->time_to_minutes( $mpp_recipe->total_time ) : 0;
|
127 |
+
|
128 |
+
// Recipe Tags.
|
129 |
+
$courses = str_replace( ';', ',', $mpp_recipe->type );
|
130 |
+
$courses = preg_split( '/[\s*,\s*]*,+[\s*,\s*]*/', $courses );
|
131 |
+
$courses = '' === $courses[0] ? array() : $courses;
|
132 |
+
|
133 |
+
$cuisines = str_replace( ';', ',', $mpp_recipe->cuisine );
|
134 |
+
$cuisines = preg_split( '/[\s*,\s*]*,+[\s*,\s*]*/', $cuisines );
|
135 |
+
$cuisines = '' === $cuisines[0] ? array() : $cuisines;
|
136 |
+
|
137 |
+
$recipe['tags'] = array(
|
138 |
+
'course' => $courses,
|
139 |
+
'cuisine' => $cuisines,
|
140 |
+
);
|
141 |
+
|
142 |
+
// Ingredients.
|
143 |
+
$ingredients = array();
|
144 |
+
$group = array(
|
145 |
+
'ingredients' => array(),
|
146 |
+
'name' => '',
|
147 |
+
);
|
148 |
+
|
149 |
+
$mpp_ingredients = preg_split( '/$\R?^/m', $mpp_recipe->ingredients );
|
150 |
+
|
151 |
+
foreach ( $mpp_ingredients as $mpp_ingredient ) {
|
152 |
+
$mpp_ingredient = $this->derichify( $mpp_ingredient );
|
153 |
+
|
154 |
+
if ( '!' === substr( $mpp_ingredient, 0, 1 ) ) {
|
155 |
+
$ingredients[] = $group;
|
156 |
+
$group = array(
|
157 |
+
'ingredients' => array(),
|
158 |
+
'name' => substr( $mpp_ingredient, 1 ),
|
159 |
+
);
|
160 |
+
} else {
|
161 |
+
$group['ingredients'][] = array(
|
162 |
+
'raw' => $mpp_ingredient,
|
163 |
+
);
|
164 |
+
}
|
165 |
+
}
|
166 |
+
$ingredients[] = $group;
|
167 |
+
$recipe['ingredients'] = $ingredients;
|
168 |
+
|
169 |
+
// Instructions.
|
170 |
+
$instructions = array();
|
171 |
+
$group = array(
|
172 |
+
'instructions' => array(),
|
173 |
+
'name' => '',
|
174 |
+
);
|
175 |
+
|
176 |
+
$mpp_instructions = preg_split( '/$\R?^/m', $mpp_recipe->instructions );
|
177 |
+
|
178 |
+
foreach ( $mpp_instructions as $mpp_instruction ) {
|
179 |
+
if ( '!' === substr( $mpp_instruction, 0, 1 ) ) {
|
180 |
+
$instructions[] = $group;
|
181 |
+
$group = array(
|
182 |
+
'instructions' => array(),
|
183 |
+
'name' => $this->derichify( substr( $mpp_instruction, 1 ) ),
|
184 |
+
);
|
185 |
+
} else {
|
186 |
+
$group['instructions'][] = array(
|
187 |
+
'text' => $this->richify( $mpp_instruction ),
|
188 |
+
);
|
189 |
+
}
|
190 |
+
}
|
191 |
+
$instructions[] = $group;
|
192 |
+
$recipe['instructions'] = $instructions;
|
193 |
+
|
194 |
+
// Nutrition Facts.
|
195 |
+
$recipe['nutrition'] = array();
|
196 |
+
|
197 |
+
return $recipe;
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Replace the original recipe with the newly imported WPRM one.
|
202 |
+
*
|
203 |
+
* @since 1.7.0
|
204 |
+
* @param mixed $id ID of the recipe we want replace.
|
205 |
+
* @param mixed $wprm_id ID of the WPRM recipe to replace with.
|
206 |
+
* @param array $post_data POST data passed along when submitting the form.
|
207 |
+
*/
|
208 |
+
public function replace_recipe( $id, $wprm_id, $post_data ) {
|
209 |
+
global $wpdb;
|
210 |
+
$mpp_recipe = $wpdb->get_row( 'SELECT post_id, server_recipe_id FROM ' . $wpdb->prefix . 'mpprecipe_recipes WHERE recipe_id=' . $id );
|
211 |
+
$post_id = $mpp_recipe->post_id;
|
212 |
+
$server_recipe_id = $mpp_recipe->server_recipe_id;
|
213 |
+
|
214 |
+
// Update server_recipe_id field to show that this recipe has been imported.
|
215 |
+
$wpdb->update( $wpdb->prefix . 'mpprecipe_recipes', array( 'server_recipe_id' => 'wprm-' . $server_recipe_id ), array( 'recipe_id' => $id ), array( '%s' ), array( '%d' ) );
|
216 |
+
|
217 |
+
$post = get_post( $post_id );
|
218 |
+
$content = $post->post_content;
|
219 |
+
|
220 |
+
$content = str_ireplace( '[mpprecipe-recipe:' . $id . ']', '[wprm-recipe id="' . $wprm_id . '"]', $content );
|
221 |
+
|
222 |
+
$update_content = array(
|
223 |
+
'ID' => $post_id,
|
224 |
+
'post_content' => $content,
|
225 |
+
);
|
226 |
+
wp_update_post( $update_content );
|
227 |
+
}
|
228 |
+
|
229 |
+
/**
|
230 |
+
* Richify text by adding links and styling.
|
231 |
+
* Source: Meal Planner Pro.
|
232 |
+
*
|
233 |
+
* @since 1.7.0
|
234 |
+
* @param mixed $text Text to richify.
|
235 |
+
*/
|
236 |
+
private function richify( $text ) {
|
237 |
+
$output = $text;
|
238 |
+
|
239 |
+
$link_ptr = '#\[(.*?)\|(.*?)( (.*?))?\]#';
|
240 |
+
preg_match_all(
|
241 |
+
$link_ptr,
|
242 |
+
$text,
|
243 |
+
$matches
|
244 |
+
);
|
245 |
+
|
246 |
+
if ( isset( $matches[0] ) ) {
|
247 |
+
|
248 |
+
$orig = $matches[0];
|
249 |
+
$substitution = preg_replace(
|
250 |
+
$link_ptr,
|
251 |
+
'<a href="\\2" target="_blank" \\3>\\1</a>',
|
252 |
+
str_replace( '"', '', $orig )
|
253 |
+
);
|
254 |
+
$output = str_replace( $orig, $substitution, $text );
|
255 |
+
}
|
256 |
+
|
257 |
+
$output = preg_replace( '/(^|\s)\*([^\s\*][^\*]*[^\s\*]|[^\s\*])\*(\W|$)/', '\\1<span class="bold">\\2</span>\\3', $output );
|
258 |
+
$output = preg_replace( '#\[br\]#', '<br/>', $output );
|
259 |
+
$output = preg_replace( '#\[b\](.*?)\[\/b\]#s', '<strong>\1</strong>', $output );
|
260 |
+
$output = preg_replace( '#\[i\](.*?)\[\/i\]#s', '<em>\1</em>', $output );
|
261 |
+
$output = preg_replace( '#\[u\](.*?)\[\/u\]#s', '<u>\1</u>', $output );
|
262 |
+
return preg_replace( '/(^|\s)_([^\s_][^_]*[^\s_]|[^\s_])_(\W|$)/', '\\1<span class="italic">\\2</span>\\3', $output );
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* Derichify text by removing links and styling.
|
267 |
+
*
|
268 |
+
* @since 1.7.0
|
269 |
+
* @param mixed $text Text to derichify.
|
270 |
+
*/
|
271 |
+
private function derichify( $text ) {
|
272 |
+
$output = $text;
|
273 |
+
|
274 |
+
$link_ptr = '#\[(.*?)\|(.*?)( (.*?))?\]#';
|
275 |
+
preg_match_all(
|
276 |
+
$link_ptr,
|
277 |
+
$text,
|
278 |
+
$matches
|
279 |
+
);
|
280 |
+
|
281 |
+
if ( isset( $matches[0] ) ) {
|
282 |
+
|
283 |
+
$orig = $matches[0];
|
284 |
+
$substitution = preg_replace(
|
285 |
+
$link_ptr,
|
286 |
+
'\\1',
|
287 |
+
str_replace( '"', '', $orig )
|
288 |
+
);
|
289 |
+
$output = str_replace( $orig, $substitution, $text );
|
290 |
+
}
|
291 |
+
|
292 |
+
$output = preg_replace( '/(^|\s)\*([^\s\*][^\*]*[^\s\*]|[^\s\*])\*(\W|$)/', '\\1\\2\\3', $output );
|
293 |
+
$output = preg_replace( '#\[br\]#', '', $output );
|
294 |
+
$output = preg_replace( '#\[b\](.*?)\[\/b\]#s', '\1', $output );
|
295 |
+
$output = preg_replace( '#\[i\](.*?)\[\/i\]#s', '\1', $output );
|
296 |
+
$output = preg_replace( '#\[u\](.*?)\[\/u\]#s', '\1', $output );
|
297 |
+
return preg_replace( '/(^|\s)_([^\s_][^_]*[^\s_]|[^\s_])_(\W|$)/', '\\1\\2\\3', $output );
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Convert time metadata to minutes.
|
302 |
+
*
|
303 |
+
* @since 1.7.0
|
304 |
+
* @param mixed $duration Time to convert.
|
305 |
+
*/
|
306 |
+
private function time_to_minutes( $duration = 'PT' ) {
|
307 |
+
$date_abbr = array(
|
308 |
+
'd' => 60 * 24,
|
309 |
+
'h' => 60,
|
310 |
+
'i' => 1,
|
311 |
+
);
|
312 |
+
$result = 0;
|
313 |
+
|
314 |
+
$arr = explode( 'T', $duration );
|
315 |
+
if ( isset( $arr[1] ) ) {
|
316 |
+
$arr[1] = str_replace( 'M', 'I', $arr[1] );
|
317 |
+
}
|
318 |
+
$duration = implode( 'T', $arr );
|
319 |
+
|
320 |
+
foreach ( $date_abbr as $abbr => $time ) {
|
321 |
+
if ( preg_match( '/(\d+)' . $abbr . '/i', $duration, $val ) ) {
|
322 |
+
$result += intval( $val[1] ) * $time;
|
323 |
+
}
|
324 |
+
}
|
325 |
+
|
326 |
+
return $result;
|
327 |
+
}
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Get image attachment ID from a given URL or sideload the image if not on the website.
|
331 |
+
*
|
332 |
+
* @since 1.7.0
|
333 |
+
* @param int $post_id Post to associate the image with.
|
334 |
+
* @param mixed $url Image URL.
|
335 |
+
*/
|
336 |
+
private function get_or_upload_attachment( $post_id, $url ) {
|
337 |
+
$image_id = $this->get_attachment_id_from_url( $url );
|
338 |
+
|
339 |
+
if ( $image_id ) {
|
340 |
+
return $image_id;
|
341 |
+
} else {
|
342 |
+
$media = media_sideload_image( $url, $post_id );
|
343 |
+
|
344 |
+
$attachments = get_posts( array(
|
345 |
+
'numberposts' => '1',
|
346 |
+
'post_parent' => $post_id,
|
347 |
+
'post_type' => 'attachment',
|
348 |
+
'post_mime_type' => 'image',
|
349 |
+
'orderby' => 'post_date',
|
350 |
+
'order' => 'DESC',
|
351 |
+
)
|
352 |
+
);
|
353 |
+
|
354 |
+
if ( count( $attachments ) > 0 ) {
|
355 |
+
return $attachments[0]->ID;
|
356 |
+
}
|
357 |
+
}
|
358 |
+
|
359 |
+
return false;
|
360 |
+
}
|
361 |
+
|
362 |
+
/**
|
363 |
+
* Get image attachment ID from a given URL.
|
364 |
+
* Source: https://philipnewcomer.net/2012/11/get-the-attachment-id-from-an-image-url-in-wordpress/
|
365 |
+
*
|
366 |
+
* @since 1.7.0
|
367 |
+
* @param mixed $attachment_url Image URL.
|
368 |
+
*/
|
369 |
+
private function get_attachment_id_from_url( $attachment_url = '' ) {
|
370 |
+
global $wpdb;
|
371 |
+
$attachment_id = false;
|
372 |
+
|
373 |
+
// If there is no url, return.
|
374 |
+
if ( '' === $attachment_url ) {
|
375 |
+
return;
|
376 |
+
}
|
377 |
+
|
378 |
+
// Get the upload directory paths.
|
379 |
+
$upload_dir_paths = wp_upload_dir();
|
380 |
+
|
381 |
+
// Make sure the upload path base directory exists in the attachment URL, to verify that we're working with a media library image.
|
382 |
+
if ( false !== strpos( $attachment_url, $upload_dir_paths['baseurl'] ) ) {
|
383 |
+
|
384 |
+
// If this is the URL of an auto-generated thumbnail, get the URL of the original image.
|
385 |
+
$attachment_url = preg_replace( '/-\d+x\d+(?=\.(jpg|jpeg|png|gif)$)/i', '', $attachment_url );
|
386 |
+
|
387 |
+
// Remove the upload path base directory from the attachment URL.
|
388 |
+
$attachment_url = str_replace( $upload_dir_paths['baseurl'] . '/', '', $attachment_url );
|
389 |
+
|
390 |
+
// Finally, run a custom database query to get the attachment ID from the modified attachment URL.
|
391 |
+
$attachment_id = $wpdb->get_var( $wpdb->prepare( "SELECT wposts.ID FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta WHERE wposts.ID = wpostmeta.post_id AND wpostmeta.meta_key = '_wp_attached_file' AND wpostmeta.meta_value = '%s' AND wposts.post_type = 'attachment'", $attachment_url ) ); // @codingStandardsIgnoreLine
|
392 |
+
}
|
393 |
+
|
394 |
+
return $attachment_id;
|
395 |
+
}
|
396 |
+
}
|
includes/admin/import/class-wprm-import-wpultimaterecipe.php
CHANGED
@@ -254,8 +254,32 @@ class WPRM_Import_Wpultimaterecipe extends WPRM_Import {
|
|
254 |
// Recipe Nutrition.
|
255 |
$recipe['nutrition'] = array();
|
256 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
257 |
$nutrition = isset( $post_meta['recipe_nutritional'] ) ? maybe_unserialize( $post_meta['recipe_nutritional'][0] ) : array();
|
258 |
-
|
|
|
|
|
|
|
259 |
|
260 |
return $recipe;
|
261 |
}
|
254 |
// Recipe Nutrition.
|
255 |
$recipe['nutrition'] = array();
|
256 |
|
257 |
+
$nutrition_mapping = array(
|
258 |
+
'serving_size' => 'serving_size',
|
259 |
+
'calories' => 'calories',
|
260 |
+
'carbohydrate' => 'carbohydrates',
|
261 |
+
'protein' => 'protein',
|
262 |
+
'fat' => 'fat',
|
263 |
+
'saturated_fat' => 'saturated_fat',
|
264 |
+
'polyunsaturated_fat' => 'polyunsaturated_fat',
|
265 |
+
'monounsaturated_fat' => 'monounsaturated_fat',
|
266 |
+
'trans_fat' => 'trans_fat',
|
267 |
+
'cholesterol' => 'cholesterol',
|
268 |
+
'sodium' => 'sodium',
|
269 |
+
'potassium' => 'potassium',
|
270 |
+
'fiber' => 'fiber',
|
271 |
+
'sugar' => 'sugar',
|
272 |
+
'vitamin_a' => 'vitamin_a',
|
273 |
+
'vitamin_c' => 'vitamin_c',
|
274 |
+
'calcium' => 'calcium',
|
275 |
+
'iron' => 'iron',
|
276 |
+
);
|
277 |
+
|
278 |
$nutrition = isset( $post_meta['recipe_nutritional'] ) ? maybe_unserialize( $post_meta['recipe_nutritional'][0] ) : array();
|
279 |
+
|
280 |
+
foreach ( $nutrition_mapping as $wpurp_field => $wprm_field ) {
|
281 |
+
$recipe['nutrition'][ $wprm_field ] = isset( $nutrition[ $wpurp_field ] ) ? $nutrition[ $wpurp_field ] : '';
|
282 |
+
}
|
283 |
|
284 |
return $recipe;
|
285 |
}
|
includes/admin/modal/class-wprm-modal.php
CHANGED
@@ -46,7 +46,10 @@ class WPRM_Modal {
|
|
46 |
wp_enqueue_script( 'rangy', WPRM_URL . 'vendor/rangy/rangy-core.js', array(), WPRM_VERSION, true );
|
47 |
wp_enqueue_script( 'wprm-rich-editor', WPRM_URL . 'assets/js/admin/rich-editor.js', array( 'jquery', 'medium-editor', 'rangy' ), WPRM_VERSION, true );
|
48 |
wp_enqueue_script( 'wprm-select2', WPRM_URL . 'vendor/select2/js/select2.min.js', array( 'jquery' ), WPRM_VERSION, true );
|
|
|
|
|
49 |
wp_enqueue_script( 'wprm-modal', WPRM_URL . 'assets/js/admin/modal.js', array( 'jquery' ), WPRM_VERSION, true );
|
|
|
50 |
wp_enqueue_script( 'wprm-recipe-form', WPRM_URL . 'assets/js/admin/recipe-form.js', array( 'jquery', 'jquery-ui-sortable', 'wprm-modal', 'medium-editor', 'wprm-select2' ), WPRM_VERSION, true );
|
51 |
wp_enqueue_script( 'wprm-recipe-snippets', WPRM_URL . 'assets/js/admin/recipe-snippets.js', array( 'jquery', 'wprm-modal' ), WPRM_VERSION, true );
|
52 |
|
@@ -59,6 +62,7 @@ class WPRM_Modal {
|
|
59 |
'media_title' => __( 'Select or Upload Image', 'wp-recipe-maker' ),
|
60 |
'media_button' => __( 'Use Image', 'wp-recipe-maker' ),
|
61 |
'shortcode_remove' => __( 'Are you sure you want to remove this recipe?', 'wp-recipe-maker' ),
|
|
|
62 |
),
|
63 |
'addons' => array(
|
64 |
'premium' => WPRM_Addons::is_active( 'premium' ),
|
@@ -112,6 +116,13 @@ class WPRM_Modal {
|
|
112 |
'default' => true,
|
113 |
'label' => __( 'Recipe', 'wp-recipe-maker' ),
|
114 |
'tabs' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
'recipe-details' => array(
|
116 |
'order' => 100,
|
117 |
'label' => __( 'Recipe Details', 'wp-recipe-maker' ),
|
46 |
wp_enqueue_script( 'rangy', WPRM_URL . 'vendor/rangy/rangy-core.js', array(), WPRM_VERSION, true );
|
47 |
wp_enqueue_script( 'wprm-rich-editor', WPRM_URL . 'assets/js/admin/rich-editor.js', array( 'jquery', 'medium-editor', 'rangy' ), WPRM_VERSION, true );
|
48 |
wp_enqueue_script( 'wprm-select2', WPRM_URL . 'vendor/select2/js/select2.min.js', array( 'jquery' ), WPRM_VERSION, true );
|
49 |
+
wp_enqueue_script( 'texthighlighter', WPRM_URL . 'vendor/texthighlighter/TextHighlighter.min.js', array( 'jquery' ), WPRM_VERSION, true );
|
50 |
+
|
51 |
wp_enqueue_script( 'wprm-modal', WPRM_URL . 'assets/js/admin/modal.js', array( 'jquery' ), WPRM_VERSION, true );
|
52 |
+
wp_enqueue_script( 'wprm-import-text', WPRM_URL . 'assets/js/admin/import-text.js', array( 'jquery', 'wprm-modal', 'texthighlighter' ), WPRM_VERSION, true );
|
53 |
wp_enqueue_script( 'wprm-recipe-form', WPRM_URL . 'assets/js/admin/recipe-form.js', array( 'jquery', 'jquery-ui-sortable', 'wprm-modal', 'medium-editor', 'wprm-select2' ), WPRM_VERSION, true );
|
54 |
wp_enqueue_script( 'wprm-recipe-snippets', WPRM_URL . 'assets/js/admin/recipe-snippets.js', array( 'jquery', 'wprm-modal' ), WPRM_VERSION, true );
|
55 |
|
62 |
'media_title' => __( 'Select or Upload Image', 'wp-recipe-maker' ),
|
63 |
'media_button' => __( 'Use Image', 'wp-recipe-maker' ),
|
64 |
'shortcode_remove' => __( 'Are you sure you want to remove this recipe?', 'wp-recipe-maker' ),
|
65 |
+
'import_text_reset' => __( 'Are you sure you want to start over with importing from text?', 'wp-recipe-maker' ),
|
66 |
),
|
67 |
'addons' => array(
|
68 |
'premium' => WPRM_Addons::is_active( 'premium' ),
|
116 |
'default' => true,
|
117 |
'label' => __( 'Recipe', 'wp-recipe-maker' ),
|
118 |
'tabs' => array(
|
119 |
+
'text-import' => array(
|
120 |
+
'order' => 50,
|
121 |
+
'label' => __( 'Import from Text', 'wp-recipe-maker' ),
|
122 |
+
'template' => WPRM_DIR . 'templates/admin/modal/tabs/import-text.php',
|
123 |
+
'callback' => '',
|
124 |
+
'init' => 'set_recipe',
|
125 |
+
),
|
126 |
'recipe-details' => array(
|
127 |
'order' => 100,
|
128 |
'label' => __( 'Recipe Details', 'wp-recipe-maker' ),
|
includes/class-wp-recipe-maker.php
CHANGED
@@ -31,7 +31,7 @@ class WP_Recipe_Maker {
|
|
31 |
* @since 1.0.0
|
32 |
*/
|
33 |
private function define_constants() {
|
34 |
-
define( 'WPRM_VERSION', '1.
|
35 |
define( 'WPRM_POST_TYPE', 'wprm_recipe' );
|
36 |
define( 'WPRM_DIR', plugin_dir_path( dirname( __FILE__ ) ) );
|
37 |
define( 'WPRM_URL', plugin_dir_url( dirname( __FILE__ ) ) );
|
@@ -57,17 +57,23 @@ class WP_Recipe_Maker {
|
|
57 |
// General.
|
58 |
require_once( WPRM_DIR . 'includes/class-wprm-i18n.php' );
|
59 |
|
|
|
|
|
|
|
60 |
// Public.
|
61 |
require_once( WPRM_DIR . 'includes/public/class-wprm-addons.php' );
|
62 |
require_once( WPRM_DIR . 'includes/public/class-wprm-api.php' );
|
63 |
-
|
|
|
|
|
|
|
|
|
64 |
require_once( WPRM_DIR . 'includes/public/class-wprm-fallback-recipe.php' );
|
65 |
require_once( WPRM_DIR . 'includes/public/class-wprm-metadata.php' );
|
66 |
require_once( WPRM_DIR . 'includes/public/class-wprm-post-type.php' );
|
67 |
require_once( WPRM_DIR . 'includes/public/class-wprm-print.php' );
|
68 |
require_once( WPRM_DIR . 'includes/public/class-wprm-recipe-manager.php' );
|
69 |
require_once( WPRM_DIR . 'includes/public/class-wprm-recipe.php' );
|
70 |
-
require_once( WPRM_DIR . 'includes/public/class-wprm-settings.php' );
|
71 |
require_once( WPRM_DIR . 'includes/public/class-wprm-shortcode.php' );
|
72 |
require_once( WPRM_DIR . 'includes/public/class-wprm-taxonomies.php' );
|
73 |
require_once( WPRM_DIR . 'includes/public/class-wprm-template-helper.php' );
|
31 |
* @since 1.0.0
|
32 |
*/
|
33 |
private function define_constants() {
|
34 |
+
define( 'WPRM_VERSION', '1.7.0' );
|
35 |
define( 'WPRM_POST_TYPE', 'wprm_recipe' );
|
36 |
define( 'WPRM_DIR', plugin_dir_path( dirname( __FILE__ ) ) );
|
37 |
define( 'WPRM_URL', plugin_dir_url( dirname( __FILE__ ) ) );
|
57 |
// General.
|
58 |
require_once( WPRM_DIR . 'includes/class-wprm-i18n.php' );
|
59 |
|
60 |
+
// Priority.
|
61 |
+
require_once( WPRM_DIR . 'includes/public/class-wprm-settings.php' );
|
62 |
+
|
63 |
// Public.
|
64 |
require_once( WPRM_DIR . 'includes/public/class-wprm-addons.php' );
|
65 |
require_once( WPRM_DIR . 'includes/public/class-wprm-api.php' );
|
66 |
+
|
67 |
+
if ( WPRM_Settings::get( 'features_comment_ratings' ) ) {
|
68 |
+
require_once( WPRM_DIR . 'includes/public/class-wprm-comment-rating.php' );
|
69 |
+
}
|
70 |
+
|
71 |
require_once( WPRM_DIR . 'includes/public/class-wprm-fallback-recipe.php' );
|
72 |
require_once( WPRM_DIR . 'includes/public/class-wprm-metadata.php' );
|
73 |
require_once( WPRM_DIR . 'includes/public/class-wprm-post-type.php' );
|
74 |
require_once( WPRM_DIR . 'includes/public/class-wprm-print.php' );
|
75 |
require_once( WPRM_DIR . 'includes/public/class-wprm-recipe-manager.php' );
|
76 |
require_once( WPRM_DIR . 'includes/public/class-wprm-recipe.php' );
|
|
|
77 |
require_once( WPRM_DIR . 'includes/public/class-wprm-shortcode.php' );
|
78 |
require_once( WPRM_DIR . 'includes/public/class-wprm-taxonomies.php' );
|
79 |
require_once( WPRM_DIR . 'includes/public/class-wprm-template-helper.php' );
|
includes/public/class-wprm-fallback-recipe.php
CHANGED
@@ -25,6 +25,7 @@ class WPRM_Fallback_Recipe {
|
|
25 |
* @since 1.0.0
|
26 |
*/
|
27 |
public static function init() {
|
|
|
28 |
add_filter( 'the_content', array( __CLASS__, 'replace_fallback_with_shortcode' ), 1 );
|
29 |
add_filter( 'content_edit_pre', array( __CLASS__, 'replace_fallback_with_shortcode' ) );
|
30 |
|
@@ -79,6 +80,38 @@ class WPRM_Fallback_Recipe {
|
|
79 |
return $content;
|
80 |
}
|
81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
/**
|
83 |
* Get fallback HTML for a specific recipe.
|
84 |
*
|
25 |
* @since 1.0.0
|
26 |
*/
|
27 |
public static function init() {
|
28 |
+
add_filter( 'the_content', array( __CLASS__, 'replace_imported_shortcodes' ), 1 );
|
29 |
add_filter( 'the_content', array( __CLASS__, 'replace_fallback_with_shortcode' ), 1 );
|
30 |
add_filter( 'content_edit_pre', array( __CLASS__, 'replace_fallback_with_shortcode' ) );
|
31 |
|
80 |
return $content;
|
81 |
}
|
82 |
|
83 |
+
/**
|
84 |
+
* Replace imported shortcodes to make sure recipes are displayed.
|
85 |
+
*
|
86 |
+
* @since 1.7.0
|
87 |
+
* @param mixed $content Content we want to filter before it gets passed along.
|
88 |
+
*/
|
89 |
+
public static function replace_imported_shortcodes( $content ) {
|
90 |
+
// BigOven.
|
91 |
+
if ( defined( 'BO_RECIPES_VERSION' ) ) {
|
92 |
+
$recipe_shortcodes = array();
|
93 |
+
$pattern = get_shortcode_regex( array( 'seo_recipe' ) );
|
94 |
+
|
95 |
+
if ( preg_match_all( '/' . $pattern . '/s', $content, $matches ) && array_key_exists( 2, $matches ) ) {
|
96 |
+
foreach ( $matches[2] as $key => $value ) {
|
97 |
+
if ( 'seo_recipe' === $value ) {
|
98 |
+
$recipe_shortcodes[ $matches[0][ $key ] ] = shortcode_parse_atts( stripslashes( $matches[3][ $key ] ) );
|
99 |
+
}
|
100 |
+
}
|
101 |
+
}
|
102 |
+
|
103 |
+
foreach ( $recipe_shortcodes as $shortcode => $shortcode_options ) {
|
104 |
+
$recipe_id = isset( $shortcode_options['id'] ) ? intval( $shortcode_options['id'] ) : 0;
|
105 |
+
|
106 |
+
if ( WPRM_POST_TYPE === get_post_type( $recipe_id ) ) {
|
107 |
+
$content = str_replace( $shortcode, '[wprm-recipe id="' . $recipe_id . '"]', $content );
|
108 |
+
}
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
return $content;
|
113 |
+
}
|
114 |
+
|
115 |
/**
|
116 |
* Get fallback HTML for a specific recipe.
|
117 |
*
|
includes/public/class-wprm-metadata.php
CHANGED
@@ -160,7 +160,7 @@ class WPRM_Metadata {
|
|
160 |
}
|
161 |
|
162 |
foreach ( $nutrition as $field => $value ) {
|
163 |
-
if ( array_key_exists( $field, $nutrition_mapping ) ) {
|
164 |
$unit = esc_html__( 'g', 'wp-recipe-maker' );
|
165 |
|
166 |
if ( 'calories' === $field ) {
|
160 |
}
|
161 |
|
162 |
foreach ( $nutrition as $field => $value ) {
|
163 |
+
if ( $value && array_key_exists( $field, $nutrition_mapping ) ) {
|
164 |
$unit = esc_html__( 'g', 'wp-recipe-maker' );
|
165 |
|
166 |
if ( 'calories' === $field ) {
|
includes/public/class-wprm-print.php
CHANGED
@@ -59,6 +59,9 @@ class WPRM_Print {
|
|
59 |
$recipe = WPRM_Recipe_Manager::get_recipe( $recipe_id );
|
60 |
|
61 |
$styles = WPRM_Template_Manager::get_template_styles( $recipe, 'print' );
|
|
|
|
|
|
|
62 |
|
63 |
$scripts = '';
|
64 |
if ( WPRM_Addons::is_active( 'premium' ) ) {
|
59 |
$recipe = WPRM_Recipe_Manager::get_recipe( $recipe_id );
|
60 |
|
61 |
$styles = WPRM_Template_Manager::get_template_styles( $recipe, 'print' );
|
62 |
+
if ( WPRM_Addons::is_active( 'premium' ) ) {
|
63 |
+
$styles .= '<link rel="stylesheet" type="text/css" href="' . WPRMP_URL . 'assets/css/public/public.min.css"/>';
|
64 |
+
}
|
65 |
|
66 |
$scripts = '';
|
67 |
if ( WPRM_Addons::is_active( 'premium' ) ) {
|
includes/public/class-wprm-settings.php
CHANGED
@@ -35,8 +35,13 @@ class WPRM_Settings {
|
|
35 |
* @var array $defaults Default values for unset settings.
|
36 |
*/
|
37 |
private static $defaults = array(
|
|
|
38 |
'default_recipe_template' => 'simple',
|
39 |
'default_print_template' => 'clean-print',
|
|
|
|
|
|
|
|
|
40 |
);
|
41 |
|
42 |
/**
|
@@ -47,7 +52,8 @@ class WPRM_Settings {
|
|
47 |
public static function init() {
|
48 |
add_action( 'admin_menu', array( __CLASS__, 'add_submenu_page' ), 20 );
|
49 |
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue' ) );
|
50 |
-
add_action( 'admin_post_wprm_settings_appearance', array( __CLASS__, '
|
|
|
51 |
|
52 |
add_action( 'wprm_settings_page', array( __CLASS__, 'settings_page' ) );
|
53 |
}
|
@@ -81,6 +87,8 @@ class WPRM_Settings {
|
|
81 |
public static function settings_page( $sub ) {
|
82 |
if ( 'appearance' === $sub ) {
|
83 |
require_once( WPRM_DIR . 'templates/admin/settings/appearance.php' );
|
|
|
|
|
84 |
}
|
85 |
}
|
86 |
|
@@ -105,12 +113,22 @@ class WPRM_Settings {
|
|
105 |
if ( isset( $settings[ $setting ] ) ) {
|
106 |
return $settings[ $setting ];
|
107 |
} else {
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
}
|
115 |
}
|
116 |
|
@@ -164,11 +182,11 @@ class WPRM_Settings {
|
|
164 |
}
|
165 |
|
166 |
/**
|
167 |
-
* Save the settings.
|
168 |
*
|
169 |
-
* @since 1.
|
170 |
*/
|
171 |
-
public static function
|
172 |
if ( isset( $_POST['wprm_settings'] ) && wp_verify_nonce( sanitize_key( $_POST['wprm_settings'] ), 'wprm_settings' ) ) { // Input var okay.
|
173 |
$default_recipe_template = isset( $_POST['default_recipe_template'] ) ? sanitize_text_field( wp_unslash( $_POST['default_recipe_template'] ) ) : ''; // Input var okay.
|
174 |
$default_print_template = isset( $_POST['default_print_template'] ) ? sanitize_text_field( wp_unslash( $_POST['default_print_template'] ) ) : ''; // Input var okay.
|
@@ -185,7 +203,28 @@ class WPRM_Settings {
|
|
185 |
|
186 |
self::update_settings( $settings );
|
187 |
}
|
188 |
-
wp_safe_redirect( admin_url( 'admin.php?page=wprm_settings' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
exit();
|
190 |
}
|
191 |
}
|
35 |
* @var array $defaults Default values for unset settings.
|
36 |
*/
|
37 |
private static $defaults = array(
|
38 |
+
// Appearance.
|
39 |
'default_recipe_template' => 'simple',
|
40 |
'default_print_template' => 'clean-print',
|
41 |
+
// Features.
|
42 |
+
'features_comment_ratings' => true,
|
43 |
+
// Features Premium.
|
44 |
+
'features_adjustable_servings' => true,
|
45 |
);
|
46 |
|
47 |
/**
|
52 |
public static function init() {
|
53 |
add_action( 'admin_menu', array( __CLASS__, 'add_submenu_page' ), 20 );
|
54 |
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue' ) );
|
55 |
+
add_action( 'admin_post_wprm_settings_appearance', array( __CLASS__, 'form_save_settings_appearance' ) );
|
56 |
+
add_action( 'admin_post_wprm_settings_features', array( __CLASS__, 'form_save_settings_features' ) );
|
57 |
|
58 |
add_action( 'wprm_settings_page', array( __CLASS__, 'settings_page' ) );
|
59 |
}
|
87 |
public static function settings_page( $sub ) {
|
88 |
if ( 'appearance' === $sub ) {
|
89 |
require_once( WPRM_DIR . 'templates/admin/settings/appearance.php' );
|
90 |
+
} elseif ( 'features' === $sub ) {
|
91 |
+
require_once( WPRM_DIR . 'templates/admin/settings/features.php' );
|
92 |
}
|
93 |
}
|
94 |
|
113 |
if ( isset( $settings[ $setting ] ) ) {
|
114 |
return $settings[ $setting ];
|
115 |
} else {
|
116 |
+
self::get_default( $setting );
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Get the default for a specific setting.
|
122 |
+
*
|
123 |
+
* @since 1.7.0
|
124 |
+
* @param mixed $setting Setting to get the default for.
|
125 |
+
*/
|
126 |
+
public static function get_default( $setting ) {
|
127 |
+
$defaults = self::get_defaults();
|
128 |
+
if ( isset( $defaults[ $setting ] ) ) {
|
129 |
+
return $defaults[ $setting ];
|
130 |
+
} else {
|
131 |
+
return false;
|
132 |
}
|
133 |
}
|
134 |
|
182 |
}
|
183 |
|
184 |
/**
|
185 |
+
* Save the appearance settings.
|
186 |
*
|
187 |
+
* @since 1.7.0
|
188 |
*/
|
189 |
+
public static function form_save_settings_appearance() {
|
190 |
if ( isset( $_POST['wprm_settings'] ) && wp_verify_nonce( sanitize_key( $_POST['wprm_settings'] ), 'wprm_settings' ) ) { // Input var okay.
|
191 |
$default_recipe_template = isset( $_POST['default_recipe_template'] ) ? sanitize_text_field( wp_unslash( $_POST['default_recipe_template'] ) ) : ''; // Input var okay.
|
192 |
$default_print_template = isset( $_POST['default_print_template'] ) ? sanitize_text_field( wp_unslash( $_POST['default_print_template'] ) ) : ''; // Input var okay.
|
203 |
|
204 |
self::update_settings( $settings );
|
205 |
}
|
206 |
+
wp_safe_redirect( admin_url( 'admin.php?page=wprm_settings&sub=appearance' ) );
|
207 |
+
exit();
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Save the features settings.
|
212 |
+
*
|
213 |
+
* @since 1.7.0
|
214 |
+
*/
|
215 |
+
public static function form_save_settings_features() {
|
216 |
+
if ( isset( $_POST['wprm_settings'] ) && wp_verify_nonce( sanitize_key( $_POST['wprm_settings'] ), 'wprm_settings' ) ) { // Input var okay.
|
217 |
+
$features_comment_ratings = isset( $_POST['features_comment_ratings'] ) && sanitize_key( $_POST['features_comment_ratings'] ) ? true : false; // Input var okay.
|
218 |
+
$features_adjustable_servings = isset( $_POST['features_adjustable_servings'] ) && sanitize_key( $_POST['features_adjustable_servings'] ) ? true : false; // Input var okay.
|
219 |
+
|
220 |
+
$settings = array();
|
221 |
+
|
222 |
+
$settings['features_comment_ratings'] = $features_comment_ratings;
|
223 |
+
$settings['features_adjustable_servings'] = $features_adjustable_servings;
|
224 |
+
|
225 |
+
self::update_settings( $settings );
|
226 |
+
}
|
227 |
+
wp_safe_redirect( admin_url( 'admin.php?page=wprm_settings&sub=features' ) );
|
228 |
exit();
|
229 |
}
|
230 |
}
|
includes/public/class-wprm-shortcode.php
CHANGED
@@ -33,6 +33,7 @@ class WPRM_Shortcode {
|
|
33 |
add_shortcode( 'timer', array( __CLASS__, 'timer_shortcode' ) );
|
34 |
|
35 |
add_filter( 'content_edit_pre', array( __CLASS__, 'replace_wpultimaterecipe_shortcode' ) );
|
|
|
36 |
|
37 |
add_action( 'init', array( __CLASS__, 'fallback_shortcodes' ), 11 );
|
38 |
add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue' ) );
|
@@ -53,6 +54,10 @@ class WPRM_Shortcode {
|
|
53 |
* @since 1.3.0
|
54 |
*/
|
55 |
public static function fallback_shortcodes() {
|
|
|
|
|
|
|
|
|
56 |
if ( ! shortcode_exists( 'ultimate-recipe' ) ) {
|
57 |
add_shortcode( 'ultimate-recipe', array( __CLASS__, 'recipe_shortcode' ) );
|
58 |
}
|
@@ -61,6 +66,10 @@ class WPRM_Shortcode {
|
|
61 |
add_shortcode( 'nutrition-label', array( __CLASS__, 'remove_shortcode' ) );
|
62 |
add_shortcode( 'ultimate-nutrition-label', array( __CLASS__, 'remove_shortcode' ) );
|
63 |
}
|
|
|
|
|
|
|
|
|
64 |
}
|
65 |
|
66 |
/**
|
@@ -80,6 +89,23 @@ class WPRM_Shortcode {
|
|
80 |
return $content;
|
81 |
}
|
82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
/**
|
84 |
* To be used for shortcodes we want to (temporarily) remove from the content.
|
85 |
*
|
@@ -189,9 +215,11 @@ class WPRM_Shortcode {
|
|
189 |
public static function nutrition_label_shortcode( $atts ) {
|
190 |
$atts = shortcode_atts( array(
|
191 |
'id' => '0',
|
|
|
192 |
), $atts, 'wprm_nutrition_label' );
|
193 |
|
194 |
$recipe_id = intval( $atts['id'] );
|
|
|
195 |
|
196 |
// Get first recipe in post content if no ID is set.
|
197 |
if ( ! $recipe_id ) {
|
@@ -205,7 +233,13 @@ class WPRM_Shortcode {
|
|
205 |
|
206 |
if ( $recipe_id && WPRM_Addons::is_active( 'premium' ) ) {
|
207 |
$recipe = WPRM_Recipe_Manager::get_recipe( $recipe_id );
|
208 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
} else {
|
210 |
return '';
|
211 |
}
|
33 |
add_shortcode( 'timer', array( __CLASS__, 'timer_shortcode' ) );
|
34 |
|
35 |
add_filter( 'content_edit_pre', array( __CLASS__, 'replace_wpultimaterecipe_shortcode' ) );
|
36 |
+
add_filter( 'content_edit_pre', array( __CLASS__, 'replace_bigoven_shortcode' ) );
|
37 |
|
38 |
add_action( 'init', array( __CLASS__, 'fallback_shortcodes' ), 11 );
|
39 |
add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue' ) );
|
54 |
* @since 1.3.0
|
55 |
*/
|
56 |
public static function fallback_shortcodes() {
|
57 |
+
if ( ! shortcode_exists( 'seo_recipe' ) ) {
|
58 |
+
add_shortcode( 'seo_recipe', array( __CLASS__, 'recipe_shortcode' ) );
|
59 |
+
}
|
60 |
+
|
61 |
if ( ! shortcode_exists( 'ultimate-recipe' ) ) {
|
62 |
add_shortcode( 'ultimate-recipe', array( __CLASS__, 'recipe_shortcode' ) );
|
63 |
}
|
66 |
add_shortcode( 'nutrition-label', array( __CLASS__, 'remove_shortcode' ) );
|
67 |
add_shortcode( 'ultimate-nutrition-label', array( __CLASS__, 'remove_shortcode' ) );
|
68 |
}
|
69 |
+
|
70 |
+
if ( ! shortcode_exists( 'recipe-timer' ) ) {
|
71 |
+
add_shortcode( 'recipe-timer', array( __CLASS__, 'timer_shortcode' ) );
|
72 |
+
}
|
73 |
}
|
74 |
|
75 |
/**
|
89 |
return $content;
|
90 |
}
|
91 |
|
92 |
+
/**
|
93 |
+
* Replace BigOven shortcode with ours.
|
94 |
+
*
|
95 |
+
* @since 1.7.0
|
96 |
+
* @param mixed $content Content we want to filter before it gets passed along.
|
97 |
+
*/
|
98 |
+
public static function replace_bigoven_shortcode( $content ) {
|
99 |
+
preg_match_all( "/\[seo_recipe\s.*?id='?\"?(\d+).*?]/im", $content, $matches );
|
100 |
+
foreach ( $matches[0] as $key => $match ) {
|
101 |
+
if ( WPRM_POST_TYPE === get_post_type( $matches[1][ $key ] ) ) {
|
102 |
+
$content = str_replace( $match, '[wprm-recipe id="' . $matches[1][ $key ] . '"]', $content );
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
return $content;
|
107 |
+
}
|
108 |
+
|
109 |
/**
|
110 |
* To be used for shortcodes we want to (temporarily) remove from the content.
|
111 |
*
|
215 |
public static function nutrition_label_shortcode( $atts ) {
|
216 |
$atts = shortcode_atts( array(
|
217 |
'id' => '0',
|
218 |
+
'align' => 'left',
|
219 |
), $atts, 'wprm_nutrition_label' );
|
220 |
|
221 |
$recipe_id = intval( $atts['id'] );
|
222 |
+
$align = in_array( $atts['align'], array( 'center', 'right' ) ) ? $atts['align'] : 'left';
|
223 |
|
224 |
// Get first recipe in post content if no ID is set.
|
225 |
if ( ! $recipe_id ) {
|
233 |
|
234 |
if ( $recipe_id && WPRM_Addons::is_active( 'premium' ) ) {
|
235 |
$recipe = WPRM_Recipe_Manager::get_recipe( $recipe_id );
|
236 |
+
$label = WPRMP_Nutrition_Label::nutrition_label( $recipe );
|
237 |
+
|
238 |
+
if ( 'left' !== $align ) {
|
239 |
+
$label = '<div class="wprm-nutrition-label-container" style="text-align: ' . $align . ';">' . $label . '</div>';
|
240 |
+
}
|
241 |
+
|
242 |
+
return $label;
|
243 |
} else {
|
244 |
return '';
|
245 |
}
|
includes/public/class-wprm-template-manager.php
CHANGED
@@ -42,8 +42,7 @@ class WPRM_Template_Manager {
|
|
42 |
* @since 1.0.0
|
43 |
*/
|
44 |
public static function enqueue() {
|
45 |
-
$
|
46 |
-
$template = self::get_template_by_slug( $template_slug );
|
47 |
|
48 |
wp_enqueue_style( 'wprm-template', $template['url'] . '/' . $template['slug'] . '.min.css', array(), WPRM_VERSION, 'all' );
|
49 |
}
|
@@ -62,13 +61,7 @@ class WPRM_Template_Manager {
|
|
62 |
}
|
63 |
|
64 |
if ( ! $slug || ! $template ) {
|
65 |
-
|
66 |
-
$template_slug = WPRM_Settings::get( 'default_print_template' );
|
67 |
-
} else {
|
68 |
-
$template_slug = WPRM_Settings::get( 'default_recipe_template' );
|
69 |
-
}
|
70 |
-
|
71 |
-
$template = self::get_template_by_slug( $template_slug );
|
72 |
}
|
73 |
|
74 |
ob_start();
|
@@ -79,6 +72,36 @@ class WPRM_Template_Manager {
|
|
79 |
// Prevent infinite shortcode loop.
|
80 |
$template = preg_replace( "/\[wprm-recipe\s+id=\"?'?" . $recipe->id() . "\"?'?\]/im", '', $template );
|
81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
return do_shortcode( $template );
|
83 |
}
|
84 |
|
@@ -90,13 +113,7 @@ class WPRM_Template_Manager {
|
|
90 |
* @param mixed $type Type of template we want to get, defaults to single.
|
91 |
*/
|
92 |
public static function get_template_styles( $recipe, $type = 'single' ) {
|
93 |
-
|
94 |
-
$template_slug = WPRM_Settings::get( 'default_print_template' );
|
95 |
-
$template = self::get_template_by_slug( $template_slug );
|
96 |
-
} else {
|
97 |
-
$template_slug = WPRM_Settings::get( 'default_recipe_template' );
|
98 |
-
$template = self::get_template_by_slug( $template_slug );
|
99 |
-
}
|
100 |
|
101 |
ob_start();
|
102 |
require( $template['dir'] . '/' . $template['slug'] . '.min.css' );
|
@@ -121,6 +138,35 @@ class WPRM_Template_Manager {
|
|
121 |
return $template;
|
122 |
}
|
123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
/**
|
125 |
* Get all available templates.
|
126 |
*
|
42 |
* @since 1.0.0
|
43 |
*/
|
44 |
public static function enqueue() {
|
45 |
+
$template = self::get_template_by_type( 'single' );
|
|
|
46 |
|
47 |
wp_enqueue_style( 'wprm-template', $template['url'] . '/' . $template['slug'] . '.min.css', array(), WPRM_VERSION, 'all' );
|
48 |
}
|
61 |
}
|
62 |
|
63 |
if ( ! $slug || ! $template ) {
|
64 |
+
$template = self::get_template_by_type( $type );
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
}
|
66 |
|
67 |
ob_start();
|
72 |
// Prevent infinite shortcode loop.
|
73 |
$template = preg_replace( "/\[wprm-recipe\s+id=\"?'?" . $recipe->id() . "\"?'?\]/im", '', $template );
|
74 |
|
75 |
+
// Replace nutrition label shortcode without ID in the print version.
|
76 |
+
if ( 'print' === $type ) {
|
77 |
+
$label_shortcodes = array();
|
78 |
+
$pattern = get_shortcode_regex( array( 'wprm-nutrition-label' ) );
|
79 |
+
|
80 |
+
if ( preg_match_all( '/' . $pattern . '/s', $template, $matches ) && array_key_exists( 2, $matches ) ) {
|
81 |
+
foreach ( $matches[2] as $key => $value ) {
|
82 |
+
if ( 'wprm-nutrition-label' === $value ) {
|
83 |
+
$label_shortcodes[ $matches[0][ $key ] ] = shortcode_parse_atts( stripslashes( $matches[3][ $key ] ) );
|
84 |
+
}
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
foreach ( $label_shortcodes as $shortcode => $shortcode_options ) {
|
89 |
+
$recipe_id = isset( $shortcode_options['id'] ) ? intval( $shortcode_options['id'] ) : 0;
|
90 |
+
|
91 |
+
if ( ! $recipe_id ) {
|
92 |
+
$shortcode_options['id'] = $recipe->id();
|
93 |
+
|
94 |
+
$new_shortcode = '[wprm-nutrition-label';
|
95 |
+
foreach ( $shortcode_options as $attr => $val ) {
|
96 |
+
$new_shortcode .= ' ' . $attr . '="' . $val . '"';
|
97 |
+
}
|
98 |
+
$new_shortcode .= ']';
|
99 |
+
|
100 |
+
$template = str_replace( $shortcode, $new_shortcode, $template );
|
101 |
+
}
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
return do_shortcode( $template );
|
106 |
}
|
107 |
|
113 |
* @param mixed $type Type of template we want to get, defaults to single.
|
114 |
*/
|
115 |
public static function get_template_styles( $recipe, $type = 'single' ) {
|
116 |
+
$template = self::get_template_by_type( $type );
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
|
118 |
ob_start();
|
119 |
require( $template['dir'] . '/' . $template['slug'] . '.min.css' );
|
138 |
return $template;
|
139 |
}
|
140 |
|
141 |
+
/**
|
142 |
+
* Get template by type.
|
143 |
+
*
|
144 |
+
* @since 1.7.0
|
145 |
+
* @param mixed $type Type of template we want to get, defaults to single.
|
146 |
+
*/
|
147 |
+
public static function get_template_by_type( $type = 'single' ) {
|
148 |
+
if ( 'print' === $type ) {
|
149 |
+
$template_slug = WPRM_Settings::get( 'default_print_template' );
|
150 |
+
} else {
|
151 |
+
$template_slug = WPRM_Settings::get( 'default_recipe_template' );
|
152 |
+
}
|
153 |
+
|
154 |
+
$template = self::get_template_by_slug( $template_slug );
|
155 |
+
|
156 |
+
// Get default template if the template in the settings doesn't exist anymore.
|
157 |
+
if ( ! $template ) {
|
158 |
+
if ( 'print' === $type ) {
|
159 |
+
$template_slug = WPRM_Settings::get_default( 'default_print_template' );
|
160 |
+
} else {
|
161 |
+
$template_slug = WPRM_Settings::get_default( 'default_recipe_template' );
|
162 |
+
}
|
163 |
+
|
164 |
+
$template = self::get_template_by_slug( $template_slug );
|
165 |
+
}
|
166 |
+
|
167 |
+
return $template;
|
168 |
+
}
|
169 |
+
|
170 |
/**
|
171 |
* Get all available templates.
|
172 |
*
|
readme.txt
CHANGED
@@ -33,6 +33,8 @@ Currently using another recipe plugin? No problem! You can easily migrate all yo
|
|
33 |
|
34 |
* EasyRecipe
|
35 |
* WP Ultimate Recipe
|
|
|
|
|
36 |
* (More coming soon!)
|
37 |
|
38 |
Looking for some more advanced functionality? We also have the [WP Recipe Maker Premium](http://bootstrapped.ventures/wp-recipe-maker/) add-on available with the following features:
|
@@ -77,6 +79,20 @@ Yes! We pride ourselves on offering awesome support and almost always answer sup
|
|
77 |
|
78 |
== Changelog ==
|
79 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
= 1.6.0 =
|
81 |
* Feature: Show hours for longer recipe times
|
82 |
* Improvement: Prevent font size inconsistencies in template
|
@@ -135,6 +151,12 @@ Yes! We pride ourselves on offering awesome support and almost always answer sup
|
|
135 |
|
136 |
== Upgrade notice ==
|
137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
= 1.6.0 =
|
139 |
Some minor updates and the release of WP Recipe Maker Premium
|
140 |
|
33 |
|
34 |
* EasyRecipe
|
35 |
* WP Ultimate Recipe
|
36 |
+
* Meal Planner Pro
|
37 |
+
* BigOven
|
38 |
* (More coming soon!)
|
39 |
|
40 |
Looking for some more advanced functionality? We also have the [WP Recipe Maker Premium](http://bootstrapped.ventures/wp-recipe-maker/) add-on available with the following features:
|
79 |
|
80 |
== Changelog ==
|
81 |
|
82 |
+
= 1.7.0 =
|
83 |
+
* Feature: Import recipe from text
|
84 |
+
* Feature: Add nofollow links in summary and instructions
|
85 |
+
* Feature: Import recipes from Meal Planner Pro
|
86 |
+
* Feature: Import recipes from BigOven
|
87 |
+
* Improvement: Setting to disable comment ratings
|
88 |
+
* Improvement: Recognize unicode fractions when importing ingredients
|
89 |
+
* Improvement: Import nutrition facts from WP Ultimate Recipe
|
90 |
+
* Fix: Only show nutritional metadata if present
|
91 |
+
* Fix: Consistent behaviour for automatic time calculations
|
92 |
+
|
93 |
+
= 1.6.1 =
|
94 |
+
* Improvement: Show warning if EasyRecipe is breaking things
|
95 |
+
|
96 |
= 1.6.0 =
|
97 |
* Feature: Show hours for longer recipe times
|
98 |
* Improvement: Prevent font size inconsistencies in template
|
151 |
|
152 |
== Upgrade notice ==
|
153 |
|
154 |
+
= 1.7.0 =
|
155 |
+
Lots of great improvements for WP Recipe Maker
|
156 |
+
|
157 |
+
= 1.6.1 =
|
158 |
+
Warning message for EasyRecipe users
|
159 |
+
|
160 |
= 1.6.0 =
|
161 |
Some minor updates and the release of WP Recipe Maker Premium
|
162 |
|
templates/admin/menu/addons.php
CHANGED
@@ -14,6 +14,9 @@
|
|
14 |
<div class="wrap wprm-addons">
|
15 |
<h1><?php echo esc_html_e( 'Add-Ons', 'wp-recipe-maker' ); ?></h1>
|
16 |
<h2>WP Recipe Maker Premium</h2>
|
|
|
|
|
|
|
17 |
<ul>
|
18 |
<li>Use <strong>ingredient links</strong> for linking to products or other recipes</li>
|
19 |
<li><strong>Adjustable servings</strong> make it easy for your visitors</li>
|
@@ -22,4 +25,5 @@
|
|
22 |
<li>More <strong>Premium templates</strong> for a unique recipe template</li>
|
23 |
</ul>
|
24 |
<a class="button button-primary" href="http://bootstrapped.ventures/wp-recipe-maker/get-the-plugin/" target="_blank">Get the Plugin</a>
|
|
|
25 |
</div>
|
14 |
<div class="wrap wprm-addons">
|
15 |
<h1><?php echo esc_html_e( 'Add-Ons', 'wp-recipe-maker' ); ?></h1>
|
16 |
<h2>WP Recipe Maker Premium</h2>
|
17 |
+
<?php if ( WPRM_Addons::is_active( 'premium' ) ) : ?>
|
18 |
+
<p>This add-on is active.</p>
|
19 |
+
<?php else : ?>
|
20 |
<ul>
|
21 |
<li>Use <strong>ingredient links</strong> for linking to products or other recipes</li>
|
22 |
<li><strong>Adjustable servings</strong> make it easy for your visitors</li>
|
25 |
<li>More <strong>Premium templates</strong> for a unique recipe template</li>
|
26 |
</ul>
|
27 |
<a class="button button-primary" href="http://bootstrapped.ventures/wp-recipe-maker/get-the-plugin/" target="_blank">Get the Plugin</a>
|
28 |
+
<?php endif; // Premium active. ?>
|
29 |
</div>
|
templates/admin/menu/faq/whats_new.php
CHANGED
@@ -11,6 +11,19 @@
|
|
11 |
|
12 |
?>
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
<h3>2016-10-25 | WP Recipe Maker Premium 1.0.0</h3>
|
15 |
<ul>
|
16 |
<li>Feature: Ingredient Links</li>
|
11 |
|
12 |
?>
|
13 |
|
14 |
+
<h3>2016-11-10 | WP Recipe Maker 1.7.0</h3>
|
15 |
+
<ul>
|
16 |
+
<li>Feature: Import recipe from text</li>
|
17 |
+
<li>Feature: Add nofollow links in summary and instructions</li>
|
18 |
+
<li>Feature: Import recipes from Meal Planner Pro</li>
|
19 |
+
<li>Feature: Import recipes from BigOven</li>
|
20 |
+
<li>Improvement: Setting to disable comment ratings</li>
|
21 |
+
<li>Improvement: Recognize unicode fractions when importing ingredients</li>
|
22 |
+
<li>Improvement: Import nutrition facts from WP Ultimate Recipe</li>
|
23 |
+
<li>Fix: Only show nutritional metadata if present</li>
|
24 |
+
<li>Fix: Consistent behaviour for automatic time calculations</li>
|
25 |
+
</ul>
|
26 |
+
|
27 |
<h3>2016-10-25 | WP Recipe Maker Premium 1.0.0</h3>
|
28 |
<ul>
|
29 |
<li>Feature: Ingredient Links</li>
|
templates/admin/modal/modal.php
CHANGED
@@ -34,6 +34,9 @@
|
|
34 |
echo '<a href="#" class="wprm-menu-item' . esc_attr( $active_class ) . '" data-menu="' . esc_attr( $menu_item ) . '" data-tab="' . esc_attr( $menu_item ) . '-' . esc_attr( $default_tab ) . '">' . esc_html( $label ) . '</a>';
|
35 |
}
|
36 |
?>
|
|
|
|
|
|
|
37 |
</div>
|
38 |
</div>
|
39 |
<div class="wprm-frame-title">
|
34 |
echo '<a href="#" class="wprm-menu-item' . esc_attr( $active_class ) . '" data-menu="' . esc_attr( $menu_item ) . '" data-tab="' . esc_attr( $menu_item ) . '-' . esc_attr( $default_tab ) . '">' . esc_html( $label ) . '</a>';
|
35 |
}
|
36 |
?>
|
37 |
+
<div class="wprm-menu-hidden">
|
38 |
+
<?php echo esc_html__( "You're currently editing a recipe.", 'wp-recipe-maker' ) . ' ' . esc_html__( 'Use the "WP Recipe Maker" button to access other features.', 'wp-recipe-maker' ); ?>
|
39 |
+
</div>
|
40 |
</div>
|
41 |
</div>
|
42 |
<div class="wprm-frame-title">
|
templates/admin/modal/tabs/import-text.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Template for the Import from Text tab in the modal.
|
4 |
+
*
|
5 |
+
* @link http://bootstrapped.ventures
|
6 |
+
* @since 1.0.0
|
7 |
+
*
|
8 |
+
* @package WP_Recipe_Maker
|
9 |
+
* @subpackage WP_Recipe_Maker/templates/admin/modal/tabs
|
10 |
+
*/
|
11 |
+
|
12 |
+
?>
|
13 |
+
|
14 |
+
<div class="wprm-recipe-form wprm-recipe-import-text-form">
|
15 |
+
<div class="import-text-buttons">
|
16 |
+
<button type="button" class="button wprm-button wprm-button-import-text-reset" disabled="disabled"><?php esc_html_e( 'Start Over', 'wp-recipe-maker' ); ?></button>
|
17 |
+
<button type="button" class="button wprm-button wprm-button-import-text-clear" disabled="disabled"><?php esc_html_e( 'Clear', 'wp-recipe-maker' ); ?></button>
|
18 |
+
<button type="button" class="button button-primary wprm-button wprm-button-import-text-next" disabled="disabled"><?php esc_html_e( 'Next', 'wp-recipe-maker' ); ?></button>
|
19 |
+
</div>
|
20 |
+
<div id="import-text-step-input" class="import-text-step">
|
21 |
+
<div class="import-text-description">
|
22 |
+
<?php esc_html_e( 'Paste the recipe you want to import in the textarea below to get started.', 'wp-recipe-maker' ); ?>
|
23 |
+
</div>
|
24 |
+
<div class="import-text-input">
|
25 |
+
<textarea id="import-text-input-recipe" rows="20"></textarea>
|
26 |
+
</div>
|
27 |
+
</div>
|
28 |
+
<div id="import-text-step-name" class="import-text-step">
|
29 |
+
<div class="import-text-description">
|
30 |
+
<?php esc_html_e( 'Highlight this part of the recipe:', 'wp-recipe-maker' ); ?> <strong><?php esc_html_e( 'Name', 'wp-recipe-maker' ); ?></strong>
|
31 |
+
</div>
|
32 |
+
</div>
|
33 |
+
<div id="import-text-step-summary" class="import-text-step">
|
34 |
+
<div class="import-text-description">
|
35 |
+
<?php esc_html_e( 'Highlight this part of the recipe:', 'wp-recipe-maker' ); ?> <strong><?php esc_html_e( 'Summary', 'wp-recipe-maker' ); ?></strong>
|
36 |
+
</div>
|
37 |
+
</div>
|
38 |
+
<div id="import-text-step-ingredients" class="import-text-step">
|
39 |
+
<div class="import-text-description">
|
40 |
+
<?php esc_html_e( 'Highlight this part of the recipe:', 'wp-recipe-maker' ); ?> <strong><?php esc_html_e( 'Ingredients', 'wp-recipe-maker' ); ?></strong>
|
41 |
+
</div>
|
42 |
+
</div>
|
43 |
+
<div id="import-text-step-ingredient-groups" class="import-text-step">
|
44 |
+
<div class="import-text-description">
|
45 |
+
<?php esc_html_e( 'Check any ingredient groups in this list:', 'wp-recipe-maker' ); ?>
|
46 |
+
</div>
|
47 |
+
<div id="import-text-ingredient-groups" class="import-text-input">
|
48 |
+
</div>
|
49 |
+
</div>
|
50 |
+
<div id="import-text-step-instructions" class="import-text-step">
|
51 |
+
<div class="import-text-description">
|
52 |
+
<?php esc_html_e( 'Highlight this part of the recipe:', 'wp-recipe-maker' ); ?> <strong><?php esc_html_e( 'Instructions', 'wp-recipe-maker' ); ?></strong>
|
53 |
+
</div>
|
54 |
+
</div>
|
55 |
+
<div id="import-text-step-instruction-groups" class="import-text-step">
|
56 |
+
<div class="import-text-description">
|
57 |
+
<?php esc_html_e( 'Check any instruction groups in this list:', 'wp-recipe-maker' ); ?>
|
58 |
+
</div>
|
59 |
+
<div id="import-text-instruction-groups" class="import-text-input">
|
60 |
+
</div>
|
61 |
+
</div>
|
62 |
+
<div id="import-text-step-notes" class="import-text-step">
|
63 |
+
<div class="import-text-description">
|
64 |
+
<?php esc_html_e( 'Highlight this part of the recipe:', 'wp-recipe-maker' ); ?> <strong><?php esc_html_e( 'Notes', 'wp-recipe-maker' ); ?></strong>
|
65 |
+
</div>
|
66 |
+
</div>
|
67 |
+
<div id="import-text-step-finished" class="import-text-step">
|
68 |
+
<div class="import-text-description">
|
69 |
+
<?php esc_html_e( 'Finished the text import.', 'wp-recipe-maker' ); ?>
|
70 |
+
</div>
|
71 |
+
</div>
|
72 |
+
<div id="import-text-highlight-sandbox">
|
73 |
+
</div>
|
74 |
+
</div>
|
templates/admin/modal/tabs/recipe-details.php
CHANGED
@@ -12,6 +12,13 @@
|
|
12 |
?>
|
13 |
|
14 |
<div class="wprm-recipe-form wprm-recipe-details-form">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
<div class="wprm-recipe-form-container wprm-recipe-image-container">
|
16 |
<label for="wprm-recipe-image-id"><?php esc_html_e( 'Image', 'wp-recipe-maker' ); ?></label>
|
17 |
<button type="button" class="button wprm-recipe-image-add"><?php esc_html_e( 'Add Image', 'wp-recipe-maker' ); ?></button>
|
@@ -27,6 +34,10 @@
|
|
27 |
<label for="wprm-recipe-summary"><?php esc_html_e( 'Summary', 'wp-recipe-maker' ); ?></label>
|
28 |
<textarea id="wprm-recipe-summary" class="wprm-rich-editor" rows="4"></textarea>
|
29 |
</div>
|
|
|
|
|
|
|
|
|
30 |
<div class="wprm-recipe-form-container wprm-recipe-form-container-halfs">
|
31 |
<label for="wprm-recipe-author-display"><?php esc_html_e( 'Author', 'wp-recipe-maker' ); ?></label>
|
32 |
<select id="wprm-recipe-author-display">
|
@@ -40,23 +51,23 @@
|
|
40 |
</div>
|
41 |
<div class="wprm-recipe-form-container">
|
42 |
<label for="wprm-recipe-servings"><?php esc_html_e( 'Servings', 'wp-recipe-maker' ); ?></label>
|
43 |
-
<input type="number" id="wprm-recipe-servings" placeholder="4" /> <input type="text" id="wprm-recipe-servings-unit" placeholder="<?php esc_attr_e( 'people', 'wp-recipe-maker' ); ?>" />
|
44 |
</div>
|
45 |
<?php if ( ! WPRM_Addons::is_active( 'premium' ) ) : ?>
|
46 |
<div class="wprm-recipe-form-container">
|
47 |
<label for="wprm-recipe-calories"><?php esc_html_e( 'Calories', 'wp-recipe-maker' ); ?></label>
|
48 |
-
<input type="number" id="wprm-recipe-calories" placeholder="280" /> <?php esc_html_e( 'kcal', 'wp-recipe-maker' ); ?>
|
49 |
</div>
|
50 |
<?php endif; // Calories. ?>
|
51 |
<div class="wprm-recipe-form-container wprm-recipe-form-container-thirds">
|
52 |
<label for="wprm-recipe-prep-time"><?php esc_html_e( 'Prep Time', 'wp-recipe-maker' ); ?></label>
|
53 |
-
<input type="number" id="wprm-recipe-prep-time" class="wprm-recipe-time" placeholder="10" /> <?php esc_html_e( 'minutes', 'wp-recipe-maker' ); ?>
|
54 |
</div><div class="wprm-recipe-form-container wprm-recipe-form-container-thirds">
|
55 |
<label for="wprm-recipe-cook-time"><?php esc_html_e( 'Cook Time', 'wp-recipe-maker' ); ?></label>
|
56 |
-
<input type="number" id="wprm-recipe-cook-time" class="wprm-recipe-time" placeholder="20" /> <?php esc_html_e( 'minutes', 'wp-recipe-maker' ); ?>
|
57 |
</div><div class="wprm-recipe-form-container wprm-recipe-form-container-thirds">
|
58 |
<label for="wprm-recipe-total-time"><?php esc_html_e( 'Total Time', 'wp-recipe-maker' ); ?></label>
|
59 |
-
<input type="number" id="wprm-recipe-total-time" class="wprm-recipe-time" placeholder="30" /> <?php esc_html_e( 'minutes', 'wp-recipe-maker' ); ?>
|
60 |
</div>
|
61 |
<div class="wprm-recipe-form-container wprm-recipe-form-container-halfs">
|
62 |
<label for="wprm-recipe-tag-course"><?php esc_html_e( 'Course', 'wp-recipe-maker' ); ?></label>
|
12 |
?>
|
13 |
|
14 |
<div class="wprm-recipe-form wprm-recipe-details-form">
|
15 |
+
<div class="wprm-easyrecipe-warning" style="display: none;">
|
16 |
+
<strong>Warning!</strong>
|
17 |
+
<p>It looks this page already has an EasyRecipe recipe in it. Unfortunately their code is breaking things and preventing our plugin (and others) from working correctly.</p>
|
18 |
+
<p>WP Recipe Maker should work correctly if you remove the EasyRecipe recipe first and update the page before using our plugin.</p>
|
19 |
+
<p>We also have an <a href="http://bootstrapped.ventures/wp-recipe-maker/import-from-easyrecipe/" target="_blank">EasyRecipe import feature</a> if you'd like to migrate those recipes!</p>
|
20 |
+
<p>This problem does not occur for new posts or posts without recipes. If you're getting this warning in those cases, please <a href="http://bootstrapped.ventures/wp-recipe-maker/support/" target="_blank">contact us</a>!</p>
|
21 |
+
</div>
|
22 |
<div class="wprm-recipe-form-container wprm-recipe-image-container">
|
23 |
<label for="wprm-recipe-image-id"><?php esc_html_e( 'Image', 'wp-recipe-maker' ); ?></label>
|
24 |
<button type="button" class="button wprm-recipe-image-add"><?php esc_html_e( 'Add Image', 'wp-recipe-maker' ); ?></button>
|
34 |
<label for="wprm-recipe-summary"><?php esc_html_e( 'Summary', 'wp-recipe-maker' ); ?></label>
|
35 |
<textarea id="wprm-recipe-summary" class="wprm-rich-editor" rows="4"></textarea>
|
36 |
</div>
|
37 |
+
<div class='wprm-modal-hint'>
|
38 |
+
<span class="wprm-modal-hint-header"><?php esc_html_e( 'Hint', 'wp-recipe-maker' ); ?></span>
|
39 |
+
<span class="wprm-modal-hint-text"><?php esc_html_e( 'Select text to add styling or links.', 'wp-recipe-maker' ); ?></span>
|
40 |
+
</div>
|
41 |
<div class="wprm-recipe-form-container wprm-recipe-form-container-halfs">
|
42 |
<label for="wprm-recipe-author-display"><?php esc_html_e( 'Author', 'wp-recipe-maker' ); ?></label>
|
43 |
<select id="wprm-recipe-author-display">
|
51 |
</div>
|
52 |
<div class="wprm-recipe-form-container">
|
53 |
<label for="wprm-recipe-servings"><?php esc_html_e( 'Servings', 'wp-recipe-maker' ); ?></label>
|
54 |
+
<input type="number" min="0" id="wprm-recipe-servings" placeholder="4" /> <input type="text" id="wprm-recipe-servings-unit" placeholder="<?php esc_attr_e( 'people', 'wp-recipe-maker' ); ?>" />
|
55 |
</div>
|
56 |
<?php if ( ! WPRM_Addons::is_active( 'premium' ) ) : ?>
|
57 |
<div class="wprm-recipe-form-container">
|
58 |
<label for="wprm-recipe-calories"><?php esc_html_e( 'Calories', 'wp-recipe-maker' ); ?></label>
|
59 |
+
<input type="number" min="0" id="wprm-recipe-calories" placeholder="280" /> <?php esc_html_e( 'kcal', 'wp-recipe-maker' ); ?>
|
60 |
</div>
|
61 |
<?php endif; // Calories. ?>
|
62 |
<div class="wprm-recipe-form-container wprm-recipe-form-container-thirds">
|
63 |
<label for="wprm-recipe-prep-time"><?php esc_html_e( 'Prep Time', 'wp-recipe-maker' ); ?></label>
|
64 |
+
<input type="number" id="wprm-recipe-prep-time" class="wprm-recipe-time" placeholder="10" min="0" /> <?php esc_html_e( 'minutes', 'wp-recipe-maker' ); ?>
|
65 |
</div><div class="wprm-recipe-form-container wprm-recipe-form-container-thirds">
|
66 |
<label for="wprm-recipe-cook-time"><?php esc_html_e( 'Cook Time', 'wp-recipe-maker' ); ?></label>
|
67 |
+
<input type="number" id="wprm-recipe-cook-time" class="wprm-recipe-time" placeholder="20" min="0" /> <?php esc_html_e( 'minutes', 'wp-recipe-maker' ); ?>
|
68 |
</div><div class="wprm-recipe-form-container wprm-recipe-form-container-thirds">
|
69 |
<label for="wprm-recipe-total-time"><?php esc_html_e( 'Total Time', 'wp-recipe-maker' ); ?></label>
|
70 |
+
<input type="number" id="wprm-recipe-total-time" class="wprm-recipe-time" placeholder="30" min="0" /> <?php esc_html_e( 'minutes', 'wp-recipe-maker' ); ?>
|
71 |
</div>
|
72 |
<div class="wprm-recipe-form-container wprm-recipe-form-container-halfs">
|
73 |
<label for="wprm-recipe-tag-course"><?php esc_html_e( 'Course', 'wp-recipe-maker' ); ?></label>
|
templates/admin/modal/tabs/recipe-ingredients-instructions.php
CHANGED
@@ -87,3 +87,7 @@
|
|
87 |
<span class="wprm-modal-hint-header"><?php esc_html_e( 'Hint', 'wp-recipe-maker' ); ?></span>
|
88 |
<span class="wprm-modal-hint-text"><?php esc_html_e( 'Use the TAB key to easily move from field to field and add ingredients/instructions without having to click the button.', 'wp-recipe-maker' ); ?></span>
|
89 |
</div>
|
|
|
|
|
|
|
|
87 |
<span class="wprm-modal-hint-header"><?php esc_html_e( 'Hint', 'wp-recipe-maker' ); ?></span>
|
88 |
<span class="wprm-modal-hint-text"><?php esc_html_e( 'Use the TAB key to easily move from field to field and add ingredients/instructions without having to click the button.', 'wp-recipe-maker' ); ?></span>
|
89 |
</div>
|
90 |
+
<div class='wprm-modal-hint'>
|
91 |
+
<span class="wprm-modal-hint-header"><?php esc_html_e( 'Hint', 'wp-recipe-maker' ); ?></span>
|
92 |
+
<span class="wprm-modal-hint-text"><?php esc_html_e( 'Select text to add styling or links.', 'wp-recipe-maker' ); ?></span>
|
93 |
+
</div>
|
templates/admin/settings.php
CHANGED
@@ -14,6 +14,7 @@ $sub = isset( $_GET['sub'] ) ? sanitize_key( wp_unslash( $_GET['sub'] ) ) : '';
|
|
14 |
|
15 |
$tabs = apply_filters( 'wprm_settings_tabs', array(
|
16 |
'appearance' => __( 'Appearance', 'wp-recipe-maker' ),
|
|
|
17 |
) );
|
18 |
|
19 |
if ( ! array_key_exists( $sub, $tabs ) ) {
|
14 |
|
15 |
$tabs = apply_filters( 'wprm_settings_tabs', array(
|
16 |
'appearance' => __( 'Appearance', 'wp-recipe-maker' ),
|
17 |
+
'features' => __( 'Features', 'wp-recipe-maker' ),
|
18 |
) );
|
19 |
|
20 |
if ( ! array_key_exists( $sub, $tabs ) ) {
|
templates/admin/settings/features.php
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Template for the features settings sub page.
|
4 |
+
*
|
5 |
+
* @link http://bootstrapped.ventures
|
6 |
+
* @since 1.0.0
|
7 |
+
*
|
8 |
+
* @package WP_Recipe_Maker
|
9 |
+
* @subpackage WP_Recipe_Maker/templates/admin/settings
|
10 |
+
*/
|
11 |
+
|
12 |
+
?>
|
13 |
+
|
14 |
+
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
|
15 |
+
<input type="hidden" name="action" value="wprm_settings_features">
|
16 |
+
<?php wp_nonce_field( 'wprm_settings', 'wprm_settings', false ); ?>
|
17 |
+
<h2 class="title"><?php esc_html_e( 'Features', 'wp-recipe-maker' ); ?></h2>
|
18 |
+
<p>
|
19 |
+
<?php esc_html_e( 'Choose the features you want to use on your website.', 'wp-recipe-maker' ); ?>
|
20 |
+
</p>
|
21 |
+
<table class="form-table">
|
22 |
+
<tbody>
|
23 |
+
<tr>
|
24 |
+
<th scope="row">
|
25 |
+
<?php esc_html_e( 'Comment Ratings', 'wp-recipe-maker' ); ?>
|
26 |
+
</th>
|
27 |
+
<td>
|
28 |
+
<label for="features_comment_ratings">
|
29 |
+
<?php $checked = WPRM_Settings::get( 'features_comment_ratings' ) ? ' checked="checked"' : ''; ?>
|
30 |
+
<input name="features_comment_ratings" type="checkbox" id="features_comment_ratings"<?php echo esc_html( $checked ); ?> />
|
31 |
+
<?php esc_html_e( 'Allow visitors to vote on your recipes when commenting', 'wp-recipe-maker' ); ?>
|
32 |
+
</label>
|
33 |
+
<p class="description">
|
34 |
+
<a href="http://bootstrapped.ventures/wp-recipe-maker/comment-ratings/" target="_blank"><?php esc_html_e( 'Learn more', 'wp-recipe-maker' ); ?></a>
|
35 |
+
</p>
|
36 |
+
</td>
|
37 |
+
</tr>
|
38 |
+
</tbody>
|
39 |
+
</table>
|
40 |
+
<h2 class="title"><?php esc_html_e( 'Premium Features', 'wp-recipe-maker' ); ?></h2>
|
41 |
+
<p>
|
42 |
+
<?php if ( ! WPRM_Addons::is_active( 'premium' ) ) : ?>
|
43 |
+
<?php esc_html_e( 'These features are only available in', 'wp-recipe-maker' ); ?> <a href="https://bootstrapped.ventures/wp-recipe-maker/get-the-plugin/" target="_blank">WP Recipe Maker Premium</a>.
|
44 |
+
<?php else : ?>
|
45 |
+
<?php esc_html_e( 'Choose the Premium features you want to use on your website.', 'wp-recipe-maker' ); ?>
|
46 |
+
<?php endif; ?>
|
47 |
+
</p>
|
48 |
+
<table class="form-table">
|
49 |
+
<tbody>
|
50 |
+
<tr>
|
51 |
+
<th scope="row">
|
52 |
+
<?php esc_html_e( 'Adjustable Servings', 'wp-recipe-maker' ); ?>
|
53 |
+
</th>
|
54 |
+
<td>
|
55 |
+
<label for="features_adjustable_servings">
|
56 |
+
<?php $checked = WPRM_Settings::get( 'features_adjustable_servings' ) ? ' checked="checked"' : ''; ?>
|
57 |
+
<input name="features_adjustable_servings" type="checkbox" id="features_adjustable_servings"<?php echo esc_html( $checked ); ?> />
|
58 |
+
<?php esc_html_e( 'Visitors can adjust the serving size of your recipes', 'wp-recipe-maker' ); ?>
|
59 |
+
</label>
|
60 |
+
<p class="description">
|
61 |
+
<a href="http://bootstrapped.ventures/wp-recipe-maker/adjustable-servings/" target="_blank"><?php esc_html_e( 'Learn more', 'wp-recipe-maker' ); ?></a>
|
62 |
+
</p>
|
63 |
+
</td>
|
64 |
+
</tr>
|
65 |
+
</tbody>
|
66 |
+
</table>
|
67 |
+
<?php submit_button( __( 'Save Changes', 'wp-recipe-maker' ) ); ?>
|
68 |
+
</form>
|
templates/recipe/clean-print-with-image/clean-print-with-image.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.wprm-recipe-clean-print-with-image{font-size:.9em}.wprm-recipe-clean-print-with-image .wprm-recipe-image{float:left;margin:0 15px 15px 0}.wprm-recipe-clean-print-with-image h2.wprm-recipe-name,.wprm-recipe-clean-print-with-image h3.wprm-recipe-header,.wprm-recipe-clean-print-with-image h4.wprm-recipe-group-name{font-variant:normal;text-transform:none;letter-spacing:normal;margin:0}.wprm-recipe-clean-print-with-image h2.wprm-recipe-name{clear:none;font-size:1.8em}.wprm-recipe-clean-print-with-image .wprm-recipe-details-container,.wprm-recipe-clean-print-with-image .wprm-recipe-summary{margin-bottom:15px}.wprm-recipe-clean-print-with-image .wprm-recipe-details-name{display:inline-block;font-weight:700;min-width:130px}.wprm-recipe-clean-print-with-image .wprm-recipe-details-unit{font-size:.8em}.wprm-recipe-clean-print-with-image h3.wprm-recipe-header{margin-top:10px;font-size:1.2em}.wprm-recipe-clean-print-with-image ol,.wprm-recipe-clean-print-with-image ul{margin:0 0 8px}.wprm-recipe-clean-print-with-image ol li,.wprm-recipe-clean-print-with-image ul li{margin:0 0 0 32px}.wprm-recipe-clean-print-with-image h4.wprm-recipe-group-name{margin-top:5px!important;font-weight:300;font-size:1em}.wprm-recipe-clean-print-with-image .wprm-recipe-ingredient-notes{color:#999}.wprm-recipe-clean-print-with-image .wprm-recipe-instructions .wprm-recipe-instruction{margin-bottom:5px}.wprm-recipe-clean-print-with-image .wprm-recipe-instruction-text p{margin:0 0 5px}.wprm-recipe-clean-print-with-image .wprm-recipe-instruction-text p:last-of-type{margin-bottom:0}.wprm-print .wprm-recipe-clean-print-with-image{max-width:750px;margin:0 auto}
|
1 |
+
.wprm-recipe-clean-print-with-image{font-size:.9em}.wprm-recipe-clean-print-with-image .wprm-recipe-image{float:left;margin:0 15px 15px 0}.wprm-recipe-clean-print-with-image h2.wprm-recipe-name,.wprm-recipe-clean-print-with-image h3.wprm-recipe-header,.wprm-recipe-clean-print-with-image h4.wprm-recipe-group-name{font-variant:normal;text-transform:none;letter-spacing:normal;margin:0;padding:0}.wprm-recipe-clean-print-with-image h2.wprm-recipe-name{clear:none;font-size:1.8em}.wprm-recipe-clean-print-with-image .wprm-recipe-details-container,.wprm-recipe-clean-print-with-image .wprm-recipe-summary{margin-bottom:15px}.wprm-recipe-clean-print-with-image .wprm-recipe-details-name{display:inline-block;font-weight:700;min-width:130px}.wprm-recipe-clean-print-with-image .wprm-recipe-details-unit{font-size:.8em}.wprm-recipe-clean-print-with-image h3.wprm-recipe-header{margin-top:10px;font-size:1.2em}.wprm-recipe-clean-print-with-image ol,.wprm-recipe-clean-print-with-image ul{margin:0 0 8px}.wprm-recipe-clean-print-with-image ol li,.wprm-recipe-clean-print-with-image ul li{margin:0 0 0 32px}.wprm-recipe-clean-print-with-image h4.wprm-recipe-group-name{margin-top:5px!important;font-weight:300;font-size:1em}.wprm-recipe-clean-print-with-image .wprm-recipe-ingredient-notes{color:#999}.wprm-recipe-clean-print-with-image .wprm-recipe-instructions .wprm-recipe-instruction{margin-bottom:5px}.wprm-recipe-clean-print-with-image .wprm-recipe-instruction-text p{margin:0 0 5px}.wprm-recipe-clean-print-with-image .wprm-recipe-instruction-text p:last-of-type{margin-bottom:0}.wprm-print .wprm-recipe-clean-print-with-image{max-width:750px;margin:0 auto}
|
templates/recipe/clean-print-with-image/clean-print-with-image.scss
CHANGED
@@ -13,6 +13,7 @@
|
|
13 |
text-transform: none;
|
14 |
letter-spacing: normal;
|
15 |
margin: 0;
|
|
|
16 |
}
|
17 |
|
18 |
h2.wprm-recipe-name {
|
13 |
text-transform: none;
|
14 |
letter-spacing: normal;
|
15 |
margin: 0;
|
16 |
+
padding: 0;
|
17 |
}
|
18 |
|
19 |
h2.wprm-recipe-name {
|
templates/recipe/clean-print/clean-print.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.wprm-recipe-clean-print{font-size:.9em}.wprm-recipe-clean-print h2.wprm-recipe-name,.wprm-recipe-clean-print h3.wprm-recipe-header,.wprm-recipe-clean-print h4.wprm-recipe-group-name{font-variant:normal;text-transform:none;letter-spacing:normal;margin:0}.wprm-recipe-clean-print h2.wprm-recipe-name{clear:none;font-size:1.8em}.wprm-recipe-clean-print .wprm-recipe-details-container,.wprm-recipe-clean-print .wprm-recipe-summary{margin-bottom:15px}.wprm-recipe-clean-print .wprm-recipe-details-name{display:inline-block;font-weight:700;min-width:130px}.wprm-recipe-clean-print .wprm-recipe-details-unit{font-size:.8em}.wprm-recipe-clean-print h3.wprm-recipe-header{margin-top:10px;font-size:1.2em}.wprm-recipe-clean-print ol,.wprm-recipe-clean-print ul{margin:0 0 8px}.wprm-recipe-clean-print ol li,.wprm-recipe-clean-print ul li{margin:0 0 0 32px}.wprm-recipe-clean-print h4.wprm-recipe-group-name{margin-top:5px!important;font-weight:300;font-size:1em}.wprm-recipe-clean-print .wprm-recipe-ingredient-notes{color:#999}.wprm-recipe-clean-print .wprm-recipe-instructions .wprm-recipe-instruction{margin-bottom:5px}.wprm-recipe-clean-print .wprm-recipe-instruction-text p{margin:0 0 5px}.wprm-recipe-clean-print .wprm-recipe-instruction-text p:last-of-type{margin-bottom:0}.wprm-print .wprm-recipe-clean-print{max-width:750px;margin:0 auto}
|
1 |
+
.wprm-recipe-clean-print{font-size:.9em}.wprm-recipe-clean-print h2.wprm-recipe-name,.wprm-recipe-clean-print h3.wprm-recipe-header,.wprm-recipe-clean-print h4.wprm-recipe-group-name{font-variant:normal;text-transform:none;letter-spacing:normal;margin:0;padding:0}.wprm-recipe-clean-print h2.wprm-recipe-name{clear:none;font-size:1.8em}.wprm-recipe-clean-print .wprm-recipe-details-container,.wprm-recipe-clean-print .wprm-recipe-summary{margin-bottom:15px}.wprm-recipe-clean-print .wprm-recipe-details-name{display:inline-block;font-weight:700;min-width:130px}.wprm-recipe-clean-print .wprm-recipe-details-unit{font-size:.8em}.wprm-recipe-clean-print h3.wprm-recipe-header{margin-top:10px;font-size:1.2em}.wprm-recipe-clean-print ol,.wprm-recipe-clean-print ul{margin:0 0 8px}.wprm-recipe-clean-print ol li,.wprm-recipe-clean-print ul li{margin:0 0 0 32px}.wprm-recipe-clean-print h4.wprm-recipe-group-name{margin-top:5px!important;font-weight:300;font-size:1em}.wprm-recipe-clean-print .wprm-recipe-ingredient-notes{color:#999}.wprm-recipe-clean-print .wprm-recipe-instructions .wprm-recipe-instruction{margin-bottom:5px}.wprm-recipe-clean-print .wprm-recipe-instruction-text p{margin:0 0 5px}.wprm-recipe-clean-print .wprm-recipe-instruction-text p:last-of-type{margin-bottom:0}.wprm-print .wprm-recipe-clean-print{max-width:750px;margin:0 auto}
|
templates/recipe/clean-print/clean-print.scss
CHANGED
@@ -8,6 +8,7 @@
|
|
8 |
text-transform: none;
|
9 |
letter-spacing: normal;
|
10 |
margin: 0;
|
|
|
11 |
}
|
12 |
|
13 |
h2.wprm-recipe-name {
|
8 |
text-transform: none;
|
9 |
letter-spacing: normal;
|
10 |
margin: 0;
|
11 |
+
padding: 0;
|
12 |
}
|
13 |
|
14 |
h2.wprm-recipe-name {
|
templates/recipe/simple/simple.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.wprm-recipe-simple{border-top:1px solid #aaa;background-color:#fafafa;padding:10px;margin:20px 0;font-size:.9em}.wprm-recipe-simple li,.wprm-recipe-simple p{font-size:1em}.wprm-recipe-simple h2.wprm-recipe-name,.wprm-recipe-simple h3.wprm-recipe-header,.wprm-recipe-simple h4.wprm-recipe-group-name{font-variant:normal;text-transform:none;letter-spacing:normal;margin:0}.wprm-recipe-simple .wprm-recipe-image-container{float:right;text-align:center;margin:0 0 10px 10px}.wprm-recipe-simple .wprm-recipe-image-container .wprm-recipe-image{margin:0}.wprm-recipe-simple .wprm-recipe-image-container .wprm-recipe-rating{margin-bottom:5px}.wprm-recipe-simple .wprm-recipe-image-container .wprm-recipe-rating svg{vertical-align:middle;width:16px;height:16px;margin:0}.wprm-recipe-simple .wprm-recipe-image-container .wprm-recipe-rating .wprm-recipe-rating-details{font-size:.8em}.wprm-recipe-simple .wprm-recipe-image-container .wprm-recipe-print{font-size:.9em;cursor:pointer}.wprm-recipe-simple h2.wprm-recipe-name{clear:none;font-size:1.8em}.wprm-recipe-simple .wprm-recipe-details-container,.wprm-recipe-simple .wprm-recipe-summary{margin-bottom:15px}.wprm-recipe-simple .wprm-recipe-details-icon svg{vertical-align:middle;width:16px;height:16px}.wprm-recipe-simple .wprm-recipe-details-name{display:inline-block;font-weight:700;min-width:130px}.wprm-recipe-simple .wprm-recipe-details-unit{font-size:.8em}.wprm-recipe-simple h3.wprm-recipe-header{margin-top:10px;font-size:1.2em}.wprm-recipe-simple ol,.wprm-recipe-simple ul{margin:0 0 8px}.wprm-recipe-simple ol li,.wprm-recipe-simple ul li{margin:0 0 0 32px}.wprm-recipe-simple h4.wprm-recipe-group-name{margin-top:5px!important;font-weight:300;font-size:1em}.wprm-recipe-simple .wprm-recipe-ingredient-notes{color:#999}.wprm-recipe-simple .wprm-recipe-instructions .wprm-recipe-instruction{margin-bottom:5px}.wprm-recipe-simple .wprm-recipe-instruction-text p{margin:0 0 5px}.wprm-recipe-simple .wprm-recipe-instruction-text p:last-of-type{margin-bottom:0}.wprm-recipe-simple .wprm-recipe-instruction-image{margin:5px 0 15px}.wprm-print .wprm-recipe-simple{max-width:750px;margin:0 auto}.wprm-print .wprm-recipe-print{display:none}@media only screen and (max-width:640px){.wprm-recipe-simple .wprm-recipe-image-container{float:none}.wprm-recipe-simple .wprm-recipe-details-name{min-width:0}}
|
1 |
+
.wprm-recipe-simple{border-top:1px solid #aaa;background-color:#fafafa;padding:10px;margin:20px 0;font-size:.9em}.wprm-recipe-simple li,.wprm-recipe-simple p{font-size:1em}.wprm-recipe-simple h2.wprm-recipe-name,.wprm-recipe-simple h3.wprm-recipe-header,.wprm-recipe-simple h4.wprm-recipe-group-name{font-variant:normal;text-transform:none;letter-spacing:normal;margin:0;padding:0}.wprm-recipe-simple .wprm-recipe-image-container{float:right;text-align:center;margin:0 0 10px 10px}.wprm-recipe-simple .wprm-recipe-image-container .wprm-recipe-image{margin:0}.wprm-recipe-simple .wprm-recipe-image-container .wprm-recipe-rating{margin-bottom:5px}.wprm-recipe-simple .wprm-recipe-image-container .wprm-recipe-rating svg{vertical-align:middle;width:16px;height:16px;margin:0}.wprm-recipe-simple .wprm-recipe-image-container .wprm-recipe-rating .wprm-recipe-rating-details{font-size:.8em}.wprm-recipe-simple .wprm-recipe-image-container .wprm-recipe-print{font-size:.9em;cursor:pointer}.wprm-recipe-simple h2.wprm-recipe-name{clear:none;font-size:1.8em}.wprm-recipe-simple .wprm-recipe-details-container,.wprm-recipe-simple .wprm-recipe-summary{margin-bottom:15px}.wprm-recipe-simple .wprm-recipe-details-icon svg{vertical-align:middle;width:16px;height:16px}.wprm-recipe-simple .wprm-recipe-details-name{display:inline-block;font-weight:700;min-width:130px}.wprm-recipe-simple .wprm-recipe-details-unit{font-size:.8em}.wprm-recipe-simple h3.wprm-recipe-header{margin-top:10px;font-size:1.2em}.wprm-recipe-simple ol,.wprm-recipe-simple ul{margin:0 0 8px}.wprm-recipe-simple ol li,.wprm-recipe-simple ul li{margin:0 0 0 32px}.wprm-recipe-simple h4.wprm-recipe-group-name{margin-top:5px!important;font-weight:300;font-size:1em}.wprm-recipe-simple .wprm-recipe-ingredient-notes{color:#999}.wprm-recipe-simple .wprm-recipe-instructions .wprm-recipe-instruction{margin-bottom:5px}.wprm-recipe-simple .wprm-recipe-instruction-text p{margin:0 0 5px}.wprm-recipe-simple .wprm-recipe-instruction-text p:last-of-type{margin-bottom:0}.wprm-recipe-simple .wprm-recipe-instruction-image{margin:5px 0 15px}.wprm-print .wprm-recipe-simple{max-width:750px;margin:0 auto}.wprm-print .wprm-recipe-print{display:none}@media only screen and (max-width:640px){.wprm-recipe-simple .wprm-recipe-image-container{float:none}.wprm-recipe-simple .wprm-recipe-details-name{min-width:0}}
|
templates/recipe/simple/simple.scss
CHANGED
@@ -16,6 +16,7 @@
|
|
16 |
text-transform: none;
|
17 |
letter-spacing: normal;
|
18 |
margin: 0;
|
|
|
19 |
}
|
20 |
|
21 |
.wprm-recipe-image-container {
|
16 |
text-transform: none;
|
17 |
letter-spacing: normal;
|
18 |
margin: 0;
|
19 |
+
padding: 0;
|
20 |
}
|
21 |
|
22 |
.wprm-recipe-image-container {
|
vendor/texthighlighter/TextHighlighter.min.js
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
The MIT License (MIT)
|
3 |
+
|
4 |
+
Copyright (c) 2011 - 2014 mirz <mirz.hq@gmail.com>
|
5 |
+
|
6 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 |
+
of this software and associated documentation files (the "Software"), to deal
|
8 |
+
in the Software without restriction, including without limitation the rights
|
9 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10 |
+
copies of the Software, and to permit persons to whom the Software is
|
11 |
+
furnished to do so, subject to the following conditions:
|
12 |
+
|
13 |
+
The above copyright notice and this permission notice shall be included in
|
14 |
+
all copies or substantial portions of the Software.
|
15 |
+
|
16 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 |
+
THE SOFTWARE.
|
23 |
+
*/
|
24 |
+
(function(l){function t(a,b){return e(a).color()===e(b).color()}function p(a,b){a=a||{};for(var c in b)b.hasOwnProperty(c)&&void 0===a[c]&&(a[c]=b[c]);return a}function m(a){return a.filter(function(a,c,d){return d.indexOf(a)===c})}function h(a,b){a.sort(function(a,d){return e(b?d:a).parents().length-e(b?a:d).parents().length})}function v(a){var b=[],c={},d=[];a.forEach(function(a){var d=a.getAttribute("data-timestamp");"undefined"===typeof c[d]&&(c[d]=[],b.push(d));c[d].push(a)});b.forEach(function(a){var b=
|
25 |
+
c[a];d.push({chunks:b,timestamp:a,toString:function(){return b.map(function(a){return a.textContent}).join("")}})});return d}function w(a,b){a.addEventListener("mouseup",b.highlightHandler.bind(b));a.addEventListener("touchend",b.highlightHandler.bind(b))}function g(a,b){if(!a)throw"Missing anchor element";this.el=a;this.options=p(b,{color:"#ffff7b",highlightedClass:"highlighted",contextClass:"highlighter-context",onRemoveHighlight:function(){return!0},onBeforeHighlight:function(){return!0},onAfterHighlight:function(){}});
|
26 |
+
e(this.el).addClass(this.options.contextClass);w(this.el,this)}var u="SCRIPT STYLE SELECT OPTION BUTTON OBJECT APPLET VIDEO AUDIO CANVAS EMBED PARAM METER PROGRESS".split(" "),e=function(a){return{addClass:function(b){a.classList?a.classList.add(b):a.className+=" "+b},removeClass:function(b){a.classList?a.classList.remove(b):a.className=a.className.replace(new RegExp("(^|\\b)"+b+"(\\b|$)","gi")," ")},prepend:function(b){b=Array.prototype.slice.call(b);for(var c=b.length;c--;)a.insertBefore(b[c],a.firstChild)},
|
27 |
+
append:function(b){b=Array.prototype.slice.call(b);for(var c=0,d=b.length;c<d;++c)a.appendChild(b[c])},insertAfter:function(b){return b.parentNode.insertBefore(a,b.nextSibling)},insertBefore:function(b){return b.parentNode.insertBefore(a,b)},remove:function(){a.parentNode.removeChild(a);a=null},contains:function(b){return a!==b&&a.contains(b)},wrap:function(b){a.parentNode&&a.parentNode.insertBefore(b,a);b.appendChild(a);return b},unwrap:function(){var b=Array.prototype.slice.call(a.childNodes),c;
|
28 |
+
b.forEach(function(a){c=a.parentNode;e(a).insertBefore(a.parentNode);e(c).remove()});return b},parents:function(){for(var b,c=[];b=a.parentNode;)c.push(b),a=b;return c},normalizeTextNodes:function(){if(a){if(3===a.nodeType)for(;a.nextSibling&&3===a.nextSibling.nodeType;)a.nodeValue+=a.nextSibling.nodeValue,a.parentNode.removeChild(a.nextSibling);else e(a.firstChild).normalizeTextNodes();e(a.nextSibling).normalizeTextNodes()}},color:function(){return a.style.backgroundColor},fromHTML:function(a){var c=
|
29 |
+
document.createElement("div");c.innerHTML=a;return c.childNodes},getRange:function(){var b=e(a).getSelection(),c;0<b.rangeCount&&(c=b.getRangeAt(0));return c},removeAllRanges:function(){e(a).getSelection().removeAllRanges()},getSelection:function(){return e(a).getWindow().getSelection()},getWindow:function(){return e(a).getDocument().defaultView},getDocument:function(){return a.ownerDocument||a}}};g.prototype.destroy=function(){var a=this.el;a.removeEventListener("mouseup",this.highlightHandler.bind(this));
|
30 |
+
a.removeEventListener("touchend",this.highlightHandler.bind(this));e(this.el).removeClass(this.options.contextClass)};g.prototype.highlightHandler=function(){this.doHighlight()};g.prototype.doHighlight=function(a){var b=e(this.el).getRange(),c,d;b&&!b.collapsed&&(!0===this.options.onBeforeHighlight(b)&&(d=+new Date,c=g.createWrapper(this.options),c.setAttribute("data-timestamp",d),c=this.highlightRange(b,c),c=this.normalizeHighlights(c),this.options.onAfterHighlight(b,c,d)),a||e(this.el).removeAllRanges())};
|
31 |
+
g.prototype.highlightRange=function(a,b){var c;if(!a||a.collapsed)return[];var d=a.startContainer;c=a.endContainer;var r=a.commonAncestorContainer,n=!0;if(0===a.endOffset){for(;!c.previousSibling&&c.parentNode!==r;)c=c.parentNode;c=c.previousSibling}else 3===c.nodeType?a.endOffset<c.nodeValue.length&&c.splitText(a.endOffset):0<a.endOffset&&(c=c.childNodes.item(a.endOffset-1));3===d.nodeType?a.startOffset===d.nodeValue.length?n=!1:0<a.startOffset&&(d=d.splitText(a.startOffset),c===d.previousSibling&&
|
32 |
+
(c=d)):d=a.startOffset<d.childNodes.length?d.childNodes.item(a.startOffset):d.nextSibling;var f=n,n=!1,r=[],k;do f&&3===d.nodeType&&(-1===u.indexOf(d.parentNode.tagName)&&""!==d.nodeValue.trim()&&(f=b.cloneNode(!0),f.setAttribute("data-highlighted",!0),k=d.parentNode,e(this.el).contains(k)||k===this.el)&&(f=e(d).wrap(f),r.push(f)),f=!1),d!==c||c.hasChildNodes()&&f||(n=!0),d.tagName&&-1<u.indexOf(d.tagName)&&(c.parentNode===d&&(n=!0),f=!1),f&&d.hasChildNodes()?d=d.firstChild:d.nextSibling?(d=d.nextSibling,
|
33 |
+
f=!0):(d=d.parentNode,f=!1);while(!n);return r};g.prototype.normalizeHighlights=function(a){this.flattenNestedHighlights(a);this.mergeSiblingHighlights(a);a=a.filter(function(a){return a.parentElement?a:null});a=m(a);a.sort(function(a,c){return a.offsetTop-c.offsetTop||a.offsetLeft-c.offsetLeft});return a};g.prototype.flattenNestedHighlights=function(a){function b(){var b=!1;a.forEach(function(c,f){var k=c.parentElement,g=k.previousSibling,h=k.nextSibling;d.isHighlight(k)&&(t(k,c)?(k.replaceChild(c.firstChild,
|
34 |
+
c),a[f]=k,b=!0):(c.nextSibling||(e(c).insertBefore(h||k),b=!0),c.previousSibling||(e(c).insertAfter(g||k),b=!0),k.hasChildNodes()||e(k).remove()))});return b}var c,d=this;h(a,!0);do c=b();while(c)};g.prototype.mergeSiblingHighlights=function(a){function b(a,b){return b&&1===b.nodeType&&t(a,b)&&c.isHighlight(b)}var c=this;a.forEach(function(a){var c=a.previousSibling,n=a.nextSibling;b(a,c)&&(e(a).prepend(c.childNodes),e(c).remove());b(a,n)&&(e(a).append(n.childNodes),e(n).remove());e(a).normalizeTextNodes()})};
|
35 |
+
g.prototype.setColor=function(a){this.options.color=a};g.prototype.getColor=function(){return this.options.color};g.prototype.removeHighlights=function(a){function b(a){e(a).unwrap().forEach(function(a){var b=a.previousSibling,c=a.nextSibling;b&&3===b.nodeType&&(a.nodeValue=b.nodeValue+a.nodeValue,e(b).remove());c&&3===c.nodeType&&(a.nodeValue+=c.nodeValue,e(c).remove())})}a=this.getHighlights({container:a||this.el});var c=this;h(a,!0);a.forEach(function(a){!0===c.options.onRemoveHighlight(a)&&b(a)})};
|
36 |
+
g.prototype.getHighlights=function(a){a=p(a,{container:this.el,andSelf:!0,grouped:!1});var b=a.container.querySelectorAll("[data-highlighted]"),b=Array.prototype.slice.call(b);!0===a.andSelf&&a.container.hasAttribute("data-highlighted")&&b.push(a.container);a.grouped&&(b=v(b));return b};g.prototype.isHighlight=function(a){return a&&1===a.nodeType&&a.hasAttribute("data-highlighted")};g.prototype.serializeHighlights=function(){var a=this.getHighlights(),b=this.el,c=[];h(a,!1);a.forEach(function(a){var e=
|
37 |
+
0,g=a.textContent.length,f=a,k=[],h;do h=Array.prototype.slice.call(f.parentNode.childNodes),k.unshift(h.indexOf(f)),f=f.parentNode;while(f!==b||!f);f=a.cloneNode(!0);f.innerHTML="";f=f.outerHTML;a.previousSibling&&3===a.previousSibling.nodeType&&(e=a.previousSibling.length);c.push([f,a.textContent,k.join(":"),e,g])});return JSON.stringify(c)};g.prototype.deserializeHighlights=function(a){var b,c=[],d=this;if(!a)return c;try{b=JSON.parse(a)}catch(g){throw"Can't parse JSON: "+g;}b.forEach(function(a){try{for(var b=
|
38 |
+
a[0],g=a[2].split(":"),h=a[3],m=a[4],l=g.pop(),s=d.el,q,p,r;r=g.shift();)s=s.childNodes[r];s.childNodes[l-1]&&3===s.childNodes[l-1].nodeType&&--l;s=s.childNodes[l];q=s.splitText(h);q.splitText(m);q.nextSibling&&!q.nextSibling.nodeValue&&e(q.nextSibling).remove();q.previousSibling&&!q.previousSibling.nodeValue&&e(q.previousSibling).remove();p=e(q).wrap(e().fromHTML(b)[0]);c.push(p)}catch(t){console&&console.warn&&console.warn("Can't deserialize highlight descriptor. Cause: "+t)}});return c};g.prototype.find=
|
39 |
+
function(a,b){var c=e(this.el).getWindow(),d=c.scrollX,g=c.scrollY,h="undefined"===typeof b?!0:b;e(this.el).removeAllRanges();if(c.find)for(;c.find(a,h);)this.doHighlight(!0);else if(c.document.body.createTextRange){var f=c.document.body.createTextRange();for(f.moveToElementText(this.el);f.findText(a,1,h?4:0)&&(e(this.el).contains(f.parentElement())||f.parentElement()===this.el);)f.select(),this.doHighlight(!0),f.collapse(!1)}e(this.el).removeAllRanges();c.scrollTo(d,g)};g.createWrapper=function(a){var b=
|
40 |
+
document.createElement("span");b.style.backgroundColor=a.color;b.className=a.highlightedClass;return b};l.TextHighlighter=g})(window);(function(l){function t(l,m){return function(){m.call(this,l)}}l.fn.getHighlighter=function(){return this.data("textHighlighter")};l.fn.textHighlighter=function(p){return this.each(function(){var m=this,h;l.data(m,"textHighlighter")||(h=new TextHighlighter(m,p),h.destroy=t(h.destroy,function(p){p.call(h);l(m).removeData("textHighlighter")}),l.data(m,"textHighlighter",h))})}})(jQuery);
|
wp-recipe-maker.php
CHANGED
@@ -15,7 +15,7 @@
|
|
15 |
* Plugin Name: WP Recipe Maker
|
16 |
* Plugin URI: http://bootstrapped.ventures/wp-recipe-maker/
|
17 |
* Description: The easy and user-friendly recipe plugin for everyone. Automatic JSON-LD metadata for better SEO will get you more visitors!
|
18 |
-
* Version: 1.
|
19 |
* Author: Bootstrapped Ventures
|
20 |
* Author URI: http://bootstrapped.ventures/
|
21 |
* License: GPL-2.0+
|
15 |
* Plugin Name: WP Recipe Maker
|
16 |
* Plugin URI: http://bootstrapped.ventures/wp-recipe-maker/
|
17 |
* Description: The easy and user-friendly recipe plugin for everyone. Automatic JSON-LD metadata for better SEO will get you more visitors!
|
18 |
+
* Version: 1.7
|
19 |
* Author: Bootstrapped Ventures
|
20 |
* Author URI: http://bootstrapped.ventures/
|
21 |
* License: GPL-2.0+
|