Version Description
- Initial Release
Download this release
Release Info
Developer | obenland |
Plugin | Full Site Editing |
Version | 0.1 |
Comparing to | |
See all releases |
Version 0.1
- full-site-editing-plugin.php +45 -0
- posts-list-block/blocks/posts-list/block.json +10 -0
- posts-list-block/blocks/posts-list/index.js +64 -0
- posts-list-block/blocks/posts-list/style.scss +9 -0
- posts-list-block/class-posts-list-block.php +147 -0
- posts-list-block/dist/posts-list-block.css +1 -0
- posts-list-block/dist/posts-list-block.deps.json +1 -0
- posts-list-block/dist/posts-list-block.js +1 -0
- posts-list-block/dist/posts-list-block.rtl.css +1 -0
- posts-list-block/index.js +4 -0
- posts-list-block/templates/no-posts.php +26 -0
- posts-list-block/templates/post-item.php +42 -0
- posts-list-block/templates/posts-list.php +39 -0
- posts-list-block/utils.php +46 -0
- readme.txt +44 -0
- starter-page-templates/class-starter-page-templates.php +134 -0
- starter-page-templates/dist/starter-page-templates.css +1 -0
- starter-page-templates/dist/starter-page-templates.deps.json +1 -0
- starter-page-templates/dist/starter-page-templates.js +12 -0
- starter-page-templates/dist/starter-page-templates.rtl.css +1 -0
- starter-page-templates/index.js +4 -0
- starter-page-templates/page-template-modal/components/template-selector-control.js +62 -0
- starter-page-templates/page-template-modal/index.js +93 -0
- starter-page-templates/page-template-modal/styles/starter-page-templates-editor.scss +121 -0
- starter-page-templates/page-template-modal/utils/replace-placeholders.js +23 -0
full-site-editing-plugin.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin Name: Full Site Editing
|
4 |
+
* Description: Enhances your page creation workflow within the Block Editor.
|
5 |
+
* Version: 0.1
|
6 |
+
* Author: Automattic
|
7 |
+
* Author URI: https://automattic.com/wordpress-plugins/
|
8 |
+
* License: GPLv2 or later
|
9 |
+
* Text Domain: full-site-editing
|
10 |
+
*
|
11 |
+
* @package full-site-editing
|
12 |
+
*/
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Load Posts List Block.
|
16 |
+
*/
|
17 |
+
function a8c_load_posts_list_block() {
|
18 |
+
if ( function_exists( 'is_automattician' ) && ! is_automattician() ) {
|
19 |
+
return;
|
20 |
+
}
|
21 |
+
|
22 |
+
if ( class_exists( 'Posts_List_Block' ) ) {
|
23 |
+
return;
|
24 |
+
}
|
25 |
+
|
26 |
+
require_once __DIR__ . '/posts-list-block/utils.php';
|
27 |
+
require_once __DIR__ . '/posts-list-block/class-posts-list-block.php';
|
28 |
+
|
29 |
+
Posts_List_Block::get_instance();
|
30 |
+
}
|
31 |
+
add_action( 'plugins_loaded', 'a8c_load_posts_list_block' );
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Load Starter_Page_Templates.
|
35 |
+
*/
|
36 |
+
function a8c_load_starter_page_templates() {
|
37 |
+
if ( function_exists( 'is_automattician' ) && ! is_automattician() ) {
|
38 |
+
return;
|
39 |
+
}
|
40 |
+
|
41 |
+
require_once __DIR__ . '/starter-page-templates/class-starter-page-templates.php';
|
42 |
+
|
43 |
+
Starter_Page_Templates::get_instance();
|
44 |
+
}
|
45 |
+
add_action( 'plugins_loaded', 'a8c_load_starter_page_templates' );
|
posts-list-block/blocks/posts-list/block.json
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "a8c/posts-list",
|
3 |
+
"category": "layout",
|
4 |
+
"attributes": {
|
5 |
+
"postsPerPage": {
|
6 |
+
"type": "number",
|
7 |
+
"default": 10
|
8 |
+
}
|
9 |
+
}
|
10 |
+
}
|
posts-list-block/blocks/posts-list/index.js
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* WordPress dependencies
|
3 |
+
*/
|
4 |
+
import { registerBlockType } from '@wordpress/blocks';
|
5 |
+
import { __ } from '@wordpress/i18n';
|
6 |
+
import { Placeholder, RangeControl, PanelBody } from '@wordpress/components';
|
7 |
+
import { Fragment } from '@wordpress/element';
|
8 |
+
import { InspectorControls } from '@wordpress/editor';
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Internal dependencies
|
12 |
+
*/
|
13 |
+
import * as metadata from './block.json';
|
14 |
+
import './style.scss';
|
15 |
+
|
16 |
+
const icon = (
|
17 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
18 |
+
<path opacity=".87" fill="none" d="M0 0h24v24H0V0z" />
|
19 |
+
<path d="M3 5v14h17V5H3zm4 2v2H5V7h2zm-2 6v-2h2v2H5zm0 2h2v2H5v-2zm13 2H9v-2h9v2zm0-4H9v-2h9v2zm0-4H9V7h9v2z" />
|
20 |
+
</svg>
|
21 |
+
);
|
22 |
+
|
23 |
+
registerBlockType( metadata.name, {
|
24 |
+
title: __( 'Blog Posts Listing', 'full-site-editing' ),
|
25 |
+
description: __( 'Displays your latest Blog Posts.', 'full-site-editing' ),
|
26 |
+
icon: icon,
|
27 |
+
category: 'layout',
|
28 |
+
supports: {
|
29 |
+
html: false,
|
30 |
+
multiple: false,
|
31 |
+
reusable: false,
|
32 |
+
},
|
33 |
+
attributes: metadata.attributes,
|
34 |
+
edit: ( { attributes, setAttributes, isSelected } ) => (
|
35 |
+
<Fragment>
|
36 |
+
<Placeholder
|
37 |
+
icon={ icon }
|
38 |
+
label={ __( 'Your recent blog posts will be displayed here.', 'full-site-editing' ) }
|
39 |
+
>
|
40 |
+
{ isSelected ? (
|
41 |
+
<RangeControl
|
42 |
+
label={ __( 'Number of posts to show', 'full-site-editing' ) }
|
43 |
+
value={ attributes.postsPerPage }
|
44 |
+
onChange={ val => setAttributes( { postsPerPage: val } ) }
|
45 |
+
min={ 1 }
|
46 |
+
max={ 50 }
|
47 |
+
/>
|
48 |
+
) : null }
|
49 |
+
</Placeholder>
|
50 |
+
<InspectorControls>
|
51 |
+
<PanelBody>
|
52 |
+
<RangeControl
|
53 |
+
label={ __( 'Number of posts', 'full-site-editing' ) }
|
54 |
+
value={ attributes.postsPerPage }
|
55 |
+
onChange={ val => setAttributes( { postsPerPage: val } ) }
|
56 |
+
min={ 1 }
|
57 |
+
max={ 50 }
|
58 |
+
/>
|
59 |
+
</PanelBody>
|
60 |
+
</InspectorControls>
|
61 |
+
</Fragment>
|
62 |
+
),
|
63 |
+
save: () => null,
|
64 |
+
} );
|
posts-list-block/blocks/posts-list/style.scss
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.a8c-posts-list__listing {
|
2 |
+
list-style: none;
|
3 |
+
margin: 0;
|
4 |
+
padding: 0;
|
5 |
+
}
|
6 |
+
|
7 |
+
.a8c-posts-list__item {
|
8 |
+
display: block;
|
9 |
+
}
|
posts-list-block/class-posts-list-block.php
ADDED
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Posts list block file.
|
4 |
+
*
|
5 |
+
* @package full-site-editing
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Post_List_Block
|
10 |
+
*/
|
11 |
+
class Posts_List_Block {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class instance.
|
15 |
+
*
|
16 |
+
* @var Posts_List_Block
|
17 |
+
*/
|
18 |
+
private static $instance = null;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* A8C_Post_List constructor.
|
22 |
+
*/
|
23 |
+
private function __construct() {
|
24 |
+
add_action( 'init', array( $this, 'register_blocks' ), 100 );
|
25 |
+
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_scripts' ), 100 );
|
26 |
+
add_action( 'enqueue_block_assets', array( $this, 'enqueue_styles' ), 100 );
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Creates instance.
|
31 |
+
*
|
32 |
+
* @return \Posts_List_Block
|
33 |
+
*/
|
34 |
+
public static function get_instance() {
|
35 |
+
if ( null === self::$instance ) {
|
36 |
+
self::$instance = new self();
|
37 |
+
}
|
38 |
+
|
39 |
+
return self::$instance;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Enqueue block editor scripts.
|
44 |
+
*/
|
45 |
+
public function enqueue_scripts() {
|
46 |
+
// phpcs:ignore WordPress
|
47 |
+
$script_dependencies = json_decode(
|
48 |
+
file_get_contents(
|
49 |
+
plugin_dir_path( __FILE__ ) . 'dist/posts-list-block.deps.json'
|
50 |
+
),
|
51 |
+
true
|
52 |
+
);
|
53 |
+
wp_enqueue_script(
|
54 |
+
'a8c-posts-list-script',
|
55 |
+
plugins_url( 'dist/posts-list-block.js', __FILE__ ),
|
56 |
+
is_array( $script_dependencies ) ? $script_dependencies : array(),
|
57 |
+
filemtime( plugin_dir_path( __FILE__ ) . 'dist/posts-list-block.js' ),
|
58 |
+
true
|
59 |
+
);
|
60 |
+
wp_set_script_translations( 'a8c-posts-list-script', 'full-site-editing' );
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Enqueue block styles.
|
65 |
+
*/
|
66 |
+
public function enqueue_styles() {
|
67 |
+
$style_file = is_rtl()
|
68 |
+
? 'posts-list-block.rtl.css'
|
69 |
+
: 'posts-list-block.css';
|
70 |
+
wp_enqueue_style(
|
71 |
+
'posts-list-block-style',
|
72 |
+
plugins_url( 'dist/' . $style_file, __FILE__ ),
|
73 |
+
array(),
|
74 |
+
filemtime( plugin_dir_path( __FILE__ ) . 'dist/' . $style_file )
|
75 |
+
);
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Register block.
|
80 |
+
*/
|
81 |
+
public function register_blocks() {
|
82 |
+
register_block_type(
|
83 |
+
'a8c/posts-list',
|
84 |
+
array(
|
85 |
+
'attributes' => array(
|
86 |
+
'postsPerPage' => array(
|
87 |
+
'type' => 'number',
|
88 |
+
'default' => 10,
|
89 |
+
),
|
90 |
+
),
|
91 |
+
'render_callback' => array( $this, 'render_a8c_post_list_block' ),
|
92 |
+
)
|
93 |
+
);
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Renders posts list.
|
98 |
+
*
|
99 |
+
* @param array $attributes Block attributes.
|
100 |
+
* @param string $content Block content.
|
101 |
+
* @return string
|
102 |
+
*/
|
103 |
+
public function render_a8c_post_list_block( $attributes, $content ) {
|
104 |
+
$posts_list = new WP_Query(
|
105 |
+
array(
|
106 |
+
'post_type' => 'post',
|
107 |
+
'posts_per_page' => $attributes['postsPerPage'],
|
108 |
+
'post_status' => 'publish',
|
109 |
+
'suppress_filters' => false,
|
110 |
+
)
|
111 |
+
);
|
112 |
+
|
113 |
+
add_filter( 'excerpt_more', array( $this, 'custom_excerpt_read_more' ) );
|
114 |
+
|
115 |
+
$content = a8c_pl_render_template(
|
116 |
+
'posts-list',
|
117 |
+
array(
|
118 |
+
'posts_list' => $posts_list,
|
119 |
+
)
|
120 |
+
);
|
121 |
+
|
122 |
+
remove_filter( 'excerpt_more', array( $this, 'custom_excerpt_read_more' ) );
|
123 |
+
|
124 |
+
// Reset the custom query.
|
125 |
+
wp_reset_postdata();
|
126 |
+
|
127 |
+
return $content;
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Excerpt more string.
|
132 |
+
*
|
133 |
+
* @return string More string.
|
134 |
+
*/
|
135 |
+
public function custom_excerpt_read_more() {
|
136 |
+
return sprintf(
|
137 |
+
'… <a href="%1$s" title="%2$s" class="a8c-posts-list-item__read-more">%3$s</a>',
|
138 |
+
esc_url( get_the_permalink() ),
|
139 |
+
sprintf(
|
140 |
+
/* translators: %s: Name of current post */
|
141 |
+
esc_attr__( 'Continue reading %s', 'full-site-editing' ),
|
142 |
+
the_title_attribute( array( 'echo' => false ) )
|
143 |
+
),
|
144 |
+
esc_html__( 'Read more', 'full-site-editing' )
|
145 |
+
);
|
146 |
+
}
|
147 |
+
}
|
posts-list-block/dist/posts-list-block.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.a8c-posts-list__listing{list-style:none;margin:0;padding:0}.a8c-posts-list__item{display:block}
|
posts-list-block/dist/posts-list-block.deps.json
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
["wp-blocks","wp-components","wp-editor","wp-element","wp-i18n"]
|
posts-list-block/dist/posts-list-block.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=8)}([function(e,t){e.exports=wp.element},function(e,t){e.exports=wp.i18n},function(e,t){e.exports=wp.components},function(e){e.exports={b:"a8c/posts-list",a:{postsPerPage:{type:"number",default:10}}}},function(e,t){e.exports=wp.blocks},function(e,t){e.exports=wp.editor},function(e,t,n){},,function(e,t,n){"use strict";n.r(t);var r=n(0),o=n(4),l=n(1),i=n(2),u=n(5),c=n(3),s=(n(6),Object(r.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},Object(r.createElement)("path",{opacity:".87",fill:"none",d:"M0 0h24v24H0V0z"}),Object(r.createElement)("path",{d:"M3 5v14h17V5H3zm4 2v2H5V7h2zm-2 6v-2h2v2H5zm0 2h2v2H5v-2zm13 2H9v-2h9v2zm0-4H9v-2h9v2zm0-4H9V7h9v2z"})));Object(o.registerBlockType)(c.b,{title:Object(l.__)("Blog Posts Listing","full-site-editing"),description:Object(l.__)("Displays your latest Blog Posts.","full-site-editing"),icon:s,category:"layout",supports:{html:!1,multiple:!1,reusable:!1},attributes:c.a,edit:function(e){var t=e.attributes,n=e.setAttributes,o=e.isSelected;return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(i.Placeholder,{icon:s,label:Object(l.__)("Your recent blog posts will be displayed here.","full-site-editing")},o?Object(r.createElement)(i.RangeControl,{label:Object(l.__)("Number of posts to show","full-site-editing"),value:t.postsPerPage,onChange:function(e){return n({postsPerPage:e})},min:1,max:50}):null),Object(r.createElement)(u.InspectorControls,null,Object(r.createElement)(i.PanelBody,null,Object(r.createElement)(i.RangeControl,{label:Object(l.__)("Number of posts","full-site-editing"),value:t.postsPerPage,onChange:function(e){return n({postsPerPage:e})},min:1,max:50}))))},save:function(){return null}})}]));
|
posts-list-block/dist/posts-list-block.rtl.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.a8c-posts-list__listing{list-style:none;margin:0;padding:0}.a8c-posts-list__item{display:block}
|
posts-list-block/index.js
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Internal dependencies
|
3 |
+
*/
|
4 |
+
import './blocks/posts-list';
|
posts-list-block/templates/no-posts.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Template part for displaying a message that posts cannot be found.
|
4 |
+
*
|
5 |
+
* @package full-site-editing
|
6 |
+
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
|
7 |
+
*/
|
8 |
+
|
9 |
+
?>
|
10 |
+
|
11 |
+
<p><?php esc_html_e( 'There are currently no posts to display.', 'full-site-editing' ); ?></p>
|
12 |
+
<?php
|
13 |
+
if ( current_user_can( 'publish_posts' ) ) :
|
14 |
+
printf(
|
15 |
+
'<p>' . wp_kses(
|
16 |
+
/* translators: 1: link to WP admin new post page. */
|
17 |
+
__( 'Ready to publish your first post? <a href="%1$s">Get started here</a>.', 'full-site-editing' ),
|
18 |
+
array(
|
19 |
+
'a' => array(
|
20 |
+
'href' => array(),
|
21 |
+
),
|
22 |
+
)
|
23 |
+
) . '</p>',
|
24 |
+
esc_url( admin_url( 'post-new.php' ) )
|
25 |
+
);
|
26 |
+
endif;
|
posts-list-block/templates/post-item.php
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Post Item.
|
4 |
+
*
|
5 |
+
* @package full-site-editing
|
6 |
+
*
|
7 |
+
* phpcs:disable WordPress.XSS.EscapeOutput.OutputNotEscaped
|
8 |
+
*/
|
9 |
+
|
10 |
+
?>
|
11 |
+
|
12 |
+
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
|
13 |
+
<?php if ( has_post_thumbnail() ) : ?>
|
14 |
+
<figure class="a8c-posts-list-item__post-thumbnail">
|
15 |
+
<a href="<?php the_permalink(); ?>">
|
16 |
+
<?php the_post_thumbnail( 'post-thumbnail' ); ?>
|
17 |
+
</a>
|
18 |
+
</figure>
|
19 |
+
<?php endif; // has_post_thumbnail. ?>
|
20 |
+
|
21 |
+
<?php if ( is_sticky() ) : ?>
|
22 |
+
<div class="a8c-posts-list-item__featured">
|
23 |
+
<span><?php esc_html_e( 'Featured', 'full-site-editing' ); ?></span>
|
24 |
+
</div>
|
25 |
+
<?php endif; // is_sticky. ?>
|
26 |
+
|
27 |
+
<?php the_title( sprintf( '<h2 class="a8c-posts-list-item__title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' ); ?>
|
28 |
+
|
29 |
+
<div class="a8c-posts-list-item__meta">
|
30 |
+
<span class="a8c-posts-list-item__datetime"><?php echo esc_html( get_the_time( get_option( 'date_format' ) ) ); ?></span>
|
31 |
+
<span class="a8c-posts-list-item__author"><?php echo esc_html_x( 'by', 'designating the post author (eg: by John Doe', 'full-site-editing' ); ?>
|
32 |
+
<?php the_author_posts_link(); ?>
|
33 |
+
</span>
|
34 |
+
<span class="a8c-posts-list-item__edit-link">
|
35 |
+
<a href="<?php echo esc_attr( get_edit_post_link() ); ?>"><?php esc_html_e( 'Edit', 'full-site-editing' ); ?></a>
|
36 |
+
</span>
|
37 |
+
</div>
|
38 |
+
|
39 |
+
<div class="a8c-posts-list-item__excerpt">
|
40 |
+
<?php the_excerpt(); ?>
|
41 |
+
</div>
|
42 |
+
</article>
|
posts-list-block/templates/posts-list.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Posts List
|
4 |
+
*
|
5 |
+
* @package full-site-editing
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Posts list.
|
10 |
+
*
|
11 |
+
* @global \WP_Query $posts_list
|
12 |
+
*/
|
13 |
+
global $posts_list;
|
14 |
+
|
15 |
+
if ( $posts_list instanceof WP_Query && $posts_list->have_posts() ) :
|
16 |
+
?>
|
17 |
+
<div class="a8c-posts-list">
|
18 |
+
<ul class="a8c-posts-list__listing">
|
19 |
+
<?php
|
20 |
+
while ( $posts_list->have_posts() ) :
|
21 |
+
$posts_list->the_post();
|
22 |
+
?>
|
23 |
+
<li class="a8c-posts-list__item">
|
24 |
+
<?php require dirname( __FILE__ ) . '/post-item.php'; ?>
|
25 |
+
</li>
|
26 |
+
<?php endwhile; ?>
|
27 |
+
</ul>
|
28 |
+
|
29 |
+
<a href="<?php echo esc_url( get_post_type_archive_link( 'post' ) ); ?>" class="a8c-posts-list__view-all">
|
30 |
+
<?php esc_html_e( 'View all posts', 'full-site-editing' ); ?>
|
31 |
+
</a>
|
32 |
+
</div>
|
33 |
+
<?php
|
34 |
+
else :
|
35 |
+
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
36 |
+
echo a8c_pl_render_template( 'no-posts' );
|
37 |
+
endif;
|
38 |
+
|
39 |
+
|
posts-list-block/utils.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Template functions.
|
4 |
+
*
|
5 |
+
* @package full-site-editing
|
6 |
+
*/
|
7 |
+
|
8 |
+
if ( ! function_exists( 'a8c_pl_render_template' ) ) {
|
9 |
+
/**
|
10 |
+
* OUTPUT BUFFERED LOAD TEMPLATE PART.
|
11 |
+
*
|
12 |
+
* Loads a given template using output buffering.
|
13 |
+
* Optionally including $data to be passed into template.
|
14 |
+
*
|
15 |
+
* @param string $template_name Name of the template to be located.
|
16 |
+
* @param array $data Optional. Associative array of data to be passed into the template. Default empty array.
|
17 |
+
* @return string
|
18 |
+
*/
|
19 |
+
function a8c_pl_render_template( $template_name, $data = array() ) {
|
20 |
+
|
21 |
+
if ( ! strpos( $template_name, '.php' ) ) {
|
22 |
+
$template_name = $template_name . '.php';
|
23 |
+
}
|
24 |
+
|
25 |
+
$template_file = __DIR__ . '/templates/' . $template_name;
|
26 |
+
|
27 |
+
if ( ! file_exists( $template_file ) ) {
|
28 |
+
return '';
|
29 |
+
}
|
30 |
+
|
31 |
+
// Optionally provided an assoc array of data to pass to template
|
32 |
+
// and it will be extracted into variables.
|
33 |
+
if ( is_array( $data ) ) {
|
34 |
+
foreach ( $data as $name => $value ) {
|
35 |
+
$GLOBALS[ $name ] = $value;
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
ob_start();
|
40 |
+
require_once $template_file;
|
41 |
+
$content = ob_get_contents();
|
42 |
+
ob_end_clean();
|
43 |
+
|
44 |
+
return $content;
|
45 |
+
}
|
46 |
+
}
|
readme.txt
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Full Site Editing ===
|
2 |
+
Contributors: automattic, get_dave, marekhrabe, mppfeiffer, obenland
|
3 |
+
Tags: block, blocks, editor, gutenberg, page
|
4 |
+
Requires at least: 5.0
|
5 |
+
Tested up to: 5.2
|
6 |
+
Stable tag: 0.1
|
7 |
+
Requires PHP: 5.6.20
|
8 |
+
License: GPLv2 or later
|
9 |
+
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
10 |
+
|
11 |
+
Enhances your page creation workflow within the Block Editor.
|
12 |
+
|
13 |
+
== Description ==
|
14 |
+
|
15 |
+
This plugin comes with a custom block to display a list of your most recent blog posts, as well as a template selector
|
16 |
+
to give you a head start on creating new pages for your site.
|
17 |
+
|
18 |
+
|
19 |
+
== Installation ==
|
20 |
+
|
21 |
+
1. Upload the plugin files to the `/wp-content/plugins/full-site-editing` directory, or install the plugin through the WordPress plugins screen directly.
|
22 |
+
1. Activate the plugin through the 'Plugins' screen in WordPress.
|
23 |
+
1. Create a new page and select a template that best suits your needs.
|
24 |
+
1. Place the "Blog Posts Listing" block anywhere you want inside the block editor.
|
25 |
+
|
26 |
+
|
27 |
+
== Frequently Asked Questions ==
|
28 |
+
|
29 |
+
= Can I use this plugin in production? =
|
30 |
+
|
31 |
+
We'll be making frequent updates to the plugin as we flesh out its feature set. You're welcome to try it, just be aware that it is only designed to work on the WordPress.com environment and could break after an update.
|
32 |
+
|
33 |
+
= How is the Blog Posts Listing block different from the Latest Posts block in Core? =
|
34 |
+
|
35 |
+
It adds an excerpt! And meta information! It really is much more useful, especially if your looking for a block that gives readers a better idea about your latest posts than just the title.
|
36 |
+
|
37 |
+
= Do you provide support for this plugin? =
|
38 |
+
|
39 |
+
This plugin is experimental, so we don't provide any support for it outside of websites hosted on WordPress.com at this time.
|
40 |
+
|
41 |
+
== Changelog ==
|
42 |
+
|
43 |
+
= 0.1 =
|
44 |
+
* Initial Release
|
starter-page-templates/class-starter-page-templates.php
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Starter page templates file.
|
4 |
+
*
|
5 |
+
* @package full-site-editing
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Starter_Page_Templates
|
10 |
+
*/
|
11 |
+
class Starter_Page_Templates {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class instance.
|
15 |
+
*
|
16 |
+
* @var Starter_Page_Templates
|
17 |
+
*/
|
18 |
+
private static $instance = null;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Starter_Page_Templates constructor.
|
22 |
+
*/
|
23 |
+
private function __construct() {
|
24 |
+
add_action( 'init', array( $this, 'register_scripts' ) );
|
25 |
+
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_assets' ) );
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Creates instance.
|
30 |
+
*
|
31 |
+
* @return \Starter_Page_Templates
|
32 |
+
*/
|
33 |
+
public static function get_instance() {
|
34 |
+
if ( null === self::$instance ) {
|
35 |
+
self::$instance = new self();
|
36 |
+
}
|
37 |
+
|
38 |
+
return self::$instance;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Register block editor scripts.
|
43 |
+
*/
|
44 |
+
public function register_scripts() {
|
45 |
+
wp_register_script(
|
46 |
+
'starter-page-templates',
|
47 |
+
plugins_url( 'dist/starter-page-templates.js', __FILE__ ),
|
48 |
+
array( 'wp-plugins', 'wp-edit-post', 'wp-element' ),
|
49 |
+
filemtime( plugin_dir_path( __FILE__ ) . 'dist/starter-page-templates.js' ),
|
50 |
+
true
|
51 |
+
);
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Enqueue block editor assets.
|
56 |
+
*/
|
57 |
+
public function enqueue_assets() {
|
58 |
+
$screen = get_current_screen();
|
59 |
+
|
60 |
+
// Return early if we don't meet conditions to show templates.
|
61 |
+
if ( 'page' !== $screen->id || 'add' !== $screen->action ) {
|
62 |
+
return;
|
63 |
+
}
|
64 |
+
|
65 |
+
// Load templates for this site.
|
66 |
+
$vertical_data = $this->fetch_vertical_data();
|
67 |
+
if ( empty( $vertical_data ) ) {
|
68 |
+
return;
|
69 |
+
}
|
70 |
+
$vertical_name = $vertical_data['vertical'];
|
71 |
+
$vertical_templates = $vertical_data['templates'];
|
72 |
+
|
73 |
+
// Bail early if we have no templates to offer.
|
74 |
+
if ( empty( $vertical_templates ) ) {
|
75 |
+
return;
|
76 |
+
}
|
77 |
+
|
78 |
+
wp_enqueue_script( 'starter-page-templates' );
|
79 |
+
|
80 |
+
$default_info = array(
|
81 |
+
'title' => get_bloginfo( 'name' ),
|
82 |
+
'vertical' => $vertical_name,
|
83 |
+
);
|
84 |
+
$default_templates = array(
|
85 |
+
array(
|
86 |
+
'title' => 'Blank',
|
87 |
+
'slug' => 'blank',
|
88 |
+
),
|
89 |
+
|
90 |
+
);
|
91 |
+
$site_info = get_option( 'site_contact_info', array() );
|
92 |
+
$config = array(
|
93 |
+
'siteInformation' => array_merge( $default_info, $site_info ),
|
94 |
+
'templates' => array_merge( $default_templates, $vertical_templates ),
|
95 |
+
);
|
96 |
+
wp_localize_script( 'starter-page-templates', 'starterPageTemplatesConfig', $config );
|
97 |
+
|
98 |
+
// Enqueue styles.
|
99 |
+
$style_file = is_rtl()
|
100 |
+
? 'starter-page-templates.rtl.css'
|
101 |
+
: 'starter-page-templates.css';
|
102 |
+
|
103 |
+
wp_enqueue_style(
|
104 |
+
'starter-page-templates',
|
105 |
+
plugins_url( 'dist/' . $style_file, __FILE__ ),
|
106 |
+
array(),
|
107 |
+
filemtime( plugin_dir_path( __FILE__ ) . 'dist/' . $style_file )
|
108 |
+
);
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Fetch vertical data from the API or return cached version if available.
|
113 |
+
*
|
114 |
+
* @return array Containing vertical name and template list or nothing if an error occurred.
|
115 |
+
*/
|
116 |
+
public function fetch_vertical_data() {
|
117 |
+
$vertical_id = get_option( 'site_vertical', 'default' );
|
118 |
+
$transient_key = 'starter_page_templates_' . $vertical_id;
|
119 |
+
$vertical_templates = get_transient( $transient_key );
|
120 |
+
|
121 |
+
// Load fresh data if we don't have any or vertical_id doesn't match.
|
122 |
+
if ( false === $vertical_templates ) {
|
123 |
+
$request_url = 'https://public-api.wordpress.com/wpcom/v2/verticals/' . $vertical_id . '/templates';
|
124 |
+
$response = wp_remote_get( esc_url_raw( $request_url ) );
|
125 |
+
if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
|
126 |
+
return array();
|
127 |
+
}
|
128 |
+
$vertical_templates = json_decode( wp_remote_retrieve_body( $response ), true );
|
129 |
+
set_transient( $transient_key, $vertical_templates, DAY_IN_SECONDS );
|
130 |
+
}
|
131 |
+
|
132 |
+
return $vertical_templates;
|
133 |
+
}
|
134 |
+
}
|
starter-page-templates/dist/starter-page-templates.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.page-template-modal{width:100%;height:100vh}@media screen and (min-width:783px){.page-template-modal{width:calc(100% - 65px);left:50px;transform:translateY(-50%)}}@media screen and (min-width:960px){.page-template-modal{width:calc(100% - 200px);left:180px}}.page-template-modal .components-modal__header-heading-container{justify-content:center}.page-template-modal__inner{max-width:700px;margin:0 auto;padding:1em 0 3em}.page-template-modal__intro{text-align:center}.page-template-modal__list{padding:1.5em 0}.page-template-modal__list .components-base-control__field{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));grid-gap:1.5em}.page-template-modal__list .components-base-control__label{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.page-template-modal__list .template-selector-control__label{display:block;width:100%;text-align:center;border:1px solid transparent;padding:2em;border-radius:4px;cursor:pointer}.page-template-modal__list .template-selector-control__label:hover{background:#f3f4f5}.page-template-modal__list .template-selector-control__label:focus{box-shadow:0 0 0 2px #00a0d2;outline:2px solid transparent;outline-offset:-2px}.page-template-modal__list .template-selector-control__media-wrap{width:100%;display:block;margin:0 auto 2em;border:1px solid rgba(25,30,35,.2);background:#f6f6f6;border-radius:4px;overflow:hidden;padding-bottom:90%;box-sizing:content-box;position:relative;pointer-events:none}.page-template-modal__list .template-selector-control__media{width:100%;display:block;position:absolute;top:0;left:0}.page-template-modal__actions{display:flex;flex-direction:column;align-items:center}@media screen and (min-width:960px){.page-template-modal__actions{flex-direction:row;justify-content:flex-end}}@media screen and (max-width:960px){.page-template-modal__action{margin-bottom:1em}}@media screen and (min-width:960px){.page-template-modal__action-use{margin-right:1em}}
|
starter-page-templates/dist/starter-page-templates.deps.json
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
["lodash","wp-components","wp-compose","wp-element"]
|
starter-page-templates/dist/starter-page-templates.js
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
!function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=7)}([function(e,t){e.exports=wp.element},function(e,t){e.exports=lodash},function(e,t,n){var r;
|
2 |
+
/*!
|
3 |
+
Copyright (c) 2017 Jed Watson.
|
4 |
+
Licensed under the MIT License (MIT), see
|
5 |
+
http://jedwatson.github.io/classnames
|
6 |
+
*/
|
7 |
+
/*!
|
8 |
+
Copyright (c) 2017 Jed Watson.
|
9 |
+
Licensed under the MIT License (MIT), see
|
10 |
+
http://jedwatson.github.io/classnames
|
11 |
+
*/
|
12 |
+
!function(){"use strict";var n={}.hasOwnProperty;function a(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof r;if("string"===o||"number"===o)e.push(r);else if(Array.isArray(r)&&r.length){var l=a.apply(null,r);l&&e.push(l)}else if("object"===o)for(var c in r)n.call(r,c)&&r[c]&&e.push(c)}}return e.join(" ")}e.exports?(a.default=a,e.exports=a):void 0===(r=function(){return a}.apply(t,[]))||(e.exports=r)}()},function(e,t){e.exports=wp.compose},function(e,t){e.exports=wp.components},function(e,t,n){},,function(e,t,n){"use strict";n.r(t);var r,a=n(0),o={Address:"123 Main St",Phone:"555-555-5555",CompanyName:(r="Your Company Name",r)},l={CompanyName:"title",Address:"address",Phone:"phone"},c=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.replace(/{{(\w+)}}/g,function(e,n){var r=o[n];return t[l[n]]||r||n})},s=(n(5),n(1)),i=n(2),p=n.n(i),u=n(3),m=n(4);var f=Object(u.withInstanceId)(function(e){var t=e.label,n=e.className,r=e.help,o=e.instanceId,l=e.onClick,c=e.templates,i=void 0===c?[]:c,u="inspector-radio-control-".concat(o),f=function(e){return l(e.target.value)};return Object(s.isEmpty)(i)?null:Object(a.createElement)(m.BaseControl,{label:t,id:u,help:r,className:p()(n,"template-selector-control")},i.map(function(e,t){return Object(a.createElement)("div",{key:"".concat(u,"-").concat(t),className:"template-selector-control__option"},Object(a.createElement)("button",{type:"button",id:"".concat(u,"-").concat(t),className:"template-selector-control__label",value:e.value,onClick:f,"aria-describedby":r?"".concat(u,"__help"):void 0},Object(a.createElement)("div",{className:"template-selector-control__media-wrap"},e.preview&&Object(a.createElement)("img",{className:"template-selector-control__media",src:e.preview,alt:"Preview of "+e.label})),e.label))}))});if(window.starterPageTemplatesConfig){var d={home:"https://starterpagetemplatesprototype.files.wordpress.com/2019/05/starter-home-2.png",menu:"https://starterpagetemplatesprototype.files.wordpress.com/2019/05/starter-menu-2.png","contact-us":"https://starterpagetemplatesprototype.files.wordpress.com/2019/05/starter-contactus-2.png"};window.starterPageTemplatesConfig.templates=Object(s.map)(window.starterPageTemplatesConfig.templates,function(e){return e.preview=d[e.slug],e})}!function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.plugins.registerPlugin,r=e.components.Modal,o=e.compose.withState,l=t.siteInformation,i=void 0===l?{}:l,p=t.templates,u=void 0===p?[]:p,m=o({isOpen:!0,isLoading:!1,verticalTemplates:Object(s.keyBy)(u,"slug")})(function(t){var n=t.isOpen,o=t.verticalTemplates,l=t.setState;return Object(a.createElement)("div",null,n&&Object(a.createElement)(r,{title:"Select Page Template",onRequestClose:function(){return l({isOpen:!1})},className:"page-template-modal"},Object(a.createElement)("div",{className:"page-template-modal__inner"},Object(a.createElement)("div",{className:"page-template-modal__intro"},Object(a.createElement)("p",null,"Pick a Template that matches the purpose of your page."),Object(a.createElement)("p",null,"You can customise each Template to meet your needs.")),Object(a.createElement)("form",{className:"page-template-modal__form"},Object(a.createElement)("fieldset",{className:"page-template-modal__list"},Object(a.createElement)(f,{label:"Template",templates:Object.values(o).map(function(e){return{label:e.title,value:e.slug,preview:e.preview}}),onClick:function(t){l({isOpen:!1}),function(t){if(Object(s.has)(t,"content")){e.data.dispatch("core/editor").editPost({title:c(t.title,i)});var n=c(t.content,i),r=e.blocks.parse(n);e.data.dispatch("core/editor").insertBlocks(r)}}(o[t])}}))))))});n("page-templates",{render:function(){return Object(a.createElement)(m,null)}})}(window.wp,window.starterPageTemplatesConfig)}]));
|
starter-page-templates/dist/starter-page-templates.rtl.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.page-template-modal{width:100%;height:100vh}@media screen and (min-width:783px){.page-template-modal{width:calc(100% - 65px);right:50px;transform:translateY(-50%)}}@media screen and (min-width:960px){.page-template-modal{width:calc(100% - 200px);right:180px}}.page-template-modal .components-modal__header-heading-container{justify-content:center}.page-template-modal__inner{max-width:700px;margin:0 auto;padding:1em 0 3em}.page-template-modal__intro{text-align:center}.page-template-modal__list{padding:1.5em 0}.page-template-modal__list .components-base-control__field{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));grid-gap:1.5em}.page-template-modal__list .components-base-control__label{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.page-template-modal__list .template-selector-control__label{display:block;width:100%;text-align:center;border:1px solid transparent;padding:2em;border-radius:4px;cursor:pointer}.page-template-modal__list .template-selector-control__label:hover{background:#f3f4f5}.page-template-modal__list .template-selector-control__label:focus{box-shadow:0 0 0 2px #00a0d2;outline:2px solid transparent;outline-offset:-2px}.page-template-modal__list .template-selector-control__media-wrap{width:100%;display:block;margin:0 auto 2em;border:1px solid rgba(25,30,35,.2);background:#f6f6f6;border-radius:4px;overflow:hidden;padding-bottom:90%;box-sizing:content-box;position:relative;pointer-events:none}.page-template-modal__list .template-selector-control__media{width:100%;display:block;position:absolute;top:0;right:0}.page-template-modal__actions{display:flex;flex-direction:column;align-items:center}@media screen and (min-width:960px){.page-template-modal__actions{flex-direction:row;justify-content:flex-end}}@media screen and (max-width:960px){.page-template-modal__action{margin-bottom:1em}}@media screen and (min-width:960px){.page-template-modal__action-use{margin-left:1em}}
|
starter-page-templates/index.js
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Internal dependencies
|
3 |
+
*/
|
4 |
+
import './page-template-modal';
|
starter-page-templates/page-template-modal/components/template-selector-control.js
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* External dependencies
|
3 |
+
*/
|
4 |
+
import { isEmpty } from 'lodash';
|
5 |
+
import classnames from 'classnames';
|
6 |
+
|
7 |
+
/**
|
8 |
+
* WordPress dependencies
|
9 |
+
*/
|
10 |
+
import { withInstanceId } from '@wordpress/compose';
|
11 |
+
import { BaseControl } from '@wordpress/components';
|
12 |
+
|
13 |
+
function TemplateSelectorControl( {
|
14 |
+
label,
|
15 |
+
className,
|
16 |
+
help,
|
17 |
+
instanceId,
|
18 |
+
onClick,
|
19 |
+
templates = [],
|
20 |
+
} ) {
|
21 |
+
const id = `inspector-radio-control-${ instanceId }`;
|
22 |
+
const handleButtonClick = event => onClick( event.target.value );
|
23 |
+
|
24 |
+
if ( isEmpty( templates ) ) {
|
25 |
+
return null;
|
26 |
+
}
|
27 |
+
|
28 |
+
return (
|
29 |
+
<BaseControl
|
30 |
+
label={ label }
|
31 |
+
id={ id }
|
32 |
+
help={ help }
|
33 |
+
className={ classnames( className, 'template-selector-control' ) }
|
34 |
+
>
|
35 |
+
{ templates.map( ( option, index ) => (
|
36 |
+
<div key={ `${ id }-${ index }` } className="template-selector-control__option">
|
37 |
+
<button
|
38 |
+
type="button"
|
39 |
+
id={ `${ id }-${ index }` }
|
40 |
+
className="template-selector-control__label"
|
41 |
+
value={ option.value }
|
42 |
+
onClick={ handleButtonClick }
|
43 |
+
aria-describedby={ help ? `${ id }__help` : undefined }
|
44 |
+
>
|
45 |
+
<div className="template-selector-control__media-wrap">
|
46 |
+
{ option.preview && (
|
47 |
+
<img
|
48 |
+
className="template-selector-control__media"
|
49 |
+
src={ option.preview }
|
50 |
+
alt={ 'Preview of ' + option.label }
|
51 |
+
/>
|
52 |
+
) }
|
53 |
+
</div>
|
54 |
+
{ option.label }
|
55 |
+
</button>
|
56 |
+
</div>
|
57 |
+
) ) }
|
58 |
+
</BaseControl>
|
59 |
+
);
|
60 |
+
}
|
61 |
+
|
62 |
+
export default withInstanceId( TemplateSelectorControl );
|
starter-page-templates/page-template-modal/index.js
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Internal dependencies
|
3 |
+
*/
|
4 |
+
import replacePlaceholders from './utils/replace-placeholders';
|
5 |
+
import './styles/starter-page-templates-editor.scss';
|
6 |
+
import TemplateSelectorControl from './components/template-selector-control';
|
7 |
+
import { keyBy, map, has } from 'lodash';
|
8 |
+
|
9 |
+
// TODO: remove once we have proper previews from API
|
10 |
+
if ( window.starterPageTemplatesConfig ) {
|
11 |
+
const PREVIEWS_BY_SLUG = {
|
12 |
+
home: 'https://starterpagetemplatesprototype.files.wordpress.com/2019/05/starter-home-2.png',
|
13 |
+
menu: 'https://starterpagetemplatesprototype.files.wordpress.com/2019/05/starter-menu-2.png',
|
14 |
+
'contact-us':
|
15 |
+
'https://starterpagetemplatesprototype.files.wordpress.com/2019/05/starter-contactus-2.png',
|
16 |
+
};
|
17 |
+
window.starterPageTemplatesConfig.templates = map(
|
18 |
+
window.starterPageTemplatesConfig.templates,
|
19 |
+
template => {
|
20 |
+
template.preview = PREVIEWS_BY_SLUG[ template.slug ];
|
21 |
+
return template;
|
22 |
+
}
|
23 |
+
);
|
24 |
+
}
|
25 |
+
|
26 |
+
( function( wp, config = {} ) {
|
27 |
+
const registerPlugin = wp.plugins.registerPlugin;
|
28 |
+
const { Modal } = wp.components;
|
29 |
+
const { withState } = wp.compose;
|
30 |
+
|
31 |
+
const { siteInformation = {}, templates = [] } = config;
|
32 |
+
|
33 |
+
const insertTemplate = template => {
|
34 |
+
// Skip inserting if there's nothing to insert.
|
35 |
+
if ( ! has( template, 'content' ) ) {
|
36 |
+
return;
|
37 |
+
}
|
38 |
+
|
39 |
+
// set title
|
40 |
+
wp.data
|
41 |
+
.dispatch( 'core/editor' )
|
42 |
+
.editPost( { title: replacePlaceholders( template.title, siteInformation ) } );
|
43 |
+
|
44 |
+
// load content
|
45 |
+
const templateString = replacePlaceholders( template.content, siteInformation );
|
46 |
+
const blocks = wp.blocks.parse( templateString );
|
47 |
+
wp.data.dispatch( 'core/editor' ).insertBlocks( blocks );
|
48 |
+
};
|
49 |
+
|
50 |
+
const PageTemplateModal = withState( {
|
51 |
+
isOpen: true,
|
52 |
+
isLoading: false,
|
53 |
+
verticalTemplates: keyBy( templates, 'slug' ),
|
54 |
+
} )( ( { isOpen, verticalTemplates, setState } ) => (
|
55 |
+
<div>
|
56 |
+
{ isOpen && (
|
57 |
+
<Modal
|
58 |
+
title="Select Page Template"
|
59 |
+
onRequestClose={ () => setState( { isOpen: false } ) }
|
60 |
+
className="page-template-modal"
|
61 |
+
>
|
62 |
+
<div className="page-template-modal__inner">
|
63 |
+
<div className="page-template-modal__intro">
|
64 |
+
<p>Pick a Template that matches the purpose of your page.</p>
|
65 |
+
<p>You can customise each Template to meet your needs.</p>
|
66 |
+
</div>
|
67 |
+
<form className="page-template-modal__form">
|
68 |
+
<fieldset className="page-template-modal__list">
|
69 |
+
<TemplateSelectorControl
|
70 |
+
label="Template"
|
71 |
+
templates={ Object.values( verticalTemplates ).map( template => ( {
|
72 |
+
label: template.title,
|
73 |
+
value: template.slug,
|
74 |
+
preview: template.preview,
|
75 |
+
} ) ) }
|
76 |
+
onClick={ newTemplate => {
|
77 |
+
setState( { isOpen: false } );
|
78 |
+
insertTemplate( verticalTemplates[ newTemplate ] );
|
79 |
+
} }
|
80 |
+
/>
|
81 |
+
</fieldset>
|
82 |
+
</form>
|
83 |
+
</div>
|
84 |
+
</Modal>
|
85 |
+
) }
|
86 |
+
</div>
|
87 |
+
) );
|
88 |
+
registerPlugin( 'page-templates', {
|
89 |
+
render: function() {
|
90 |
+
return <PageTemplateModal />;
|
91 |
+
},
|
92 |
+
} );
|
93 |
+
} )( window.wp, window.starterPageTemplatesConfig );
|
starter-page-templates/page-template-modal/styles/starter-page-templates-editor.scss
ADDED
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@mixin screen-reader-text() {
|
2 |
+
border: 0;
|
3 |
+
clip: rect( 1px, 1px, 1px, 1px );
|
4 |
+
clip-path: inset( 50% );
|
5 |
+
height: 1px;
|
6 |
+
margin: -1px;
|
7 |
+
overflow: hidden;
|
8 |
+
padding: 0;
|
9 |
+
position: absolute;
|
10 |
+
width: 1px;
|
11 |
+
word-wrap: normal !important;
|
12 |
+
}
|
13 |
+
.page-template-modal {
|
14 |
+
width: 100%;
|
15 |
+
height: 100vh;
|
16 |
+
|
17 |
+
@media screen and ( min-width: 783px ) {
|
18 |
+
width: calc( 100% - 65px );
|
19 |
+
left: 50px;
|
20 |
+
transform: translateY( -50% );
|
21 |
+
}
|
22 |
+
|
23 |
+
@media screen and ( min-width: 960px ) {
|
24 |
+
width: calc( 100% - 200px );
|
25 |
+
left: 180px;
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
.page-template-modal .components-modal__header-heading-container {
|
30 |
+
justify-content: center;
|
31 |
+
}
|
32 |
+
|
33 |
+
.page-template-modal__inner {
|
34 |
+
max-width: 700px;
|
35 |
+
margin: 0 auto;
|
36 |
+
padding: 1em 0 3em;
|
37 |
+
}
|
38 |
+
|
39 |
+
.page-template-modal__intro {
|
40 |
+
text-align: center;
|
41 |
+
}
|
42 |
+
|
43 |
+
.page-template-modal__list {
|
44 |
+
padding: 1.5em 0;
|
45 |
+
|
46 |
+
.components-base-control__field {
|
47 |
+
display: grid;
|
48 |
+
// stylelint-disable-next-line unit-whitelist
|
49 |
+
grid-template-columns: repeat( auto-fit, minmax( 200px, 1fr ) );
|
50 |
+
grid-gap: 1.5em;
|
51 |
+
}
|
52 |
+
|
53 |
+
.components-base-control__label {
|
54 |
+
@include screen-reader-text();
|
55 |
+
}
|
56 |
+
|
57 |
+
.template-selector-control__label {
|
58 |
+
display: block;
|
59 |
+
width: 100%;
|
60 |
+
text-align: center;
|
61 |
+
border: 1px solid transparent;
|
62 |
+
padding: 2em;
|
63 |
+
border-radius: 4px;
|
64 |
+
cursor: pointer;
|
65 |
+
|
66 |
+
&:hover {
|
67 |
+
background: #f3f4f5;
|
68 |
+
}
|
69 |
+
|
70 |
+
&:focus {
|
71 |
+
box-shadow: 0 0 0 2px #00a0d2;
|
72 |
+
outline: 2px solid transparent;
|
73 |
+
outline-offset: -2px;
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
.template-selector-control__media-wrap {
|
78 |
+
width: 100%;
|
79 |
+
display: block;
|
80 |
+
margin: 0 auto 2em;
|
81 |
+
border: 1px solid rgba( 25, 30, 35, 0.2 );
|
82 |
+
background: #f6f6f6;
|
83 |
+
border-radius: 4px;
|
84 |
+
overflow: hidden;
|
85 |
+
padding-bottom: 90%;
|
86 |
+
box-sizing: content-box;
|
87 |
+
position: relative;
|
88 |
+
pointer-events: none;
|
89 |
+
}
|
90 |
+
|
91 |
+
.template-selector-control__media {
|
92 |
+
width: 100%;
|
93 |
+
display: block;
|
94 |
+
position: absolute;
|
95 |
+
top: 0;
|
96 |
+
left: 0;
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
.page-template-modal__actions {
|
101 |
+
display: flex;
|
102 |
+
flex-direction: column;
|
103 |
+
align-items: center;
|
104 |
+
|
105 |
+
@media screen and ( min-width: 960px ) {
|
106 |
+
flex-direction: row;
|
107 |
+
justify-content: flex-end;
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
.page-template-modal__action {
|
112 |
+
@media screen and ( max-width: 960px ) {
|
113 |
+
margin-bottom: 1em;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
.page-template-modal__action-use {
|
118 |
+
@media screen and ( min-width: 960px ) {
|
119 |
+
margin-right: 1em;
|
120 |
+
}
|
121 |
+
}
|
starter-page-templates/page-template-modal/utils/replace-placeholders.js
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const __ = a => a;
|
2 |
+
|
3 |
+
const PLACEHOLDER_DEFAULTS = {
|
4 |
+
Address: '123 Main St',
|
5 |
+
Phone: '555-555-5555',
|
6 |
+
CompanyName: __( 'Your Company Name' ),
|
7 |
+
};
|
8 |
+
|
9 |
+
const KEY_MAP = {
|
10 |
+
CompanyName: 'title',
|
11 |
+
Address: 'address',
|
12 |
+
Phone: 'phone',
|
13 |
+
};
|
14 |
+
|
15 |
+
const replacePlaceholders = ( pageContent, siteInformation = {} ) => {
|
16 |
+
return pageContent.replace( /{{(\w+)}}/g, ( match, placeholder ) => {
|
17 |
+
const defaultValue = PLACEHOLDER_DEFAULTS[ placeholder ];
|
18 |
+
const key = KEY_MAP[ placeholder ];
|
19 |
+
return siteInformation[ key ] || defaultValue || placeholder;
|
20 |
+
} );
|
21 |
+
};
|
22 |
+
|
23 |
+
export default replacePlaceholders;
|