commit 028d59514486341ec1999bf774cbf28930957031 Author: Daniel Reintanz <85614916+FreelancerAMP@users.noreply.github.com> Date: Wed Oct 1 11:43:20 2025 +0200 ADDED Code of Version 2.0.0 of the Advanced Composer Blocks for Newsletter Plugin diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..b4c35a8 --- /dev/null +++ b/README.txt @@ -0,0 +1,81 @@ +=== Advanced Composer Blocks for Newsletter === +Contributors: mdburnette +Tags: email, newsletter, composer, blocks +License: GPLv2 or later +Requires at least: 6.0 +Tested up to: 6.7 +Requires PHP: 7.0 +Stable tag: 2.0.0 + +A set of enhanced composer blocks and additional settings to extend The Newsletter Plugin. + +== Description == +The WordPress plugin that lets you craft modern email newsletters with custom fields and new design options. + +With upgraded blocks and custom field functionality, Advanced Composer Blocks elevates your newsletter with design and content options not available anywhere else for the Newsletter plugin. + +NOTE: Requires at least free version of the [Newsletter](https://wordpress.org/plugins/newsletter/) plugin. + +## Plugin features: + +- 6 new, feature-packed blocks - Six additional, advanced composer blocks open up a ton of new design and content options. +- Composer editing enhancement - Make testing your newsletters even easier with the "Live Preview" button that allows you to quickly preview your email newsletter in a new tab. +- Composer editing enhancement - Make crafting your newsletters faster with composer block "COPY" and "PASTE" features - which allows you to duplicate blocks between emails as well! +- WordPress custom field tags - Take advantage of the custom fields you already have to further simplify creating post listings. + +## Blocks included: + +- Text+ [Watch demo video](https://youtu.be/Im6x9rhhYqs) +- Image+ [Watch demo video](https://youtu.be/bbLuWLMpkms) +- Posts List [Watch demo video](https://youtu.be/IgBt_GlWT6w) +- Cover [Watch demo video](https://youtu.be/xl7HzM2PmXE) +- Call to Action+ [Watch demo video](https://youtu.be/cW2Am-ehr0c) +- Single Post+ [Watch demo video](https://youtu.be/8s4DFUUJ4NI) + +== Screenshots == +1. Included composer blocks, each with a distinct dark blue icon +2. Font, color, and layout options for the Posts List block +3. Example of Text+ block and options +4. Cover block with image upload, overlay, and layout options + +== Changelog == +→ 11.29.24 - 2.0.0 +- Rolled premium features into the free version, discontinued paid offering + +→ 06.26.24 - 1.3.2 +- Fixed issue with copy/paste links showing in final email + +→ 06.24.24 - 1.3.1 +- Fixed CSS nesting issue +- Updated Freemius SDK to 2.7.2 + +→ 06.24.24 - 1.3.0 +- Added ability to copy/paste blocks between emails + +→ 04.11.24 - 1.2.0 +- Fixed double-declaring of a function +- Misc typos + +→ 03.23.24 - 1.1.1 +- Additional cleanup for inclusion in the WordPress.org repo + +→ 03.13.24 - 1.1 +- Lots of PHP cleanup for inclusion in the WordPress.org repo + +→ 01.26.24 - 1.0.4 +- Added free version of plugin with Posts List and Image+ as free blocks! +- Updates to be WordPress.org repository compliant +- Fixed Posts List thumbnail showing by default + +→ 01.18.24 - 1.0.3 +- Fixed Single Post+ button hiding not working. + +→ 01.18.24 - 1.0.2 +- Fixed naming of a couple of blocks. + +→ 01.17.24 - 1.0.1 +- Removed "row gap" option from Single Post+ (not needed). +- Changed how custom field tags are used and updated instructions. + +→ 01.16.24 - 1.0.0 +- Initial soft release. \ No newline at end of file diff --git a/blocks/mbtnp-cover/block.php b/blocks/mbtnp-cover/block.php new file mode 100644 index 0000000..a9ff8f4 --- /dev/null +++ b/blocks/mbtnp-cover/block.php @@ -0,0 +1,160 @@ + 'Cover Title', + 'title_font_family' => '', + 'title_font_size' => '', + 'title_font_weight' => '', + 'title_font_color' => '', + 'title_font_align' => 'center', + 'text' => 'Cover block text (optional)', + 'font_family' => '', + 'font_size' => '', + 'font_weight' => '', + 'font_color' => '', + 'overlay-opacity' => 50, + 'padding-top' => 40, + 'padding-bottom' => 40, + 'padding-left' => 40, + 'padding-right' => 40, + 'block_padding_top' => 30, + 'block_padding_bottom' => 30, + 'block_padding_left' => 0, + 'block_padding_right' => 0, + 'block_background' => '', +); + +$options = array_merge($defaults, $options); + +$title_style = TNP_Composer::get_title_style($options, 'title', $composer); +$text_style = TNP_Composer::get_text_style($options, '', $composer); + +$media = false; + +if ( !empty($options['image']['id']) ) { + $td_width = round(($composer['width'] - $options['block_padding_left'] - $options['block_padding_right'] - 20) / 2); + //$image_width = 300 - $options['block_padding_left']; + $media = tnp_resize_2x( $options['image']['id'], [$td_width, 0] ); +} ?> + + + + + +
+ + + + + + + + + + + + + + +
+ +
+ +
+
\ No newline at end of file diff --git a/blocks/mbtnp-cover/icon.png b/blocks/mbtnp-cover/icon.png new file mode 100644 index 0000000..405c5db Binary files /dev/null and b/blocks/mbtnp-cover/icon.png differ diff --git a/blocks/mbtnp-cover/options.php b/blocks/mbtnp-cover/options.php new file mode 100644 index 0000000..70a8684 --- /dev/null +++ b/blocks/mbtnp-cover/options.php @@ -0,0 +1,64 @@ + + +hidden('image_url') ?> + +media('image', __('Image', 'advanced-composer-blocks-for-newsletter'), array('alt' => false)) ?> + +
+
+ color('overlay-color', __('Overlay color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ number('overlay-opacity', __('Overlay opacity', 'advanced-composer-blocks-for-newsletter'), array('min' => 0, 'max' => 100)) ?> + +
+
+ size('border-radius', __('Border radius', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ +text('title', __('Title', 'advanced-composer-blocks-for-newsletter')) ?> +font('title_font', '', ['family_default'=>true, 'size_default'=>true, 'weight_default'=>true, 'align'=>true]) ?> + +textarea('text', __('Text', 'advanced-composer-blocks-for-newsletter')) ?> +font( 'font', '', [ 'family_default' => true, 'size_default' => true, 'weight_default' => true, 'align'=>true ] ) ?> + +
+
+

Padding

+ + + + + + +
size('padding-left', __('← Left', 'advanced-composer-blocks-for-newsletter')) ?>size('padding-top', __('↑ Top', 'advanced-composer-blocks-for-newsletter')) ?>size('padding-bottom', __('↓ Bottom', 'advanced-composer-blocks-for-newsletter')) ?>size('padding-right', __('→ Right', 'advanced-composer-blocks-for-newsletter')) ?>
+
+
+ +
+
+

Box shadow

+ + + + + + + + +
color('box-shadow-color', __('Color', 'advanced-composer-blocks-for-newsletter')) ?>size('box-shadow-x', __('↔ X-offset', 'advanced-composer-blocks-for-newsletter')) ?>size('box-shadow-y', __('↕ Y-offset', 'advanced-composer-blocks-for-newsletter')) ?>size('box-shadow-blur', __('Blur', 'advanced-composer-blocks-for-newsletter')) ?>size('box-shadow-spread', __('Spread', 'advanced-composer-blocks-for-newsletter')) ?>
+
+
+ +
+ +block_commons() ?> \ No newline at end of file diff --git a/blocks/mbtnp-cta/block.php b/blocks/mbtnp-cta/block.php new file mode 100644 index 0000000..f7efa36 --- /dev/null +++ b/blocks/mbtnp-cta/block.php @@ -0,0 +1,59 @@ + 'Learn more', + 'button_url' => '', + 'button_color' => '#000000', + 'button_border_radius' => '3', + 'text_color' => '#ffffff', + 'align' => 'center', + 'block_background' => '', + 'button_width' => 'inline', + 'button_align' => 'center', + 'block_padding_top' => 20, + 'block_padding_bottom' => 20, + 'schema' => '' +); + +$options = array_merge($default_options, $options); + +$text_style = TNP_Composer::get_style($options, 'button_text', $composer, 'text'); +?> + + + + + + + +
+ +
\ No newline at end of file diff --git a/blocks/mbtnp-cta/icon.png b/blocks/mbtnp-cta/icon.png new file mode 100644 index 0000000..4be4c9e Binary files /dev/null and b/blocks/mbtnp-cta/icon.png differ diff --git a/blocks/mbtnp-cta/options.php b/blocks/mbtnp-cta/options.php new file mode 100644 index 0000000..3e874fa --- /dev/null +++ b/blocks/mbtnp-cta/options.php @@ -0,0 +1,39 @@ + + +text('button_text', __('Button text', 'advanced-composer-blocks-for-newsletter')) ?> +font('button_text_font', '', [ 'family_default' => true, 'size_default' => true, 'weight_default' => true, 'align'=>false, 'color'=>false ] ) ?> + +url('button_url', __('Button link URL', 'advanced-composer-blocks-for-newsletter') ) ?> + + +
+
+ color('text_color', __('Text color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ color('button_color', __('Button color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ size('button_border_radius', __('Border radius', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ +
+
+ select('button_width', 'Width', ['inline' => __('Inline'), 'full_width' => __('Full width')]) ?> +
+
+ select('button_align', 'Alignment', ['center' => __('Center'), 'left' => __('Left'), 'right' => __('Right')]) ?> +
+
+ +
+ +block_commons() ?> diff --git a/blocks/mbtnp-image/block.php b/blocks/mbtnp-image/block.php new file mode 100644 index 0000000..6a1ad8a --- /dev/null +++ b/blocks/mbtnp-image/block.php @@ -0,0 +1,110 @@ + '', + 'image-alt' => '', + 'url' => '', + 'width' => 0, + 'border-radius' => '7', + 'box-shadow-x' => '0', + 'box-shadow-y' => '0', + 'box-shadow-blur' => '0', + 'box-shadow-spread' => '0', + 'box-shadow-color' => '#ffffff', + 'align' => 'center', + 'block_background' => '', + 'block_padding_left' => 0, + 'block_padding_right' => 0, + 'block_padding_bottom' => 15, + 'block_padding_top' => 15 +); + +$options = array_merge($defaults, $options); + +if (empty($options['image']['id'])) { + if ( !empty($options['image-url']) ) { + $media = new TNP_Media(); + $media->url = $options['image-url']; + $media->width = $composer['width']; + } else { + $media = new TNP_Media(); + // A placeholder can be set by a preset and it is kept indefinitely + if ( !empty($options['placeholder']) ) { + $media->url = $options['placeholder']; + $media->width = $composer['width']; + $media->height = 250; + } else { + $media->url = esc_url( MBTNP_PLUGIN_URL . '/images/placeholder-image.jpg' ); + $media->width = $composer['width']; + $media->height = 250; + } + } +} else { + $media = tnp_resize_2x($options['image']['id'], [$composer['width'], 0]); + // Should never happen but... it happens + if (!$media) { + echo 'The selected media file cannot be processed'; + return; + } +} + +if (!empty($options['width'])) { + $media->set_width( $options['width'] ); +} +$media->link = $options['url']; +$media->alt = $options['image-alt']; +$media->border_radius = $options['border-radius']; + +echo '
'; + +if ( $media->link ) { + echo ''; +} else { +} + +echo 'height ) { + echo ' height="', esc_attr( $media->height ), '"'; +} +echo ' alt="', esc_attr( $media->alt ), '"'; +// The font size is important for the alt text +echo ' border="0" style="display: block; height: auto; max-width: ', esc_attr( $media->width ), 'px !important; width: 100%; padding: 0; border: 0; font-size: 12px;'; +if( $media->border_radius ){ + echo ' border-radius: ' . esc_attr( $media->border_radius ) . 'px;'; +} +if( $options['box-shadow-x'] || $options['box-shadow-y'] || $options['box-shadow-blur'] || $options['box-shadow-spread'] || $options['box-shadow-color'] ){ + + if( empty($options['box-shadow-x']) ){ $options['box-shadow-x'] = '0'; } + if( empty($options['box-shadow-y']) ){ $options['box-shadow-y'] = '0'; } + if( empty($options['box-shadow-blur']) ){ $options['box-shadow-blur'] = '0'; } + if( empty($options['box-shadow-spread']) ){ $options['box-shadow-spread'] = '0'; } + if( empty($options['box-shadow-color']) ){ $options['box-shadow-color'] = '#000000'; } + + echo ' box-shadow: ' . esc_attr( $options['box-shadow-x'] ) . 'px ' . esc_attr( $options['box-shadow-y'] ) . 'px ' . esc_attr( $options['box-shadow-blur'] ) . 'px ' . esc_attr( $options['box-shadow-spread'] ) . 'px ' . esc_attr( $options['box-shadow-color'] ) . ';'; +} +echo '">'; + +if ( $media->link ) { + echo ''; +} else { +} + +echo '
'; \ No newline at end of file diff --git a/blocks/mbtnp-image/icon.png b/blocks/mbtnp-image/icon.png new file mode 100644 index 0000000..3cb940c Binary files /dev/null and b/blocks/mbtnp-image/icon.png differ diff --git a/blocks/mbtnp-image/options.php b/blocks/mbtnp-image/options.php new file mode 100644 index 0000000..ea6e8da --- /dev/null +++ b/blocks/mbtnp-image/options.php @@ -0,0 +1,53 @@ + + +hidden('placeholder') ?> +media('image', 'Choose an image', array('alt' => false)) ?> +url('image-url', 'or full path to an external image') ?> +text('image-alt', 'Alternative text') ?> +url('url', __('Link URL (if you want to link the image)', 'advanced-composer-blocks-for-newsletter')) ?> + +
+
+ size('width', __('Width', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ align() ?> +
+
+ +
+ +
+
+ size('border-radius', __('Border radius', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+

Box shadow

+ + + + + + + + +
color('box-shadow-color', __('Color', 'advanced-composer-blocks-for-newsletter')) ?>size('box-shadow-x', __('↔ X-offset', 'advanced-composer-blocks-for-newsletter')) ?>size('box-shadow-y', __('↕ Y-offset', 'advanced-composer-blocks-for-newsletter')) ?>size('box-shadow-blur', __('Blur', 'advanced-composer-blocks-for-newsletter')) ?>size('box-shadow-spread', __('Spread', 'advanced-composer-blocks-for-newsletter')) ?>
+
+
+ +
+ +block_commons() ?> diff --git a/blocks/mbtnp-posts-list/block.php b/blocks/mbtnp-posts-list/block.php new file mode 100644 index 0000000..940e3b4 --- /dev/null +++ b/blocks/mbtnp-posts-list/block.php @@ -0,0 +1,223 @@ +'post', + 'number_posts' => 3, + 'wrap_padding_left' => 10, + 'wrap_padding_right' => 10, + 'wrap_padding_top' => 10, + 'wrap_padding_bottom' => 10, + 'wrap_border_width' => 0, + 'wrap_border_color' => '#000000', + 'wrap_border_radius' => 0, + 'post_list_row_gap' => 0, + 'image_align' => 'left', + 'image_size' => 'none', + 'border_radius' => 0, + 'hide_titles' => '', + 'link_titles' => '', + 'title_font_size' => '24', + 'title_font_align' => 'left', + 'post_date_font_size' => '14', + 'post_date_font_align' => 'left', + 'post_content_font_size' => '16', + 'post_content_font_align' => 'left', + 'show_content' => 'none', + 'button_text' => 'Read more', + 'button_text_font_size' => '16', + 'button_color' => '#000000', + 'button_text_color' => '#ffffff', + 'button_border_radius' => '3', + 'button_align' => 'left', + 'block_padding_left'=>15, + 'block_padding_right'=>15, + 'block_padding_top' => 20, + 'block_padding_bottom' => 20, + 'block_background'=>'#eeeeee' +); + +$options = array_merge($default_options, $options); + +$title_style = TNP_Composer::get_title_style($options, 'title', $composer); +$post_date_style = TNP_Composer::get_title_style($options, 'post_date', $composer); +$post_content_style = TNP_Composer::get_title_style($options, 'post_content', $composer); +$button_text_style = TNP_Composer::get_title_style($options, 'button_text', $composer); +$text_style = TNP_Composer::get_style($options, '', $composer, 'text'); +$post_custom_html_style = TNP_Composer::get_style($options, '', $composer, 'post_custom_html'); + +?> + + +
+ + + $options['post_type'], + 'posts_per_page' => $options['number_posts'] + ); + if( $options['post_order'] == 'title_asc' ){ + $post_list_args['orderby'] = 'title'; + $post_list_args['order'] = 'ASC'; + } else if( $options['post_order'] == 'title_desc' ){ + $post_list_args['orderby'] = 'title'; + $post_list_args['order'] = 'DESC'; + } else if( $options['post_order'] == 'date_asc' ){ + $post_list_args['orderby'] = 'date'; + $post_list_args['order'] = 'ASC'; + } else if( $options['post_order'] == 'date_desc' ){ + $post_list_args['orderby'] = 'date'; + $post_list_args['order'] = 'DESC'; + } + $posts_list = get_posts($post_list_args); ?> + + + + + + +
+ +
+ ID) ).'" inline-class="featured-image-link">'; } ?> + + '; } ?> +
+ + +

+ ID) ).'" inline-class="title-link">'; } ?> + post_title ); ?> + '; } ?> +

+ + +

+ post_date) ) ); ?> +

