├── .babelrc
├── .gitignore
├── README.md
├── blocks
├── block-layout
│ ├── block-layout.build.js
│ ├── block-layout.editor.css
│ ├── block-layout.view.css
│ ├── block-layout.view.js
│ └── index.php
├── carousel
│ ├── carousel.build.js
│ ├── carousel.editor.css
│ ├── carousel.view.css
│ ├── carousel.view.js
│ └── index.php
├── gallery
│ ├── dist
│ │ ├── css
│ │ │ ├── lightbox.css
│ │ │ └── lightbox.min.css
│ │ ├── images
│ │ │ ├── close.png
│ │ │ ├── loading.gif
│ │ │ ├── next.png
│ │ │ └── prev.png
│ │ └── js
│ │ │ ├── lightbox-plus-jquery.js
│ │ │ ├── lightbox-plus-jquery.min.js
│ │ │ ├── lightbox-plus-jquery.min.map
│ │ │ ├── lightbox.js
│ │ │ ├── lightbox.min.js
│ │ │ └── lightbox.min.map
│ ├── gallery.build.js
│ ├── gallery.editor.css
│ ├── gallery.view.css
│ └── index.php
├── hello-world
│ ├── hello-world.build.js
│ ├── hello-world.editor.css
│ ├── hello-world.view.css
│ ├── hello-world.view.js
│ └── index.php
├── image-hero
│ ├── image-hero.build.js
│ ├── image-hero.editor.css
│ ├── image-hero.view.css
│ ├── image-hero.view.js
│ └── index.php
├── media-block
│ ├── index.php
│ ├── media-block.build.js
│ ├── media-block.editor.css
│ ├── media-block.view.css
│ └── media-block.view.js
├── prism-code
│ ├── index.php
│ ├── prism-code.build.js
│ ├── prism-code.editor.css
│ ├── prism-code.view.css
│ └── prism-code.view.js
├── quote
│ ├── index.php
│ ├── quote.build.js
│ ├── quote.editor.css
│ └── quote.view.css
├── react-view
│ ├── index.php
│ ├── react-view.build.js
│ ├── react-view.editor.css
│ ├── react-view.view.css
│ └── react-view.view.js
├── recent-posts
│ ├── index.php
│ ├── recent-posts.build.js
│ ├── recent-posts.editor.css
│ ├── recent-posts.view.css
│ └── recent-posts.view.js
└── side-by-side
│ ├── index.php
│ ├── side-by-side.build.js
│ ├── side-by-side.editor.css
│ └── side-by-side.view.css
├── index.php
├── js
└── i18n.js
├── package-lock.json
├── package.json
├── src
├── block-layout
│ ├── block-layout.editor.css
│ ├── block-layout.src.js
│ └── block-layout.view.css
├── carousel
│ ├── carousel.editor.css
│ ├── carousel.src.js
│ └── carousel.view.css
├── gallery
│ ├── Image.js
│ ├── gallery.editor.css
│ ├── gallery.src.js
│ └── gallery.view.css
├── hello-world
│ ├── _test.scss
│ ├── hello-world.editor.css
│ ├── hello-world.src.js
│ └── hello-world.view.scss
├── image-hero
│ ├── image-hero.editor.css
│ ├── image-hero.src.js
│ └── image-hero.view.css
├── media-block
│ ├── media-block.editor.css
│ ├── media-block.src.js
│ └── media-block.view.css
├── prism-code
│ ├── prism-code.editor.css
│ ├── prism-code.src.js
│ ├── prism-code.view.css
│ └── prismjs
│ │ ├── prism.css
│ │ └── prism.js
├── quote
│ ├── quote.editor.css
│ ├── quote.src.js
│ └── quote.view.css
├── react-view
│ ├── components
│ │ └── Editor.jsx
│ ├── react-view.editor.css
│ ├── react-view.src.js
│ ├── react-view.view.js
│ └── react-view.view.scss
├── recent-posts
│ ├── recent-posts.editor.css
│ ├── recent-posts.src.js
│ └── recent-posts.view.css
└── side-by-side
│ ├── side-by-side.editor.scss
│ ├── side-by-side.src.js
│ └── side-by-side.view.scss
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | [
4 | "@wordpress/babel-plugin-makepot",
5 | {
6 | "output": "languages/guty-blocks-js.pot"
7 | }
8 | ],
9 | [
10 | "transform-react-jsx",
11 | {
12 | "pragma": "wp.element.createElement"
13 | }
14 | ]
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # guty-blocks
2 |
3 | A build environment for [Gutenberg blocks](https://wordpress.org/gutenberg/handbook/block-api/) with a few example blocks.
4 |
5 | ## How to use the blocks
6 |
7 | 1. Install and activate the [Gutenberg plugin](https://WordPress.org/plugins/gutenberg/) inside of WordPress
8 | 2. Clone this project into the plugins folder of WordPress
9 | 3. Activate this plugin inside of WordPress
10 | 4. You now should have access to guty-blocks in the Gutenberg editor
11 |
12 | ## Current example blocks:
13 |
14 | - Hello world - simple static block
15 | - Media - Allows adding an image and text to the side
16 | - Quote - a simple quote block
17 | - Custom Gallery - A custom image gallery that you can add images, title, rearrange images, etc. It uses [lightbox2](http://lokeshdhakar.com/projects/lightbox2/) by Lokesh Dhakar (MIT).
18 | - Carousel - A simple carousel example
19 | - Image hero - Includes a background, hero text, and a gradient overlay
20 | - Recent posts - Uses WordPress API to fetch posts and include them in the block
21 | - Block layout - Uses InnerBlock component to nest blocks into blocks on the page (css)
22 | - Prism code - A code formatter using [prismjs](http://prismjs.com/)
23 | - React View - An example where a live react app is included in the view of the page. In the editor posts are selected. In the view, the react app will fetch those post ids and preview the post.
24 | - Side by Side - A simple image next to text that is responsive.
25 |
26 | ## How to make blocks
27 |
28 | Make sure you have installed and activated the [Gutenberg plugin](https://wordpress.org/plugins/gutenberg/) and this project plugin. You will need to have `npm` installed and configured correctly for your Operating System.
29 |
30 | 1. Run `npm install` within this project plugin's main directory.
31 | 2. Duplicate any of the folders within the src folder and make sure to rename the js and css files to your new block name. You will need to rename file names inside of the `src.js` file as well.
32 | 3. You will need to create an `index.php` file that loads your new block in the `blocks/[yourblockname]` folder after the block is built. You can follow the pattern in the example blocks inside of the blocks folder
33 | 4. Webpack looks for `*.js` files following this pattern: `./source/[yourblockname]/[yourblockname].src.js`. If you do not include the `.src.js` suffix, Webpack will not consider it the main gutenberg block JS file.
34 | 5. Webpack also looks for `*.view.js` files to build files that may be called as a part of the view functionality, but are separate from the editor.
35 |
36 | ## How to build the block files
37 |
38 | 1. `npm run watch`
39 | Sets up a "watcher" that monitors files for changes to trigger a rebuild. Essentially the same as `npm run build` below, but continuous.
40 | 2. `npm run build`
41 | This command runs [Babel](https://babeljs.io/) to transpile modern JavaScript to something more browsers understand. It uses the [@WordPress/babel-plugin-makepot](https://www.npmjs.com/package/@wordpress/babel-plugin-makepot) Babel plugin to automatically extract all translatable strings from the JavaScript, and create a POT file for them (`guty-blocks-js.pot`). This `-js.pot` POT file is an intermediary step to internationlizing all strings for the plugin.
42 |
43 | ## Internationlization (i18n) / Localization
44 |
45 | ### What is [internationalization](https://developer.wordpress.org/plugins/internationalization/) (i18n)?
46 | > Internationalization is the process of developing a plugin, so it can easily be translated into other languages. Internationalization is often abbreviated as i18n (because there are 18 letters between the letters i and n).
47 |
48 | In WordPress, we use the gettext family of functions to make "literal strings" in our code available for translation. This is "internationalization."
49 |
50 | For example, a 404 page might have a hard-coded message that says "Oops! That page can’t be found." That literal string is not content coming from the database, and it can't easily be changed to another language by the site owner, without editing our code.
51 |
52 | However, to internationalize that string, we would wrap it in a gettext function, so that it is made available for translation.
53 |
54 | A simple example of how we might do this in WordPress PHP:
55 | ``
56 |
57 | The Gutenberg team has taken those gettext functions, and made them available to JS as well, via the [@wordpress/i18n](https://www.npmjs.com/package/@wordpress/i18n#api) npm package. The same concepts from WordPress PHP can now be used in your Gutenblocks.
58 |
59 | Now let's assume we have a Gutenblock that has a literal string in it, that we need to make available for translation.
60 |
61 | We would import the __() function into our block like so, `const { __ } = wp.i18n;`.
62 |
63 | Then we would use that function to wrap a literal string that needs to be available for translation, like so, `title: __( 'Hello World!', 'my-plugin-text-domain' )`.
64 |
65 | We would then use a tool (of which there are many) to create a POT (Portable Object Template) file. This file contains the original strings (in English) from the plugin. It is sort of like a dictionary, containing all the known literal strings.
66 |
67 | ### What is [localization](https://developer.wordpress.org/plugins/internationalization/localization/) (l10n)?
68 | > Localization describes the subsequent process of translating an internationalized plugin. Localization is abbreviated as l10n (because there are 10 letters between the l and the n).
69 |
70 | Localization then, is when a translator provides translated versions of those literal string in another language.
71 |
72 | > Every translator will take the POT file and translate the msgstr sections into their own language. The result is a PO (Portable Object) file with the same format as a POT, but with translations and some specific headers. There is one PO file per language.
73 |
74 | > From every translated PO file, an MO (Machine Object) file is built. These are machine-readable, binary files that the gettext functions actually use (they don’t care about .POT or .PO files), and are a “compiled” version of the PO file. The conversion is done using the msgfmt tool. In general, an application may use more than one large logical translatable module and a different MO file accordingly. A text domain is a handle of each module, which has a different MO file.
75 |
76 | ### How do we create the plugin's POT file?
77 |
78 | Gutenberg's [internationalization](https://developer.wordpress.org/plugins/internationalization/) (i18n) and [localization](https://developer.wordpress.org/plugins/internationalization/localization/) (l10n) features, much like Gutenberg itself, are evolving quickly. The workflow for i18n/l10n may change, improve, and simplify as the project evolves.
79 |
80 | For the purposes of `guty-blocks`, we are using a combination of three methods to generate our plugin's final POT file.
81 |
82 | First, the build process, either with `npm run watch` or `npm run build`, will use the [@WordPress/babel-plugin-makepot](https://www.npmjs.com/package/@wordpress/babel-plugin-makepot) Babel plugin, to automatically extract all translatable strings from the JavaScript, and create a POT file specifically for those JS strings (`guty-blocks-js.pot`).
83 |
84 | Second, the build process provides the command `npm run pot-to-php` to generate a PHP file, `guty-blocks-js-translations.php`, containing the JS strings from `guty-blocks-js.pot`, via [@wordpress/i18n's](https://www.npmjs.com/package/@wordpress/i18n) [pot-to-php](https://www.npmjs.com/package/@wordpress/i18n#build) script.
85 |
86 | Third, the build process provides the command `npm run makepot`* to utilize [WP-CLI's](https://wp-cli.org/#installing) [`wp i18n make-pot`](https://github.com/wp-cli/i18n-command) command, to build a final POT file, `guty-blocks.pot`, that contains all the strings from both JS and PHP. `guty-blocks.pot` is the final POT file, the one used for our plugin's text domain, and is the one that any localized PO/MO files should be built from.
87 |
88 | ***NOTE:** `npm run makepot` requires that you have [WP-CLI](https://wp-cli.org/#installing) installed and configured properly for your project. The [i18n command](https://github.com/wp-cli/i18n-command) is slated for future inclusion as a bundled WP-CLI command, but as of WP-CLI v 1.5.0, it is still an add-on command that must be installed separately. Refer to the i18n command's [installation instructions](https://github.com/wp-cli/i18n-command#installing).
89 |
--------------------------------------------------------------------------------
/blocks/block-layout/block-layout.build.js:
--------------------------------------------------------------------------------
1 | /******/ (function(modules) { // webpackBootstrap
2 | /******/ // The module cache
3 | /******/ var installedModules = {};
4 | /******/
5 | /******/ // The require function
6 | /******/ function __webpack_require__(moduleId) {
7 | /******/
8 | /******/ // Check if module is in cache
9 | /******/ if(installedModules[moduleId]) {
10 | /******/ return installedModules[moduleId].exports;
11 | /******/ }
12 | /******/ // Create a new module (and put it into the cache)
13 | /******/ var module = installedModules[moduleId] = {
14 | /******/ i: moduleId,
15 | /******/ l: false,
16 | /******/ exports: {}
17 | /******/ };
18 | /******/
19 | /******/ // Execute the module function
20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21 | /******/
22 | /******/ // Flag the module as loaded
23 | /******/ module.l = true;
24 | /******/
25 | /******/ // Return the exports of the module
26 | /******/ return module.exports;
27 | /******/ }
28 | /******/
29 | /******/
30 | /******/ // expose the modules object (__webpack_modules__)
31 | /******/ __webpack_require__.m = modules;
32 | /******/
33 | /******/ // expose the module cache
34 | /******/ __webpack_require__.c = installedModules;
35 | /******/
36 | /******/ // define getter function for harmony exports
37 | /******/ __webpack_require__.d = function(exports, name, getter) {
38 | /******/ if(!__webpack_require__.o(exports, name)) {
39 | /******/ Object.defineProperty(exports, name, {
40 | /******/ configurable: false,
41 | /******/ enumerable: true,
42 | /******/ get: getter
43 | /******/ });
44 | /******/ }
45 | /******/ };
46 | /******/
47 | /******/ // getDefaultExport function for compatibility with non-harmony modules
48 | /******/ __webpack_require__.n = function(module) {
49 | /******/ var getter = module && module.__esModule ?
50 | /******/ function getDefault() { return module['default']; } :
51 | /******/ function getModuleExports() { return module; };
52 | /******/ __webpack_require__.d(getter, 'a', getter);
53 | /******/ return getter;
54 | /******/ };
55 | /******/
56 | /******/ // Object.prototype.hasOwnProperty.call
57 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
58 | /******/
59 | /******/ // __webpack_public_path__
60 | /******/ __webpack_require__.p = "";
61 | /******/
62 | /******/ // Load entry module and return exports
63 | /******/ return __webpack_require__(__webpack_require__.s = 11);
64 | /******/ })
65 | /************************************************************************/
66 | /******/ ({
67 |
68 | /***/ 11:
69 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
70 |
71 | "use strict";
72 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
73 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__block_layout_editor_css__ = __webpack_require__(12);
74 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__block_layout_editor_css___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__block_layout_editor_css__);
75 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__block_layout_view_css__ = __webpack_require__(13);
76 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__block_layout_view_css___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__block_layout_view_css__);
77 |
78 |
79 |
80 | const {
81 | registerBlockType
82 | } = wp.blocks;
83 |
84 | const {
85 | InnerBlocks,
86 | InspectorControls
87 | } = wp.editor;
88 |
89 | registerBlockType('guty-blocks/block-layout', {
90 | title: 'Block Layout',
91 | category: 'layout',
92 |
93 | attributes: {// Somewhat like setting initial state in a react app.
94 | // Strategy for mapping rendered attributes back into editable state
95 |
96 | },
97 |
98 | // The editor "render" function
99 | edit(props) {
100 | return [props.isSelected && wp.element.createElement(
101 | InspectorControls,
102 | null,
103 | 'Select the number of columns for your blocks:'
104 | ), wp.element.createElement(
105 | 'div',
106 | { 'class': props.className },
107 | wp.element.createElement(InnerBlocks, {
108 | layouts: {
109 | normal: { label: 'Normal Width', icon: 'align-center' },
110 | wide: { label: 'Width Width', icon: 'align-wide' }
111 | } })
112 | )];
113 | },
114 |
115 | // The save "render" function
116 | save(props) {
117 | return wp.element.createElement(
118 | 'div',
119 | { 'class': props.className },
120 | wp.element.createElement(InnerBlocks.Content, null)
121 | );
122 | }
123 |
124 | });
125 |
126 | /***/ }),
127 |
128 | /***/ 12:
129 | /***/ (function(module, exports) {
130 |
131 | // removed by extract-text-webpack-plugin
132 |
133 | /***/ }),
134 |
135 | /***/ 13:
136 | /***/ (function(module, exports) {
137 |
138 | // removed by extract-text-webpack-plugin
139 |
140 | /***/ })
141 |
142 | /******/ });
--------------------------------------------------------------------------------
/blocks/block-layout/block-layout.editor.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-block-layout .editor-block-list__layout{
2 | width: 100%
3 | }
4 |
5 | .wp-block-guty-blocks-block-layout .editor-block-list__layout > .editor-block-list__block {
6 | display: inline-block;
7 | width: 50%;
8 | padding: 8px;
9 | }
10 |
--------------------------------------------------------------------------------
/blocks/block-layout/block-layout.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-block-layout {
2 | display: flex;
3 | flex-direction: row;
4 | flex-wrap: wrap;
5 | align-items: stretch;
6 | }
7 |
8 | .wp-block-guty-blocks-block-layout > * {
9 | width: 50%;
10 | }
11 |
--------------------------------------------------------------------------------
/blocks/block-layout/block-layout.view.js:
--------------------------------------------------------------------------------
1 | /******/ (function(modules) { // webpackBootstrap
2 | /******/ // The module cache
3 | /******/ var installedModules = {};
4 | /******/
5 | /******/ // The require function
6 | /******/ function __webpack_require__(moduleId) {
7 | /******/
8 | /******/ // Check if module is in cache
9 | /******/ if(installedModules[moduleId]) {
10 | /******/ return installedModules[moduleId].exports;
11 | /******/ }
12 | /******/ // Create a new module (and put it into the cache)
13 | /******/ var module = installedModules[moduleId] = {
14 | /******/ i: moduleId,
15 | /******/ l: false,
16 | /******/ exports: {}
17 | /******/ };
18 | /******/
19 | /******/ // Execute the module function
20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21 | /******/
22 | /******/ // Flag the module as loaded
23 | /******/ module.l = true;
24 | /******/
25 | /******/ // Return the exports of the module
26 | /******/ return module.exports;
27 | /******/ }
28 | /******/
29 | /******/
30 | /******/ // expose the modules object (__webpack_modules__)
31 | /******/ __webpack_require__.m = modules;
32 | /******/
33 | /******/ // expose the module cache
34 | /******/ __webpack_require__.c = installedModules;
35 | /******/
36 | /******/ // define getter function for harmony exports
37 | /******/ __webpack_require__.d = function(exports, name, getter) {
38 | /******/ if(!__webpack_require__.o(exports, name)) {
39 | /******/ Object.defineProperty(exports, name, {
40 | /******/ configurable: false,
41 | /******/ enumerable: true,
42 | /******/ get: getter
43 | /******/ });
44 | /******/ }
45 | /******/ };
46 | /******/
47 | /******/ // getDefaultExport function for compatibility with non-harmony modules
48 | /******/ __webpack_require__.n = function(module) {
49 | /******/ var getter = module && module.__esModule ?
50 | /******/ function getDefault() { return module['default']; } :
51 | /******/ function getModuleExports() { return module; };
52 | /******/ __webpack_require__.d(getter, 'a', getter);
53 | /******/ return getter;
54 | /******/ };
55 | /******/
56 | /******/ // Object.prototype.hasOwnProperty.call
57 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
58 | /******/
59 | /******/ // __webpack_public_path__
60 | /******/ __webpack_require__.p = "";
61 | /******/
62 | /******/ // Load entry module and return exports
63 | /******/ return __webpack_require__(__webpack_require__.s = 8);
64 | /******/ })
65 | /************************************************************************/
66 | /******/ ({
67 |
68 | /***/ 10:
69 | /***/ (function(module, exports) {
70 |
71 | throw new Error("Module parse failed: Unexpected token (1:0)\nYou may need an appropriate loader to handle this file type.\n| .wp-block-guty-blocks-block-layout {\n| display: flex;\n| flex-direction: row;");
72 |
73 | /***/ }),
74 |
75 | /***/ 8:
76 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
77 |
78 | "use strict";
79 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
80 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__block_layout_editor_css__ = __webpack_require__(9);
81 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__block_layout_editor_css___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__block_layout_editor_css__);
82 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__block_layout_view_css__ = __webpack_require__(10);
83 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__block_layout_view_css___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__block_layout_view_css__);
84 |
85 |
86 |
87 | const {
88 | registerBlockType,
89 | InnerBlocks,
90 | InspectorControls
91 | } = wp.blocks;
92 |
93 | registerBlockType('guty-blocks/block-layout', {
94 | title: 'Block Layout',
95 | category: 'layout',
96 |
97 | attributes: {// Somewhat like setting initial state in a react app.
98 | // Strategy for mapping rendered attributes back into editable state
99 |
100 | },
101 |
102 | // The editor "render" function
103 | edit(props) {
104 | return [props.isSelected && wp.element.createElement(
105 | InspectorControls,
106 | null,
107 | 'Select the number of columns for your blocks:'
108 | ), wp.element.createElement(
109 | 'div',
110 | { 'class': props.className },
111 | wp.element.createElement(InnerBlocks, {
112 | layouts: {
113 | normal: { label: 'Normal Width', icon: 'align-center' },
114 | wide: { label: 'Width Width', icon: 'align-wide' }
115 | } })
116 | )];
117 | },
118 |
119 | // The save "render" function
120 | save(props) {
121 | return wp.element.createElement(
122 | 'div',
123 | { 'class': props.className },
124 | wp.element.createElement(InnerBlocks.Content, null)
125 | );
126 | }
127 |
128 | });
129 |
130 | /***/ }),
131 |
132 | /***/ 9:
133 | /***/ (function(module, exports) {
134 |
135 | throw new Error("Module parse failed: Unexpected token (1:0)\nYou may need an appropriate loader to handle this file type.\n| .wp-block-guty-blocks-block-layout .editor-block-list__layout{\n| width: 100%\n| }");
136 |
137 | /***/ })
138 |
139 | /******/ });
--------------------------------------------------------------------------------
/blocks/block-layout/index.php:
--------------------------------------------------------------------------------
1 | wp.element.createElement(
137 | 'button',
138 | {
139 | onClick: open,
140 | style: { marginBottom: '16px' } },
141 | 'Select/Change Images'
142 | )
143 | });
144 |
145 | return [wp.element.createElement(
146 | InspectorControls,
147 | null,
148 | wp.element.createElement(
149 | 'div',
150 | null,
151 | MyMediaUpload
152 | ),
153 | wp.element.createElement(
154 | 'div',
155 | { style: { marginBottom: '16px' } },
156 | 'Set fade length (milliseconds):',
157 | wp.element.createElement('input', {
158 | type: 'number',
159 | value: fadeTime,
160 | onChange: changeFadeTime
161 | })
162 | ),
163 | wp.element.createElement(
164 | 'div',
165 | { style: { marginBottom: '16px' } },
166 | 'Set slide interval (seconds):',
167 | wp.element.createElement('input', {
168 | type: 'number',
169 | value: carouselTime,
170 | onChange: changeCarouselTime
171 | })
172 | )
173 | ), MyMediaUpload, wp.element.createElement(
174 | 'div',
175 | {
176 | className: className,
177 | 'data-carousel-time': carouselTime,
178 | style: {
179 | paddingBottom: '56.25%'
180 | } },
181 | wp.element.createElement(
182 | 'div',
183 | { className: 'inner' },
184 | carouselImages.length ? carouselImages.map((el, index) => {
185 | return wp.element.createElement('img', {
186 | src: el.sizes.full.url,
187 | className: !index ? 'active' : null,
188 | style: { transition: `opacity ${fadeTime}ms` }
189 | });
190 | }) : 'No Images Yet'
191 | )
192 | )];
193 | },
194 |
195 | // The save "render" function
196 | save(props) {
197 | const {
198 | className,
199 | attributes: {
200 | carouselImages,
201 | carouselTime,
202 | fadeTime
203 | }
204 | } = props;
205 |
206 | return wp.element.createElement(
207 | 'div',
208 | {
209 | className: className,
210 | 'data-carousel-time': carouselTime,
211 | style: {
212 | paddingBottom: '56.25%'
213 | } },
214 | wp.element.createElement(
215 | 'div',
216 | { className: 'inner' },
217 | carouselImages.length ? carouselImages.map((el, index) => {
218 | return wp.element.createElement('img', {
219 | src: el.sizes.full.url,
220 | className: !index ? 'active' : null,
221 | style: { transition: `opacity ${fadeTime}ms` }
222 | });
223 | }) : 'No images yet...'
224 | )
225 | );
226 | }
227 |
228 | });``;
229 |
230 | /***/ }),
231 |
232 | /***/ 15:
233 | /***/ (function(module, exports) {
234 |
235 | // removed by extract-text-webpack-plugin
236 |
237 | /***/ }),
238 |
239 | /***/ 16:
240 | /***/ (function(module, exports) {
241 |
242 | // removed by extract-text-webpack-plugin
243 |
244 | /***/ })
245 |
246 | /******/ });
--------------------------------------------------------------------------------
/blocks/carousel/carousel.editor.css:
--------------------------------------------------------------------------------
1 | /* .wp-block-guty-blocks-hello-world {
2 | background: cadetblue;
3 | color: white;
4 | } */
5 |
6 |
--------------------------------------------------------------------------------
/blocks/carousel/carousel.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-carousel {
2 | width: 100%;
3 | position: relative;
4 | }
5 |
6 | .wp-block-guty-blocks-carousel .inner {
7 | position: absolute;
8 | top: 0;
9 | left: 0;
10 | width: 100%;
11 | height: 100%;
12 | overflow: hidden;
13 | }
14 |
15 | .wp-block-guty-blocks-carousel .inner img {
16 | position: absolute;
17 | width: 100%;
18 | top: 50%;
19 | transform: translateY(-50%);
20 | opacity: 0;
21 | }
22 |
23 | .wp-block-guty-blocks-carousel .inner img.active {
24 | opacity: 1;
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/blocks/carousel/carousel.view.js:
--------------------------------------------------------------------------------
1 | /*
2 | A simple carousel script that cycles through the carousel images
3 | */
4 |
5 | function Carousel(container) {
6 | //reference to carousel container
7 | this.container = container;
8 |
9 | // reference to carousel slides
10 | this.slides = null;
11 |
12 | // reference top setInterval
13 | this.slideTimer = null;
14 |
15 | // Pull off data attribute to set carousel timing
16 | // Defaults to 5 if something goes wrong
17 | this.carouselTime = this.container.getAttribute('data-carousel-time') * 1000 || 5000;
18 |
19 |
20 | // engage!
21 | this.init();
22 | }
23 |
24 | var proto = Carousel.prototype;
25 |
26 | proto.init = function () {
27 | this.createChildren()
28 | .enable()
29 | .run();
30 | }
31 |
32 | proto.createChildren = function() {
33 | this.slides = this.container.querySelectorAll(':scope img');
34 | // this.slides[0].classList.add('active');
35 | return this;
36 | }
37 |
38 | proto.enable = function() {
39 | this.nextSlide = this.nextSlide.bind(this);
40 | return this;
41 | }
42 |
43 | proto.run = function() {
44 |
45 | this.slideTimer = setInterval(
46 | this.nextSlide,
47 | this.carouselTime
48 | );
49 | }
50 |
51 | proto.nextSlide = function() {
52 | var activeSlide = this.container.querySelector(':scope .active');
53 |
54 | activeSlide.classList.remove('active');
55 |
56 | if (activeSlide.nextSibling) {
57 | activeSlide.nextSibling.classList.add('active');
58 | } else {
59 | this.slides[0].classList.add('active');
60 | }
61 | }
62 |
63 |
64 | // Instantiate for every carousel on page
65 | document.addEventListener("DOMContentLoaded", function (event) {
66 | var carousels = document.querySelectorAll('.wp-block-guty-blocks-carousel');
67 | for (var i = 0; i < carousels.length; i++) {
68 | console.log("%c Carousel present on page and running...", "color: cadetblue;");
69 | new Carousel(carousels[i]);
70 | }
71 | });
--------------------------------------------------------------------------------
/blocks/carousel/index.php:
--------------------------------------------------------------------------------
1 | .nav {
92 | left: 0;
93 | }
94 |
95 | .lb-nav a {
96 | outline: none;
97 | background-image: url('data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');
98 | }
99 |
100 | .lb-prev, .lb-next {
101 | height: 100%;
102 | cursor: pointer;
103 | display: block;
104 | }
105 |
106 | .lb-nav a.lb-prev {
107 | width: 34%;
108 | left: 0;
109 | float: left;
110 | background: url(../images/prev.png) left 48% no-repeat;
111 | filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
112 | opacity: 0;
113 | -webkit-transition: opacity 0.6s;
114 | -moz-transition: opacity 0.6s;
115 | -o-transition: opacity 0.6s;
116 | transition: opacity 0.6s;
117 | }
118 |
119 | .lb-nav a.lb-prev:hover {
120 | filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
121 | opacity: 1;
122 | }
123 |
124 | .lb-nav a.lb-next {
125 | width: 64%;
126 | right: 0;
127 | float: right;
128 | background: url(../images/next.png) right 48% no-repeat;
129 | filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
130 | opacity: 0;
131 | -webkit-transition: opacity 0.6s;
132 | -moz-transition: opacity 0.6s;
133 | -o-transition: opacity 0.6s;
134 | transition: opacity 0.6s;
135 | }
136 |
137 | .lb-nav a.lb-next:hover {
138 | filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
139 | opacity: 1;
140 | }
141 |
142 | .lb-dataContainer {
143 | margin: 0 auto;
144 | padding-top: 5px;
145 | *zoom: 1;
146 | width: 100%;
147 | border-bottom-left-radius: 4px;
148 | border-bottom-right-radius: 4px;
149 | }
150 |
151 | .lb-dataContainer:after {
152 | content: "";
153 | display: table;
154 | clear: both;
155 | }
156 |
157 | .lb-data {
158 | padding: 0 4px;
159 | color: #ccc;
160 | }
161 |
162 | .lb-data .lb-details {
163 | width: 85%;
164 | float: left;
165 | text-align: left;
166 | line-height: 1.1em;
167 | }
168 |
169 | .lb-data .lb-caption {
170 | font-size: 13px;
171 | font-weight: bold;
172 | line-height: 1em;
173 | }
174 |
175 | .lb-data .lb-caption a {
176 | color: #4ae;
177 | }
178 |
179 | .lb-data .lb-number {
180 | display: block;
181 | clear: left;
182 | padding-bottom: 1em;
183 | font-size: 12px;
184 | color: #999999;
185 | }
186 |
187 | .lb-data .lb-close {
188 | display: block;
189 | float: right;
190 | width: 30px;
191 | height: 30px;
192 | background: url(../images/close.png) top right no-repeat;
193 | text-align: right;
194 | outline: none;
195 | filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
196 | opacity: 0.7;
197 | -webkit-transition: opacity 0.2s;
198 | -moz-transition: opacity 0.2s;
199 | -o-transition: opacity 0.2s;
200 | transition: opacity 0.2s;
201 | }
202 |
203 | .lb-data .lb-close:hover {
204 | cursor: pointer;
205 | filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
206 | opacity: 1;
207 | }
208 |
--------------------------------------------------------------------------------
/blocks/gallery/dist/css/lightbox.min.css:
--------------------------------------------------------------------------------
1 | .lb-loader,.lightbox{text-align:center;line-height:0}.lb-dataContainer:after,.lb-outerContainer:after{content:"";clear:both}html.lb-disable-scrolling{overflow:hidden;position:fixed;height:100vh;width:100vw}.lightboxOverlay{position:absolute;top:0;left:0;z-index:9999;background-color:#000;filter:alpha(Opacity=80);opacity:.8;display:none}.lightbox{position:absolute;left:0;width:100%;z-index:10000;font-weight:400}.lightbox .lb-image{display:block;height:auto;max-width:inherit;max-height:none;border-radius:3px;border:4px solid #fff}.lightbox a img{border:none}.lb-outerContainer{position:relative;width:250px;height:250px;margin:0 auto;border-radius:4px;background-color:#fff}.lb-loader,.lb-nav{position:absolute;left:0}.lb-outerContainer:after{display:table}.lb-loader{top:43%;height:25%;width:100%}.lb-cancel{display:block;width:32px;height:32px;margin:0 auto;background:url(../images/loading.gif) no-repeat}.lb-nav{top:0;height:100%;width:100%;z-index:10}.lb-container>.nav{left:0}.lb-nav a{outline:0;background-image:url(data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}.lb-next,.lb-prev{height:100%;cursor:pointer;display:block}.lb-nav a.lb-prev{width:34%;left:0;float:left;background:url(../images/prev.png) left 48% no-repeat;filter:alpha(Opacity=0);opacity:0;-webkit-transition:opacity .6s;-moz-transition:opacity .6s;-o-transition:opacity .6s;transition:opacity .6s}.lb-nav a.lb-prev:hover{filter:alpha(Opacity=100);opacity:1}.lb-nav a.lb-next{width:64%;right:0;float:right;background:url(../images/next.png) right 48% no-repeat;filter:alpha(Opacity=0);opacity:0;-webkit-transition:opacity .6s;-moz-transition:opacity .6s;-o-transition:opacity .6s;transition:opacity .6s}.lb-nav a.lb-next:hover{filter:alpha(Opacity=100);opacity:1}.lb-dataContainer{margin:0 auto;padding-top:5px;width:100%;border-bottom-left-radius:4px;border-bottom-right-radius:4px}.lb-dataContainer:after{display:table}.lb-data{padding:0 4px;color:#ccc}.lb-data .lb-details{width:85%;float:left;text-align:left;line-height:1.1em}.lb-data .lb-caption{font-size:13px;font-weight:700;line-height:1em}.lb-data .lb-caption a{color:#4ae}.lb-data .lb-number{display:block;clear:left;padding-bottom:1em;font-size:12px;color:#999}.lb-data .lb-close{display:block;float:right;width:30px;height:30px;background:url(../images/close.png) top right no-repeat;text-align:right;outline:0;filter:alpha(Opacity=70);opacity:.7;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s}.lb-data .lb-close:hover{cursor:pointer;filter:alpha(Opacity=100);opacity:1}
--------------------------------------------------------------------------------
/blocks/gallery/dist/images/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JimSchofield/guty-blocks/099aa6135d75ff0a10517f2919efcb1dbf67775c/blocks/gallery/dist/images/close.png
--------------------------------------------------------------------------------
/blocks/gallery/dist/images/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JimSchofield/guty-blocks/099aa6135d75ff0a10517f2919efcb1dbf67775c/blocks/gallery/dist/images/loading.gif
--------------------------------------------------------------------------------
/blocks/gallery/dist/images/next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JimSchofield/guty-blocks/099aa6135d75ff0a10517f2919efcb1dbf67775c/blocks/gallery/dist/images/next.png
--------------------------------------------------------------------------------
/blocks/gallery/dist/images/prev.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JimSchofield/guty-blocks/099aa6135d75ff0a10517f2919efcb1dbf67775c/blocks/gallery/dist/images/prev.png
--------------------------------------------------------------------------------
/blocks/gallery/dist/js/lightbox.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Lightbox v2.10.0
3 | * by Lokesh Dhakar
4 | *
5 | * More info:
6 | * http://lokeshdhakar.com/projects/lightbox2/
7 | *
8 | * Copyright 2007, 2018 Lokesh Dhakar
9 | * Released under the MIT license
10 | * https://github.com/lokesh/lightbox2/blob/master/LICENSE
11 | *
12 | * @preserve
13 | */
14 | !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],b):"object"==typeof exports?module.exports=b(require("jquery")):a.lightbox=b(a.jQuery)}(this,function(a){function b(b){this.album=[],this.currentImageIndex=void 0,this.init(),this.options=a.extend({},this.constructor.defaults),this.option(b)}return b.defaults={albumLabel:"Image %1 of %2",alwaysShowNavOnTouchDevices:!1,fadeDuration:600,fitImagesInViewport:!0,imageFadeDuration:600,positionFromTop:50,resizeDuration:700,showImageNumberLabel:!0,wrapAround:!1,disableScrolling:!1,sanitizeTitle:!1},b.prototype.option=function(b){a.extend(this.options,b)},b.prototype.imageCountLabel=function(a,b){return this.options.albumLabel.replace(/%1/g,a).replace(/%2/g,b)},b.prototype.init=function(){var b=this;a(document).ready(function(){b.enable(),b.build()})},b.prototype.enable=function(){var b=this;a("body").on("click","a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]",function(c){return b.start(a(c.currentTarget)),!1})},b.prototype.build=function(){if(!(a("#lightbox").length>0)){var b=this;a('
').appendTo(a("body")),this.$lightbox=a("#lightbox"),this.$overlay=a("#lightboxOverlay"),this.$outerContainer=this.$lightbox.find(".lb-outerContainer"),this.$container=this.$lightbox.find(".lb-container"),this.$image=this.$lightbox.find(".lb-image"),this.$nav=this.$lightbox.find(".lb-nav"),this.containerPadding={top:parseInt(this.$container.css("padding-top"),10),right:parseInt(this.$container.css("padding-right"),10),bottom:parseInt(this.$container.css("padding-bottom"),10),left:parseInt(this.$container.css("padding-left"),10)},this.imageBorderWidth={top:parseInt(this.$image.css("border-top-width"),10),right:parseInt(this.$image.css("border-right-width"),10),bottom:parseInt(this.$image.css("border-bottom-width"),10),left:parseInt(this.$image.css("border-left-width"),10)},this.$overlay.hide().on("click",function(){return b.end(),!1}),this.$lightbox.hide().on("click",function(c){return"lightbox"===a(c.target).attr("id")&&b.end(),!1}),this.$outerContainer.on("click",function(c){return"lightbox"===a(c.target).attr("id")&&b.end(),!1}),this.$lightbox.find(".lb-prev").on("click",function(){return 0===b.currentImageIndex?b.changeImage(b.album.length-1):b.changeImage(b.currentImageIndex-1),!1}),this.$lightbox.find(".lb-next").on("click",function(){return b.currentImageIndex===b.album.length-1?b.changeImage(0):b.changeImage(b.currentImageIndex+1),!1}),this.$nav.on("mousedown",function(a){3===a.which&&(b.$nav.css("pointer-events","none"),b.$lightbox.one("contextmenu",function(){setTimeout(function(){this.$nav.css("pointer-events","auto")}.bind(b),0)}))}),this.$lightbox.find(".lb-loader, .lb-close").on("click",function(){return b.end(),!1})}},b.prototype.start=function(b){function c(a){d.album.push({alt:a.attr("data-alt"),link:a.attr("href"),title:a.attr("data-title")||a.attr("title")})}var d=this,e=a(window);e.on("resize",a.proxy(this.sizeOverlay,this)),a("select, object, embed").css({visibility:"hidden"}),this.sizeOverlay(),this.album=[];var f,g=0,h=b.attr("data-lightbox");if(h){f=a(b.prop("tagName")+'[data-lightbox="'+h+'"]');for(var i=0;ii||e.height>h)&&(e.width/i>e.height/h?(g=i,f=parseInt(e.height/(e.width/g),10),d.width(g),d.height(f)):(f=h,g=parseInt(e.width/(e.height/f),10),d.width(g),d.height(f)))),c.sizeContainer(d.width(),d.height())},e.src=this.album[b].link,this.currentImageIndex=b},b.prototype.sizeOverlay=function(){this.$overlay.width(a(document).width()).height(a(document).height())},b.prototype.sizeContainer=function(a,b){function c(){d.$lightbox.find(".lb-dataContainer").width(g),d.$lightbox.find(".lb-prevLink").height(h),d.$lightbox.find(".lb-nextLink").height(h),d.showImage()}var d=this,e=this.$outerContainer.outerWidth(),f=this.$outerContainer.outerHeight(),g=a+this.containerPadding.left+this.containerPadding.right+this.imageBorderWidth.left+this.imageBorderWidth.right,h=b+this.containerPadding.top+this.containerPadding.bottom+this.imageBorderWidth.top+this.imageBorderWidth.bottom;e!==g||f!==h?this.$outerContainer.animate({width:g,height:h},this.options.resizeDuration,"swing",function(){c()}):c()},b.prototype.showImage=function(){this.$lightbox.find(".lb-loader").stop(!0).hide(),this.$lightbox.find(".lb-image").fadeIn(this.options.imageFadeDuration),this.updateNav(),this.updateDetails(),this.preloadNeighboringImages(),this.enableKeyboardNav()},b.prototype.updateNav=function(){var a=!1;try{document.createEvent("TouchEvent"),a=!!this.options.alwaysShowNavOnTouchDevices}catch(a){}this.$lightbox.find(".lb-nav").show(),this.album.length>1&&(this.options.wrapAround?(a&&this.$lightbox.find(".lb-prev, .lb-next").css("opacity","1"),this.$lightbox.find(".lb-prev, .lb-next").show()):(this.currentImageIndex>0&&(this.$lightbox.find(".lb-prev").show(),a&&this.$lightbox.find(".lb-prev").css("opacity","1")),this.currentImageIndex1&&this.options.showImageNumberLabel){var d=this.imageCountLabel(this.currentImageIndex+1,this.album.length);this.$lightbox.find(".lb-number").text(d).fadeIn("fast")}else this.$lightbox.find(".lb-number").hide();this.$outerContainer.removeClass("animating"),this.$lightbox.find(".lb-dataContainer").fadeIn(this.options.resizeDuration,function(){return b.sizeOverlay()})},b.prototype.preloadNeighboringImages=function(){if(this.album.length>this.currentImageIndex+1){(new Image).src=this.album[this.currentImageIndex+1].link}if(this.currentImageIndex>0){(new Image).src=this.album[this.currentImageIndex-1].link}},b.prototype.enableKeyboardNav=function(){a(document).on("keyup.keyboard",a.proxy(this.keyboardAction,this))},b.prototype.disableKeyboardNav=function(){a(document).off(".keyboard")},b.prototype.keyboardAction=function(a){var b=a.keyCode,c=String.fromCharCode(b).toLowerCase();27===b||c.match(/x|o|c/)?this.end():"p"===c||37===b?0!==this.currentImageIndex?this.changeImage(this.currentImageIndex-1):this.options.wrapAround&&this.album.length>1&&this.changeImage(this.album.length-1):"n"!==c&&39!==b||(this.currentImageIndex!==this.album.length-1?this.changeImage(this.currentImageIndex+1):this.options.wrapAround&&this.album.length>1&&this.changeImage(0))},b.prototype.end=function(){this.disableKeyboardNav(),a(window).off("resize",this.sizeOverlay),this.$lightbox.fadeOut(this.options.fadeDuration),this.$overlay.fadeOut(this.options.fadeDuration),a("select, object, embed").css({visibility:"visible"}),this.options.disableScrolling&&a("html").removeClass("lb-disable-scrolling")},new b});
15 | //# sourceMappingURL=lightbox.min.map
--------------------------------------------------------------------------------
/blocks/gallery/dist/js/lightbox.min.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["../../src/js/lightbox.js"],"names":["root","factory","define","amd","exports","module","require","lightbox","jQuery","this","$","Lightbox","options","album","currentImageIndex","init","extend","constructor","defaults","option","albumLabel","alwaysShowNavOnTouchDevices","fadeDuration","fitImagesInViewport","imageFadeDuration","positionFromTop","resizeDuration","showImageNumberLabel","wrapAround","disableScrolling","sanitizeTitle","prototype","imageCountLabel","currentImageNum","totalImages","replace","self","document","ready","enable","build","on","event","start","currentTarget","length","appendTo","$lightbox","$overlay","$outerContainer","find","$container","$image","$nav","containerPadding","top","parseInt","css","right","bottom","left","imageBorderWidth","hide","end","target","attr","changeImage","which","one","setTimeout","bind","$link","addToAlbum","push","alt","link","title","$window","window","proxy","sizeOverlay","visibility","$links","imageNumber","dataLightboxValue","prop","i","j","scrollTop","scrollLeft","fadeIn","addClass","disableKeyboardNav","preloader","Image","onload","imageHeight","imageWidth","maxImageHeight","maxImageWidth","windowHeight","windowWidth","src","width","height","maxWidth","maxHeight","sizeContainer","postResize","newWidth","newHeight","showImage","oldWidth","outerWidth","oldHeight","outerHeight","animate","stop","updateNav","updateDetails","preloadNeighboringImages","enableKeyboardNav","alwaysShowNav","createEvent","e","show","$caption","text","html","undefined","open","location","href","labelText","removeClass","keyboardAction","off","keycode","keyCode","key","String","fromCharCode","toLowerCase","match","fadeOut"],"mappings":"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","file":"lightbox.min.js"}
--------------------------------------------------------------------------------
/blocks/gallery/gallery.editor.css:
--------------------------------------------------------------------------------
1 | /* .wp-block-guty-blocks-hello-world {
2 | background: cadetblue;
3 | color: white;
4 | } */
5 |
6 |
7 | .galleryInspector > *{
8 | display: block;
9 | margin: 15px;
10 | }
11 |
--------------------------------------------------------------------------------
/blocks/gallery/gallery.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-gallery h1 {
2 | margin-bottom: 16px;
3 | }
4 |
5 | .wp-block-guty-blocks-gallery * {
6 | box-sizing: border-box;
7 | }
8 |
9 | :root {
10 | --PADDING: 32px;
11 | }
12 |
13 | @media (max-width: 450px) {
14 | :root {
15 | --PADDING: 16px;
16 | }
17 | }
18 |
19 | .wp-block-guty-blocks-gallery .galleryContainer {
20 | position: relative;
21 | display: flex;
22 | flex-direction: row;
23 | flex-wrap: wrap;
24 | margin: calc(-1 * var(--PADDING)) calc(-.5 * var(--PADDING)) 0 calc(-.5 * var(--PADDING));
25 | }
26 |
27 | .wp-block-guty-blocks-gallery .galleryContainer>* {
28 | padding: var(--PADDING) calc(0.5 * var(--PADDING)) 0 calc(0.5 * var(--PADDING));
29 | }
30 |
31 | .wp-block-guty-blocks-gallery .galleryContainer>* {
32 | width: 100%;
33 | }
34 |
35 | .wp-block-guty-blocks-gallery .galleryContainer_2up>* {
36 | width: 50%;
37 | }
38 |
39 | .wp-block-guty-blocks-gallery .galleryContainer_3up>* {
40 | width: 33.3%;
41 | }
42 |
43 | .wp-block-guty-blocks-gallery .galleryContainer_4up>* {
44 | width: 25%;
45 | }
46 |
47 | @media (max-width: 450px) {
48 | .wp-block-guty-blocks-gallery .galleryContainer>*,
49 | .wp-block-guty-blocks-gallery .galleryContainer_2up>*,
50 | .wp-block-guty-blocks-gallery .galleryContainer_3up>*,
51 | .wp-block-guty-blocks-gallery .galleryContainer_4up>* {
52 | width: 100%;
53 | }
54 | }
55 |
56 | .wp-block-guty-blocks-gallery .galleryContainer_alignLeft {
57 | justify-content: flex-start;
58 | }
59 |
60 | .wp-block-guty-blocks-gallery .galleryContainer_alignCenter {
61 | justify-content: center;
62 | }
63 |
64 | .wp-block-guty-blocks-gallery .galleryContainer_alignRight {
65 | justify-content: flex-end;
66 | }
67 |
68 | .imageWrapper {
69 | position: relative;
70 | }
71 |
72 | .imageWrapper-buttons {
73 | position: absolute;
74 | display: flex;
75 | padding: 0 30px;
76 | justify-content: space-between;
77 | width: 100%;
78 | top: calc(50% + 16px);
79 | left: 0;
80 | transform: translateY(-50%);
81 | }
82 |
83 | .imageWrapper-buttons button {
84 | opacity: 0;
85 | transition: 200ms;
86 | }
87 |
88 | .imageWrapper:hover button {
89 | opacity: 1;
90 | cursor: pointer;
91 | border: none;
92 | background: cadetblue;
93 | color: white;
94 | }
95 |
96 | .imageWrapper:hover button:hover {
97 | color: cadetblue;
98 | background: white;
99 | }
100 |
101 | .galleryContainer .galleryContainer-addPhoto {
102 | position: absolute;
103 | bottom: 0;
104 | right: 0;
105 | text-align: right;
106 | }
107 |
108 | .galleryContainer .galleryContainer-addPhoto button {
109 | cursor: pointer;
110 | border: none;
111 | background: cadetblue;
112 | color: white;
113 | transition: 200ms;
114 | }
115 |
116 | .galleryContainer .galleryContainer-addPhoto button:hover {
117 | background: rgba(95, 158, 160, .8);
118 | color: white;
119 | }
--------------------------------------------------------------------------------
/blocks/gallery/index.php:
--------------------------------------------------------------------------------
1 | wp.element.createElement(
132 | 'button',
133 | { onClick: open },
134 | 'Open Media Library'
135 | )
136 | });
137 | }
138 |
139 | // Actual elements being rendered
140 | return [isSelected && wp.element.createElement(
141 | InspectorControls,
142 | { key: 'controls' },
143 | wp.element.createElement(
144 | 'p',
145 | null,
146 | 'This is where some style options can be presented for your block!'
147 | )
148 | ), wp.element.createElement(
149 | 'div',
150 | { className: props.className },
151 | wp.element.createElement(
152 | 'div',
153 | { 'class': 'left' },
154 | imageSide
155 | ),
156 | wp.element.createElement(
157 | 'div',
158 | { 'class': 'right' },
159 | wp.element.createElement(RichText, {
160 | tagName: 'p',
161 | onChange: onChangeContent,
162 | value: content
163 | })
164 | )
165 | )];
166 | },
167 |
168 | // The save "render" function
169 | save(props) {
170 | return wp.element.createElement(
171 | 'div',
172 | { className: props.className },
173 | wp.element.createElement(
174 | 'div',
175 | { 'class': 'left' },
176 | wp.element.createElement('img', { src: props.attributes.imageUrl, alt: '' })
177 | ),
178 | wp.element.createElement(
179 | 'div',
180 | { 'class': 'right' },
181 | wp.element.createElement(
182 | 'p',
183 | null,
184 | props.attributes.content
185 | )
186 | )
187 | );
188 | }
189 |
190 | });
191 |
192 | /***/ }),
193 |
194 | /***/ 28:
195 | /***/ (function(module, exports) {
196 |
197 | // removed by extract-text-webpack-plugin
198 |
199 | /***/ }),
200 |
201 | /***/ 29:
202 | /***/ (function(module, exports) {
203 |
204 | // removed by extract-text-webpack-plugin
205 |
206 | /***/ })
207 |
208 | /******/ });
--------------------------------------------------------------------------------
/blocks/media-block/media-block.editor.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-media-block {
2 | position: relative;
3 | background: cadetblue;
4 | padding:2em;
5 | display: flex;
6 | flex-direction: row;
7 | }
8 | .wp-block-guty-blocks-media-block:before {
9 | content:'Editing mode';
10 | position: absolute;
11 | top: 4px;
12 | left: 4px;
13 | color: red;
14 | }
15 |
16 | .wp-block-guty-blocks-media-block .left {
17 | flex: 33%;
18 | padding-right: 16px;
19 | }
20 |
21 | .wp-block-guty-blocks-media-block .right {
22 | flex: 66%;
23 | }
24 |
25 | .wp-block-guty-blocks-media-block p {
26 | font-size: 24px;
27 | color: white;
28 | }
--------------------------------------------------------------------------------
/blocks/media-block/media-block.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-media-block {
2 | position: relative;
3 | background: cadetblue;
4 | padding:2em;
5 | display: flex;
6 | flex-direction: row;
7 | }
8 | .wp-block-guty-blocks-media-block:before {
9 | content:'View Mode';
10 | position: absolute;
11 | top: 4px;
12 | left: 4px;
13 | color: blue;
14 | }
15 |
16 | .wp-block-guty-blocks-media-block .left {
17 | flex: 33%;
18 | padding-right: 16px;
19 | }
20 |
21 | .wp-block-guty-blocks-media-block .right {
22 | flex: 66%;
23 | }
24 |
25 | .wp-block-guty-blocks-media-block p {
26 | font-size: 24px;
27 | color: white;
28 | }
--------------------------------------------------------------------------------
/blocks/media-block/media-block.view.js:
--------------------------------------------------------------------------------
1 | /******/ (function(modules) { // webpackBootstrap
2 | /******/ // The module cache
3 | /******/ var installedModules = {};
4 | /******/
5 | /******/ // The require function
6 | /******/ function __webpack_require__(moduleId) {
7 | /******/
8 | /******/ // Check if module is in cache
9 | /******/ if(installedModules[moduleId]) {
10 | /******/ return installedModules[moduleId].exports;
11 | /******/ }
12 | /******/ // Create a new module (and put it into the cache)
13 | /******/ var module = installedModules[moduleId] = {
14 | /******/ i: moduleId,
15 | /******/ l: false,
16 | /******/ exports: {}
17 | /******/ };
18 | /******/
19 | /******/ // Execute the module function
20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21 | /******/
22 | /******/ // Flag the module as loaded
23 | /******/ module.l = true;
24 | /******/
25 | /******/ // Return the exports of the module
26 | /******/ return module.exports;
27 | /******/ }
28 | /******/
29 | /******/
30 | /******/ // expose the modules object (__webpack_modules__)
31 | /******/ __webpack_require__.m = modules;
32 | /******/
33 | /******/ // expose the module cache
34 | /******/ __webpack_require__.c = installedModules;
35 | /******/
36 | /******/ // define getter function for harmony exports
37 | /******/ __webpack_require__.d = function(exports, name, getter) {
38 | /******/ if(!__webpack_require__.o(exports, name)) {
39 | /******/ Object.defineProperty(exports, name, {
40 | /******/ configurable: false,
41 | /******/ enumerable: true,
42 | /******/ get: getter
43 | /******/ });
44 | /******/ }
45 | /******/ };
46 | /******/
47 | /******/ // getDefaultExport function for compatibility with non-harmony modules
48 | /******/ __webpack_require__.n = function(module) {
49 | /******/ var getter = module && module.__esModule ?
50 | /******/ function getDefault() { return module['default']; } :
51 | /******/ function getModuleExports() { return module; };
52 | /******/ __webpack_require__.d(getter, 'a', getter);
53 | /******/ return getter;
54 | /******/ };
55 | /******/
56 | /******/ // Object.prototype.hasOwnProperty.call
57 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
58 | /******/
59 | /******/ // __webpack_public_path__
60 | /******/ __webpack_require__.p = "";
61 | /******/
62 | /******/ // Load entry module and return exports
63 | /******/ return __webpack_require__(__webpack_require__.s = 17);
64 | /******/ })
65 | /************************************************************************/
66 | /******/ ({
67 |
68 | /***/ 17:
69 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
70 |
71 | "use strict";
72 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
73 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__media_block_editor_css__ = __webpack_require__(18);
74 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__media_block_editor_css___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__media_block_editor_css__);
75 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__media_block_view_css__ = __webpack_require__(19);
76 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__media_block_view_css___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__media_block_view_css__);
77 |
78 |
79 |
80 | const {
81 | registerBlockType,
82 | RichText, // Editable field
83 | InspectorControls, // allows us to add controls on the sidebar
84 | MediaUpload // allows us to upload images
85 | } = wp.blocks;
86 |
87 | registerBlockType('guty-blocks/media-block', {
88 | title: 'Media Item Block',
89 | icon: 'smiley',
90 | category: 'common',
91 |
92 | attributes: { // Somewhat like setting initial state in a react app
93 | content: {
94 | type: 'array',
95 | source: 'children',
96 | selector: 'p',
97 | default: 'Editable block content...'
98 | },
99 | imageUrl: {
100 | type: 'string',
101 | default: null
102 | }
103 | },
104 |
105 | // The editor "render" function
106 | edit(props) {
107 |
108 | let { content, imageUrl, focus, isSelected } = props.attributes;
109 |
110 | function onChangeContent(updatedContent) {
111 | props.setAttributes({ content: updatedContent });
112 | }
113 |
114 | function setImage(image) {
115 | console.log(image);
116 | props.setAttributes({ imageUrl: image.url });
117 | }
118 |
119 | // If an image isn't selected show the upload button
120 | // otherwise, show the image
121 | let imageSide = null;
122 | if (imageUrl) {
123 | imageSide = wp.element.createElement('img', { src: imageUrl, alt: '' });
124 | } else {
125 | imageSide = wp.element.createElement(MediaUpload, {
126 | type: 'image',
127 | onSelect: setImage,
128 | render: ({ open }) => wp.element.createElement(
129 | 'button',
130 | { onClick: open },
131 | 'Open Media Library'
132 | )
133 | });
134 | }
135 |
136 | // Actual elements being rendered
137 | return [isSelected && wp.element.createElement(
138 | InspectorControls,
139 | { key: 'controls' },
140 | wp.element.createElement(
141 | 'p',
142 | null,
143 | 'This is where some style options can be presented for your block!'
144 | )
145 | ), wp.element.createElement(
146 | 'div',
147 | { className: props.className },
148 | wp.element.createElement(
149 | 'div',
150 | { 'class': 'left' },
151 | imageSide
152 | ),
153 | wp.element.createElement(
154 | 'div',
155 | { 'class': 'right' },
156 | wp.element.createElement(RichText, {
157 | tagName: 'p',
158 | onChange: onChangeContent,
159 | value: content
160 | })
161 | )
162 | )];
163 | },
164 |
165 | // The save "render" function
166 | save(props) {
167 | return wp.element.createElement(
168 | 'div',
169 | { className: props.className },
170 | wp.element.createElement(
171 | 'div',
172 | { 'class': 'left' },
173 | wp.element.createElement('img', { src: props.attributes.imageUrl, alt: '' })
174 | ),
175 | wp.element.createElement(
176 | 'div',
177 | { 'class': 'right' },
178 | wp.element.createElement(
179 | 'p',
180 | null,
181 | props.attributes.content
182 | )
183 | )
184 | );
185 | }
186 |
187 | });
188 |
189 | /***/ }),
190 |
191 | /***/ 18:
192 | /***/ (function(module, exports) {
193 |
194 | throw new Error("Module parse failed: Unexpected token (1:0)\nYou may need an appropriate loader to handle this file type.\n| .wp-block-guty-blocks-media-block {\n| position: relative;\n| background: cadetblue;");
195 |
196 | /***/ }),
197 |
198 | /***/ 19:
199 | /***/ (function(module, exports) {
200 |
201 | throw new Error("Module parse failed: Unexpected token (1:0)\nYou may need an appropriate loader to handle this file type.\n| .wp-block-guty-blocks-media-block {\n| position: relative;\n| background: cadetblue;");
202 |
203 | /***/ })
204 |
205 | /******/ });
--------------------------------------------------------------------------------
/blocks/prism-code/index.php:
--------------------------------------------------------------------------------
1 | 'guty-blocks/prism-code-editor-script',
27 | 'editor_style' => 'guty-blocks/prism-code-editor-style',
28 | 'style' => 'guty-blocks/prism-code-editor-style',
29 | ) );
30 | }
31 | add_action( 'init', 'gutenberg_prism_code_block' );
--------------------------------------------------------------------------------
/blocks/prism-code/prism-code.editor.css:
--------------------------------------------------------------------------------
1 | /* .wp-block-guty-blocks-hello-world {
2 | background: cadetblue;
3 | color: white;
4 | } */
5 |
6 |
--------------------------------------------------------------------------------
/blocks/prism-code/prism-code.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-prism-code.wp-block-guty-blocks-prism-code textarea {
2 | box-shadow: none;
3 | font-family: inherit;
4 | font-size: inherit;
5 | color: inherit;
6 | line-height: inherit;
7 | border: none;
8 | padding: 0;
9 | margin: 0;
10 | width: 100%;
11 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
12 | background: transparent;
13 | }
14 |
15 | code {
16 | padding: 0;
17 | margin: 0;
18 | font-size: inherit;
19 | }
20 |
21 |
22 | /* Prism styles */
23 | /* PrismJS 1.12.2
24 | http://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+jsx */
25 | /**
26 | * prism.js default theme for JavaScript, CSS and HTML
27 | * Based on dabblet (http://dabblet.com)
28 | * @author Lea Verou
29 | */
30 |
31 | code[class*="language-"],
32 | pre[class*="language-"] {
33 | color: black;
34 | background: none;
35 | text-shadow: 0 1px white;
36 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
37 | text-align: left;
38 | white-space: pre;
39 | word-spacing: normal;
40 | word-break: normal;
41 | word-wrap: normal;
42 | line-height: 1.5;
43 |
44 | -moz-tab-size: 4;
45 | -o-tab-size: 4;
46 | tab-size: 4;
47 |
48 | -webkit-hyphens: none;
49 | -moz-hyphens: none;
50 | -ms-hyphens: none;
51 | hyphens: none;
52 | }
53 |
54 | pre[class*="language-"]::-moz-selection,
55 | pre[class*="language-"] ::-moz-selection,
56 | code[class*="language-"]::-moz-selection,
57 | code[class*="language-"] ::-moz-selection {
58 | text-shadow: none;
59 | background: #b3d4fc;
60 | }
61 |
62 | pre[class*="language-"]::selection,
63 | pre[class*="language-"] ::selection,
64 | code[class*="language-"]::selection,
65 | code[class*="language-"] ::selection {
66 | text-shadow: none;
67 | background: #b3d4fc;
68 | }
69 |
70 | @media print {
71 |
72 | code[class*="language-"],
73 | pre[class*="language-"] {
74 | text-shadow: none;
75 | }
76 | }
77 |
78 | /* Code blocks */
79 | pre[class*="language-"] {
80 | padding: 1em;
81 | margin: .5em 0;
82 | overflow: auto;
83 | }
84 |
85 | :not(pre)>code[class*="language-"],
86 | pre[class*="language-"] {
87 | background: #f5f2f0;
88 | }
89 |
90 | /* Inline code */
91 | :not(pre)>code[class*="language-"] {
92 | padding: .1em;
93 | border-radius: .3em;
94 | white-space: normal;
95 | }
96 |
97 | .token.comment,
98 | .token.prolog,
99 | .token.doctype,
100 | .token.cdata {
101 | color: slategray;
102 | }
103 |
104 | .token.punctuation {
105 | color: #999;
106 | }
107 |
108 | .namespace {
109 | opacity: .7;
110 | }
111 |
112 | .token.property,
113 | .token.tag,
114 | .token.boolean,
115 | .token.number,
116 | .token.constant,
117 | .token.symbol,
118 | .token.deleted {
119 | color: #905;
120 | }
121 |
122 | .token.selector,
123 | .token.attr-name,
124 | .token.string,
125 | .token.char,
126 | .token.builtin,
127 | .token.inserted {
128 | color: #690;
129 | }
130 |
131 | .token.operator,
132 | .token.entity,
133 | .token.url,
134 | .language-css .token.string,
135 | .style .token.string {
136 | color: #a67f59;
137 | background: hsla(0, 0%, 100%, .5);
138 | }
139 |
140 | .token.atrule,
141 | .token.attr-value,
142 | .token.keyword {
143 | color: #07a;
144 | }
145 |
146 | .token.function,
147 | .token.class-name {
148 | color: #DD4A68;
149 | }
150 |
151 | .token.regex,
152 | .token.important,
153 | .token.variable {
154 | color: #e90;
155 | }
156 |
157 | .token.important,
158 | .token.bold {
159 | font-weight: bold;
160 | }
161 |
162 | .token.italic {
163 | font-style: italic;
164 | }
165 |
166 | .token.entity {
167 | cursor: help;
168 | }
--------------------------------------------------------------------------------
/blocks/quote/index.php:
--------------------------------------------------------------------------------
1 | props.setAttributes({ quoteContent: changes })
122 | }),
123 | wp.element.createElement(
124 | 'span',
125 | { className: 'first-last-quotes' },
126 | '\u201D'
127 | )
128 | ),
129 | wp.element.createElement(
130 | 'div',
131 | { className: 'author' },
132 | '- ',
133 | wp.element.createElement(RichText, {
134 | tagName: 'span',
135 | value: props.attributes.author,
136 | onChange: changes => props.setAttributes({ author: changes })
137 | })
138 | )
139 | );
140 | },
141 |
142 | // The save "render" function
143 | save(props) {
144 | let { className } = props;
145 | return wp.element.createElement(
146 | 'aside',
147 | { className: "quote " + className },
148 | wp.element.createElement(
149 | 'div',
150 | { className: 'quote-text' },
151 | wp.element.createElement(
152 | 'span',
153 | { className: 'first-last-quotes' },
154 | '\u201C'
155 | ),
156 | props.attributes.quoteContent,
157 | wp.element.createElement(
158 | 'span',
159 | { className: 'first-last-quotes' },
160 | '\u201D'
161 | )
162 | ),
163 | wp.element.createElement(
164 | 'div',
165 | { className: 'author' },
166 | '- ',
167 | props.attributes.author
168 | )
169 | );
170 | }
171 |
172 | });
173 |
174 | /***/ }),
175 |
176 | /***/ 45:
177 | /***/ (function(module, exports) {
178 |
179 | // removed by extract-text-webpack-plugin
180 |
181 | /***/ }),
182 |
183 | /***/ 46:
184 | /***/ (function(module, exports) {
185 |
186 | // removed by extract-text-webpack-plugin
187 |
188 | /***/ })
189 |
190 | /******/ });
--------------------------------------------------------------------------------
/blocks/quote/quote.editor.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-quote .blocks-rich-text {
2 | display: inline;
3 | }
4 |
5 | .wp-block-guty-blocks-quote .author .blocks-rich-text {
6 | font-variant: small-caps;
7 | color: #646464;
8 | }
9 |
--------------------------------------------------------------------------------
/blocks/quote/quote.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-quote {
2 | width: 80%;
3 | margin: 50px auto 25px;
4 | padding: 8px;
5 | border: 1px solid #d8d2d0;
6 | text-align: center;
7 | }
8 |
9 | .wp-block-guty-blocks-quote .quote-text {
10 | padding: 8px;
11 | font-size: 24px;
12 | }
13 |
14 | .wp-block-guty-blocks-quote .first-last-quotes {
15 | display: inline-block;
16 | font-size: 36px;
17 | line-height: 24px;
18 | }
19 |
20 | .wp-block-guty-blocks-quote .author {
21 | display: inline-block;
22 | font-variant: small-caps;
23 | color: #646464;
24 | }
25 |
26 |
27 |
--------------------------------------------------------------------------------
/blocks/react-view/index.php:
--------------------------------------------------------------------------------
1 | {
174 | return wp.element.createElement(RenderArticleButton, {
175 | title: el.title.rendered,
176 | desc: el.excerpt.rendered,
177 | url: el.link
178 | });
179 | })
180 | )
181 | )];
182 | },
183 |
184 | // The save "render" function
185 | save(props) {
186 |
187 | let { posts, numberUp } = props.attributes;
188 |
189 | return wp.element.createElement(
190 | 'div',
191 | { className: props.className },
192 | wp.element.createElement(
193 | 'div',
194 | { className: `articleContainer ${numberUp}` },
195 | posts && posts.map(el => {
196 | return wp.element.createElement(RenderArticleButton, {
197 | title: el.title.rendered,
198 | desc: el.excerpt.rendered,
199 | url: el.link
200 | });
201 | })
202 | )
203 | );
204 | }
205 |
206 | });
207 |
208 | function RenderArticleButton(props) {
209 | return wp.element.createElement(
210 | 'div',
211 | { 'class': 'articleButton' },
212 | wp.element.createElement('h3', { dangerouslySetInnerHTML: { __html: props.title } }),
213 | wp.element.createElement('p', { dangerouslySetInnerHTML: { __html: props.desc } }),
214 | wp.element.createElement(
215 | 'a',
216 | { href: props.url },
217 | 'Go to article...'
218 | )
219 | );
220 | }
221 |
222 | /***/ }),
223 |
224 | /***/ 52:
225 | /***/ (function(module, exports) {
226 |
227 | // removed by extract-text-webpack-plugin
228 |
229 | /***/ }),
230 |
231 | /***/ 53:
232 | /***/ (function(module, exports) {
233 |
234 | // removed by extract-text-webpack-plugin
235 |
236 | /***/ })
237 |
238 | /******/ });
--------------------------------------------------------------------------------
/blocks/recent-posts/recent-posts.editor.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-recent-posts {
2 | }
3 |
4 | .articleContainer {
5 | display: grid;
6 | }
7 |
8 | .one_up {
9 | grid-template-columns: repeat(1, 1fr);
10 | }
11 | .two_up {
12 | grid-template-columns: repeat(2, 1fr);
13 | }
14 | .three_up {
15 | grid-template-columns: repeat(3, 1fr);
16 | }
17 |
18 | .articleContainer > * {
19 | grid-column: auto;
20 | margin: 8px;
21 | padding: 1em;
22 | border: 1px solid grey;
23 | }
24 |
--------------------------------------------------------------------------------
/blocks/recent-posts/recent-posts.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-recent-posts {
2 | }
3 |
4 | .articleContainer {
5 | display: grid;
6 | }
7 |
8 | .one_up {
9 | grid-template-columns: repeat(1, 1fr);
10 | }
11 | .two_up {
12 | grid-template-columns: repeat(2, 1fr);
13 | }
14 | .three_up {
15 | grid-template-columns: repeat(3, 1fr);
16 | }
17 |
18 | .articleContainer > * {
19 | grid-column: auto;
20 | margin: 8px;
21 | padding: 1em;
22 | border: 1px solid grey;
23 | }
24 |
--------------------------------------------------------------------------------
/blocks/recent-posts/recent-posts.view.js:
--------------------------------------------------------------------------------
1 | /******/ (function(modules) { // webpackBootstrap
2 | /******/ // The module cache
3 | /******/ var installedModules = {};
4 | /******/
5 | /******/ // The require function
6 | /******/ function __webpack_require__(moduleId) {
7 | /******/
8 | /******/ // Check if module is in cache
9 | /******/ if(installedModules[moduleId]) {
10 | /******/ return installedModules[moduleId].exports;
11 | /******/ }
12 | /******/ // Create a new module (and put it into the cache)
13 | /******/ var module = installedModules[moduleId] = {
14 | /******/ i: moduleId,
15 | /******/ l: false,
16 | /******/ exports: {}
17 | /******/ };
18 | /******/
19 | /******/ // Execute the module function
20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21 | /******/
22 | /******/ // Flag the module as loaded
23 | /******/ module.l = true;
24 | /******/
25 | /******/ // Return the exports of the module
26 | /******/ return module.exports;
27 | /******/ }
28 | /******/
29 | /******/
30 | /******/ // expose the modules object (__webpack_modules__)
31 | /******/ __webpack_require__.m = modules;
32 | /******/
33 | /******/ // expose the module cache
34 | /******/ __webpack_require__.c = installedModules;
35 | /******/
36 | /******/ // define getter function for harmony exports
37 | /******/ __webpack_require__.d = function(exports, name, getter) {
38 | /******/ if(!__webpack_require__.o(exports, name)) {
39 | /******/ Object.defineProperty(exports, name, {
40 | /******/ configurable: false,
41 | /******/ enumerable: true,
42 | /******/ get: getter
43 | /******/ });
44 | /******/ }
45 | /******/ };
46 | /******/
47 | /******/ // getDefaultExport function for compatibility with non-harmony modules
48 | /******/ __webpack_require__.n = function(module) {
49 | /******/ var getter = module && module.__esModule ?
50 | /******/ function getDefault() { return module['default']; } :
51 | /******/ function getModuleExports() { return module; };
52 | /******/ __webpack_require__.d(getter, 'a', getter);
53 | /******/ return getter;
54 | /******/ };
55 | /******/
56 | /******/ // Object.prototype.hasOwnProperty.call
57 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
58 | /******/
59 | /******/ // __webpack_public_path__
60 | /******/ __webpack_require__.p = "";
61 | /******/
62 | /******/ // Load entry module and return exports
63 | /******/ return __webpack_require__(__webpack_require__.s = 39);
64 | /******/ })
65 | /************************************************************************/
66 | /******/ ({
67 |
68 | /***/ 39:
69 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
70 |
71 | "use strict";
72 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
73 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__recent_posts_editor_css__ = __webpack_require__(40);
74 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__recent_posts_editor_css___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__recent_posts_editor_css__);
75 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__recent_posts_view_css__ = __webpack_require__(41);
76 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__recent_posts_view_css___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__recent_posts_view_css__);
77 |
78 |
79 |
80 | const {
81 | registerBlockType,
82 | Editable, // Text field - will be replaced by RichText in future updates
83 | InspectorControls // allows us to add controls on the sidebar
84 | } = wp.blocks;
85 |
86 | registerBlockType('guty-blocks/recent-posts', {
87 | title: 'Recent Posts Block',
88 | icon: 'welcome-write-blog',
89 | category: 'common',
90 |
91 | attributes: { // Somewhat like setting initial state in a react app
92 | numberUp: {
93 | type: 'string',
94 | default: '1_up'
95 | },
96 | posts: {
97 | type: 'array',
98 | default: []
99 | }
100 | },
101 |
102 | // The editor "render" function
103 | edit(props) {
104 |
105 | let { content, posts, numberUp } = props.attributes;
106 |
107 | function onChangeContent(updatedContent) {
108 | props.setAttributes({ content: updatedContent });
109 | }
110 | function onChangeNumberUp(newNumberUp) {
111 | props.setAttributes({ numberUp: newNumberUp.target.value });
112 | }
113 |
114 | async function fetchArticles() {
115 | let data = await fetch('/wp-json/wp/v2/posts/');
116 | let posts = await data.json();
117 | props.setAttributes({ posts });
118 | }
119 |
120 | // Actual elements being rendered
121 | return [!!focus && wp.element.createElement(
122 | InspectorControls,
123 | { key: 'controls' },
124 | 'Select Layout:',
125 | wp.element.createElement(
126 | 'select',
127 | {
128 | onChange: onChangeNumberUp },
129 | wp.element.createElement(
130 | 'option',
131 | { value: 'one_up' },
132 | '1 up blocks'
133 | ),
134 | wp.element.createElement(
135 | 'option',
136 | { value: 'two_up' },
137 | '2 up blocks'
138 | ),
139 | wp.element.createElement(
140 | 'option',
141 | { value: 'three_up' },
142 | '3 up blocks'
143 | )
144 | )
145 | ), wp.element.createElement(
146 | 'div',
147 | { className: props.className },
148 | wp.element.createElement(
149 | 'div',
150 | { className: 'sysMessage' },
151 | wp.element.createElement(
152 | 'button',
153 | { onClick: fetchArticles },
154 | 'Fetch me recent articles!'
155 | ),
156 | posts.length === 0 ? wp.element.createElement(
157 | 'h1',
158 | null,
159 | 'Posts not pulled yet'
160 | ) : wp.element.createElement(
161 | 'h1',
162 | null,
163 | posts.length,
164 | ' found!'
165 | )
166 | ),
167 | wp.element.createElement(
168 | 'div',
169 | { className: `articleContainer ${numberUp}` },
170 | posts && posts.map(el => {
171 | return wp.element.createElement(RenderArticleButton, {
172 | title: el.title.rendered,
173 | desc: el.excerpt.rendered,
174 | url: el.link
175 | });
176 | })
177 | )
178 | )];
179 | },
180 |
181 | // The save "render" function
182 | save(props) {
183 |
184 | let { posts, numberUp } = props.attributes;
185 |
186 | return wp.element.createElement(
187 | 'div',
188 | { className: props.className },
189 | wp.element.createElement(
190 | 'div',
191 | { className: `articleContainer ${numberUp}` },
192 | posts && posts.map(el => {
193 | return wp.element.createElement(RenderArticleButton, {
194 | title: el.title.rendered,
195 | desc: el.excerpt.rendered,
196 | url: el.link
197 | });
198 | })
199 | )
200 | );
201 | }
202 |
203 | });
204 |
205 | function RenderArticleButton(props) {
206 | return wp.element.createElement(
207 | 'div',
208 | { 'class': 'articleButton' },
209 | wp.element.createElement('h3', { dangerouslySetInnerHTML: { __html: props.title } }),
210 | wp.element.createElement('p', { dangerouslySetInnerHTML: { __html: props.desc } }),
211 | wp.element.createElement(
212 | 'a',
213 | { href: props.url },
214 | 'Go to article...'
215 | )
216 | );
217 | }
218 |
219 | /***/ }),
220 |
221 | /***/ 40:
222 | /***/ (function(module, exports) {
223 |
224 | throw new Error("Module parse failed: Unexpected token (1:0)\nYou may need an appropriate loader to handle this file type.\n| .wp-block-guty-blocks-recent-posts {\n| }\n| ");
225 |
226 | /***/ }),
227 |
228 | /***/ 41:
229 | /***/ (function(module, exports) {
230 |
231 | throw new Error("Module parse failed: Unexpected token (1:0)\nYou may need an appropriate loader to handle this file type.\n| .wp-block-guty-blocks-recent-posts {\n| }\n| ");
232 |
233 | /***/ })
234 |
235 | /******/ });
--------------------------------------------------------------------------------
/blocks/side-by-side/index.php:
--------------------------------------------------------------------------------
1 | {
122 | const newImage = image.sizes.medium || image.sizes.thumbnail;
123 | const url = newImage.url;
124 | setAttributes({ selectedImage: url });
125 | },
126 | type: 'image',
127 | value: selectedImage,
128 | render: ({ open }) => wp.element.createElement('div', {
129 | className: 'left-image',
130 | onClick: open,
131 | style: { backgroundImage: `url(${selectedImage})` } })
132 | })
133 | ),
134 | wp.element.createElement(
135 | 'div',
136 | { className: 'right' },
137 | wp.element.createElement(RichText, {
138 | tagName: 'p',
139 | value: content,
140 | onChange: changeText,
141 | placeholder: 'Enter text here...',
142 | isSelected: isSelected
143 | })
144 | )
145 | );
146 | },
147 |
148 | save(props) {
149 | const { className } = props;
150 | const { selectedImage, content } = props.attributes;
151 |
152 | return wp.element.createElement(
153 | 'div',
154 | { className: className },
155 | wp.element.createElement(
156 | 'div',
157 | { className: 'left' },
158 | wp.element.createElement('div', {
159 | className: 'left-image',
160 | onClick: open,
161 | style: { backgroundImage: `url(${selectedImage})` }
162 | })
163 | ),
164 | wp.element.createElement(
165 | 'div',
166 | { className: 'right' },
167 | wp.element.createElement(
168 | 'p',
169 | null,
170 | content
171 | )
172 | )
173 | );
174 | }
175 |
176 | });
177 |
178 | /***/ }),
179 |
180 | /***/ 55:
181 | /***/ (function(module, exports) {
182 |
183 | // removed by extract-text-webpack-plugin
184 |
185 | /***/ }),
186 |
187 | /***/ 56:
188 | /***/ (function(module, exports) {
189 |
190 | // removed by extract-text-webpack-plugin
191 |
192 | /***/ })
193 |
194 | /******/ });
--------------------------------------------------------------------------------
/blocks/side-by-side/side-by-side.editor.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-side-by-side .left-image {
2 | border: 2px solid transparent;
3 | transition: border 200ms; }
4 |
5 | .wp-block-guty-blocks-side-by-side .left-image:hover {
6 | cursor: pointer;
7 | border: 2px solid green; }
8 |
9 | .wp-block-guty-blocks-side-by-side .left-image:active {
10 | border: 2px solid lightgreen; }
11 |
--------------------------------------------------------------------------------
/blocks/side-by-side/side-by-side.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-side-by-side {
2 | margin: auto;
3 | max-width: 30em;
4 | display: flex;
5 | flex-direction: row; }
6 | .wp-block-guty-blocks-side-by-side .left {
7 | width: 30%;
8 | padding: 2em 0;
9 | display: flex;
10 | justify-content: flex-end;
11 | align-items: center; }
12 | .wp-block-guty-blocks-side-by-side .left .left-image {
13 | position: relative;
14 | width: 100%;
15 | padding-top: 100%;
16 | border-radius: 20%;
17 | overflow: hidden;
18 | background-size: cover;
19 | background-position: center;
20 | box-shadow: 0 0 20px rgba(0, 0, 0, 0.3); }
21 | .wp-block-guty-blocks-side-by-side .right {
22 | width: 70%;
23 | padding: 2em 1em;
24 | display: flex;
25 | justify-content: flex-start;
26 | align-items: center; }
27 | .wp-block-guty-blocks-side-by-side .right p {
28 | margin: 0; }
29 |
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | .editor-block-list__block {
6 | display: inline-block;
7 | width: 50%;
8 | padding: 8px;
9 | }
10 |
--------------------------------------------------------------------------------
/src/block-layout/block-layout.src.js:
--------------------------------------------------------------------------------
1 | import './block-layout.editor.css';
2 | import './block-layout.view.css';
3 |
4 | const {
5 | registerBlockType,
6 | } = wp.blocks;
7 |
8 | const {
9 | InnerBlocks,
10 | InspectorControls
11 | } = wp.editor;
12 |
13 | registerBlockType('guty-blocks/block-layout', {
14 | title: 'Block Layout',
15 | category: 'layout',
16 |
17 | attributes: { // Somewhat like setting initial state in a react app.
18 | // Strategy for mapping rendered attributes back into editable state
19 |
20 | },
21 |
22 | // The editor "render" function
23 | edit(props) {
24 | return ([
25 | props.isSelected && (
26 |
27 | Select the number of columns for your blocks:
28 |
29 |
30 | ),
31 | < div class={ props.className }>
32 |
37 |
38 | ]);
39 | },
40 |
41 | // The save "render" function
42 | save(props) {
43 | return (
44 |
45 |
46 |
47 | );
48 | }
49 |
50 | });
51 |
--------------------------------------------------------------------------------
/src/block-layout/block-layout.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-block-layout {
2 | display: flex;
3 | flex-direction: row;
4 | flex-wrap: wrap;
5 | align-items: stretch;
6 | }
7 |
8 | .wp-block-guty-blocks-block-layout > * {
9 | width: 50%;
10 | }
11 |
--------------------------------------------------------------------------------
/src/carousel/carousel.editor.css:
--------------------------------------------------------------------------------
1 | /* .wp-block-guty-blocks-hello-world {
2 | background: cadetblue;
3 | color: white;
4 | } */
5 |
6 |
--------------------------------------------------------------------------------
/src/carousel/carousel.src.js:
--------------------------------------------------------------------------------
1 | import './carousel.editor.css';
2 | import './carousel.view.css';
3 |
4 | const {
5 | registerBlockType,
6 | } = wp.blocks;
7 |
8 | const {
9 | MediaUpload,
10 | InspectorControls
11 | } = wp.editor;
12 |
13 | registerBlockType('guty-blocks/carousel', {
14 | title: 'Carousel',
15 | icon: 'welcome-write-blog',
16 | category: 'common',
17 |
18 | attributes: { // Somewhat like setting initial state in a react app
19 | carouselImages: {
20 | type: 'array',
21 | default: []
22 | },
23 | carouselTime: {
24 | type: 'number',
25 | default: '5'
26 | },
27 | fadeTime: {
28 | type: 'number',
29 | default: '500'
30 | }
31 | },
32 |
33 | // The editor "render" function
34 | edit(props) {
35 | const {
36 | className,
37 | setAttributes,
38 | attributes: {
39 | carouselImages,
40 | carouselTime,
41 | fadeTime
42 | }
43 | } = props;
44 |
45 | function changeImageArray(changes) {
46 | setAttributes({ carouselImages: changes });
47 | }
48 | function changeCarouselTime(changes) {
49 | setAttributes({ carouselTime: changes.target.value });
50 | }
51 |
52 | function changeFadeTime(changes) {
53 | setAttributes({ fadeTime: changes.target.value });
54 | }
55 |
56 |
57 | const MyMediaUpload = (
62 |
65 | Select/Change Images
66 |
67 | )}
68 | />;
69 |
70 | return ([
71 |
72 |
73 | {MyMediaUpload}
74 |
75 |
76 | Set fade length (milliseconds):
77 |
82 |
83 |
84 | Set slide interval (seconds):
85 |
90 |
91 |
92 | ,
93 | MyMediaUpload
94 | ,
95 |
101 |
102 | {carouselImages.length ?
103 | carouselImages.map((el, index) => {
104 | return
;
109 | })
110 | :
111 | 'No Images Yet'
112 | }
113 |
114 |
115 | ]);
116 | },
117 |
118 | // The save "render" function
119 | save(props) {
120 | const {
121 | className,
122 | attributes: {
123 | carouselImages,
124 | carouselTime,
125 | fadeTime
126 | }
127 | } = props;
128 |
129 | return (
130 |
136 |
137 | {carouselImages.length ?
138 | carouselImages.map((el, index) => {
139 | return
;
144 | })
145 | :
146 | 'No images yet...'
147 | }
148 |
149 |
150 | );
151 | }
152 |
153 | }); ``
--------------------------------------------------------------------------------
/src/carousel/carousel.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-carousel {
2 | width: 100%;
3 | position: relative;
4 | }
5 |
6 | .wp-block-guty-blocks-carousel .inner {
7 | position: absolute;
8 | top: 0;
9 | left: 0;
10 | width: 100%;
11 | height: 100%;
12 | overflow: hidden;
13 | }
14 |
15 | .wp-block-guty-blocks-carousel .inner img {
16 | position: absolute;
17 | width: 100%;
18 | top: 50%;
19 | transform: translateY(-50%);
20 | opacity: 0;
21 | }
22 |
23 | .wp-block-guty-blocks-carousel .inner img.active {
24 | opacity: 1;
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/src/gallery/Image.js:
--------------------------------------------------------------------------------
1 | const Image = function(props) {
2 |
3 | const { photo, galleryID } = props;
4 | const photoThumb = photo.sizes.medium || photo.sizes.thumbnail;
5 |
6 | return (
7 |
8 |
15 |
16 | );
17 | }
18 |
19 | export { Image };
--------------------------------------------------------------------------------
/src/gallery/gallery.editor.css:
--------------------------------------------------------------------------------
1 | /* .wp-block-guty-blocks-hello-world {
2 | background: cadetblue;
3 | color: white;
4 | } */
5 |
6 |
7 | .galleryInspector > *{
8 | display: block;
9 | margin: 15px;
10 | }
11 |
--------------------------------------------------------------------------------
/src/gallery/gallery.src.js:
--------------------------------------------------------------------------------
1 | import './gallery.editor.css';
2 | import './gallery.view.css';
3 |
4 | import { Image } from './Image';
5 |
6 | const {
7 | registerBlockType,
8 | } = wp.blocks;
9 |
10 | const {
11 | RichText,
12 | PlainText,
13 | InspectorControls,
14 | MediaUpload
15 | } = wp.editor;
16 |
17 | registerBlockType('guty-blocks/gallery', {
18 | title: 'Custom Photo Gallery',
19 | icon: 'format-gallery',
20 | category: 'common',
21 |
22 | attributes: {
23 | titleText: {
24 | type: 'string'
25 | },
26 | imagesArray: {
27 | type: 'array',
28 | default: []
29 | },
30 | columns: {
31 | type: 'number',
32 | default: 2
33 | },
34 | alignment: {
35 | type: 'string',
36 | default: 'alignLeft'
37 | }
38 | },
39 |
40 | // The editor "render" function
41 | edit(props) {
42 |
43 | const { focus, className, setAttributes } = props;
44 | const { titleText, imagesArray, columns, alignment } = props.attributes;
45 |
46 | const changeTitle = (changes) => {
47 | setAttributes({ titleText: changes })
48 | };
49 |
50 | function changeImageArray(changes) {
51 | setAttributes({ imagesArray: changes })
52 | }
53 |
54 | function changeColumns(changes) {
55 | setAttributes({ columns: changes.target.value });
56 | }
57 |
58 | function changeAlignment(changes) {
59 | setAttributes({ alignment: changes.target.value });
60 | }
61 |
62 | function moveElement(elIndex, direction) {
63 | let tempArray = [...imagesArray];
64 |
65 | //take out element
66 | const el = tempArray.splice(elIndex, 1)[0];
67 |
68 | // place element in either previous or next
69 | tempArray.splice(elIndex + direction, 0, el);
70 |
71 | //set array back
72 | setAttributes({ imagesArray: tempArray });
73 | }
74 |
75 | function removeElement(elIndex) {
76 | let tempArray = [...imagesArray];
77 | tempArray.splice(elIndex, 1);
78 | setAttributes({ imagesArray: tempArray });
79 | }
80 |
81 | function addPhotos(images) {
82 | setAttributes({
83 | imagesArray: [...imagesArray, ...images]
84 | });
85 | }
86 |
87 | const MyMediaUpload = (
92 |
94 | Select Images
95 |
96 | )}
97 | />;
98 |
99 | const AddPhotosUpload = {
104 | return (
105 |
106 | Add photo
107 |
108 | )
109 | }}
110 | />;
111 |
112 |
113 | return ([
114 | focus &&
115 |
116 |
Settings for gallery:"{titleText}"
117 | {MyMediaUpload}
118 |
119 | Select Number of Columns:
120 |
121 | {/* Adding a map to dynamically place selected option based off of attribtues */}
122 | {[1, 2, 3, 4].map((el) => {el} Column )}
123 |
124 |
125 |
126 | Select Alignment:
127 |
128 | {/* Adding a map to dynamically place selected option based off of attribtues */}
129 | {["alignLeft", "alignCenter", "alignRight"].map((el) => {el} )}
130 |
131 |
132 |
133 | ,
134 |
135 |
136 |
137 |
143 |
144 |
145 |
146 | {imagesArray.length ?
147 | imagesArray.map((el, index) => {
148 | return (
149 |
150 |
155 |
156 | {index !== 0 && moveElement(index, -1)}>< }
157 | removeElement(index)}>Remove
158 | {(index !== (imagesArray.length - 1)) && moveElement(index, 1)}>> }
159 |
160 |
161 | );
162 | })
163 | :
164 |
165 |
No images yet
166 | {MyMediaUpload}
167 |
168 | }
169 | {AddPhotosUpload}
170 |
171 |
172 |
173 |
174 | ]);
175 | },
176 |
177 | // The save "render" function
178 | save(props) {
179 |
180 | const { className } = props;
181 | const { titleText, imagesArray, columns, alignment } = props.attributes;
182 |
183 | return (
184 |
185 |
186 | {titleText}
187 |
188 |
189 | {
190 | imagesArray.map((el, index) => {
191 | return
196 | })
197 | }
198 |
199 |
200 |
201 | );
202 | }
203 |
204 | });
--------------------------------------------------------------------------------
/src/gallery/gallery.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-gallery h1 {
2 | margin-bottom: 16px;
3 | }
4 |
5 | .wp-block-guty-blocks-gallery * {
6 | box-sizing: border-box;
7 | }
8 |
9 | :root {
10 | --PADDING: 32px;
11 | }
12 |
13 | @media (max-width: 450px) {
14 | :root {
15 | --PADDING: 16px;
16 | }
17 | }
18 |
19 | .wp-block-guty-blocks-gallery .galleryContainer {
20 | position: relative;
21 | display: flex;
22 | flex-direction: row;
23 | flex-wrap: wrap;
24 | margin: calc(-1 * var(--PADDING)) calc(-.5 * var(--PADDING)) 0 calc(-.5 * var(--PADDING));
25 | }
26 |
27 | .wp-block-guty-blocks-gallery .galleryContainer>* {
28 | padding: var(--PADDING) calc(0.5 * var(--PADDING)) 0 calc(0.5 * var(--PADDING));
29 | }
30 |
31 | .wp-block-guty-blocks-gallery .galleryContainer>* {
32 | width: 100%;
33 | }
34 |
35 | .wp-block-guty-blocks-gallery .galleryContainer_2up>* {
36 | width: 50%;
37 | }
38 |
39 | .wp-block-guty-blocks-gallery .galleryContainer_3up>* {
40 | width: 33.3%;
41 | }
42 |
43 | .wp-block-guty-blocks-gallery .galleryContainer_4up>* {
44 | width: 25%;
45 | }
46 |
47 | @media (max-width: 450px) {
48 | .wp-block-guty-blocks-gallery .galleryContainer>*,
49 | .wp-block-guty-blocks-gallery .galleryContainer_2up>*,
50 | .wp-block-guty-blocks-gallery .galleryContainer_3up>*,
51 | .wp-block-guty-blocks-gallery .galleryContainer_4up>* {
52 | width: 100%;
53 | }
54 | }
55 |
56 | .wp-block-guty-blocks-gallery .galleryContainer_alignLeft {
57 | justify-content: flex-start;
58 | }
59 |
60 | .wp-block-guty-blocks-gallery .galleryContainer_alignCenter {
61 | justify-content: center;
62 | }
63 |
64 | .wp-block-guty-blocks-gallery .galleryContainer_alignRight {
65 | justify-content: flex-end;
66 | }
67 |
68 | .imageWrapper {
69 | position: relative;
70 | }
71 |
72 | .imageWrapper-buttons {
73 | position: absolute;
74 | display: flex;
75 | padding: 0 30px;
76 | justify-content: space-between;
77 | width: 100%;
78 | top: calc(50% + 16px);
79 | left: 0;
80 | transform: translateY(-50%);
81 | }
82 |
83 | .imageWrapper-buttons button {
84 | opacity: 0;
85 | transition: 200ms;
86 | }
87 |
88 | .imageWrapper:hover button {
89 | opacity: 1;
90 | cursor: pointer;
91 | border: none;
92 | background: cadetblue;
93 | color: white;
94 | }
95 |
96 | .imageWrapper:hover button:hover {
97 | color: cadetblue;
98 | background: white;
99 | }
100 |
101 | .galleryContainer .galleryContainer-addPhoto {
102 | position: absolute;
103 | bottom: 0;
104 | right: 0;
105 | text-align: right;
106 | }
107 |
108 | .galleryContainer .galleryContainer-addPhoto button {
109 | cursor: pointer;
110 | border: none;
111 | background: cadetblue;
112 | color: white;
113 | transition: 200ms;
114 | }
115 |
116 | .galleryContainer .galleryContainer-addPhoto button:hover {
117 | background: rgba(95, 158, 160, .8);
118 | color: white;
119 | }
--------------------------------------------------------------------------------
/src/hello-world/_test.scss:
--------------------------------------------------------------------------------
1 | body {
2 |
3 | }
--------------------------------------------------------------------------------
/src/hello-world/hello-world.editor.css:
--------------------------------------------------------------------------------
1 | /* .wp-block-guty-blocks-hello-world {
2 | background: cadetblue;
3 | color: white;
4 | } */
5 |
6 |
--------------------------------------------------------------------------------
/src/hello-world/hello-world.src.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | const { registerBlockType } = wp.blocks;
5 | // const { __ } = wp.i18n;
6 |
7 | import './hello-world.editor.css';
8 | import './hello-world.view.scss';
9 |
10 | registerBlockType('guty-blocks/hello-world', {
11 | title: 'Hello World!',
12 | icon: 'welcome-write-blog',
13 | category: 'common',
14 |
15 | attributes: { // Somewhat like setting initial state in a react app
16 | },
17 |
18 | // The editor "render" function
19 | edit(props) {
20 | const { className } = props;
21 |
22 | return (
23 |
24 | {/*
{ __( 'Hello World!', 'guty-blocks' ) } */}
25 | Hello World!
26 |
27 | );
28 | },
29 |
30 | // The save "render" function
31 | save(props) {
32 | const { className } = props;
33 |
34 | return (
35 |
36 | {/*
{ __( 'Hello World!', 'guty-blocks' ) } */}
37 | Hello World!
38 |
39 | );
40 | }
41 |
42 | });
43 |
--------------------------------------------------------------------------------
/src/hello-world/hello-world.view.scss:
--------------------------------------------------------------------------------
1 | // @import 'test';
2 |
3 |
4 | .wp-block-guty-blocks-hello-world {
5 | background: tomato;
6 | color: white;
7 | }
--------------------------------------------------------------------------------
/src/image-hero/image-hero.editor.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-image-hero {
2 | position: relative;
3 | background-position: center;
4 | background-size: cover;
5 | text-align: center;
6 | padding: 8em 0;
7 | }
8 |
9 | .overlay {
10 | position: absolute;
11 | top:0;
12 | left: 0;
13 | width: 100%;
14 | height: 100%;
15 | }
16 |
17 | .wp-block-guty-blocks-image-hero h1 {
18 | position: relative;
19 | z-index:1;
20 | }
--------------------------------------------------------------------------------
/src/image-hero/image-hero.src.js:
--------------------------------------------------------------------------------
1 | import './image-hero.editor.css';
2 | import './image-hero.view.css';
3 |
4 | const {
5 | registerBlockType,
6 | } = wp.blocks;
7 |
8 | const {
9 | AlignmentToolbar, //prebuild alignment button component that we put in block controls for this block
10 | RichText,
11 | InspectorControls, // allows us to add controls on the sidebar
12 | BlockControls, //component that appears right above block when it is selected
13 | MediaUpload, // allows us to upload images
14 | ColorPalette, // prebuilt component that allows color picking in inspector controls
15 | } = wp.editor;
16 |
17 | registerBlockType('guty-blocks/image-hero', {
18 | title: 'Image Hero Block',
19 | icon: 'format-image',
20 | category: 'common',
21 |
22 | // Somewhat like setting initial state in a react app
23 | attributes: {
24 | alignement: {
25 | type: 'string'
26 | },
27 | content: {
28 | type: 'array',
29 | source: 'children',
30 | selector: 'h1',
31 | default: 'Editable block content...',
32 | },
33 | imageUrl: {
34 | type: 'string',
35 | default: "http://placehold.it/800x300"
36 | },
37 | textColor: {
38 | type: 'string',
39 | default: null
40 | },
41 | gradientColor: {
42 | type: 'string',
43 | default: null
44 | }
45 | },
46 |
47 | // The editor "render" function
48 | edit(props) {
49 |
50 | let { focus } = props;
51 | let { alignment, content, imageUrl, textColor, gradientColor } = props.attributes;
52 |
53 | function onChangeContent(updatedContent) {
54 | props.setAttributes({ content: updatedContent });
55 | }
56 | function onChangeImage(imgObject) {
57 | props.setAttributes({ imageUrl: imgObject.url });
58 | }
59 | function onChangeGradientColor(color) {
60 | props.setAttributes({ gradientColor: color });
61 | }
62 | function onChangeTextColor(color) {
63 | props.setAttributes({ textColor: color });
64 | }
65 |
66 | // Actual elements being
67 | return ([
68 | props.isSelected && (
69 | (
73 |
74 | Select a background image
75 |
76 | )}
77 | />
78 | Select text color:
79 |
83 |
84 | Select a gradient color:
85 |
89 |
90 |
91 | ),
92 | props.isSelected && (
93 |
94 | props.setAttributes({alignment: change}) }
97 | />
98 |
99 | ),
100 |
119 | ]);
120 | },
121 |
122 | // The save "render" function
123 | save(props) {
124 | let { className } = props;
125 | let { alignment, content, imageUrl, gradientColor, textColor } = props.attributes;
126 |
127 | return (
128 |
129 |
136 |
{content}
140 |
141 | );
142 | }
143 |
144 | });
--------------------------------------------------------------------------------
/src/image-hero/image-hero.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-image-hero {
2 | position: relative;
3 | background-position: center;
4 | background-size: cover;
5 | text-align: center;
6 | padding: 8em 0;
7 | left: calc(50% - 50vw);
8 | width: 100vw;
9 | }
10 |
11 | .overlay {
12 | position: absolute;
13 | top:0;
14 | left: 0;
15 | width: 100%;
16 | height: 100%;
17 | }
18 |
19 | .wp-block-guty-blocks-image-hero h1 {
20 | position: relative;
21 | z-index:1;
22 | }
--------------------------------------------------------------------------------
/src/media-block/media-block.editor.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-media-block {
2 | position: relative;
3 | background: cadetblue;
4 | padding:2em;
5 | display: flex;
6 | flex-direction: row;
7 | }
8 | .wp-block-guty-blocks-media-block:before {
9 | content:'Editing mode';
10 | position: absolute;
11 | top: 4px;
12 | left: 4px;
13 | color: red;
14 | }
15 |
16 | .wp-block-guty-blocks-media-block .left {
17 | flex: 33%;
18 | padding-right: 16px;
19 | }
20 |
21 | .wp-block-guty-blocks-media-block .right {
22 | flex: 66%;
23 | }
24 |
25 | .wp-block-guty-blocks-media-block p {
26 | font-size: 24px;
27 | color: white;
28 | }
--------------------------------------------------------------------------------
/src/media-block/media-block.src.js:
--------------------------------------------------------------------------------
1 | import './media-block.editor.css';
2 | import './media-block.view.css';
3 |
4 | const {
5 | registerBlockType,
6 | } = wp.blocks;
7 |
8 | const {
9 | RichText, // Editable field
10 | InspectorControls, // allows us to add controls on the sidebar
11 | MediaUpload // allows us to upload images
12 | } = wp.editor
13 |
14 | registerBlockType('guty-blocks/media-block', {
15 | title: 'Media Item Block',
16 | icon: 'smiley',
17 | category: 'common',
18 |
19 | attributes: { // Somewhat like setting initial state in a react app
20 | content: {
21 | type: 'array',
22 | source: 'children',
23 | selector: 'p',
24 | default: 'Editable block content...',
25 | },
26 | imageUrl: {
27 | type: 'string',
28 | default: null
29 | }
30 | },
31 |
32 | // The editor "render" function
33 | edit(props) {
34 |
35 | let { content, imageUrl, focus, isSelected } = props.attributes;
36 |
37 | function onChangeContent(updatedContent) {
38 | props.setAttributes({ content: updatedContent });
39 | }
40 |
41 | function setImage(image) {
42 | console.log(image);
43 | props.setAttributes({ imageUrl: image.url })
44 | }
45 |
46 |
47 | // If an image isn't selected show the upload button
48 | // otherwise, show the image
49 | let imageSide = null;
50 | if (imageUrl) {
51 | imageSide = ;
52 | } else {
53 | imageSide = (
57 |
58 | Open Media Library
59 |
60 | )}
61 | />
62 | }
63 |
64 | // Actual elements being rendered
65 | return ([
66 | isSelected && (
67 |
68 | This is where some style options can be presented for your block!
69 |
70 | ),
71 |
72 |
73 | {imageSide}
74 |
75 |
76 |
81 |
82 |
83 | ]);
84 | },
85 |
86 | // The save "render" function
87 | save(props) {
88 | return (
89 |
90 |
91 |
92 |
93 |
94 |
{props.attributes.content}
95 |
96 |
97 | );
98 | }
99 |
100 | });
--------------------------------------------------------------------------------
/src/media-block/media-block.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-media-block {
2 | position: relative;
3 | background: cadetblue;
4 | padding:2em;
5 | display: flex;
6 | flex-direction: row;
7 | }
8 | .wp-block-guty-blocks-media-block:before {
9 | content:'View Mode';
10 | position: absolute;
11 | top: 4px;
12 | left: 4px;
13 | color: blue;
14 | }
15 |
16 | .wp-block-guty-blocks-media-block .left {
17 | flex: 33%;
18 | padding-right: 16px;
19 | }
20 |
21 | .wp-block-guty-blocks-media-block .right {
22 | flex: 66%;
23 | }
24 |
25 | .wp-block-guty-blocks-media-block p {
26 | font-size: 24px;
27 | color: white;
28 | }
--------------------------------------------------------------------------------
/src/prism-code/prism-code.editor.css:
--------------------------------------------------------------------------------
1 | /* .wp-block-guty-blocks-hello-world {
2 | background: cadetblue;
3 | color: white;
4 | } */
5 |
6 |
--------------------------------------------------------------------------------
/src/prism-code/prism-code.src.js:
--------------------------------------------------------------------------------
1 | import './prism-code.editor.css';
2 | import './prism-code.view.css';
3 |
4 | import TextareaAutosize from 'react-autosize-textarea';
5 |
6 | var Prism = require('./prismjs/prism.js');
7 |
8 | var nativeElements = {};
9 |
10 | const {
11 | registerBlockType,
12 | } = wp.blocks;
13 |
14 | const {
15 | PlainText,
16 | BlockControls,
17 | InspectorControls
18 | } = wp.editor;
19 |
20 | console.log(wp.editor);
21 |
22 | registerBlockType('guty-blocks/prism-code', {
23 | title: 'Prism Code Formatter',
24 | icon: 'editor-code',
25 | category: 'common',
26 |
27 | attributes: { // Somewhat like setting initial state in a react app
28 | codeString: {
29 | type: 'string',
30 | default: '',
31 | },
32 | beautifulCode: {
33 | type: 'string',
34 | default: ''
35 | },
36 | language: {
37 | type: 'string',
38 | default: 'javascript'
39 | },
40 | tabLength: {
41 | type: 'number',
42 | default: 4
43 | }
44 | },
45 |
46 | // The editor "render" function
47 | edit(props) {
48 | const {
49 | className,
50 | setAttributes,
51 | focus,
52 | attributes: {
53 | codeString,
54 | beautifulCode,
55 | language,
56 | tabLength
57 | }
58 | } = props;
59 |
60 | function changeLanguage(event) {
61 | let newLanguage = event.target.value;
62 | let tempCodeString = Prism.highlight(codeString, Prism.languages[newLanguage]);
63 | setAttributes({
64 | language: newLanguage,
65 | beautifulCode: tempCodeString
66 | })
67 | }
68 | function changeCode(changes, event) {
69 | let tempCodeString = Prism.highlight(changes, Prism.languages[language]);
70 | setAttributes({
71 | beautifulCode: tempCodeString,
72 | codeString: changes
73 | });
74 | }
75 |
76 | function changeTabLength(event) {
77 | console.log(event.target.value, parseInt(event.target.value))
78 | setAttributes({ tabLength: parseInt(event.target.value) })
79 | }
80 |
81 | function checkKey(event) {
82 | // checks for a tab, and if present, manually adds spacing
83 | if(event.keyCode == 9) {
84 | // escape browser tabbing
85 | event.preventDefault();
86 |
87 | // get cursor location
88 | let location = event.nativeEvent.target.selectionEnd;
89 |
90 | // "splice" a tab
91 | let newCodeString = codeString.slice(0,location) + ' '.repeat(tabLength) + codeString.slice(location);
92 |
93 |
94 | let newBeautifulCodeString = Prism.highlight(newCodeString, Prism.languages[language]);
95 |
96 | setAttributes({
97 | codeString: newCodeString,
98 | beautifulCode: newBeautifulCodeString
99 | });
100 |
101 | // setTimout hack will have to suffice since setAttribute callback is not available
102 | setTimeout(() => {
103 | nativeElements.inputRef.focus();
104 | nativeElements.inputRef.selectionEnd = location + tabLength;
105 | }, 0);
106 | }
107 | }
108 |
109 | return ([
110 |
111 |
112 | Change the language:
113 |
114 | Javascript
115 | JSX
116 | HTML
117 | CSS
118 | PHP
119 |
120 |
121 |
122 | Tab character length:
123 |
124 | 2
125 | 4
126 |
127 |
128 |
129 | ,
130 |
131 |
132 | changeCode(e.target.value, e)}
136 | onKeyDown={checkKey}
137 | placeholder='Type some code here...'
138 | innerRef={el => (nativeElements.inputRef = el)} //storing reference to try to set cursor position
139 | />
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 | ]);
148 | },
149 |
150 | // The save "render" function
151 | save(props) {
152 | const {
153 | className,
154 | attributes: {
155 | codeString,
156 | beautifulCode,
157 | language
158 | }
159 | } = props;
160 |
161 | return (
162 |
163 |
164 |
165 |
166 |
167 |
168 | );
169 | }
170 |
171 | });
--------------------------------------------------------------------------------
/src/prism-code/prism-code.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-prism-code.wp-block-guty-blocks-prism-code textarea {
2 | box-shadow: none;
3 | font-family: inherit;
4 | font-size: inherit;
5 | color: inherit;
6 | line-height: inherit;
7 | border: none;
8 | padding: 0;
9 | margin: 0;
10 | width: 100%;
11 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
12 | background: transparent;
13 | }
14 |
15 | code {
16 | padding: 0;
17 | margin: 0;
18 | font-size: inherit;
19 | }
20 |
21 |
22 | /* Prism styles */
23 | /* PrismJS 1.12.2
24 | http://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+jsx */
25 | /**
26 | * prism.js default theme for JavaScript, CSS and HTML
27 | * Based on dabblet (http://dabblet.com)
28 | * @author Lea Verou
29 | */
30 |
31 | code[class*="language-"],
32 | pre[class*="language-"] {
33 | color: black;
34 | background: none;
35 | text-shadow: 0 1px white;
36 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
37 | text-align: left;
38 | white-space: pre;
39 | word-spacing: normal;
40 | word-break: normal;
41 | word-wrap: normal;
42 | line-height: 1.5;
43 |
44 | -moz-tab-size: 4;
45 | -o-tab-size: 4;
46 | tab-size: 4;
47 |
48 | -webkit-hyphens: none;
49 | -moz-hyphens: none;
50 | -ms-hyphens: none;
51 | hyphens: none;
52 | }
53 |
54 | pre[class*="language-"]::-moz-selection,
55 | pre[class*="language-"] ::-moz-selection,
56 | code[class*="language-"]::-moz-selection,
57 | code[class*="language-"] ::-moz-selection {
58 | text-shadow: none;
59 | background: #b3d4fc;
60 | }
61 |
62 | pre[class*="language-"]::selection,
63 | pre[class*="language-"] ::selection,
64 | code[class*="language-"]::selection,
65 | code[class*="language-"] ::selection {
66 | text-shadow: none;
67 | background: #b3d4fc;
68 | }
69 |
70 | @media print {
71 |
72 | code[class*="language-"],
73 | pre[class*="language-"] {
74 | text-shadow: none;
75 | }
76 | }
77 |
78 | /* Code blocks */
79 | pre[class*="language-"] {
80 | padding: 1em;
81 | margin: .5em 0;
82 | overflow: auto;
83 | }
84 |
85 | :not(pre)>code[class*="language-"],
86 | pre[class*="language-"] {
87 | background: #f5f2f0;
88 | }
89 |
90 | /* Inline code */
91 | :not(pre)>code[class*="language-"] {
92 | padding: .1em;
93 | border-radius: .3em;
94 | white-space: normal;
95 | }
96 |
97 | .token.comment,
98 | .token.prolog,
99 | .token.doctype,
100 | .token.cdata {
101 | color: slategray;
102 | }
103 |
104 | .token.punctuation {
105 | color: #999;
106 | }
107 |
108 | .namespace {
109 | opacity: .7;
110 | }
111 |
112 | .token.property,
113 | .token.tag,
114 | .token.boolean,
115 | .token.number,
116 | .token.constant,
117 | .token.symbol,
118 | .token.deleted {
119 | color: #905;
120 | }
121 |
122 | .token.selector,
123 | .token.attr-name,
124 | .token.string,
125 | .token.char,
126 | .token.builtin,
127 | .token.inserted {
128 | color: #690;
129 | }
130 |
131 | .token.operator,
132 | .token.entity,
133 | .token.url,
134 | .language-css .token.string,
135 | .style .token.string {
136 | color: #a67f59;
137 | background: hsla(0, 0%, 100%, .5);
138 | }
139 |
140 | .token.atrule,
141 | .token.attr-value,
142 | .token.keyword {
143 | color: #07a;
144 | }
145 |
146 | .token.function,
147 | .token.class-name {
148 | color: #DD4A68;
149 | }
150 |
151 | .token.regex,
152 | .token.important,
153 | .token.variable {
154 | color: #e90;
155 | }
156 |
157 | .token.important,
158 | .token.bold {
159 | font-weight: bold;
160 | }
161 |
162 | .token.italic {
163 | font-style: italic;
164 | }
165 |
166 | .token.entity {
167 | cursor: help;
168 | }
--------------------------------------------------------------------------------
/src/prism-code/prismjs/prism.css:
--------------------------------------------------------------------------------
1 | /* PrismJS 1.12.2
2 | http://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+php+jsx */
3 | /**
4 | * prism.js default theme for JavaScript, CSS and HTML
5 | * Based on dabblet (http://dabblet.com)
6 | * @author Lea Verou
7 | */
8 |
9 | code[class*="language-"],
10 | pre[class*="language-"] {
11 | color: black;
12 | background: none;
13 | text-shadow: 0 1px white;
14 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
15 | text-align: left;
16 | white-space: pre;
17 | word-spacing: normal;
18 | word-break: normal;
19 | word-wrap: normal;
20 | line-height: 1.5;
21 |
22 | -moz-tab-size: 4;
23 | -o-tab-size: 4;
24 | tab-size: 4;
25 |
26 | -webkit-hyphens: none;
27 | -moz-hyphens: none;
28 | -ms-hyphens: none;
29 | hyphens: none;
30 | }
31 |
32 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
33 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
34 | text-shadow: none;
35 | background: #b3d4fc;
36 | }
37 |
38 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
39 | code[class*="language-"]::selection, code[class*="language-"] ::selection {
40 | text-shadow: none;
41 | background: #b3d4fc;
42 | }
43 |
44 | @media print {
45 | code[class*="language-"],
46 | pre[class*="language-"] {
47 | text-shadow: none;
48 | }
49 | }
50 |
51 | /* Code blocks */
52 | pre[class*="language-"] {
53 | padding: 1em;
54 | margin: .5em 0;
55 | overflow: auto;
56 | }
57 |
58 | :not(pre) > code[class*="language-"],
59 | pre[class*="language-"] {
60 | background: #f5f2f0;
61 | }
62 |
63 | /* Inline code */
64 | :not(pre) > code[class*="language-"] {
65 | padding: .1em;
66 | border-radius: .3em;
67 | white-space: normal;
68 | }
69 |
70 | .token.comment,
71 | .token.prolog,
72 | .token.doctype,
73 | .token.cdata {
74 | color: slategray;
75 | }
76 |
77 | .token.punctuation {
78 | color: #999;
79 | }
80 |
81 | .namespace {
82 | opacity: .7;
83 | }
84 |
85 | .token.property,
86 | .token.tag,
87 | .token.boolean,
88 | .token.number,
89 | .token.constant,
90 | .token.symbol,
91 | .token.deleted {
92 | color: #905;
93 | }
94 |
95 | .token.selector,
96 | .token.attr-name,
97 | .token.string,
98 | .token.char,
99 | .token.builtin,
100 | .token.inserted {
101 | color: #690;
102 | }
103 |
104 | .token.operator,
105 | .token.entity,
106 | .token.url,
107 | .language-css .token.string,
108 | .style .token.string {
109 | color: #a67f59;
110 | background: hsla(0, 0%, 100%, .5);
111 | }
112 |
113 | .token.atrule,
114 | .token.attr-value,
115 | .token.keyword {
116 | color: #07a;
117 | }
118 |
119 | .token.function,
120 | .token.class-name {
121 | color: #DD4A68;
122 | }
123 |
124 | .token.regex,
125 | .token.important,
126 | .token.variable {
127 | color: #e90;
128 | }
129 |
130 | .token.important,
131 | .token.bold {
132 | font-weight: bold;
133 | }
134 | .token.italic {
135 | font-style: italic;
136 | }
137 |
138 | .token.entity {
139 | cursor: help;
140 | }
--------------------------------------------------------------------------------
/src/quote/quote.editor.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-quote .blocks-rich-text {
2 | display: inline;
3 | }
4 |
5 | .wp-block-guty-blocks-quote .author .blocks-rich-text {
6 | font-variant: small-caps;
7 | color: #646464;
8 | }
9 |
--------------------------------------------------------------------------------
/src/quote/quote.src.js:
--------------------------------------------------------------------------------
1 | import './quote.editor.css';
2 | import './quote.view.css';
3 |
4 | const {
5 | registerBlockType,
6 | } = wp.blocks;
7 |
8 | const {
9 | RichText
10 | } = wp.editor;
11 |
12 | registerBlockType('guty-blocks/quote', {
13 | title: 'Custom Quote Block',
14 | category: 'common',
15 |
16 | attributes: { // Somewhat like setting initial state in a react app.
17 | // Strategy for mapping rendered attributes back into editable state
18 | author: {
19 | type: 'string',
20 | default: 'author'
21 | },
22 | quoteContent: {
23 | type: 'string',
24 | default: 'Enter quote here'
25 | }
26 | },
27 |
28 | // The editor "render" function
29 | edit(props) {
30 | let {className} = props;
31 | return (
32 |
33 |
34 | “
35 | props.setAttributes({ quoteContent:changes })}
39 | />
40 | ”
41 |
42 |
43 | - props.setAttributes({ author: changes})}
47 | />
48 |
49 |
50 | );
51 | },
52 |
53 | // The save "render" function
54 | save(props) {
55 | let {className} = props;
56 | return (
57 |
58 |
59 | “
60 | {props.attributes.quoteContent}
61 | ”
62 |
63 |
64 | - {props.attributes.author}
65 |
66 |
67 | );
68 | }
69 |
70 | });
71 |
--------------------------------------------------------------------------------
/src/quote/quote.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-quote {
2 | width: 80%;
3 | margin: 50px auto 25px;
4 | padding: 8px;
5 | border: 1px solid #d8d2d0;
6 | text-align: center;
7 | }
8 |
9 | .wp-block-guty-blocks-quote .quote-text {
10 | padding: 8px;
11 | font-size: 24px;
12 | }
13 |
14 | .wp-block-guty-blocks-quote .first-last-quotes {
15 | display: inline-block;
16 | font-size: 36px;
17 | line-height: 24px;
18 | }
19 |
20 | .wp-block-guty-blocks-quote .author {
21 | display: inline-block;
22 | font-variant: small-caps;
23 | color: #646464;
24 | }
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/react-view/components/Editor.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const buttonStyles = {
4 | padding: '.5em',
5 | margin: '.5em .5em 0 0',
6 | background: 'white',
7 | border: '1px solid #222',
8 | cursor: 'pointer'
9 | }
10 |
11 | const buttonStyles_selected = Object.assign({}, buttonStyles, {background: '#faf'})
12 |
13 | export default class Editor extends React.Component {
14 | constructor(props) {
15 | super(props);
16 | this.state = {
17 | currentPage: 1,
18 | totalPages: null,
19 | results: [],
20 | }
21 | this.fetchSomePosts = this.fetchSomePosts.bind(this);
22 | this.pageUp = this.pageUp.bind(this);
23 | this.pageBack = this.pageBack.bind(this);
24 | }
25 |
26 | componentDidMount() {
27 | this.fetchSomePosts(1);
28 | }
29 |
30 | fetchSomePosts(pageIndex) {
31 | fetch(`/wp-json/wp/v2/posts/?per_page=30&page=${pageIndex}`)
32 | .then((res) => {
33 |
34 | !this.state.totalPages && this.setState({
35 | totalPages: res.headers.get('X-WP-TotalPages')
36 | })
37 |
38 | return res.json()
39 | })
40 | .then((data) => {
41 | console.log(data);
42 | this.setState({
43 | results: data,
44 | currentPage: pageIndex
45 | })
46 | });
47 | }
48 |
49 | pageUp() {
50 | let nextPage = this.state.currentPage + 1;
51 | this.fetchSomePosts(nextPage);
52 | }
53 |
54 | pageBack() {
55 | let previousPage = this.state.currentPage - 1;
56 | this.fetchSomePosts(previousPage);
57 | }
58 |
59 |
60 | render() {
61 |
62 | const { results } = this.state;
63 | const { selectedPostIds, togglePost } = this.props;
64 |
65 | return (
66 |
67 |
Select related posts:
68 |
Showing page {this.state.currentPage} of {this.state.totalPages} pages
69 |
70 | {
71 | this.state.results.map((el, i) => {
72 |
73 | let isSelected = !(selectedPostIds.indexOf(el.id) === -1);
74 |
75 | return (
76 |
79 | togglePost(el.id)}
82 | >{el.title.rendered}
83 |
84 | );
85 | })
86 | }
87 |
88 | {
89 | this.state.currentPage > 1 &&
90 |
Previous 20
91 | }
92 | {
93 | this.state.currentPage < this.state.totalPages &&
94 |
Next 20
95 | }
96 |
97 | );
98 | }
99 | }
--------------------------------------------------------------------------------
/src/react-view/react-view.editor.css:
--------------------------------------------------------------------------------
1 | /* .wp-block-guty-blocks-hello-world {
2 | background: cadetblue;
3 | color: white;
4 | } */
5 |
6 |
--------------------------------------------------------------------------------
/src/react-view/react-view.src.js:
--------------------------------------------------------------------------------
1 | import './react-view.editor.css';
2 | import './react-view.view.scss';
3 |
4 | import Editor from './components/Editor.jsx'
5 |
6 | const {
7 | registerBlockType,
8 | } = wp.blocks;
9 |
10 | registerBlockType('guty-blocks/react-view', {
11 | title: 'React View Test',
12 | icon: 'welcome-write-blog',
13 | category: 'common',
14 |
15 | attributes: { // Somewhat like setting initial state in a react app
16 | selectedPostIds: {
17 | type: 'array',
18 | default: []
19 | },
20 | },
21 |
22 | // The editor "render" function
23 | edit(props) {
24 | const {
25 | className,
26 | setAttributes,
27 | attributes: {
28 | selectedPostIds,
29 | posts
30 | }
31 | } = props;
32 |
33 | function togglePost( postId ) {
34 | const index = selectedPostIds.indexOf(postId);
35 | if (index === -1) {
36 | setAttributes({
37 | selectedPostIds: [ ...selectedPostIds, postId ]
38 | });
39 | } else {
40 | setAttributes({
41 | selectedPostIds: selectedPostIds.filter((el, i) => i !== index),
42 | })
43 | }
44 | }
45 |
46 | return (
47 |
52 |
56 |
57 | );
58 | },
59 |
60 | // The save "render" function
61 | save(props) {
62 | const {
63 | className,
64 | attributes: { selectedPostIds }
65 | } = props;
66 |
67 | return (
68 |
73 | Javascript must be enabled to view this block.
74 |
75 | );
76 | }
77 |
78 | });
--------------------------------------------------------------------------------
/src/react-view/react-view.view.js:
--------------------------------------------------------------------------------
1 | // import React from 'react';
2 | // import ReactDOM from 'react-dom';
3 |
4 | /**
5 | * Import HTML entity encoder/decoder.
6 | *
7 | * Lodash has it's own "unescape" entity decoder, but it is not as "robust" as he.
8 | *
9 | * @link https://lodash.com/docs/4.17.5#unescape
10 | * @link https://github.com/mathiasbynens/he
11 | */
12 | import he from 'he';
13 |
14 | class ReactLive extends React.Component {
15 | constructor(props) {
16 | super(props);
17 | this.state = {
18 | postsIds: JSON.parse( this.props.posts ),
19 | posts: []
20 | }
21 |
22 | this.fetchPosts = this.fetchPosts.bind(this);
23 | this.createMarkup = this.createMarkup.bind(this);
24 | }
25 |
26 | componentDidMount() {
27 | this.fetchPosts();
28 | }
29 |
30 | fetchPosts() {
31 | fetch('/wp-json/wp/v2/posts/' + '?include[]=' + this.state.postsIds.join('&include[]='))
32 | .then((res) => res.json())
33 | .then((json) => {
34 | this.setState({
35 | posts: json
36 | })
37 | });
38 | }
39 |
40 | /**
41 | * Do not expect REST API to return plain old strings for everything.
42 | * It is common and expected that WP content from the REST API will contain markup of one kind or another,
43 | * depending on the field.
44 | *
45 | * @link https://github.com/WP-API/WP-API/issues/1227
46 | *
47 | * @param string
48 | * @returns {{__html}}
49 | */
50 | createMarkup( string ) {
51 | return { __html: he.decode( string ).trim() };
52 | };
53 |
54 | render() {
55 | return (
56 |
57 |
58 | React is running live in the view. It takes the ids of the posts from the saved div in the editor and fetches the post content from the REST API to render below:
59 |
60 |
61 | {!this.state.posts.length ?
62 | Loading...
63 | :
64 | this.state.posts.map((el, i) => {
65 | return (
66 |
67 |
68 |
69 |
70 | )
71 | })
72 | }
73 |
74 |
75 | );
76 | }
77 | }
78 |
79 | window.onload = function () {
80 | let container = document.getElementById('live-react');
81 | if (container) {
82 | let postData = container.getAttribute('data-post-ids')
83 | ReactDOM.render(
84 | ,
85 | container
86 | )
87 | }
88 | };
89 |
--------------------------------------------------------------------------------
/src/react-view/react-view.view.scss:
--------------------------------------------------------------------------------
1 | // @import 'test';
2 |
3 |
4 | .wp-block-guty-blocks-hello-world {
5 |
6 | }
--------------------------------------------------------------------------------
/src/recent-posts/recent-posts.editor.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-recent-posts {
2 | }
3 |
4 | .articleContainer {
5 | display: grid;
6 | }
7 |
8 | .one_up {
9 | grid-template-columns: repeat(1, 1fr);
10 | }
11 | .two_up {
12 | grid-template-columns: repeat(2, 1fr);
13 | }
14 | .three_up {
15 | grid-template-columns: repeat(3, 1fr);
16 | }
17 |
18 | .articleContainer > * {
19 | grid-column: auto;
20 | margin: 8px;
21 | padding: 1em;
22 | border: 1px solid grey;
23 | }
24 |
--------------------------------------------------------------------------------
/src/recent-posts/recent-posts.src.js:
--------------------------------------------------------------------------------
1 | import './recent-posts.editor.css';
2 | import './recent-posts.view.css';
3 |
4 | const {
5 | registerBlockType,
6 | } = wp.blocks;
7 |
8 | const {
9 | Editable, // Text field - will be replaced by RichText in future updates
10 | InspectorControls, // allows us to add controls on the sidebar
11 | } = wp.editor;
12 |
13 | registerBlockType('guty-blocks/recent-posts', {
14 | title: 'Recent Posts Block',
15 | icon: 'welcome-write-blog',
16 | category: 'common',
17 |
18 | attributes: { // Somewhat like setting initial state in a react app
19 | numberUp: {
20 | type: 'string',
21 | default: '1_up'
22 | },
23 | posts: {
24 | type: 'array',
25 | default: []
26 | }
27 | },
28 |
29 | // The editor "render" function
30 | edit(props) {
31 |
32 | let { content, posts, numberUp } = props.attributes;
33 |
34 | function onChangeContent(updatedContent) {
35 | props.setAttributes({ content: updatedContent });
36 | }
37 | function onChangeNumberUp(newNumberUp) {
38 | props.setAttributes({ numberUp: newNumberUp.target.value });
39 | }
40 |
41 | async function fetchArticles() {
42 | let data = await fetch('/wp-json/wp/v2/posts/');
43 | let posts = await data.json();
44 | props.setAttributes({ posts });
45 | }
46 |
47 | // Actual elements being rendered
48 | return ([
49 | !!focus && (
50 |
51 | Select Layout:
52 |
54 | 1 up blocks
55 | 2 up blocks
56 | 3 up blocks
57 |
58 |
59 |
60 | ),
61 |
62 |
63 | Fetch me recent articles!
64 | {posts.length === 0 ?
65 |
Posts not pulled yet
66 | :
67 | {posts.length} found! }
68 |
69 |
70 | {posts && posts.map((el) => {
71 | return
76 | })}
77 |
78 |
79 | ]);
80 | },
81 |
82 | // The save "render" function
83 | save(props) {
84 |
85 | let { posts, numberUp } = props.attributes;
86 |
87 | return (
88 |
89 |
90 | {posts && posts.map((el) => {
91 | return
96 | })}
97 |
98 |
99 | );
100 | }
101 |
102 | });
103 |
104 | function RenderArticleButton(props) {
105 | return (
106 |
111 | )
112 | }
--------------------------------------------------------------------------------
/src/recent-posts/recent-posts.view.css:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-recent-posts {
2 | }
3 |
4 | .articleContainer {
5 | display: grid;
6 | }
7 |
8 | .one_up {
9 | grid-template-columns: repeat(1, 1fr);
10 | }
11 | .two_up {
12 | grid-template-columns: repeat(2, 1fr);
13 | }
14 | .three_up {
15 | grid-template-columns: repeat(3, 1fr);
16 | }
17 |
18 | .articleContainer > * {
19 | grid-column: auto;
20 | margin: 8px;
21 | padding: 1em;
22 | border: 1px solid grey;
23 | }
24 |
--------------------------------------------------------------------------------
/src/side-by-side/side-by-side.editor.scss:
--------------------------------------------------------------------------------
1 | .wp-block-guty-blocks-side-by-side {
2 |
3 | .left-image {
4 | border: 2px solid transparent;
5 | transition: border 200ms;
6 | }
7 | .left-image:hover {
8 | cursor: pointer;
9 | border: 2px solid green;
10 | }
11 |
12 | .left-image:active {
13 | border: 2px solid lightgreen;
14 | }
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/src/side-by-side/side-by-side.src.js:
--------------------------------------------------------------------------------
1 | import './side-by-side.editor.scss';
2 | import './side-by-side.view.scss';
3 |
4 | const {
5 | registerBlockType,
6 | } = wp.blocks;
7 |
8 | const {
9 | RichText,
10 | MediaUpload
11 | } = wp.editor;
12 |
13 | registerBlockType('guty-blocks/side-by-side', {
14 | title: 'Side by side block',
15 | icon: '',
16 | category: 'common',
17 |
18 | attributes: {
19 | selectedImage: {
20 | type: 'string',
21 | default: 'http://placehold.it/200x200'
22 | },
23 | content: {
24 | type: 'array',
25 | source: 'children',
26 | selector: 'p'
27 | }
28 | },
29 |
30 | edit(props) {
31 | const { className, setAttributes } = props;
32 | const { selectedImage, content, isSelected } = props.attributes;
33 |
34 | function changeText(changes) {
35 | setAttributes({ content: changes });
36 | }
37 |
38 | return (
39 |
40 |
41 |
{
43 | const newImage = image.sizes.medium || image.sizes.thumbnail;
44 | const url = newImage.url;
45 | setAttributes({ selectedImage: url })
46 | }}
47 | type="image"
48 | value={selectedImage}
49 | render={ ({ open } ) =>(
50 |
54 |
55 | )}
56 | />
57 |
58 |
59 |
66 |
67 |
68 | );
69 | },
70 |
71 | save(props) {
72 | const { className } = props;
73 | const { selectedImage, content } = props.attributes;
74 |
75 | return (
76 |
77 |
85 |
86 |
87 | {content}
88 |
89 |
90 |
91 | );
92 | }
93 |
94 | });
--------------------------------------------------------------------------------
/src/side-by-side/side-by-side.view.scss:
--------------------------------------------------------------------------------
1 | // @import 'test';
2 | .wp-block-guty-blocks-side-by-side {
3 | margin: auto;
4 | max-width: 30em;
5 | display: flex;
6 | flex-direction: row;
7 | .left {
8 | width: 30%;
9 | padding: 2em 0;
10 | display: flex;
11 | justify-content: flex-end;
12 | align-items: center;
13 |
14 | .left-image {
15 | position: relative;
16 | width: 100%;
17 | padding-top:100%;
18 | border-radius: 20%;
19 | overflow: hidden;
20 | background-size: cover;
21 | background-position: center;
22 | box-shadow: 0 0 20px rgba(0,0,0,.3);
23 | }
24 |
25 | }
26 | .right {
27 | width: 70%;
28 | padding: 2em 1em;
29 | display: flex;
30 | justify-content: flex-start;
31 | align-items: center;
32 |
33 | p {
34 | margin: 0;
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const ExtractTextPlugin = require("extract-text-webpack-plugin");
3 | const glob = require('glob');
4 |
5 | // different instances for editor or view css files
6 | const editorExtractTextPlugin = new ExtractTextPlugin("[name]/[name].editor.css");
7 | const viewExtractTextPlugin = new ExtractTextPlugin("[name]/[name].view.css");
8 |
9 | module.exports = [{
10 | entry: function () {
11 | /*
12 | function to map globs to appropriate entries for separate build files
13 | object that is returned looks like:
14 | {
15 | block-name: 'src/block-name/block-name.js',
16 | ...
17 | }
18 | */
19 | let entriesObject = {}
20 | glob.sync("./src/**/*.src.js").map((el) => {
21 | let path = el;
22 | let name = el.split('/').pop().split('.')[0];
23 | entriesObject[name] = path;
24 | })
25 | return entriesObject;
26 | },
27 | // {
28 | // 'media-block': './src/media-block/media-block.js',
29 | // 'image-hero': './src/image-hero/image-hero.js',
30 | // 'recent-posts': './src/recent-posts/recent-posts.js',
31 | // 'hello-world': './src/hello-world/hello-world.js'
32 | // },
33 | output: {
34 | path: path.resolve(__dirname, 'blocks'),
35 | filename: '[name]/[name].build.js'
36 | },
37 | module: {
38 | rules: [{
39 | test: /\.editor.css$/,
40 | use: editorExtractTextPlugin.extract({
41 | fallback: 'style-loader',
42 | use: 'css-loader'
43 | })
44 | },
45 | {
46 | test: /\.view.css$/,
47 | use: viewExtractTextPlugin.extract({
48 | fallback: 'style-loader',
49 | use: 'css-loader'
50 | })
51 | },
52 | {
53 | test: /\.editor.scss$/,
54 | use: editorExtractTextPlugin.extract({
55 | use: [{
56 | loader: 'css-loader'
57 | }, {
58 | loader: 'sass-loader'
59 | }],
60 | fallback: 'style-loader'
61 | })
62 | },
63 | {
64 | test: /\.view.scss$/,
65 | use: viewExtractTextPlugin.extract({
66 | use: [{
67 | loader: 'css-loader'
68 | }, {
69 | loader: 'sass-loader'
70 | }],
71 | fallback: 'style-loader'
72 | })
73 | },
74 | {
75 | test: /\.jsx?$/,
76 | loader: 'babel-loader'
77 | }
78 | ]
79 | },
80 | plugins: [
81 | editorExtractTextPlugin,
82 | viewExtractTextPlugin
83 | ],
84 | stats: {
85 | colors: true
86 | }
87 | },
88 | // Config for view javacsript files
89 | {
90 | entry: function () {
91 | /*
92 | function to map globs to appropriate entries for separate build files
93 | object that is returned looks like:
94 | {
95 | block-name: 'src/block-name/block-name.js',
96 | ...
97 | }
98 | */
99 | let entriesObject = {}
100 | glob.sync("./src/**/*.view.js").map((el) => {
101 | let path = el;
102 | let name = el.split('/').pop().split('.')[0];
103 | entriesObject[name] = path;
104 | })
105 | return entriesObject;
106 | },
107 | output: {
108 | path: path.resolve(__dirname, 'blocks'),
109 | filename: '[name]/[name].view.js'
110 | },
111 | module: {
112 | rules: [{
113 | test: /.view.js/,
114 | loader: 'babel-loader'
115 | }]
116 | },
117 | stats: {
118 | colors: true
119 | }
120 |
121 | }
122 | ];
--------------------------------------------------------------------------------