PluginProbe
LIQUID BLOCKS – Slider, Carousel, Accordion / 1.3.7
LIQUID BLOCKS – Slider, Carousel, Accordion v1.3.7
1.3.7 1.3.6 trunk 1.0 1.0.2 1.0.3 1.0.4 1.0.5 1.0.8 1.0.9 1.1.1 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5
liquid-blocks / liquid-blocks.php

liquid-blocks.php in LIQUID BLOCKS – Slider, Carousel, Accordion 1.3.7, at liquid-blocks.php

1,031 lines 44.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: LIQUID BLOCKS
4 Plugin URI: https://lqd.jp/wp/plugin.html
5 Description: A magic tool to master WordPress blocks.
6 Author: LIQUID DESIGN Ltd.
7 Author URI: https://lqd.jp/wp/
8 License: GPLv2
9 License URI: https://www.gnu.org/licenses/gpl-2.0.html
10 Text Domain: liquid-blocks
11 Version: 1.3.7
12 Requires at least: 6.0
13 */
14 /* Copyright 2019 LIQUID DESIGN Ltd. (email : info@lqd.jp)
15
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License, version 2, as
18 published by the Free Software Foundation.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 */
28
29 // ------------------------------------
30 // Plugin
31 // ------------------------------------
32 $liquid_blocks_data = get_file_data( __FILE__, array( 'version' => 'Version'));
33
34 // api
35 if ( is_admin() ) {
36 $liquid_blocks_api = require_once 'inc/api.php';
37 $liquid_blocks_json = $liquid_blocks_api('https://lqd.jp/wp/data/p/liquid-blocks.json', 'liquid_blocks_json');
38 }
39
40 // LIQUID PRO ライセンス認証(�
41 �有ファイル・他プラグインと多重同梱可)
42 require_once plugin_dir_path( __FILE__ ) . 'inc/liquid-pro.php';
43
44 // notices
45 function liquid_blocks_admin_notices() {
46 global $liquid_blocks_json;
47 if( !empty($liquid_blocks_json) ) {
48 if ( isset( $_GET['liquid_admin_notices_dismissed'] ) && current_user_can( 'manage_options' ) ) {
49 set_transient( 'liquid_admin_notices', 'dismissed', 60*60*24*180 );
50 }
51 if ( isset( $_GET['liquid_admin_offer_dismissed'] ) && current_user_can( 'manage_options' ) ) {
52 set_transient( 'liquid_admin_offer', 'dismissed', 60*60*24*180 );
53 }
54 if( !empty($liquid_blocks_json['news']) && get_transient( 'liquid_admin_notices' ) != 'dismissed' ){
55 echo '<div class="notice notice-info" style="position: relative;"><p>'.wp_kses_post($liquid_blocks_json['news']).'</p><a href="?liquid_admin_notices_dismissed" style="position: absolute; right: 10px; top: 10px;">&times;</a></div>';
56 }
57 if( !empty($liquid_blocks_json['offer']) && get_transient( 'liquid_admin_offer' ) != 'dismissed' ){
58 echo '<div class="notice notice-info" style="position: relative;"><p>'.wp_kses_post($liquid_blocks_json['offer']).'</p><a href="?liquid_admin_offer_dismissed" style="position: absolute; right: 10px; top: 10px;">&times;</a></div>';
59 }
60 }
61 }
62 add_action( 'admin_notices', 'liquid_blocks_admin_notices' );
63
64 // get_option
65 $liquid_blocks_toggle = get_option( 'liquid_blocks_toggle' );
66 $liquid_blocks_no = get_option( 'liquid_blocks_no' ) ? get_option( 'liquid_blocks_no' ) : [];
67 $liquid_blocks_type = get_option( 'liquid_blocks_type' ) ? get_option( 'liquid_blocks_type' ) : [];
68 $liquid_blocks_name = get_option( 'liquid_blocks_name' ) ? get_option( 'liquid_blocks_name' ) : [];
69 $liquid_blocks_clean = get_option( 'liquid_blocks_clean' ) ? get_option( 'liquid_blocks_clean' ) : [];
70 if( empty( $liquid_blocks_toggle ) ){
71 add_action( 'init', 'liquid_blocks_init' );
72 add_action( 'enqueue_block_assets', 'liquid_blocks_assets' );
73 add_action( 'enqueue_block_editor_assets', 'liquid_blocks_enqueue_block_editor_assets' );
74 add_action( 'admin_footer', 'liquid_blocks_admin_footer' );
75 add_action( 'plugins_loaded', function () {
76 load_plugin_textdomain(
77 'liquid-blocks',
78 false,
79 dirname(plugin_basename(__FILE__)) . '/languages/'
80 );
81 } );
82 }
83
84 // plugin_action_links
85 function liquid_blocks_plugin_action_links( $links ) {
86 $settings = '<a href="' . esc_url( admin_url('admin.php?page=liquid-blocks') ) . '">'
87 . esc_html__( 'Settings', 'liquid-blocks' ) . '</a>';
88 if ( function_exists( 'is_liquid_pro' ) && is_liquid_pro() ) {
89 array_unshift( $links, $settings );
90 } else {
91 $pro = '<a href="' . esc_url( 'https://lqd.jp/wp/plugin/blocks_pro.html' ) . '" target="_blank" rel="noopener" style="font-weight:bold;">'
92 . esc_html__( 'Get Pro', 'liquid-blocks' ) . '</a>';
93 array_unshift( $links, $pro, $settings );
94 }
95 return $links;
96 }
97 add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), 'liquid_blocks_plugin_action_links' );
98
99 function liquid_blocks_assets() {
100 global $liquid_blocks_data;
101 wp_enqueue_style( 'liquid-blocks', plugins_url( 'css/block.css' , __FILE__ ), array( 'swiper' ), $liquid_blocks_data['version'] );
102 // slider
103 wp_enqueue_style( 'swiper', plugins_url( 'css/swiper-bundle.min.css' , __FILE__ ), array() );
104 wp_enqueue_script( 'swiper', plugins_url( 'lib/swiper-bundle.min.js' , __FILE__ ), array() );
105 wp_enqueue_script( 'liquid-blocks', plugins_url( 'lib/liquid-blocks.js' , __FILE__ ), array( 'swiper' ) );
106 // エディター用スタイルもここで読み込む。
107 // ※ enqueue_block_editor_assets は親ドキュメントにしか読み込まれず、
108 // iframe 化されたエディター(WP 7.1 で�
109 �面適用)のキャンバス�
110 に届かないため、
111 // タブ/スライダーのエディターレイアウトが崩れる(enqueue_block_assets は iframe �
112 にも反映される)
113 if ( is_admin() ) {
114 wp_enqueue_style( 'liquid-blocks-editor', plugins_url( 'css/block-editor.css' , __FILE__ ), array(), $liquid_blocks_data['version'] );
115 }
116 }
117
118 function liquid_blocks_enqueue_block_editor_assets(){
119 global $liquid_blocks_data, $liquid_blocks_no, $liquid_blocks_type, $liquid_blocks_name, $pagenow;
120 // wp-edit-post 依存の block.js は新ウィジェットエディターでは読み込まない(wp-editor 競合の Notice 回避)
121 $liquid_blocks_skip_block = ( $pagenow == 'widgets.php' || $pagenow == 'customize.php' );
122 // wp_enqueue_script
123 wp_enqueue_script( 'clipboard' );
124 wp_enqueue_script( 'liquid-blocks-template', plugins_url( 'lib/template.js', __FILE__ ), array(), $liquid_blocks_data['version'] );
125 // ライセンス認証の結果を各ブロック JS に渡す(判定は PHP 側の is_liquid_pro())
126 wp_add_inline_script( 'liquid-blocks-template', 'window.LIQUID_PRO = { enabled: ' . ( is_liquid_pro() ? 'true' : 'false' ) . ' };', 'before' );
127 if ( ! $liquid_blocks_skip_block ) {
128 wp_enqueue_script( 'liquid-blocks-block', plugins_url( 'lib/block.js', __FILE__ ), array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-block-editor', 'wp-plugins', 'wp-edit-post', 'wp-components', 'liquid-blocks-template', 'clipboard' ), $liquid_blocks_data['version'] );
129 }
130 // 書式(Mark/Big/Small/Underline)は wp-edit-post 非依存のため�
131 �画面でエンキュー
132 wp_enqueue_script( 'liquid-blocks-format', plugins_url( 'lib/block-format.js', __FILE__ ), array( 'wp-rich-text', 'wp-block-editor', 'wp-element', 'wp-i18n' ), $liquid_blocks_data['version'] );
133 wp_enqueue_script( 'liquid-blocks-cards', plugins_url( 'lib/block-cards.js', __FILE__ ), array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-block-editor', 'wp-components' ) );
134 wp_enqueue_script( 'liquid-blocks-tabs', plugins_url( 'lib/block-tabs.js', __FILE__ ), array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-block-editor', 'wp-components' ) );
135 wp_enqueue_script( 'liquid-blocks-table', plugins_url( 'lib/block-table.js', __FILE__ ), array('wp-blocks', 'wp-i18n', 'wp-hooks', 'wp-element', 'wp-components', 'wp-compose', 'wp-block-editor') );
136 wp_enqueue_script( 'liquid-blocks-fixed', plugins_url( 'lib/block-fixed.js', __FILE__ ), array( 'wp-blocks', 'wp-i18n', 'wp-hooks', 'wp-element', 'wp-components', 'wp-compose', 'wp-block-editor', 'wp-data' ) );
137
138 // wp_set_script_translations
139 wp_set_script_translations( 'liquid-blocks', 'liquid-blocks', plugin_dir_path( __FILE__ ) . 'languages' );
140 if ( ! $liquid_blocks_skip_block ) {
141 wp_set_script_translations( 'liquid-blocks-block', 'liquid-blocks', plugin_dir_path( __FILE__ ) . 'languages' );
142 }
143 wp_set_script_translations( 'liquid-blocks-format', 'liquid-blocks', plugin_dir_path( __FILE__ ) . 'languages' );
144 wp_set_script_translations( 'liquid-blocks-cards', 'liquid-blocks', plugin_dir_path( __FILE__ ) . 'languages' );
145 wp_set_script_translations( 'liquid-blocks-tabs', 'liquid-blocks', plugin_dir_path( __FILE__ ) . 'languages' );
146 wp_set_script_translations( 'liquid-blocks-slider', 'liquid-blocks', plugin_dir_path( __FILE__ ) . 'languages' );
147 wp_set_script_translations( 'liquid-blocks-custom-field', 'liquid-blocks', plugin_dir_path( __FILE__ ) . 'languages' );
148 wp_set_script_translations( 'liquid-blocks-if-conditions', 'liquid-blocks', plugin_dir_path( __FILE__ ) . 'languages' );
149 wp_set_script_translations( 'liquid-blocks-table', 'liquid-blocks', plugin_dir_path( __FILE__ ) . 'languages' );
150 wp_set_script_translations( 'liquid-blocks-fixed', 'liquid-blocks', plugin_dir_path( __FILE__ ) . 'languages' );
151
152 // wp_localize_script
153 wp_localize_script( 'liquid-blocks-template', 'liquid_blocks_imgurl', array( plugins_url( 'images/', __FILE__ ) ) );
154 if ( ! $liquid_blocks_skip_block ) {
155 wp_localize_script( 'liquid-blocks-block', 'liquid_blocks_imgurl', array( plugins_url( 'images/', __FILE__ ) ) );
156 wp_localize_script( 'liquid-blocks-block', 'liquid_blocks_no', $liquid_blocks_no );
157 wp_localize_script( 'liquid-blocks-block', 'liquid_blocks_type', $liquid_blocks_type );
158 wp_localize_script( 'liquid-blocks-block', 'liquid_blocks_name', $liquid_blocks_name );
159 }
160
161 // wp_enqueue_style
162 wp_enqueue_style( 'liquid-blocks', plugins_url( 'css/block.css' , __FILE__ ), array(), $liquid_blocks_data['version'] );
163 wp_enqueue_style( 'liquid-blocks-editor', plugins_url( 'css/block-editor.css' , __FILE__ ), array(), $liquid_blocks_data['version'] );
164
165 // theme.json の layout.contentSize をブレークポイントとして使用
166 $content_size = '';
167 if (function_exists('wp_get_global_settings')) {
168 // まず theme.json 由来を取りに行く(環境差に強い)
169 $content_size = (string) wp_get_global_settings(['layout', 'contentSize'], ['origin' => 'base']);
170 }
171 $content_size = trim((string) $content_size);
172 // フォールバック:theme.json に無い / 空なら $content_width を採用
173 if ($content_size === '' && isset($content_width) && is_numeric($content_width) && (int) $content_width > 0) {
174 $content_size = (int) $content_width . 'px';
175 }
176 // media query に使えない値(var(...))は無効扱い
177 $usable_bp = ($content_size !== '' && stripos($content_size, 'var(') === false);
178 $settings = array(
179 'hasContentSize' => $usable_bp,
180 'breakpoint' => $usable_bp ? $content_size : '',
181 );
182 wp_add_inline_script(
183 'liquid-blocks-table',
184 'window.LiquidBlocksBlockTableSettings=' . wp_json_encode($settings) . ';',
185 'before'
186 );
187 }
188
189 function liquid_blocks_admin_footer() {
190 global $pagenow, $post;
191 if( $pagenow == 'post.php' || $pagenow == 'post-new.php' ){
192 if ( apply_filters( 'replace_editor', false, $post ) !== true ) {
193 if ( use_block_editor_for_post( $post ) ) {
194 ?>
195 <!-- Gallery -->
196 <div id="liquid_blocks_modal" class="liquid_blocks_modal" style="display:none;">
197 <div class="liquid_blocks_modal_gallery">
198
199 <?php
200 /* ブロックCSS+グローバルスタイル+テーマCSSを読み込んだプレビュー === */
201 if ( ! function_exists( 'liquid_blocks_preview_src' ) ) {
202 function liquid_blocks_preview_src( $raw_html ) {
203 $rendered = function_exists('do_blocks') ? do_blocks($raw_html) : apply_filters('the_content', $raw_html);
204
205 $links = '';
206 $styles = wp_styles();
207 if ( wp_style_is('wp-block-library','registered') && ! empty($styles->registered['wp-block-library']->src) ) {
208 $href = $styles->registered['wp-block-library']->src;
209 if ( 0 !== strpos($href,'http') ) $href = site_url($href);
210 $links .= '<link rel="stylesheet" href="'.esc_url($href).'">';
211 } else {
212 $links .= '<link rel="stylesheet" href="'.esc_url( includes_url('css/dist/block-library/style.min.css') ).'">';
213 }
214 if ( function_exists('wp_get_global_stylesheet') ) {
215 $links .= '<style>'.wp_get_global_stylesheet().'</style>';
216 }
217 $links .= '<link rel="stylesheet" href="'.esc_url( get_stylesheet_uri() ).'">';
218
219 $doc = '<!doctype html><html><head><meta charset="'.esc_attr( get_bloginfo('charset') ).'">'.$links.'<style>img{max-width:100%;height:auto;display:block}</style></head><body>'.$rendered.'</body></html>';
220
221 return 'data:text/html;charset=UTF-8;base64,'.base64_encode($doc);
222 }
223 }
224
225 /* === Site Editor のユーザーパターン(wp_block)を一覧表示 === */
226 $user_args = array(
227 'post_type' => array( 'wp_block' ), // Site Editor で作るユーザーパターン
228 'post_status' => array( 'publish' ),
229 'posts_per_page' => -1,
230 'orderby' => 'date', // 安定のため日付→ID
231 'order' => 'ASC',
232 );
233 $uquery = new WP_Query( $user_args );
234
235 if ( $uquery->have_posts() ) {
236 echo '<h3>' . esc_html__( 'Block Patterns', 'liquid-blocks' ) . ' <small>User</small></h3>';
237 echo '<script>if(!window.LiquidGallery){window.LiquidGallery={}}; if(!LiquidGallery["user"]){LiquidGallery["user"]=[]}</script>';
238
239 $i = 0;
240 while ( $uquery->have_posts() ) {
241 $uquery->the_post();
242 $post_id = get_the_ID();
243 $pattern_title = get_the_title();
244 if ( ! $pattern_title ) {
245 $pattern_title = __( 'Untitled pattern', 'liquid-blocks' );
246 }
247
248 // 生のブロックコンテンツ(クリック時にそのまま parse → insert)
249 $raw = get_post_field( 'post_content', $post_id );
250 if ( ! $raw ) {
251 continue;
252 }
253
254 // プレビューURL(コアCSS適用の実HTMLを返す)
255 $preview_src = liquid_blocks_preview_src( $raw );
256
257 // JSに詰める(JSONエンコードで安�
258 �に)
259 $raw_no_newline = preg_replace( "/\r|\n/", '', $raw );
260 $raw_json = wp_json_encode( $raw_no_newline );
261
262 // 画像 + タイトル(既存と同フォーマット)
263 echo '<script>LiquidGallery["user"][' . (int) $i . '] = ' . $raw_json . ';</script>';
264 echo '<a onclick="LiquidGalleryButton(LiquidGallery[\'user\'][' . (int) $i . '], this)" class="liquid_blocks_iframe">';
265
266 // iframe
267 $frame_w = 420; // サムネイル枠の見た目�
268
269 $frame_h = 280; // サムネイル枠の見た目高さ
270 $desktop_vw = 1280; // PCレイアウトとして見せたい�
271 (ブレークポイント用)
272 $scale = $frame_w / $desktop_vw;
273 $desktop_h = (int) round($frame_h / $scale);
274 $preview_src = liquid_blocks_preview_src( $raw );
275 echo '<iframe src="'.esc_attr($preview_src).'"
276 style="width:'.$desktop_vw.'px;height:'.$desktop_h.'px;
277 transform:scale('.$scale.');transform-origin:0 0;
278 border:0;pointer-events:none;display:block;background:#fff"
279 loading="lazy" referrerpolicy="no-referrer"></iframe>';
280
281 echo '<span>' . ( (int) ($i + 1) ) . ': ' . esc_html( $pattern_title ) . '</span>';
282 echo '</a>';
283
284 $i++;
285 }
286 wp_reset_postdata();
287 }
288 ?>
289
290 <?php
291 /* === liquid_block === */
292 $args = array(
293 'post_type' => array( 'liquid_block' ),
294 'post_status' => array( 'publish' ),
295 'posts_per_page' => -1,
296 'order' => 'ASC',
297 );
298 $the_query = new WP_Query( $args );
299 if ( $the_query->have_posts() ) {
300 $i = 0;
301 echo '<h3>'.__( 'Block Patterns', 'liquid-blocks' ).' <small>Patterns</small></h3>';
302 echo '<script>LiquidGallery[\'Patterns\'] = []</script>';
303 while ( $the_query->have_posts() ) {
304 $j = $i + 1;
305 $the_query->the_post();
306 $pattern_title = get_the_title();
307 if( !$pattern_title ){
308 $pattern_title = __( 'Untitled block', 'liquid-blocks' );
309 }
310 $pattern_content = get_the_content();
311 $pattern_categories = array();
312 $terms = get_the_terms( 0, 'liquid_patterns' );
313 if( !empty( $terms ) && !is_wp_error( $terms ) ){
314 foreach( $terms as $term ){
315 $pattern_categories[] = $term->slug;
316 }
317 }
318 if( has_post_thumbnail() ) {
319 $thumbnail_id = get_post_thumbnail_id();
320 $src_info = wp_get_attachment_image_src($thumbnail_id, $size = array(600,400));
321 $src = $src_info ? $src_info[0] : '';
322 $class = '';
323 } else {
324 $src = plugins_url( 'images/noimage.png', __FILE__ );
325 $class = 'liquid_noimage';
326 }
327 if( $pattern_content ){
328 $pattern_content = str_replace( array("\r", "\n"), '', $pattern_content );
329 echo '<script>LiquidGallery[\'Patterns\']['.$i.'] = '.wp_json_encode($pattern_content).';</script>';
330 echo '<a onclick="LiquidGalleryButton(LiquidGallery[\'Patterns\']['.$i.'], this)" class="liquid_blocks_img '.$class.'"><img src="'.$src.'" alt=""><span>'.$j.': '.$pattern_title.'</span></a>';
331 $i++;
332 }
333 }
334 wp_reset_postdata();
335 }
336 ?>
337
338 <h3><?php _e( 'Headlines', 'liquid-blocks' ); ?> <small>Headlines</small></h3>
339 <script>LiquidGalleryList('Headlines');</script>
340 <h3><?php _e( 'Layouts', 'liquid-blocks' ); ?> <small>Layouts</small></h3>
341 <script>LiquidGalleryList('Layouts');</script>
342 <h3><?php _e( 'Price list', 'liquid-blocks' ); ?> <small>Price</small></h3>
343 <script>LiquidGalleryList('Price');</script>
344 <h3><?php _e( 'CTA: Call To Action', 'liquid-blocks' ); ?> <small>CTA</small></h3>
345 <script>LiquidGalleryList('CTA');</script>
346 <h3><?php _e( 'Landing pages', 'liquid-blocks' ); ?> <small>Landing</small></h3>
347 <script>LiquidGalleryList('Landing');</script>
348 <h3><?php _e( 'Recommended Plugins', 'liquid-blocks' ); ?></h3>
349 <a href="https://wordpress.org/plugins/liquid-speech-balloon/" target="_blank"><img src="<?php echo plugins_url( 'images/Recommend/liquid-speech-balloon.png', __FILE__ ); ?>" alt=""></a>
350 </div>
351 </div>
352 <!-- Multiple -->
353 <div id="liquid_blocks_buttons" class="liquid_blocks_buttons">
354 <a id="liquid_blocks_copy" class="liquid_blocks_copy liquid_blocks_btn none"><?php _e( 'Copy', 'liquid-blocks' ); ?></a><script>LiquidGalleryCopy();</script>
355 <a id="liquid_blocks_insert" onclick="LiquidGalleryInsert()" class="liquid_blocks_btn none"><?php _e( 'Insert', 'liquid-blocks' ); ?><span id="liquid_blocks_count"></span></a>
356 <a id="liquid_blocks_multiple" onclick="LiquidGalleryMultiple()" class="liquid_blocks_btn"><?php _e( 'Select', 'liquid-blocks' ); ?></a>
357 <a id="liquid_blocks_cancel" onclick="LiquidGalleryCancel()" class="liquid_blocks_btn none"><?php _e( 'Cancel', 'liquid-blocks' ); ?></a>
358 <a id="liquid_blocks_close" onclick="LiquidGalleryClose()" class="liquid_blocks_btn"><?php _e( 'Close', 'liquid-blocks' ); ?></a>
359 </div>
360 <?php
361 }
362 }
363 }
364 }
365
366 // ------------------------------------
367 // init
368 // ------------------------------------
369
370 // block_categories
371 function liquid_block_categories($categories, $post) {
372 return array_merge(
373 $categories,
374 array(
375 array(
376 'slug' => 'liquid',
377 'title' => 'LIQUID',
378 ),
379 )
380 );
381 }
382 add_filter('block_categories_all', 'liquid_block_categories', 10, 2);
383
384 function liquid_blocks_init(){
385 global $liquid_blocks_clean;
386
387 // pattern_category
388 register_block_pattern_category(
389 'liquid_headlines',
390 array( 'label' => __( 'Headlines', 'liquid-blocks' ) )
391 );
392 // img_path
393 $path = plugins_url( 'images/', __FILE__ );
394
395 // slider
396 register_block_type( 'liquid/slider', array(
397 'editor_script' => 'liquid-blocks-slider',
398 'editor_style' => 'liquid-blocks-editor',
399 'attributes' => array(
400 'fields' => array(
401 'type' => 'array',
402 ),
403 'delay' => array(
404 'type' => 'number',
405 ),
406 'speed' => array(
407 'type' => 'number',
408 ),
409 'slidesPerView' => array(
410 'type' => 'number',
411 ),
412 'animationType' => array(
413 'type' => 'string',
414 ),
415 ),
416 ) );
417 wp_register_script(
418 'liquid-blocks-slider',
419 plugins_url( 'lib/block-slider.js', __FILE__ ),
420 array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-block-editor', 'wp-components' )
421 );
422
423 // カスタムフィールド
424 register_block_type('liquid/custom-field', array(
425 'editor_script' => 'liquid-blocks-custom-field',
426 'render_callback' => 'liquid_blocks_render_custom_field',
427 ));
428 wp_register_script(
429 'liquid-blocks-custom-field',
430 plugin_dir_url(__FILE__) . 'lib/block-custom-field.js',
431 array('wp-blocks', 'wp-i18n', 'wp-element', 'wp-block-editor', 'wp-components')
432 );
433
434 // isカスタム
435 register_block_type( 'liquid/if-conditions', array(
436 'editor_script' => 'liquid-blocks-if-conditions',
437 'render_callback' => 'liquid_blocks_is_custom',
438 ) );
439 wp_register_script(
440 'liquid-blocks-if-conditions',
441 plugins_url( 'lib/block-if-conditions.js', __FILE__ ),
442 array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-block-editor', 'wp-components' )
443 );
444 function liquid_blocks_is_custom( $attributes, $content ) {
445 $visibility = isset( $attributes['visibility'] ) ? $attributes['visibility'] : '';
446 $role = isset( $attributes['role'] ) ? $attributes['role'] : '';
447 $parameters = isset( $attributes['parameters'] ) ? sanitize_text_field($attributes['parameters']) : '';
448 $conditionType = isset( $attributes['conditionType'] ) ? $attributes['conditionType'] : '';
449
450 // helper: Not Match 判定の�
451 �通化
452 $invert = ( $conditionType === 'not_match' );
453
454 // is_user_logged_in
455 if ( 'is_user_logged_in' === $visibility ) {
456 if( ! $conditionType ){
457 if ( ! is_user_logged_in() ) { return ''; }
458 // role
459 if ( $role ) {
460 $current_user = wp_get_current_user();
461 if ( ! in_array( $role, (array) $current_user->roles, true ) ) { return ''; }
462 }
463 } else {
464 if ( is_user_logged_in() ) { return ''; }
465 }
466 }
467 // is_front_page
468 if ( 'is_front_page' === $visibility ) {
469 if( ! $conditionType ){
470 if ( ! is_front_page() ) { return ''; }
471 } else {
472 if ( is_front_page() ) { return ''; }
473 }
474 }
475 // is_front_page
476 if ( 'is_front_page' === $visibility ) {
477 if( ! $conditionType ){
478 if ( ! is_front_page() ) { return ''; }
479 } else {
480 if ( is_front_page() ) { return ''; }
481 }
482 }
483 // is_home
484 if ( 'is_home' === $visibility ) {
485 if( ! $conditionType ){
486 if ( ! is_home() ) { return ''; }
487 } else {
488 if ( is_home() ) { return ''; }
489 }
490 }
491 // is_page
492 if ( 'is_page' === $visibility ) {
493 if( ! $conditionType ){
494 if ( ! is_page($parameters) ) { return ''; }
495 } else {
496 if ( is_page($parameters) ) { return ''; }
497 }
498 }
499 // is_single
500 if ( 'is_single' === $visibility ) {
501 if( ! $conditionType ){
502 if ( ! is_single($parameters) ) { return ''; }
503 } else {
504 if ( is_single($parameters) ) { return ''; }
505 }
506 }
507 // is_singular
508 if ( 'is_singular' === $visibility ) {
509 if( ! $conditionType ){
510 if ( ! is_singular($parameters) ) { return ''; }
511 } else {
512 if ( is_singular($parameters) ) { return ''; }
513 }
514 }
515 // is_archive
516 if ( 'is_archive' === $visibility ) {
517 if( ! $conditionType ){
518 if ( ! is_archive() ) { return ''; }
519 } else {
520 if ( is_archive() ) { return ''; }
521 }
522 }
523 // is_category
524 if ( 'is_category' === $visibility ) {
525 if( ! $conditionType ){
526 if ( ! is_category($parameters) ) { return ''; }
527 } else {
528 if ( is_category($parameters) ) { return ''; }
529 }
530 }
531 // is_tag
532 if ( 'is_tag' === $visibility ) {
533 if( ! $conditionType ){
534 if ( ! is_tag($parameters) ) { return ''; }
535 } else {
536 if ( is_tag($parameters) ) { return ''; }
537 }
538 }
539 // is_author
540 if ( 'is_author' === $visibility ) {
541 if( ! $conditionType ){
542 if ( ! is_author($parameters) ) { return ''; }
543 } else {
544 if ( is_author($parameters) ) { return ''; }
545 }
546 }
547 // is_tax
548 if ( 'is_tax' === $visibility ) {
549 if( ! $conditionType ){
550 if ( ! is_tax($parameters) ) { return ''; }
551 } else {
552 if ( is_tax($parameters) ) { return ''; }
553 }
554 }
555 // has_post_format
556 if ( 'has_post_format' === $visibility ) {
557 if( ! $conditionType ){
558 if ( ! has_post_format($parameters) ) { return ''; }
559 } else {
560 if ( has_post_format($parameters) ) { return ''; }
561 }
562 }
563 // wp_is_mobile
564 if ( 'wp_is_mobile' === $visibility ) {
565 if( ! $conditionType ){
566 if ( ! wp_is_mobile() ) { return ''; }
567 } else {
568 if ( wp_is_mobile() ) { return ''; }
569 }
570 }
571 // get_locale
572 if ( 'get_locale' === $visibility ) {
573 $locale = function_exists('get_locale') ? (string) get_locale() : '';
574 $list = array_filter( array_map( 'trim', preg_split( '/[,\s]+/', $parameters ) ) );
575 $matched = false;
576 foreach ( $list as $p ) {
577 if ( $p !== '' && strpos( $locale, $p ) === 0 ) { // prefix match
578 $matched = true;
579 break;
580 }
581 }
582 if ( ! $invert ) {
583 if ( ! $matched ) { return ''; }
584 } else {
585 if ( $matched ) { return ''; }
586 }
587 }
588
589 // content
590 return '<div class="liquid-if-conditions">' . $content . '</div>';
591 }
592
593 // fixed
594 register_block_type('liquid/fixed', array(
595 'editor_script' => 'liquid-blocks-fixed',
596 'style' => 'liquid-blocks-fixed',
597 'render_callback' => 'liquid_blocks_render_fixed',
598 'attributes' => array(
599 'positionX' => array('type' => 'string', 'default' => 'right'), // left/right
600 'positionY' => array('type' => 'string', 'default' => 'bottom'), // top/bottom
601 'offsetTop' => array('type' => 'string', 'default' => '0px'),
602 'offsetBottom' => array('type' => 'string', 'default' => '0px'),
603 'offsetLeft' => array('type' => 'string', 'default' => '0px'),
604 'offsetRight' => array('type' => 'string', 'default' => '0px'),
605
606 'showOnScroll' => array('type' => 'boolean', 'default' => false),
607 'scrollThreshold' => array('type' => 'number', 'default' => 200),
608 'scrollMode' => array('type' => 'string', 'default' => 'after'), // after/up/down
609
610 'closeable' => array('type' => 'boolean', 'default' => false),
611 'closePersist' => array('type' => 'boolean', 'default' => true),
612 'persistKey' => array('type' => 'string', 'default' => ''), // 自動生成
613 ),
614 ));
615
616 // ------------------------------------
617 // unregister_block_pattern
618 // ------------------------------------
619 if( !empty($liquid_blocks_clean) ){
620 add_action( 'after_setup_theme', function() {
621 remove_theme_support( 'core-block-patterns' );
622 } );
623 add_filter( 'should_load_remote_block_patterns', '__return_false' );
624 }
625
626 // register_post_type
627 register_post_type(
628 'liquid_block',
629 array(
630 'public' => true,
631 'description' => __( 'Block Pattern Manager', 'liquid-blocks' ),
632 'hierarchical' => false,
633 'has_archive' => false,
634 'labels' => array(
635 'name' => __( 'Block Pattern', 'liquid-blocks' ),
636 'menu_name' => __( 'Block Pattern', 'liquid-blocks' ),
637 'singular_name' => __( 'Block Pattern', 'liquid-blocks' ),
638 'all_items' => __( 'Block Pattern List', 'liquid-blocks' ),
639 'add_new' => __( 'Add New', 'liquid-blocks' ),
640 'add_new_item' => __( 'Add New', 'liquid-blocks' ),
641 'edit_item' => __( 'Edit', 'liquid-blocks' ),
642 ),
643 'publicly_queryable' => false,
644 'show_ui' => true,
645 'show_in_menu' => false,
646 'show_in_nav_menus' => false,
647 'show_in_admin_bar' => true,
648 'capability_type' => 'post',
649 'menu_position' => 9,
650 'query_var' => false,
651 'exclude_from_search' => true,
652 'publicly_queryable' => false,
653 'supports' => array(
654 'title',
655 'editor',
656 'author',
657 'thumbnail',
658 ),
659 'taxonomies' => array('liquid_block'),
660 'show_in_rest' => true,
661 )
662 );
663 register_taxonomy(
664 'liquid_patterns',
665 'liquid_block',
666 array(
667 'label' => __( 'Block Pattern Category', 'liquid-blocks' ),
668 'hierarchical' => false,
669 'public' => false,
670 'show_ui' => true,
671 'show_in_rest' => true,
672 'show_tagcloud' => false,
673 'labels' => array(
674 'singular_name' => __( 'Block Pattern Category', 'liquid-blocks' ),
675 'add_new_item' => __( 'Add New', 'liquid-blocks' ),
676 'separate_items_with_commas' => __( 'Press the Enter key.', 'liquid-blocks' ),
677 ),
678 )
679 );
680
681 $terms = get_terms( array( 'taxonomy' => 'liquid_patterns', 'get'=>'all' ) );
682 if( !empty( $terms ) && !is_wp_error( $terms ) ){
683 foreach( $terms as $term ){
684 register_block_pattern_category(
685 $term->slug,
686 array( 'label' => $term->name )
687 );
688 }
689 }
690
691 // register_block_pattern self-made
692 $args = array(
693 'post_type' => array( 'liquid_block' ),
694 'post_status' => array( 'publish' ),
695 'posts_per_page' => -1,
696 'order' => 'ASC',
697 );
698 $the_query = new WP_Query( $args );
699 if ( $the_query->have_posts() ) {
700 $i = 0;
701 while ( $the_query->have_posts() ) {
702 $the_query->the_post();
703 $pattern_title = get_the_title();
704 if( !$pattern_title ){
705 $pattern_title = __( 'Untitled block', 'liquid-blocks' );
706 }
707 $pattern_content = get_the_content();
708 $pattern_categories = array();
709 $terms = get_the_terms( 0, 'liquid_patterns' );
710 if( !empty( $terms ) && !is_wp_error( $terms ) ){
711 foreach( $terms as $term ){
712 $pattern_categories[] = $term->slug;
713 }
714 }
715 if( $pattern_content ){
716 register_block_pattern(
717 'liquid/liquid_pattern_' . $i,
718 array(
719 'title' => $pattern_title,
720 'content' => $pattern_content,
721 'categories' => $pattern_categories,
722 )
723 );
724 $i++;
725 }
726 }
727 wp_reset_postdata();
728 }
729 }
730
731 // カスタムフィールドブロックのレンダリング
732 function liquid_blocks_render_custom_field($attributes) {
733 // カスタムフィールドキーと投稿IDの取得
734 $fieldKey = isset($attributes['fieldKey']) ? $attributes['fieldKey'] : '';
735 $postId = isset($attributes['postId']) && !empty($attributes['postId']) ? intval($attributes['postId']) : get_the_ID();
736
737 // フィールドタイプを取得(テキストか画像か)
738 $fieldType = isset($attributes['fieldType']) ? $attributes['fieldType'] : 'text';
739
740 // デフォルトの alignment を設定
741 $alignment = isset($attributes['alignment']) ? $attributes['alignment'] : 'left';
742
743 // 追加CSSクラスを取得
744 $customClass = isset($attributes['className']) ? $attributes['className'] : '';
745
746 // スタイル属性を構築
747 $style = 'text-align:' . esc_attr($alignment) . ';';
748
749 // カスタムフィールドデータの取得
750 if (!empty($fieldKey)) {
751 $fieldValue = get_post_meta($postId, $fieldKey, true);
752
753 // フィールドタイプに基づいて処理を分ける
754 if ($fieldType === 'image') {
755 // 画像の場合
756 if (is_array($fieldValue)) {
757 // 繰り返し画像フィールドの場合の処理
758 $output = '<div class="liquid_custom_field_repeatable">';
759 foreach ($fieldValue as $mediaId) {
760 $image_url = wp_get_attachment_url($mediaId);
761 if ($image_url) {
762 $output .= '<div class="liquid_custom_field_item"><img src="' . esc_url($image_url) . '" alt="" /></div>';
763 }
764 }
765 $output .= '</div>';
766 } else {
767 // 単一画像フィールドの場合
768 $image_url = wp_get_attachment_url($fieldValue);
769 if ($image_url) {
770 $output = '<div class="liquid_custom_field_item"><img src="' . esc_url($image_url) . '" alt="" /></div>';
771 }
772 }
773 } else {
774 // テキストの場合
775 if (is_array($fieldValue)) {
776 // 繰り返しテキストフィールドの場合の処理
777 $output = '<div class="liquid_custom_field_repeatable">';
778 foreach ($fieldValue as $value) {
779 $output .= '<div class="liquid_custom_field_item">' . esc_html($value) . '</div>';
780 }
781 $output .= '</div>';
782 } else {
783 // 単一テキストフィールドの場合の処理
784 $output = '<div class="liquid_custom_field_item">' . esc_html($fieldValue) . '</div>';
785 }
786 }
787
788 // 追加CSSクラスを適用してカスタムフィールドの�
789 容をスタイル付きのdivでラップ
790 return '<div class="liquid_custom_field ' . esc_attr($customClass) . '" style="' . esc_attr($style) . '">' . $output . '</div>';
791 } else {
792 return '<div class="liquid_custom_field ' . esc_attr($customClass) . '">' . __('No custom field selected.', 'liquid-blocks') . '</div>';
793 }
794 }
795
796 // Fixedブロックのレンダリング
797 function liquid_blocks_render_fixed($attributes, $content, $block) {
798 $x = $attributes['positionX'] ?? 'right';
799 $y = $attributes['positionY'] ?? 'top';
800
801 $style = array(
802 'position:fixed',
803 'z-index:9999',
804 );
805
806 if ($y === 'top') {
807 $style[] = 'top:' . ($attributes['offsetTop'] ?? '0');
808 } else {
809 $style[] = 'bottom:' . ($attributes['offsetBottom'] ?? '0');
810 }
811
812 if ($x === 'left') {
813 $style[] = 'left:' . ($attributes['offsetLeft'] ?? '0');
814 } else {
815 $style[] = 'right:' . ($attributes['offsetRight'] ?? '0');
816 }
817
818 $persist_key = trim((string)($attributes['persistKey'] ?? ''));
819 $close_persist = !empty($attributes['closePersist']) && $persist_key !== '';
820
821 $wrapper_attrs = get_block_wrapper_attributes(array(
822 'class' => 'liquid-fixed',
823 'style' => implode(';', $style) . ';',
824 'data-liquid-fixed' => '1',
825 'data-liquid-scroll' => !empty($attributes['showOnScroll']) ? '1' : '0',
826 'data-liquid-scroll-threshold'=> (string)($attributes['scrollThreshold'] ?? 0),
827 'data-liquid-scroll-mode' => (string)($attributes['scrollMode'] ?? 'after'),
828 'data-liquid-close' => !empty($attributes['closeable']) ? '1' : '0',
829 'data-liquid-close-key' => $persist_key,
830 'data-liquid-close-persist' => $close_persist ? '1' : '0',
831 ));
832
833 return '<div ' . $wrapper_attrs . '>' . $content . '</div>';
834 }
835
836 // ------------------------------------
837 // Admin
838 // ------------------------------------
839 function liquid_blocks_admin() {
840 add_menu_page(
841 'LIQUID BLOCKS',
842 'LIQUID BLOCKS',
843 'administrator',
844 'liquid-blocks',
845 'liquid_blocks_admin_page',
846 'dashicons-screenoptions'
847 );
848 add_theme_page(
849 __( 'Patterns', 'liquid-blocks' ),
850 __( 'Patterns', 'liquid-blocks' ),
851 'administrator',
852 'edit.php?post_type=liquid_block'
853 );
854 // 親メニューと同名の�
855 �頭子メニュー(自動生成)を削除
856 remove_submenu_page( 'liquid-blocks', 'liquid-blocks' );
857
858 // License ページ(liquid-pro.php �
859 �通。option �
860 �有のため他プラグインと重複表示されてもよい)
861 if ( function_exists( 'liquid_pro_render_page' ) ) {
862 add_submenu_page(
863 'liquid-blocks',
864 'License',
865 'License',
866 'manage_options',
867 'liquid-blocks-license',
868 'liquid_pro_render_page'
869 );
870 }
871 register_setting(
872 'liquid_blocks_group',
873 'liquid_blocks_toggle',
874 'liquid_blocks_toggle_validation'
875 );
876 register_setting(
877 'liquid_blocks_group',
878 'liquid_blocks_no', array(
879 'sanitize_callback' => function( $input ) {
880 if ( ! is_array( $input ) ) {
881 return array();
882 }
883 return array_map( 'absint', $input );
884 },
885 )
886 );
887 register_setting(
888 'liquid_blocks_group',
889 'liquid_blocks_type', array(
890 'sanitize_callback' => function( $input ) {
891 if ( ! is_array( $input ) ) {
892 return array();
893 }
894 return array_map( 'sanitize_text_field', $input );
895 },
896 )
897 );
898 register_setting(
899 'liquid_blocks_group',
900 'liquid_blocks_name', array(
901 'sanitize_callback' => function( $input ) {
902 if ( ! is_array( $input ) ) {
903 return array();
904 }
905 return array_map( 'sanitize_text_field', $input );
906 },
907 )
908 );
909 register_setting(
910 'liquid_blocks_group',
911 'liquid_blocks_clean', array(
912 'sanitize_callback' => 'absint',
913 )
914 );
915 }
916 add_action( 'admin_menu', 'liquid_blocks_admin' );
917
918 add_action( 'admin_enqueue_scripts', function( $hook ) {
919 // Recommend の開閉 UI(Pro 版のみ)。判定は PHP 側の is_liquid_pro()
920 if ( $hook !== 'toplevel_page_liquid-blocks' || ! is_liquid_pro() ) {
921 return;
922 }
923 wp_enqueue_script(
924 'liquid-blocks-settings',
925 plugins_url( 'lib/liquid-blocks-settings.js', __FILE__ ),
926 array( 'jquery' ),
927 '1.0.0',
928 true
929 );
930 } );
931
932 function liquid_blocks_toggle_validation( $input ) {
933 $input = (int) $input;
934 if ( $input === 0 || $input === 1 ) {
935 return $input;
936 } else {
937 add_settings_error(
938 'liquid_blocks_toggle',
939 'liquid_blocks_toggle_validation_error',
940 __( 'illegal data', 'liquid-blocks' ),
941 'error'
942 );
943 }
944 }
945
946 function liquid_blocks_admin_page() {
947 global $liquid_blocks_json, $liquid_blocks_toggle, $liquid_blocks_no, $liquid_blocks_type, $liquid_blocks_name, $liquid_blocks_clean;
948 if( empty( $liquid_blocks_toggle ) ){
949 $toggle_on = 'checked="checked"';
950 $toggle_off = '';
951 } else {
952 $toggle_on = '';
953 $toggle_off = 'checked="checked"';
954 }
955 if( empty( $liquid_blocks_clean ) ){
956 $clean_on = 'checked="checked"';
957 $clean_off = '';
958 } else {
959 $clean_on = '';
960 $clean_off = 'checked="checked"';
961 }
962 ?>
963 <div class="wrap">
964 <h1>LIQUID BLOCKS<?php if ( is_liquid_pro() ) { ?><span style="display:inline-block;vertical-align:middle;background:#2271b1;color:#fff;font-size:12px;font-weight:600;line-height:1;padding:4px 8px;border-radius:3px;margin-left:8px;letter-spacing:0.05em;">PRO</span><?php } ?></h1>
965
966 <div id="poststuff">
967
968 <!-- Recommend -->
969 <?php if( !empty($liquid_blocks_json) && !empty($liquid_blocks_json['recommend']) ){ ?>
970 <div class="postbox" id="liquid-blocks-recommend">
971 <h2 style="border-bottom: 1px solid #eee; cursor:pointer;"><?php _e( 'Recommend', 'liquid-blocks' ); ?></h2>
972 <div class="inside"><?php echo wp_kses_post($liquid_blocks_json['recommend']); ?></div>
973 </div>
974 <?php } ?>
975
976 <!-- Settings -->
977 <div class="postbox">
978 <h2 style="border-bottom: 1px solid #eee;"><?php _e( 'Settings', 'liquid-blocks' ); ?></h2>
979 <div class="inside">
980 <form method="post" action="options.php">
981 <?php
982 settings_fields( 'liquid_blocks_group' );
983 do_settings_sections( 'default' );
984 ?>
985 <?php if ( function_exists('register_block_pattern') ) { ?>
986 <?php if ( ! is_liquid_pro() ) { ?>
987 <h3 class="liquid-blocks-pro-ttl"><?php _e( 'LIQUID BLOCKS Pro', 'liquid-blocks' ); ?></h3>
988 <div class="liquid-blocks-pro-box">
989 <p><?php _e('Unlock all features with the Pro version.', 'liquid-blocks'); ?></p>
990 <ul style="list-style:disc;padding-left:1.5em;margin-bottom:1.5em;">
991 <li><?php _e('Unlimited Slider and Tabs (free version: up to 10 each)', 'liquid-blocks'); ?></li>
992 <li><?php _e('Fixed blocks and If conditional blocks: Advanced options', 'liquid-blocks'); ?></li>
993 </ul>
994 <a href="https://lqd.jp/wp/plugin/blocks_pro.html" target="_blank" rel="noopener" class="button button-primary" style="font-size:14px;height:auto;padding:8px 20px;"><?php _e( 'Get Pro', 'liquid-blocks' ); ?></a>
995 </div>
996 <?php } ?>
997 <h3><?php _e( 'Block Pattern Manager', 'liquid-blocks' ); ?></h3>
998 <a href="site-editor.php?p=%2Fpattern" class="button button-primary"><?php _e( 'Block Pattern Manager', 'liquid-blocks' ); ?></a>
999 <h3><?php _e( 'Enable default block pattern', 'liquid-blocks' ); ?></h3>
1000 <p>
1001 <label for="liquid_blocks_clean_on"><input type="radio" id="liquid_blocks_clean_on" name="liquid_blocks_clean" value="0" <?php echo $clean_on; ?>>On</label>
1002 <label for="liquid_blocks_clean_off"><input type="radio" id="liquid_blocks_clean_off" name="liquid_blocks_clean" value="1" <?php echo $clean_off; ?>>Off</label>
1003 </p>
1004 <?php } ?>
1005 <h3><?php _e( 'Shortcuts', 'liquid-blocks' ); ?></h3>
1006 <p><?php _e( 'Sidebar shortcut button settings.', 'liquid-blocks' ); ?><br><?php _e( 'Enter any name, gallery category name, and number.', 'liquid-blocks' ); ?></p>
1007 <?php
1008 for ($i=0; $i<10; $i++) {
1009 $j = $i + 1;
1010 $no = !empty($liquid_blocks_no[$i]) ? $liquid_blocks_no[$i] : "";
1011 $type = !empty($liquid_blocks_type[$i]) ? $liquid_blocks_type[$i] : "";
1012 $name = !empty($liquid_blocks_name[$i]) ? $liquid_blocks_name[$i] : "";
1013 echo '<p>'.$j.' Name:<input type="text" name="liquid_blocks_name['.$i.']" value="'.esc_html($name).'" placeholder="intro"> ';
1014 echo 'Type:<input type="text" name="liquid_blocks_type['.$i.']" value="'.esc_html($type).'" placeholder="Headlines"> ';
1015 echo 'No:<input type="number" name="liquid_blocks_no['.$i.']" value="'.esc_html($no).'"></p>';
1016 }
1017 ?>
1018 <h3><?php _e( 'Enable', 'liquid-blocks' ); ?> LIQUID BLOCKS</h3>
1019 <p>
1020 <label for="liquid_blocks_toggle_on"><input type="radio" id="liquid_blocks_toggle_on" name="liquid_blocks_toggle" value="0" <?php echo $toggle_on; ?>>On</label>
1021 <label for="liquid_blocks_toggle_off"><input type="radio" id="liquid_blocks_toggle_off" name="liquid_blocks_toggle" value="1" <?php echo $toggle_off; ?>>Off</label>
1022 </p>
1023 <?php submit_button(); ?>
1024 </form>
1025 </div>
1026 </div>
1027
1028 </div><!-- /poststuff -->
1029 <hr><a href="https://lqd.jp/wp/" target="_blank">LIQUID PRESS</a>
1030 </div><!-- /wrap -->
1031 <?php } ?>