├── filters ├── index.js ├── frontend.js └── code-block │ ├── frontend.js │ ├── editor.scss │ ├── style.scss │ └── index.js ├── lib ├── meta.php ├── register-post-type.php ├── block-filters.php └── register-scripts.php ├── plugins ├── index.js └── 01-content-templates-sidebar │ ├── plugin.scss │ └── index.js ├── languages ├── de_DE.mo ├── content-templates.pot └── de_DE.po ├── assets └── css │ ├── filters.style.css.map │ ├── filters.editor.css.map │ ├── filters.editor.css │ └── filters.style.css ├── .babelrc ├── .gitignore ├── composer.json ├── README.md ├── package.json ├── plugin.php └── webpack.config.js /filters/index.js: -------------------------------------------------------------------------------- 1 | import './code-block'; -------------------------------------------------------------------------------- /filters/frontend.js: -------------------------------------------------------------------------------- 1 | import './code-block/frontend'; -------------------------------------------------------------------------------- /lib/meta.php: -------------------------------------------------------------------------------- 1 | { 9 | 10 | const language = codeElement.dataset.language; 11 | const code = codeElement.getElementsByTagName( 'pre' )[0].childNodes[0].innerText; 12 | 13 | render( 14 | 15 | {code} 16 | , 17 | codeElement 18 | ); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gutenberg Content Templates 2 | ## Reusable Content Templates for Gutenberg like PowerPoint Slide Master 3 | 4 | ## How to use 5 | 6 | 1. Install the Plugin via Plugin Install Screen 7 | 2. Create one or more Templates via the Templates Post Type 8 | 3. Create a new Post 9 | 4. Open the Content Templates Sidebar via the Icon on the top Right or Options > Content Templates 10 | 5. Choose a Template 11 | 12 | ## Development 13 | 14 | 1. Download or fork the course repo 15 | 2. Install themes and plugins as needed 16 | 3. Run `npm install` and `npm start` to make changes 17 | 4. Run `npm run build` to build 18 | -------------------------------------------------------------------------------- /lib/block-filters.php: -------------------------------------------------------------------------------- 1 | '; 21 | $output .= $block_content; 22 | $output .= ''; 23 | return $output; 24 | } -------------------------------------------------------------------------------- /languages/de_DE.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Content-Type: text/plain; charset=UTF-8\n" 4 | "X-Generator: Poedit 2.2.1\n" 5 | "Project-Id-Version: \n" 6 | "POT-Creation-Date: \n" 7 | "PO-Revision-Date: \n" 8 | "Language-Team: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Transfer-Encoding: 8bit\n" 11 | "Last-Translator: \n" 12 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 13 | "Language: de\n" 14 | 15 | #: plugins/01-content-templates-sidebar/index.js:123 16 | msgid "No Templates Found" 17 | msgstr "Es wurden keine Templates gefunden." 18 | 19 | #: plugins/01-content-templates-sidebar/index.js:124 20 | msgid "You don't have any Templates" 21 | msgstr "Du hast bisher keine Templates erstellt." 22 | 23 | #: plugins/01-content-templates-sidebar/index.js:125 24 | msgid "Please create a new Template first." 25 | msgstr "Bitte erstelle zuerst ein neues Template." 26 | 27 | #: plugins/01-content-templates-sidebar/index.js:141 28 | msgid "Content Templates" 29 | msgstr "Content Templates" 30 | 31 | #: plugins/01-content-templates-sidebar/index.js:143 32 | msgid "Select a Template" 33 | msgstr "Template auswählen" 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "content-templates", 3 | "version": "3.0.0", 4 | "license": "MIT", 5 | "main": "blocks/index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/derweili/content-templates" 9 | }, 10 | "scripts": { 11 | "start": "cross-env BABEL_ENV=default webpack --watch", 12 | "build": "cross-env BABEL_ENV=default NODE_ENV=production webpack -p" 13 | }, 14 | "devDependencies": { 15 | "@wordpress/babel-plugin-makepot": "^2.1.2", 16 | "@wordpress/babel-preset-default": "^1.2.0", 17 | "babel-core": "^6.26.3", 18 | "babel-eslint": "^8.2.3", 19 | "babel-loader": "^7.1.4", 20 | "babel-plugin-transform-class-properties": "^6.24.1", 21 | "classnames": "^2.2.6", 22 | "cross-env": "^5.1.5", 23 | "css-loader": "^0.28.11", 24 | "eslint": "^4.19.1", 25 | "extract-text-webpack-plugin": "^3.0.2", 26 | "node-sass": "^4.9.0", 27 | "postcss-loader": "^2.1.5", 28 | "raw-loader": "^0.5.1", 29 | "sass-loader": "^6.0.7", 30 | "style-loader": "^0.19.1", 31 | "webpack": "^3.11.0" 32 | }, 33 | "dependencies": { 34 | "react-highlight.js": "^1.0.7", 35 | "react-images": "^1.0.0", 36 | "react-photo-gallery": "^7.0.2" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /plugin.php: -------------------------------------------------------------------------------- 1 | { 58 | 59 | return props => { 60 | console.log(props); 61 | if( "core/code" !== props.name ) return ; 62 | 63 | if( !props.isSelected){ 64 | return ( 65 | 66 | {props.attributes.content} 67 | 68 | ); 69 | } 70 | 71 | return ( 72 | 73 | 74 | 75 | 76 | { props.setAttributes( {language} ) } } 91 | /> 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | ); 101 | 102 | } 103 | 104 | }); 105 | 106 | return withInspectorControls(BlockEdit); 107 | 108 | } 109 | 110 | -------------------------------------------------------------------------------- /plugins/01-content-templates-sidebar/index.js: -------------------------------------------------------------------------------- 1 | const { __ } = wp.i18n; 2 | const { Fragment } = wp.element; 3 | const { PanelBody, PanelRow, Button, Modal } = wp.components; 4 | const { registerPlugin } = wp.plugins; 5 | const { PluginSidebar, PluginSidebarMoreMenuItem } = wp.editPost; 6 | const { parse } = wp.blockSerializationDefaultParser; 7 | const { select, dispatch} = wp.data; 8 | const apiRequest = wp.apiRequest; 9 | const ajax= wp.ajax; 10 | 11 | 12 | const {createBlock, rawHandler} = wp.blocks; 13 | 14 | 15 | 16 | import "./plugin.scss"; 17 | 18 | /** 19 | * 20 | */ 21 | 22 | class ContentTemplatesSidebar extends React.Component { 23 | 24 | state = { 25 | templates : [], // available templates 26 | selectedTemplate: null, // currently selected template 27 | isOpen: false // is modal open 28 | }; 29 | 30 | /** 31 | * Load Available Templates 32 | */ 33 | componentDidMount(){ 34 | 35 | apiRequest( { path: '/wp/v2/content-template' } ).then( posts => { 36 | this.onNewPosts( posts ); 37 | } ); 38 | 39 | } 40 | 41 | /** 42 | * Receive Templates from REST API 43 | * 44 | * @param {array} posts Content Template Posts (REST) 45 | */ 46 | onNewPosts( posts ){ 47 | 48 | const templates = posts.map( post => { 49 | 50 | return { 51 | id: post.id, 52 | title: post.title.rendered, 53 | content: post.plain_content, 54 | icon: post.icon 55 | } 56 | 57 | }) 58 | 59 | this.setState( {templates } ); 60 | 61 | } 62 | 63 | onReloadEditor(){ 64 | } 65 | 66 | /** 67 | * Overwrite Blocks on Template Select 68 | * 69 | * @param {*} template Selected Template 70 | * @param {*} force Skip user consent modal 71 | */ 72 | onSelectTemplate( template, force = false){ 73 | // const newBlockTemplate = parse(template.content); 74 | // console.log('newBlockTemplate', newBlockTemplate); 75 | 76 | const isNewPost = select("core/editor").isCleanNewPost(); 77 | 78 | // show warning if 79 | if (force || isNewPost){ 80 | 81 | // get an array of gutenberg blocks from raw HTML (parse blocks) 82 | var gutblock = wp.blocks.rawHandler({ 83 | HTML: template.content, 84 | }); 85 | 86 | // re-serialize blocks 87 | // var serelized = wp.blocks.serialize(gutblock); 88 | // serelized = serelized; 89 | 90 | // delete all Blocks 91 | dispatch("core/editor").resetBlocks([]); 92 | 93 | // insert new Blocks 94 | dispatch("core/editor").insertBlocks(gutblock, 0); 95 | 96 | // close Modal and reset selected Template 97 | this.setState({isOpen:false, selectedTemplate: null}) 98 | 99 | }else{ 100 | this.setState({ 101 | isOpen: true, 102 | selectedTemplate: template 103 | }); 104 | } 105 | } 106 | 107 | /** 108 | * Close the user consent modal 109 | */ 110 | closeModal(){ 111 | this.setState({isOpen:false, selectedTemplate: null}) 112 | } 113 | 114 | /** 115 | * Render "No Templates Found" Message 116 | * 117 | * The templatesAdminLink comes from wp_localize_script 118 | * 119 | */ 120 | noTemplatesFound(){ 121 | return ( 122 | 123 | {__("No Templates Found", "content-templates")} 124 | {__("You don't have any Templates", "content-templates")} 125 | {__("Please create a new Template first.", "content-templates")} 126 | 127 | ); 128 | } 129 | 130 | render(){ 131 | 132 | const { templates, isOpen } = this.state; 133 | 134 | return ( 135 | 136 | 137 | {__("Content Templates", "content-templates")} 138 | 139 | 143 | 144 | 145 | 146 | { 147 | templates.length > 0 ? 148 | templates.map(template => { 149 | return ( 150 | 151 | { this.onSelectTemplate(template) } } className="template-button"> 152 | 153 | {template.title} 154 | 155 | 156 | ); 157 | }) : this.noTemplatesFound() 158 | 159 | } 160 | 161 | 162 | 163 | 164 | { 165 | isOpen && ( 166 | this.closeModal() }> 169 | 170 | Do you want to overwrite all Existing Content? 171 | 172 | { this.onSelectTemplate( this.state.selectedTemplate, true ) } } > 173 | Overwrite Content 174 | 175 | 176 | ) 177 | } 178 | 179 | ) 180 | } 181 | } 182 | 183 | registerPlugin( "contenttemplates-sidebar", { 184 | icon: "layout", 185 | render: ContentTemplatesSidebar 186 | }) --------------------------------------------------------------------------------
{__("You don't have any Templates", "content-templates")}
170 | Do you want to overwrite all Existing Content? 171 |