+ + +
+ ID, $options['excerpt_length'] ) ); + } else { + echo wp_kses_post( get_the_excerpt( $post->ID ) ); + } ?> +
+ + +
+ ID) ); ?> +
+ + +
+ ID ) ); ?> +
+ + + + +
+
\ No newline at end of file diff --git a/blocks/mbtnp-posts-list/icon.png b/blocks/mbtnp-posts-list/icon.png new file mode 100644 index 0000000..6b5d1d6 Binary files /dev/null and b/blocks/mbtnp-posts-list/icon.png differ diff --git a/blocks/mbtnp-posts-list/options.php b/blocks/mbtnp-posts-list/options.php new file mode 100644 index 0000000..20ac015 --- /dev/null +++ b/blocks/mbtnp-posts-list/options.php @@ -0,0 +1,246 @@ + + + true ), 'objects' ); +$post_type_options = []; +foreach($post_types as $post_type){ + $post_type_options[$post_type->name] = $post_type->label; +} + +// get all thumbnail size options +$image_sizes = wp_get_registered_image_subsizes(); +$image_size_options = ['none' => 'None']; +foreach($image_sizes as $name => $details){ + $image_size_options[$name] = ucfirst(str_replace('_', ' ', $name)) . ' (' . $details['width'] . 'x' . $details['height'] . ')'; +} +$image_size_options['full'] = 'Full'; +?> + +
+
+ select('post_type', __('Post type'), $post_type_options) ?> +
+
+ select('post_order', __('Post order'), ['title_asc' => 'Title ASC', 'title_desc' => 'Title DESC', 'date_asc' => 'Post date ASC', 'date_desc' => 'Post date DESC']) ?> +
+
+ number('number_posts', __('Number of posts'), ['min' => 1]) ?> +
+
+ +

Featured images

+
+
+ select('image_size', __('Image size'), $image_size_options) ?> +
+ +
+ +
+
+ select('image_align', __('Align'), ['left' => 'Left', 'center' => 'Center', 'right' => 'Right']) ?> +
+
+ size('border_radius', __('Border radius', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ +

Titles

+
+
+ checkbox('hide_titles', __('Hide titles')) ?> +
+ +
+ +
+ font('title_font', '', ['family_default'=>true, 'size_default'=>true, 'weight_default'=>true, 'align'=>true]) ?> +
+ +

Post dates

+
+
+ checkbox('show_post_dates', __('Show post dates')) ?> +
+
+ +
+ font('post_date_font', '', ['family_default'=>true, 'size_default'=>true, 'weight_default'=>true, 'align'=>true]) ?> +
+ +

Post content

+
+
+ select('show_content', __('Show content'), ['none' => 'None', 'excerpt' => 'Excerpt', 'full' => 'Full']) ?> +
+
+ number('excerpt_length', __('Excerpt length (characters)')) ?> +
+
+ +
+ font('post_content_font', '', ['family_default'=>true, 'size_default'=>true, 'weight_default'=>true, 'align'=>true]) ?> +
+ +

Custom content

+

Add custom fields by using brackets. Ex: for "custom_name", use {field_custom_name}

+wp_editor( 'post_custom_html', 'Content', [ + 'post_custom_html_font_family' => $composer['post_custom_html_font_family'], + 'post_custom_html_font_size' => $composer['post_custom_html_font_size'], + 'post_custom_html_font_weight' => $composer['post_custom_html_font_weight'], + 'post_custom_html_font_color' => $composer['post_custom_html_font_color'], +] ) ?> + +

Buttons

+checkbox('hide_buttons', __('Hide buttons')) ?> +
+ text('button_text', __('Button text', 'advanced-composer-blocks-for-newsletter')) ?> + font('button_text_font', '', [ 'family_default' => true, 'size_default' => true, 'weight_default' => true, 'align'=>false, 'color'=>false ] ) ?> +
+ +
+
+ color('button_text_color', __('Text color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ color('button_color', __('Button color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ size('button_border_radius', __('Border radius', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ +
+
+ select('button_width', 'Width', ['inline' => __('Inline'), 'full_width' => __('Full width')]) ?> +
+
+ select('button_align', 'Alignment', ['center' => __('Center'), 'left' => __('Left'), 'right' => __('Right')]) ?> +
+
+ +

Layout

+size('post_list_row_gap', __('Row gap', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ size('wrap_border_radius', __('Border radius', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ color('wrap_background_color', __('Background color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ size('wrap_border_width', __('Border width', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ color('wrap_border_color', __('Border color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ +
+
+ + + + + + +
size('wrap_padding_left', __('← Left', 'advanced-composer-blocks-for-newsletter')) ?>size('wrap_padding_top', __('↑ Top', 'advanced-composer-blocks-for-newsletter')) ?>size('wrap_padding_bottom', __('↓ Bottom', 'advanced-composer-blocks-for-newsletter')) ?>size('wrap_padding_right', __('→ Right', 'advanced-composer-blocks-for-newsletter')) ?>
+
+
+ + +
+ + + +block_commons() ?> \ No newline at end of file diff --git a/blocks/mbtnp-single-post/block.php b/blocks/mbtnp-single-post/block.php new file mode 100644 index 0000000..342f032 --- /dev/null +++ b/blocks/mbtnp-single-post/block.php @@ -0,0 +1,234 @@ + 10, + 'wrap_padding_right' => 10, + 'wrap_padding_top' => 10, + 'wrap_padding_bottom' => 10, + 'wrap_border_width' => 0, + 'wrap_border_color' => '#000000', + 'wrap_border_radius' => 0, + 'image_align' => 'center', + 'image_size' => 'medium', + 'link_image' => '', + 'border_radius' => 0, + 'hide_title' => '', + 'link_title' => '', + 'title_font_size' => '24', + 'title_font_align' => 'left', + 'post_date_font_size' => '16', + 'post_date_font_align' => 'left', + 'post_content_font_size' => '16', + 'post_content_font_align' => 'left', + 'post_custom_html_font_size' => '16', + 'post_custom_html_font_align' => 'left', + 'post_custom_html_font_color' => '#000000', + 'show_content' => 'excerpt', + 'hide_button' => '', + 'button_text' => 'Read more', + 'button_text_font_size' => '16', + 'button_color' => '#000000', + 'button_text_color' => '#ffffff', + 'button_border_radius' => '3', + 'button_align' => 'left', + 'block_padding_left'=>15, + 'block_padding_right'=>15, + 'block_padding_top' => 20, + 'block_padding_bottom' => 20, + 'block_background'=>'#eeeeee' +); + +$options = array_merge($default_options, $options); + +$title_style = TNP_Composer::get_title_style($options, 'title', $composer); +$post_date_style = TNP_Composer::get_title_style($options, 'post_date', $composer); +$post_content_style = TNP_Composer::get_title_style($options, 'post_content', $composer); +$button_text_style = TNP_Composer::get_title_style($options, 'button_text', $composer); +$text_style = TNP_Composer::get_style($options, '', $composer, 'text'); +$post_custom_html_style = TNP_Composer::get_style($options, 'post_custom_html', $composer); + +?> + + +
+ + + + $post_arr, + 'posts_per_page' => 1, + 'post_type' => $post_type + ); + $posts_list = get_posts($post_list_args); ?> + + + + + + + + + + + + + + + +
+ +
+ ID) ) . '" inline-class="featured-image-link">'; } ?> + + '; } ?> +
+ + +

+ ID) ) . '" inline-class="title-link">'; } ?> + post_title ); ?> + '; } ?> +

+ + +

+ post_date) ) ); ?> +

+ + +
+ ID, $options['excerpt_length'] ) ); + } else { + echo wp_kses_post( get_the_excerpt( $post->ID ) ); + } ?> +
+ + +
+ ID) ); ?> +
+ + +
+ ID ) ); ?> +
+ + + + +

That post ID is not valid. How to find your post ID.

Please enter a post ID. How to find your post ID.

+
\ No newline at end of file diff --git a/blocks/mbtnp-single-post/icon.png b/blocks/mbtnp-single-post/icon.png new file mode 100644 index 0000000..10143f4 Binary files /dev/null and b/blocks/mbtnp-single-post/icon.png differ diff --git a/blocks/mbtnp-single-post/options.php b/blocks/mbtnp-single-post/options.php new file mode 100644 index 0000000..c629417 --- /dev/null +++ b/blocks/mbtnp-single-post/options.php @@ -0,0 +1,248 @@ + + + true ), 'objects' ); +$post_type_options = []; +foreach($post_types as $post_type){ + $post_type_options[$post_type->name] = $post_type->label; +} + +// get all thumbnail size options +$image_sizes = wp_get_registered_image_subsizes(); +$image_size_options = ['none' => 'None']; +foreach($image_sizes as $name => $details){ + $image_size_options[$name] = ucfirst(str_replace('_', ' ', $name)) . ' (' . $details['width'] . 'x' . $details['height'] . ')'; +} +$image_size_options['full'] = 'Full'; +?> + +
+
+ text('post_id', __('Post ID', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+   +
+
+   +
+
+ +

Featured image

+
+
+ select('image_size', __('Image size', 'advanced-composer-blocks-for-newsletter'), $image_size_options) ?> +
+ +
+ +
+
+ select('image_align', __('Align', 'advanced-composer-blocks-for-newsletter'), ['center' => 'Center', 'left' => 'Left', 'right' => 'Right']) ?> +
+
+ size('border_radius', __('Border radius', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ +

Title

+
+
+ checkbox('hide_title', __('Hide title', 'advanced-composer-blocks-for-newsletter')) ?> +
+ +
+ +
+ font('title_font', '', ['family_default'=>true, 'size_default'=>true, 'weight_default'=>true, 'align'=>true]) ?> +
+ +

Post date

+
+
+ checkbox('show_post_date', __('Show post date', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ +
+ font('post_date_font', '', ['family_default'=>true, 'size_default'=>true, 'weight_default'=>true, 'align'=>true]) ?> +
+ +

Post content

+
+
+ select('show_content', __('Show content', 'advanced-composer-blocks-for-newsletter'), ['none' => 'None', 'excerpt' => 'Excerpt', 'full' => 'Full']) ?> +
+
+ number('excerpt_length', __('Excerpt length (characters)', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ +
+ font('post_content_font', '', ['family_default'=>true, 'size_default'=>true, 'weight_default'=>true, 'align'=>true]) ?> +
+ +

Custom content

+

Add custom fields by using brackets. Ex: for "custom_name", use {field_custom_name}

+wp_editor( 'post_custom_html', 'Content', [ + 'post_custom_html_font_family' => $composer['post_custom_html_font_family'], + 'post_custom_html_font_size' => $composer['post_custom_html_font_size'], + 'post_custom_html_font_weight' => $composer['post_custom_html_font_weight'], + 'post_custom_html_font_color' => $composer['post_custom_html_font_color'], +] ) ?> + +

Button

+checkbox('hide_button', __('Hide button', 'advanced-composer-blocks-for-newsletter')) ?> +
+ text('button_text', __('Button text', 'advanced-composer-blocks-for-newsletter')) ?> + font('button_text_font', '', [ 'family_default' => true, 'size_default' => true, 'weight_default' => true, 'align'=>false, 'color'=>false ] ) ?> +
+ +
+
+ color('button_text_color', __('Text color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ color('button_color', __('Button color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ size('button_border_radius', __('Border radius', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ +
+
+ select('button_width', 'Width', ['inline' => __('Inline', 'advanced-composer-blocks-for-newsletter'), 'full_width' => __('Full width', 'advanced-composer-blocks-for-newsletter')]) ?> +
+
+ select('button_align', 'Alignment', ['center' => __('Center'), 'left' => __('Left'), 'right' => __('Right')]) ?> +
+
+ +

Layout

+
+
+ size('wrap_border_radius', __('Border radius', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ color('wrap_background_color', __('Background color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ size('wrap_border_width', __('Border width', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ color('wrap_border_color', __('Border color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ +
+
+ + + + + + +
size('wrap_padding_left', __('← Left', 'advanced-composer-blocks-for-newsletter')) ?>size('wrap_padding_top', __('↑ Top', 'advanced-composer-blocks-for-newsletter')) ?>size('wrap_padding_bottom', __('↓ Bottom', 'advanced-composer-blocks-for-newsletter')) ?>size('wrap_padding_right', __('→ Right', 'advanced-composer-blocks-for-newsletter')) ?>
+
+
+ + +
+ + + +block_commons() ?> \ No newline at end of file diff --git a/blocks/mbtnp-text/block.php b/blocks/mbtnp-text/block.php new file mode 100644 index 0000000..030d490 --- /dev/null +++ b/blocks/mbtnp-text/block.php @@ -0,0 +1,96 @@ +'

Insert your text here.

', + 'font_family'=>'', + 'font_size'=>'', + 'font_color'=>'', + 'block_padding_left'=>15, + 'block_padding_right'=>15, + 'block_padding_top' => 20, + 'block_padding_bottom' => 20, + 'block_background'=>'#eeeeee' +); + +$options = array_merge($default_options, $options); + +$text_style = TNP_Composer::get_style($options, '', $composer, 'text'); + +?> + + + + + + +
+ +
\ No newline at end of file diff --git a/blocks/mbtnp-text/icon.png b/blocks/mbtnp-text/icon.png new file mode 100644 index 0000000..73ef94e Binary files /dev/null and b/blocks/mbtnp-text/icon.png differ diff --git a/blocks/mbtnp-text/options.php b/blocks/mbtnp-text/options.php new file mode 100644 index 0000000..7d85b08 --- /dev/null +++ b/blocks/mbtnp-text/options.php @@ -0,0 +1,83 @@ + +

+ You can use tags to inject subscriber fields. +

+ +wp_editor( 'html', 'Content', [ + 'text_font_family' => $composer['text_font_family'], + 'text_font_size' => $composer['text_font_size'], + 'text_font_weight' => $composer['text_font_weight'], + 'text_font_color' => $composer['text_font_color'], + 'background' => $background +] ) ?> + +
+
+ size('border-radius', __('Border radius', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ color('background-color', __('Background color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ color('border-color', __('Border color', 'advanced-composer-blocks-for-newsletter')) ?> +
+
+ +
+
+

Padding

+ + + + + + +
size('padding-left', __('← Left', 'advanced-composer-blocks-for-newsletter')) ?>size('padding-top', __('↑ Top', 'advanced-composer-blocks-for-newsletter')) ?>size('padding-bottom', __('↓ Bottom', 'advanced-composer-blocks-for-newsletter')) ?>size('padding-right', __('→ Right', 'advanced-composer-blocks-for-newsletter')) ?>
+
+
+ +
+
+

Border

+ + + + + + +
size('border-left', __('← Left', 'advanced-composer-blocks-for-newsletter')) ?>size('border-top', __('↑ Top', 'advanced-composer-blocks-for-newsletter')) ?>size('border-bottom', __('↓ Bottom', 'advanced-composer-blocks-for-newsletter')) ?>size('border-right', __('→ Right', 'advanced-composer-blocks-for-newsletter')) ?>
+
+
+ +
+
+

Box shadow

+ + + + + + + + +
color('box-shadow-color', __('Color', 'advanced-composer-blocks-for-newsletter')) ?>size('box-shadow-x', __('↔ X-offset', 'advanced-composer-blocks-for-newsletter')) ?>size('box-shadow-y', __('↕ Y-offset', 'advanced-composer-blocks-for-newsletter')) ?>size('box-shadow-blur', __('Blur', 'advanced-composer-blocks-for-newsletter')) ?>size('box-shadow-spread', __('Spread', 'advanced-composer-blocks-for-newsletter')) ?>
+
+
+ +
+ +block_commons() ?> \ No newline at end of file diff --git a/css/mbtnp-blocks-copy-paste-block.css b/css/mbtnp-blocks-copy-paste-block.css new file mode 100644 index 0000000..62436ce --- /dev/null +++ b/css/mbtnp-blocks-copy-paste-block.css @@ -0,0 +1,39 @@ +/* Copy/Paste styles */ +.tnpc-row-mbtnp-copy, +.tnpc-row-mbtnp-paste { + height: 30px; + width: 30px; + top: 0px; + background-color: rgba(255,255,255,0.5); + z-index: 5; + position: absolute; + color: rgba(102,102,102,1); + transition: all 0.2s; + opacity: 0; + text-align: center; + font-size: 18px; + cursor: pointer; + + &:hover { + background-color: #e0e0e0; + cursor: pointer; + color: rgba(0, 0, 0, 1); + + img { + transform: scale(0.8); + } + } +} + +.tnpc-row-mbtnp-copy { + right: 120px; +} + +.tnpc-row-mbtnp-paste { + right: 90px; +} + +.tnpc-row:hover .tnpc-row-mbtnp-copy, +.tnpc-row:hover .tnpc-row-mbtnp-paste { + opacity: 1; +} \ No newline at end of file diff --git a/images/icon-copy.png b/images/icon-copy.png new file mode 100644 index 0000000..5ebe587 Binary files /dev/null and b/images/icon-copy.png differ diff --git a/images/icon-paste.png b/images/icon-paste.png new file mode 100644 index 0000000..4136d99 Binary files /dev/null and b/images/icon-paste.png differ diff --git a/images/placeholder-image.jpg b/images/placeholder-image.jpg new file mode 100644 index 0000000..4585af8 Binary files /dev/null and b/images/placeholder-image.jpg differ diff --git a/inc/menus.php b/inc/menus.php new file mode 100644 index 0000000..7598c05 --- /dev/null +++ b/inc/menus.php @@ -0,0 +1,77 @@ + +
+

Advanced Composer Blocks Settings

+
+ +
+
+ Customize the behavior of Advanced Composer Blocks.

'; +} + +function mbtnp_disable_live_preview_cb() { + $options = get_option('acb_settings'); + ?> + /> +
'; + + function showToast(message, type = 'info') { + let backgroundColor = '#000'; // Default color for 'info' + if (type === 'success') { + backgroundColor = '#234567'; // MBTNP blue for success + } else if (type === 'error') { + backgroundColor = '#dc3545'; // Red for error + } + + Toastify({ + text: message, + backgroundColor: backgroundColor, + duration: 3000, + gravity: 'top', // 'top' or 'bottom' + position: 'center', // 'left', 'center' or 'right' + }).showToast(); + } + + function addCopyPasteButtons() { + // add new copy/paste buttons + $('.tnpc-row .tnpc-row-clone').each(function () { + console.log($(this).parents('table').find('.tnpc-row-mbtnp-copy').length); + if ($(this).parents('table').find('.tnpc-row-mbtnp-copy').length < 1) { + $(this).after(copyPasteHTML); + } + }); + // remove any instances not in a table element + $('.tnpc-row-mbtnp-copy.ui-sortable-handle, .tnpc-row-mbtnp-paste.ui-sortable-handle').each(function () { + $(this).remove(); + }); + } + + function initializeCopyPasteFunctionality() { + $(document).delegate('.tnpc-row-mbtnp-copy', 'click', function (e) { + e.preventDefault(); + + let row = $(this).closest('.tnpc-row'); + let new_row = row.clone(); + let row_operations = new_row.find('.tnpc-row-delete, .tnpc-row-edit-block, .tnpc-row-clone, .tnpc-row-mbtnp-copy, .tnpc-row-mbtnp-paste'); + + // remove row operations + row_operations.remove(); + + // save row outer HTML to localStorage + localStorage.setItem('mbtnp-row-ops-copy', row_operations[0].outerHTML); + localStorage.setItem('mbtnp-row-copy', new_row[0].outerHTML); + + showToast('Block copied!', 'success'); + }); + + $(document).delegate('.tnpc-row-mbtnp-paste', 'click', function (e) { + e.preventDefault(); + + let row = $(this).closest('.tnpc-row'); + let row_copy = localStorage.getItem('mbtnp-row-copy'); + let row_ops = localStorage.getItem('mbtnp-row-ops-copy'); + + if (row_copy) { + // Create a jQuery object from the copied HTML string + let new_row = $(row_copy); + + // Append the new row after the current row + row.after(new_row); + + // Add row operations inside the new row + new_row.append(row_ops); + + // Re-add delete, edit, and clone functionality + new_row.add_delete(); + new_row.add_block_edit(); + new_row.add_block_clone(); + + // Add copy/paste buttons to new block + new_row.find('.tnpc-row-clone').after(copyPasteHTML); + + // Scroll to the new row within the tnpb-content div + $('#tnpb-content').animate({ + scrollTop: new_row.offset().top - $('#tnpb-content').offset().top + $('#tnpb-content').scrollTop() + }, 500); + + showToast('Block pasted successfully!', 'success'); + } else { + showToast('No copied block found. Please copy a block first.', 'error'); + } + }); + } + + function customInitBuilderArea() { + init_builder_area(); // Call the original builder initialization + addCopyPasteButtons(); // Add custom copy/paste buttons + initializeCopyPasteFunctionality(); // Initialize copy/paste functionality + + // Add copy/paste buttons to any new blocks inserted into the editor + $(document).on('DOMNodeInserted', '.tnpc-row', function () { + addCopyPasteButtons(); + }); + } + + // Override the original start_composer function + function customStartComposer() { + customInitBuilderArea(); + + // The rest of the original start_composer code + // Closes the block options layer (without saving) + jQuery("#tnpc-block-options-cancel").click(function () { + tnpc_hide_block_options(); + var _target = target; + jQuery.post(ajaxurl, start_options, function (response) { + _target.html(response); + jQuery("#tnpc-block-options-form").html(""); + }); + }); + + // Fires the save event for block options + jQuery("#tnpc-block-options-save").click(function (e) { + e.preventDefault(); + var _target = target; + + // fix for Codemirror + if (typeof templateEditor !== 'undefined') { + templateEditor.save(); + } + + if (window.tinymce) + window.tinymce.triggerSave(); + + var data = jQuery("#tnpc-block-options-form").serializeArray(); + tnpc_add_global_options(data); + tnpc_hide_block_options(); + + jQuery.post(ajaxurl, data, function (response) { + _target.html(response); + jQuery("#tnpc-block-options-form").html(""); + }); + }); + + jQuery('#tnpc-block-options-form').change(function (event) { + var data = jQuery("#tnpc-block-options-form").serializeArray(); + var _container = tnp_container; + var _target = target; + tnpc_add_global_options(data); + + jQuery.post(ajaxurl, data, function (response) { + _target.html(response); + if (event.target.dataset.afterRendering === 'reload') { + _container.find(".tnpc-row-edit-block").click(); + } + }).fail(function () { + showToast("Block rendering failed", 'error'); + }); + }); + } + + // Assign the new start_composer function to be called + window.start_composer = customStartComposer; + + // Call the new start_composer function on document ready + $(document).ready(function () { + start_composer(); + }); + + + // when hovering over tnpc-button[value="Save"], remove copy/paste buttons + $(document).on('mouseenter', '.tnpc-button', function () { + $('.tnpc-row-mbtnp-copy, .tnpc-row-mbtnp-paste').remove(); + }); + +}); diff --git a/js/mbtnp-blocks-live-preview.js b/js/mbtnp-blocks-live-preview.js new file mode 100644 index 0000000..212d02e --- /dev/null +++ b/js/mbtnp-blocks-live-preview.js @@ -0,0 +1,26 @@ +jQuery(function ($) { + // ------------------------------------------------------------------- + + // Extract the ID from the URL + var urlParams = new URLSearchParams(window.location.search); + var id = urlParams.get('id'); + + // Only proceed if the ID is present + if (id) { + // Get the root domain + var domain = window.location.protocol + '//' + window.location.hostname; + + // Create the new button + var livePreviewButton = $('', { + class: 'button-primary', + href: domain + '/?na=view&id=' + id, + target: '_blank', + html: '' + }); + + // Append the button to the menu + $('.tnpb-actions').append(livePreviewButton); + } + + // ------------------------------------------------------------------- +}); \ No newline at end of file diff --git a/mbtnp-blocks.php b/mbtnp-blocks.php new file mode 100644 index 0000000..15b8fb1 --- /dev/null +++ b/mbtnp-blocks.php @@ -0,0 +1,150 @@ +Settings', + ); + $actions = array_merge( $actions, $mylinks ); + return $actions; +} + + +// --------------------------------------------------------------------------------- +// ----- REGISTER NEW BLOCKS ------------------------------------------------------- +// --------------------------------------------------------------------------------- +function mbtnp_newsletter_register_blocks() { + + $mbtnp_blocks = [ + "mbtnp-image", + "mbtnp-posts-list", + "mbtnp-text", + "mbtnp-cover", + "mbtnp-cta", + "mbtnp-single-post" + ]; + + $dir = __DIR__; + + foreach($mbtnp_blocks as $block){ + + if ( file_exists( $dir . '/blocks/' . $block ) ) { + TNP_Composer::register_block( $dir . '/blocks/' . $block ); + } + } +} +add_action( 'newsletter_register_blocks', 'mbtnp_newsletter_register_blocks' ); + + +// --------------------------------------------------------------------------------- +// ----- ADD LIVE PREVIEW BUTTON TO COMPOSER --------------------------------------- +// --------------------------------------------------------------------------------- +function mbtnp_add_live_preview_button_in_admin() { + // Get the current site's URL + $site_url = get_site_url(); + $acb_settings = get_option('acb_settings'); + $acb_live_preview_disable = isset($acb_settings['acb_disable_live_preview']) ? $acb_settings['acb_disable_live_preview'] : false; + + if ($acb_live_preview_disable) { + return; + } + + // enqueue live preview script + wp_enqueue_script( 'mbtnp-blocks-live-preview', plugin_dir_url( __FILE__ ) . 'js/mbtnp-blocks-live-preview.js', array('jquery'), '', true ); +} +add_action('admin_footer', 'mbtnp_add_live_preview_button_in_admin'); + + +// --------------------------------------------------------------------------------- +// ----- ADD COPY/PASTE BUTTONS TO COMPOSER BLOCKS --------------------------------- +// --------------------------------------------------------------------------------- +function mbtnp_add_blocks_copy_paste() { + + // enqueue live preview script and css + wp_enqueue_script( 'mbtnp-blocks-copy-paste', plugin_dir_url( __FILE__ ) . 'js/mbtnp-blocks-copy-paste-block.js', array('jquery'), '', true ); + wp_enqueue_style( 'mbtnp-blocks-copy-paste', plugin_dir_url( __FILE__ ) . 'css/mbtnp-blocks-copy-paste-block.css' ); +} +add_action('admin_footer', 'mbtnp_add_blocks_copy_paste'); + +// --------------------------------------------------------------------------------- +// ----- GET SHORTENED EXCERPT ------------------------------------------------------------------------ +// --------------------------------------------------------------------------------- +function mbtnp_get_the_excerpt( $post_id, $count ) { + $excerpt = get_the_content( '', '', $post_id ); + $excerpt = wp_strip_all_tags( $excerpt ); + if( strlen($excerpt) > $count ){ + $excerpt = trim(substr($excerpt, 0, $count)); + $excerpt .= '...'; + } + return $excerpt; +} + + +// --------------------------------------------------------------------------------- +// ----- REPLACE CUSTOM TAGS (helper) ---------------------------------------------- +// --------------------------------------------------------------------------------- +function mbtnp_replace_tags( $content, $post_id = null ){ + + if( empty($post_id) ){ + return $content; + } + + $post = get_post($post_id); + + // replace {field_XYZ} with value from XYZ custom field + $content = preg_replace_callback( + '/\{field_([^}]+)\}/', + function ($matches) use ($post) { + return get_post_meta($post->ID, $matches[1], true); + }, + $content + ); + + // replace {title} with post title + $content = preg_replace_callback( + '/\{title\}/', + function ($matches) use ($post) { + return get_the_title($post->ID); + }, + $content + ); + + return $content; +} \ No newline at end of file diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..190704c --- /dev/null +++ b/styles.css @@ -0,0 +1,28 @@ +.tnpb-actions { + text-align: center !important; + padding: 0.5rem 1rem !important; +} + +.tnpc-row-edit-block:hover img { + transform: scale(0.8); +} + +.tnpc-row-clone:hover img { + transform: scale(0.8); +} + +.tnpc-row-delete:hover img { + filter: brightness(100); + transform: scale(0.8); +} + +/* ----- Custom styles ----- */ +.mbtnp-section-title { + clear: both; + margin: 0; + font-size: 15px; + font-weight: 500 !important; + padding-top: 17px; + padding-bottom: 5px; + color: #666 !important; +} \ No newline at end of file