Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
File Manager
/
wp-content
/
themes
/
bricks
/
includes
:
builder.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php namespace Bricks; if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly class Builder { public static $dynamic_data = []; // key: DD tag; value: DD tag value (@since 1.7.1) public function __construct() { add_filter( 'show_admin_bar', [ $this, 'show_admin_bar' ] ); add_action( 'init', [ $this, 'set_language_direction' ] ); add_filter( 'locale', [ $this, 'maybe_set_locale' ], 99999, 1 ); // Hook in after TranslatePress add_action( 'send_headers', [ $this, 'dont_cache_headers' ] ); add_action( 'wp_footer', [ $this, 'element_x_templates' ] ); add_action( 'bricks_before_site_wrapper', [ $this, 'before_site_wrapper' ] ); add_action( 'bricks_after_site_wrapper', [ $this, 'after_site_wrapper' ] ); add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); add_filter( 'tiny_mce_before_init', [ $this, 'tiny_mce_before_init' ] ); add_action( 'template_redirect', [ $this, 'template_redirect' ] ); // In the builder force our own template to avoid conflicts with other builders add_filter( 'template_include', [ $this, 'template_include' ], 1001 ); } /** * Don't cache headers or browser history buffer in builder * * To fix browser back button issue. * * https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control * * "at present any pages using Cache-Control: no-store will not be eligible for bfcache." * - https://web.dev/bfcache/#minimize-use-of-cache-control-no-store * * @since 1.6.2 */ public function dont_cache_headers() { header_remove( 'Cache-Control' ); header( 'Cache-Control: no-cache, no-store, must-revalidate, max-age=0' ); // HTTP 1.1 header( 'Pragma: no-cache' ); // HTTP 1.0 header( 'Expires: 0' ); // HTTP 1.0 proxies } /** * Remove admin bar and CSS * * @since 1.0 */ public function show_admin_bar() { remove_action( 'wp_head', '_admin_bar_bump_cb' ); return false; } /** * Set a different language locale in builder if user has specified a different admin language * * @since 1.1.2 */ public function maybe_set_locale( $locale ) { // Check for builder language $builder_locale = Database::get_setting( 'builderLocale', false ); if ( $builder_locale && $builder_locale !== 'site-default' ) { return $builder_locale; } // Check for specific WP dashboard user language $user = wp_get_current_user(); $locale = ! empty( $user->locale ) ? $user->locale : $locale; return $locale; } /** * Set language direction in builder (panels) * * Apply only to main window (toolbar & panels). Canvas should use frontend direction. * * @since 1.5 */ public function set_language_direction() { // Return: Window is not main builder window if ( ! bricks_is_builder_main() ) { return; } $direction = Database::get_setting( 'builderLanguageDirection', false ); if ( ! $direction ) { return; } global $wp_locale, $wp_styles; $wp_locale->text_direction = $direction; if ( ! is_a( $wp_styles, 'WP_Styles' ) ) { $wp_styles = new \WP_Styles(); } $wp_styles->text_direction = $direction; } /** * Canvas: Add element x-template render scripts to wp_footer */ public function element_x_templates() { if ( ! bricks_is_builder_iframe() ) { return; } foreach ( Elements::$elements as $element ) { echo $element['class']::render_builder(); } } /** * Before site wrapper (opening tag to render builder) * * @since 1.0 */ public function before_site_wrapper() { if ( bricks_is_builder_main() ) { echo '<div class="brx-body main">'; } elseif ( bricks_is_builder_iframe() ) { echo '<div class="brx-body iframe">'; } } /** * After site wrapper (closing tag to render builder) * * @since 1.0 */ public function after_site_wrapper() { if ( bricks_is_builder() ) { echo '</div>'; // END .brx-body } } /** * Enqueue styles and scripts * * @since 1.0 */ public function enqueue_scripts() { // Access MediaElementsJS (element: Audio) and to get global 'wp' object to open media library (control type 'image', 'audio' etc.) wp_enqueue_media(); // Order matters for CSS flexbox (enqueue builder styles before frontend styles) if ( bricks_is_builder() ) { wp_enqueue_style( 'bricks-builder', BRICKS_URL_ASSETS . 'css/builder.min.css', [], filemtime( BRICKS_PATH_ASSETS . 'css/builder.min.css' ) ); if ( is_rtl() ) { wp_enqueue_style( 'bricks-builder-rtl', BRICKS_URL_ASSETS . 'css/builder-rtl.min.css', [], filemtime( BRICKS_PATH_ASSETS . 'css/builder-rtl.min.css' ) ); } // PopupDocs.vue: Load prettify wp_enqueue_script( 'bricks-prettify' ); wp_enqueue_style( 'bricks-prettify' ); // Builder isotope (PopupUnsplash.vue) wp_enqueue_script( 'bricks-isotope' ); // Datepicker (form & countdown) wp_enqueue_script( 'bricks-flatpickr' ); wp_enqueue_style( 'bricks-flatpickr' ); add_filter( 'mce_buttons_2', [ $this, 'add_editor_buttons' ] ); } if ( bricks_is_builder_main() ) { // Manually enqueue dashicons for 'wp_enqueue_media' as 'get_wp_editor' prevents dashicons enqueue wp_enqueue_style( 'bricks-dashicons', includes_url( '/css/dashicons.min.css' ), [], null ); wp_enqueue_script( 'bricks-builder', BRICKS_URL_ASSETS . 'js/main.min.js', [ 'bricks-scripts', 'jquery' ], filemtime( BRICKS_PATH_ASSETS . 'js/main.min.js' ), true ); // Builder Mode "Custom": Add CSS variables as inline CSS $builder_mode = Database::get_setting( 'builderMode', 'dark' ); $builder_ui_css = Database::get_setting( 'builderModeCss', '' ); if ( $builder_mode === 'custom' && ! empty( $builder_ui_css ) ) { wp_add_inline_style( 'bricks-tooltips', $builder_ui_css ); } } if ( bricks_is_builder_iframe() ) { // Load Adobe fonts file (@since 1.7.1) $adobe_fonts_project_id = ! empty( Database::get_setting( 'adobeFontsProjectId' ) ) ? Database::get_setting( 'adobeFontsProjectId' ) : false; if ( $adobe_fonts_project_id ) { wp_enqueue_style( "adobe-fonts-project-id-$adobe_fonts_project_id", "https://use.typekit.net/$adobe_fonts_project_id.css" ); } wp_enqueue_script( 'bricks-countdown' ); wp_enqueue_script( 'bricks-counter' ); wp_enqueue_script( 'bricks-flatpickr' ); wp_enqueue_script( 'bricks-google-maps' ); wp_enqueue_script( 'bricks-piechart' ); wp_enqueue_script( 'bricks-swiper' ); wp_enqueue_script( 'bricks-typed' ); wp_enqueue_script( 'bricks-builder', BRICKS_URL_ASSETS . 'js/iframe.min.js', [ 'bricks-scripts', 'jquery' ], filemtime( BRICKS_PATH_ASSETS . 'js/iframe.min.js' ), true ); } $post_id = get_the_ID(); $featured_image = false; /** * Get control options to ensure filter 'bricks/setup/control_options' ran * * Eaxmples: 'queryTypes', custom user control options, etc. * * @since 1.5.5 */ $control_options = Setup::get_control_options(); // NOTE: Set post ID to posts page if ( is_home() ) { $post_id = get_option( 'page_for_posts' ); } // NOTE: Undocumented $post_id = apply_filters( 'bricks/builder/data_post_id', $post_id ); if ( has_post_thumbnail( $post_id ) ) { $featured_image = [ 'id' => get_post_thumbnail_id(), 'url' => get_the_post_thumbnail_url( $post_id ), ]; $image_sizes = array_keys( $control_options['imageSizes'] ); foreach ( $image_sizes as $image_size ) { $featured_image[ $image_size ] = get_the_post_thumbnail_url( $post_id, $image_size ); } } wp_localize_script( 'bricks-builder', 'bricksData', [ 'loadData' => self::builder_data( $post_id ), // Initial data to bootstrap builder iframe // Bricks settings 'customBreakpoints' => Database::get_setting( 'customBreakpoints', false ), 'disableClassChaining' => Database::get_setting( 'disableClassChaining', false ), 'disableGlobalClasses' => Database::get_setting( 'builderDisableGlobalClassesInterface', false ), 'disableElementSpacing' => Database::get_setting( 'disableElementSpacing', false ), 'canvasScrollIntoView' => Database::get_setting( 'canvasScrollIntoView', false ), 'structureAutoSync' => Database::get_setting( 'structureAutoSync', false ), 'structureDuplicateElement' => Database::get_setting( 'structureDuplicateElement', false ), 'structureDeleteElement' => Database::get_setting( 'structureDeleteElement', false ), 'structureCollapsed' => Database::get_setting( 'structureCollapsed', false ), 'builderDisableRestApi' => Database::get_setting( 'builderDisableRestApi', false ), 'builderWrapElement' => Database::get_setting( 'builderWrapElement', 'block' ), 'builderInsertElement' => Database::get_setting( 'builderInsertElement', 'block' ), 'builderInsertLayout' => Database::get_setting( 'builderInsertLayout', 'block' ), 'enableDynamicDataPreview' => Database::get_setting( 'enableDynamicDataPreview', false ), 'builderDynamicDropdownKey' => Database::get_setting( 'builderDynamicDropdownKey', false ), 'builderDynamicDropdownNoLabel' => Database::get_setting( 'builderDynamicDropdownNoLabel', false ), 'builderDynamicDropdownExpand' => Database::get_setting( 'builderDynamicDropdownExpand', false ), 'autosave' => [ 'disabled' => Database::get_setting( 'builderAutosaveDisabled', false ), 'interval' => Database::get_setting( 'builderAutosaveInterval', 60 ), ], 'toolbarLogoLink' => Database::get_setting( 'builderToolbarLogoLink', 'current' ), 'toolbarLogoLinkNewTab' => Database::get_setting( 'builderToolbarLogoLinkNewTab', '' ), 'mode' => Database::get_setting( 'builderMode', 'dark' ), 'featuredImage' => $featured_image, 'panelWidth' => get_option( BRICKS_DB_PANEL_WIDTH, 300 ), 'scaleOff' => get_user_meta( get_current_user_id(), BRICKS_DB_BUILDER_SCALE_OFF, true ), 'widthLocked' => get_user_meta( get_current_user_id(), BRICKS_DB_BUILDER_WIDTH_LOCKED, true ), 'wp' => self::get_wordpress_data(), 'academy' => [ 'home' => 'https://academy.bricksbuilder.io/', 'layout' => 'https://academy.bricksbuilder.io/article/layout/', 'headerTemplate' => 'https://academy.bricksbuilder.io/article/create-template/', 'footerTemplate' => 'https://academy.bricksbuilder.io/article/create-template/', 'createElement' => 'https://academy.bricksbuilder.io/article/create-your-own-elements/', 'globalElement' => 'https://academy.bricksbuilder.io/article/global-elements/', 'keyboardShortcuts' => 'https://academy.bricksbuilder.io/article/keyboard-shortcuts/', 'pseudoClasses' => 'https://academy.bricksbuilder.io/article/pseudo-classes/', 'conditions' => 'https://academy.bricksbuilder.io/article/element-conditions/', 'interactions' => 'https://academy.bricksbuilder.io/article/interactions/', 'popups' => 'https://academy.bricksbuilder.io/article/popup-builder/', ], 'version' => BRICKS_VERSION, 'debug' => isset( $_GET['debug'] ) && Capabilities::current_user_has_full_access() ? $_GET['debug'] : false, 'message' => isset( $_GET['message'] ) ? $_GET['message'] : false, 'breakpoints' => Breakpoints::$breakpoints, 'builderPreviewParam' => BRICKS_BUILDER_IFRAME_PARAM, 'maxUploadSize' => wp_max_upload_size(), 'dynamicTags' => Integrations\Dynamic_Data\Providers::get_dynamic_tags_list(), // URL to edit header/content/footer templates 'editHeaderUrl' => ! empty( Database::$active_templates['header'] ) ? Helpers::get_builder_edit_link( Database::$active_templates['header'] ) : '', 'editContentUrl' => ! empty( Database::$active_templates['content'] ) ? Helpers::get_builder_edit_link( Database::$active_templates['content'] ) : '', 'editFooterUrl' => ! empty( Database::$active_templates['footer'] ) ? Helpers::get_builder_edit_link( Database::$active_templates['footer'] ) : '', 'locale' => get_locale(), 'i18n' => self::i18n(), 'nonce' => wp_create_nonce( 'bricks-nonce' ), 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'restApiUrl' => Api::get_rest_api_url(), 'homeUrl' => home_url( '/' ), 'adminUrl' => admin_url(), 'loginUrl' => wp_login_url(), 'themeUrl' => BRICKS_URL, 'assetsUrl' => BRICKS_URL_ASSETS, 'editPostUrl' => get_edit_post_link( $post_id ), 'previewUrl' => add_query_arg( 'bricks_preview', time(), get_the_permalink( $post_id ) ), 'siteName' => get_bloginfo( 'name' ), 'siteUrl' => get_site_url(), 'settingsUrl' => Helpers::settings_url(), 'defaultImageSize' => 'large', 'author' => get_the_author_meta( 'display_name', get_post_field( 'post_author', $post_id ) ), 'isAdmin' => current_user_can( 'manage_options' ), 'isTemplate' => get_post_type() === BRICKS_DB_TEMPLATE_SLUG, 'isRtl' => is_rtl(), 'postId' => $post_id, 'postStatus' => get_post_status( $post_id ), 'postType' => get_post_type( $post_id ), 'postTypeUrl' => admin_url( 'edit.php?post_type=' ) . get_post_type( $post_id ), 'postTypesRegistered' => Helpers::get_registered_post_types(), 'postTypesSupported' => Helpers::get_supported_post_types(), 'postsPerPage' => get_option( 'posts_per_page' ), 'elements' => Elements::$elements, 'elementsCatFirst' => $this->get_first_elements_category( $post_id ), 'wpEditor' => $this->get_wp_editor(), 'recaptchaIds' => [], 'saveMessages' => $this->save_messages(), 'builderParam' => BRICKS_BUILDER_PARAM, 'animatedTypingInstances' => [], // Necessary to destroy and then reinit TypedJS instances 'videoInstances' => [], // Necessary to destroy and then reinit Plyr instances 'splideInstances' => [], // Necessary to destroy and then reinit SplideJS instances 'swiperInstances' => [], // Necessary to destroy and then reinit SwiperJS instances 'mapStyles' => Setup::get_map_styles(), 'icons' => self::get_icon_font_classes(), 'controls' => [ 'themeStyles' => Theme_Styles::get_controls_data(), 'settings' => Settings::get_controls_data(), 'conditions' => Conditions::get_controls_data(), 'interactions' => Interactions::get_controls_data(), ], 'controlOptions' => $control_options, // Static data 'themeStyles' => Theme_Styles::$styles, 'template' => [ 'defaultTemplatesDisabled' => Database::get_setting( 'defaultTemplatesDisabled' ), 'remoteUrl' => Database::get_setting( 'remoteTemplatesUrl' ), 'orderBy' => $control_options['templatesOrderBy'], 'preview' => self::get_template_preview_data( $post_id ), 'authors' => Templates::get_template_authors(), 'bundles' => Templates::get_template_bundles(), 'tags' => Templates::get_template_tags(), 'types' => $control_options['templateTypes'], ], 'userCan' => [ 'publishPosts' => current_user_can( 'publish_posts' ), 'publishPages' => current_user_can( 'publish_pages' ), 'fullAccess' => Capabilities::current_user_has_full_access(), 'uploadSvg' => Capabilities::current_user_can_upload_svg(), 'executeCode' => Capabilities::current_user_can_execute_code(), ], 'mailchimpLists' => Integrations\Form\Actions\Mailchimp::get_list_options(), 'wooCommerceActive' => Woocommerce::$is_active, 'googleFontsDisabled' => Helpers::google_fonts_disabled(), 'fonts' => self::get_fonts(), // @since 1.7.1 ] ); } /** * Get WordPress data for use in builder x-template (to reduce AJAX calls) * * @return array * * @since 1.0 */ public static function get_wordpress_data() { return [ 'post' => [ 'title' => Helpers::get_the_title( get_the_ID(), false ), 'title_context' => Helpers::get_the_title( get_the_ID(), true ), ], ]; } /** * Get all fonts * * - Adobe fonts (@since 1.7.1) * - Custom fonts * - Google fonts * - Standard fonts * * @since 1.2.1 * * @return array */ public static function get_fonts() { $fonts = []; // Build font dropdown 'options' for ControlTypography.vue $options = []; // STEP: Adobe fonts $adobe_fonts = Database::$adobe_fonts; if ( is_array( $adobe_fonts ) && count( $adobe_fonts ) ) { $options['adobeFontsGroupTitle'] = 'Adobe fonts'; foreach ( $adobe_fonts as $adobe_font ) { if ( isset( $adobe_font['slug'] ) && isset( $adobe_font['name'] ) ) { $options[ $adobe_font['slug'] ] = $adobe_font['name']; } } if ( count( $adobe_fonts ) ) { $fonts['adobe'] = $adobe_fonts; } } // STEP: Custom fonts $custom_fonts = Custom_Fonts::get_custom_fonts(); if ( $custom_fonts ) { $options['customFontsGroupTitle'] = esc_html__( 'Custom Fonts', 'bricks' ); foreach ( $custom_fonts as $custom_font_id => $custom_font ) { $options[ $custom_font_id ] = $custom_font['family']; } $fonts['custom'] = $custom_fonts; } // STEP: Google fonts (if not disabled via filter OR settings) if ( ! Helpers::google_fonts_disabled() ) { $google_fonts = self::get_google_fonts(); $options['googleFontsGroupTitle'] = 'Google fonts'; foreach ( $google_fonts as $google_font ) { $options[ $google_font['family'] ] = $google_font['family']; } $fonts['google'] = $google_fonts; } // STEP: Standard fonts $standard_fonts = self::get_standard_fonts(); $options['standardFontsGroupTitle'] = esc_html__( 'Standard fonts', 'bricks' ); foreach ( $standard_fonts as $standard_font ) { $options[ $standard_font ] = $standard_font; } $fonts['standard'] = $standard_fonts; $fonts['options'] = $options; return $fonts; } /** * Get standard (web safe) fonts * * @since 1.0 * * @return array */ public static function get_standard_fonts() { $standard_fonts = [ 'Arial', 'Helvetica', 'Helvetica Neue', 'Times New Roman', 'Times', 'Georgia', 'Courier New', ]; return apply_filters( 'bricks/builder/standard_fonts', $standard_fonts ); } /** * Get Google fonts * * Return fonts array with 'family' & 'variants' (to update font-weight for each font in builder) * * @since 1.0 * * @return array */ public static function get_google_fonts() { /** * STEP: Generate Google fonts JSON file from API response * * We only need the 'family' & 'variants' properties from the Google fonts API response. * * DEV_ONLY: Set $google_fonts_generate below to true to generate the JSON file! * * @since 1.7.1 */ $google_fonts_generate = false; if ( $google_fonts_generate ) { $google_fonts = file_get_contents( BRICKS_URL . 'src/assets/fonts/google-fonts.json' ); $google_fonts = json_decode( $google_fonts, true ); $google_fonts = ! empty( $google_fonts['items'] ) ? $google_fonts['items'] : []; $google_fonts_processed = []; foreach ( $google_fonts as $google_font ) { $family = ! empty( $google_font['family'] ) ? $google_font['family'] : false; $variants = ! empty( $google_font['variants'] ) ? json_encode( $google_font['variants'] ) : false; $variants = str_replace( 'regular', '400', $variants ); if ( ! $family ) { continue; } $google_fonts_processed[] = [ 'family' => $family, 'variants' => json_decode( $variants, true ), ]; } // Encode into minified JSON format $json = json_encode( $google_fonts_processed, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ); // Save the modified JSON data back to the file file_put_contents( BRICKS_PATH . 'src/assets/fonts/google-fonts.min.json', $json ); return []; } // STEP: Get contents of the Google fonts JSON file $google_fonts = Helpers::file_get_contents( BRICKS_PATH_ASSETS . 'fonts/google-fonts.min.json' ); // Return: Empty file OR not found if ( ! $google_fonts ) { return []; } // Decode the JSON data into a PHP object $google_fonts = json_decode( $google_fonts, true ); return is_array( $google_fonts ) ? $google_fonts : []; } /** * Template placeholder image (if importImages set to false) * * @since 1.0 */ public static function get_template_placeholder_image() { return get_template_directory_uri() . '/assets/images/placeholder-image-800x600.jpg'; } /** * Template preview data * * @since 1.0 */ public static function get_template_preview_data( $post_id ) { $preview_data = []; // Placeholder HTML $placeholder = '<section class="brxe-container brxe-alert" style="cursor: pointer">'; $placeholder .= Helpers::get_element_placeholder( [ 'icon-class' => 'ti-layout', 'text' => esc_html__( 'Click to set preview content.', 'bricks' ), ] ); $placeholder .= '</section>'; $preview_data['placeholder'] = $placeholder; // Only add the preview post id if there is a preview (@since 1.5.1) if ( Helpers::is_bricks_template( $post_id ) ) { $template_settings = Helpers::get_template_settings( $post_id ); if ( ! empty( $template_settings['templatePreviewPostId'] ) ) { $post_id = intval( $template_settings['templatePreviewPostId'] ); } $preview_data['postId'] = $post_id; } return $preview_data; } /** * Post thumbnail data (for use in _background control) * * @since 1.0 */ public function get_post_thumbnail() { return [ 'filename' => basename( get_attached_file( get_post_thumbnail_id( get_the_ID() ) ) ), 'full' => get_the_post_thumbnail_url( get_the_ID(), 'full' ), 'id' => get_post_thumbnail_id( get_the_ID() ), 'size' => BRICKS_DEFAULT_IMAGE_SIZE, 'url' => get_the_post_thumbnail_url( get_the_ID(), BRICKS_DEFAULT_IMAGE_SIZE ), ]; } /** * Custom TinyMCE settings for builder * * @since 1.0 */ public function tiny_mce_before_init( $in ) { // Remove certain TinyMCE plugins in builder $plugins = explode( ',', $in['plugins'] ); if ( ( $key = array_search( 'fullscreen', $plugins ) ) !== false ) { unset( $plugins[ $key ] ); } $in['plugins'] = join( ',', $plugins ); return $in; } /** * WordPress editor * * Without tag button, "Add media" button (use respective elements instead) * * @since 1.0 */ public function get_wp_editor() { ob_start(); $mce_buttons = add_filter( 'mce_buttons', function( $buttons ) { // NOTE: Show all editor controls @since 1.3.6 ("Basic Text" element) // Remove formatselect button (paragraph/heading/preformatted etc.) // $buttons_to_remove = [ 'formatselect' ]; // foreach ( $buttons as $index => $button_name ) { // if ( in_array( $button_name, $buttons_to_remove ) ) { // unset( $buttons[ $index ] ); // } // } // Add dynamic tag picker dropdown button to tinyMCE editor $buttons[] = 'tagPickerButton'; return $buttons; } ); $content = '%%BRICKS_EDITOR_CONTENT_PLACEHOLDER%%'; $editor_id = 'brickswpeditor'; // No dashes, see https://codex.wordpress.org/Function_Reference/wp_editor $settings = [ 'editor_class' => 'bricks-wp-editor', // 'media_buttons' => false, // Use image element instead 'quicktags' => [ 'buttons' => 'sup', // 'buttons' => 'strong,em,ul,ol,li,link,close', // No spaces ], ]; wp_editor( $content, $editor_id, $settings ); return ob_get_clean(); } /** * Add 'superscript' & 'subscript' button to TinyMCE in builder * * @since 1.4 */ public function add_editor_buttons( $buttons ) { if ( ! in_array( 'superscript', $buttons ) ) { $buttons[] = 'superscript'; } if ( ! in_array( 'subscript', $buttons ) ) { $buttons[] = 'subscript'; } return $buttons; } /** * Builder strings * * @since 1.0 */ public static function i18n() { $post_type = get_post_type(); $post_type_object = get_post_type_object( $post_type ); $post_type_name = $post_type_object ? $post_type_object->labels->singular_name : $post_type; $i18n = [ 'actions' => esc_html__( 'Actions', 'bricks' ), 'active' => esc_html__( 'Active', 'bricks' ), 'add' => esc_html__( 'Add', 'bricks' ), 'added' => esc_html__( 'added', 'bricks' ), 'addClass' => esc_html__( 'Add class', 'bricks' ), 'addImages' => esc_html__( 'Add images', 'bricks' ), 'addItem' => esc_html__( 'Add Item', 'bricks' ), 'advanced' => esc_html__( 'Advanced', 'bricks' ), 'align' => esc_html__( 'Align', 'bricks' ), 'alignItems' => esc_html__( 'Align items', 'bricks' ), 'all' => esc_html__( 'All', 'bricks' ), 'alpha' => esc_html__( 'Transparency', 'bricks' ), 'and' => esc_html__( 'And', 'bricks' ), 'angle' => esc_html__( 'Angle in °', 'bricks' ), 'any' => esc_html__( 'Any', 'bricks' ), 'apply' => esc_html__( 'Apply', 'bricks' ), 'applyTo' => esc_html__( 'Apply to', 'bricks' ), 'archive' => esc_html__( 'Archive', 'bricks' ), 'arrows' => esc_html__( 'Arrows', 'bricks' ), 'ascending' => esc_html__( 'Ascending', 'bricks' ), 'author' => esc_html__( 'Author', 'bricks' ), 'attachment' => esc_html__( 'Attachment', 'bricks' ), 'attribute' => esc_html__( 'Attribute', 'bricks' ), 'autosaveBy' => esc_html__( 'Autosave by', 'bricks' ), 'background' => esc_html__( 'Background', 'bricks' ), 'backgroundColor' => esc_html__( 'Background color', 'bricks' ), 'backgroundCustomSize' => esc_html__( 'Background custom size', 'bricks' ), 'backgroundCustomSizePlaceholder' => esc_html__( '50% or 200px', 'bricks' ), 'backgroundPosition' => esc_html__( 'Background position', 'bricks' ), 'backgroundRepeat' => esc_html__( 'Background repeat', 'bricks' ), 'backgroundSize' => esc_html__( 'Background size', 'bricks' ), 'backgroundAttachment' => esc_html__( 'Background attachment', 'bricks' ), 'backgroundVideo' => esc_html__( 'Background video', 'bricks' ), 'backgroundVideoAspectRatio' => esc_html__( 'Aspect ratio', 'bricks' ), 'backgroundVideoDescription' => esc_html__( 'YouTube, Vimeo or file URL.', 'bricks' ), 'backgroundVideoScale' => esc_html__( 'BG video scale', 'bricks' ), 'backToBuilder' => esc_html__( 'Back to builder', 'bricks' ), 'baseBreakpoint' => esc_html__( 'Base breakpoint', 'bricks' ), 'baseline' => esc_html__( 'Baseline', 'bricks' ), 'basic' => esc_html__( 'Basic', 'bricks' ), 'blockquote' => esc_html__( 'Blockquote', 'bricks' ), 'align' => esc_html__( 'Align', 'bricks' ), 'bulletedList' => esc_html__( 'Bullet List', 'bricks' ), 'block' => esc_html__( 'Block', 'bricks' ), 'blur' => esc_html__( 'Blur', 'bricks' ), 'bold' => esc_html__( 'Bold', 'bricks' ), 'border' => esc_html__( 'Border', 'bricks' ), 'borderColor' => esc_html__( 'Border color', 'bricks' ), 'bottom' => esc_html__( 'Bottom', 'bricks' ), 'bottomLeft' => esc_html__( 'Bottom left', 'bricks' ), 'bottomCenter' => esc_html__( 'Bottom center', 'bricks' ), 'bottomRight' => esc_html__( 'Bottom right', 'bricks' ), 'boxShadow' => esc_html__( 'Box shadow', 'bricks' ), 'breakpoint' => esc_html__( 'Breakpoint', 'bricks' ), 'breakpoints' => esc_html__( 'Breakpoints', 'bricks' ), 'breakpointBaseMessage' => esc_html__( 'Editing the base breakpoint width affects all media queries.', 'bricks' ), 'breakpointDeleteDescription' => esc_html__( 'Are you sure that you want to delete this breakpoint?', 'bricks' ), 'bricksAcademy' => esc_html__( 'Bricks Academy', 'bricks' ), 'brightness' => esc_html__( 'Brightness', 'bricks' ), 'browse' => esc_html__( 'Browse', 'bricks' ), 'browseMediaLibrary' => esc_html__( 'Browse Media Library', 'bricks' ), 'browseUnsplash' => esc_html__( 'Browse Unsplash', 'bricks' ), 'builder' => esc_html__( 'Builder', 'bricks' ), 'builderHelpTitle' => esc_html__( 'Need help? Found a bug? Suggest a feature?', 'bricks' ), 'builderHelpDescription' => sprintf( __( 'Please use your Bricks account email address for all customer support requests. To attach larger files, please send an email directly to %1$s. To see what is currently in development or submit/upvote feature requests please visit our %2$s.', 'bricks' ), '<a href="mailto:help@bricksbuilder.io" target="_blank">help@bricksbuilder.io</a>', '<a href="https://bricksbuilder.io/roadmap/" target="_blank" rel="noopener">' . esc_html__( 'official roadmap', 'bricks' ) . '</a>' ), 'builderHelpUploadLimitExceeded' => sprintf( esc_html__( 'Your attached files exceed your server max. upload size of %s.', 'bricks' ), size_format( wp_max_upload_size() ) ), 'builderHelpGmailLimitExceeded' => esc_html__( 'Your attached files exceed the max. upload limit of 25 MB.', 'bricks' ), 'bulletedlist' => esc_html__( 'Bulleted list', 'bricks' ), 'by' => esc_html__( 'by', 'bricks' ), 'cancel' => esc_html__( 'Cancel', 'bricks' ), 'capitalize' => esc_html__( 'Capitalize', 'bricks' ), 'center' => esc_html__( 'Center', 'bricks' ), 'centerLeft' => esc_html__( 'Center left', 'bricks' ), 'centerCenter' => esc_html__( 'Center center', 'bricks' ), 'centerRight' => esc_html__( 'Center right', 'bricks' ), 'childOf' => esc_html__( 'Child of', 'bricks' ), 'childless' => esc_html__( 'Childless', 'bricks' ), 'classNamePlaceholder' => esc_html__( 'Enter CSS class name', 'bricks' ), 'clickToDownload' => esc_html__( 'Click to download', 'bricks' ), 'chooseFiles' => esc_html__( 'Choose files', 'bricks' ), 'chooseImage' => esc_html__( 'Choose image', 'bricks' ), 'clearSearchControlFilters' => esc_html__( 'Clear search filter', 'bricks' ), 'clone' => esc_html__( 'Clone', 'bricks' ), 'cloned' => esc_html__( 'cloned', 'bricks' ), 'clean' => esc_html__( 'Clean', 'bricks' ), 'clear' => esc_html__( 'Clear', 'bricks' ), 'close' => esc_html__( 'Close', 'bricks' ), 'closeEsc' => esc_html__( 'Close (ESC)', 'bricks' ), 'collapse' => esc_html__( 'Collapse', 'bricks' ), 'color' => esc_html__( 'Color', 'bricks' ), 'colors' => esc_html__( 'Colors', 'bricks' ), 'colorStop' => esc_html__( 'Color stop in %', 'bricks' ), 'colorPalette' => esc_html__( 'Color palette', 'bricks' ), 'column' => esc_html__( 'Column', 'bricks' ), 'commentCount' => esc_html__( 'Comment count', 'bricks' ), 'community' => esc_html__( 'Community', 'bricks' ), 'communityTemplates' => esc_html__( 'Community templates', 'bricks' ), 'compare' => esc_html__( 'Compare', 'bricks' ), 'condition' => esc_html__( 'Condition', 'bricks' ), 'conditions' => esc_html__( 'Conditions', 'bricks' ), 'conditionSelect' => esc_html__( 'Select condition', 'bricks' ), 'configure' => esc_html__( 'Configure', 'bricks' ), 'confirm' => esc_html__( 'Confirm', 'bricks' ), 'contactUs' => esc_html__( 'Contact us', 'bricks' ), 'contain' => esc_html__( 'Contain', 'bricks' ), 'container' => esc_html__( 'Container', 'bricks' ), 'content' => esc_html__( 'Content', 'bricks' ), 'contrast' => esc_html__( 'Contrast', 'bricks' ), 'copied' => esc_html__( 'Copied', 'bricks' ), 'copiedToClipboard' => esc_html__( 'Copied to clipboard', 'bricks' ), 'copy' => esc_html__( 'Copy', 'bricks' ), 'copyStyles' => esc_html__( 'Copy styles', 'bricks' ), 'copyToClipboard' => esc_html__( 'Copy to clipboard', 'bricks' ), 'copyElementSelector' => esc_html__( 'Copy CSS selector', 'bricks' ), 'contenteditablePlaceholder' => esc_html__( 'Here goes my text ...', 'bricks' ), 'convert' => esc_html__( 'Convert', 'bricks' ), 'cover' => esc_html__( 'Cover', 'bricks' ), 'create' => esc_html__( 'Create', 'bricks' ), 'createTemplate' => esc_html__( 'Create template', 'bricks' ), 'createTemplateTitlePlaceholder' => esc_html__( 'Template title', 'bricks' ), 'createTemplateTitle' => esc_html__( 'Create new template:', 'bricks' ), 'createYourOwnElements' => esc_html__( 'Create your own elements', 'bricks' ), 'cssClass' => esc_html__( 'CSS class', 'bricks' ), 'cssClassName' => esc_html__( 'Class name', 'bricks' ), 'cssClassesTooltip' => esc_html__( 'Separated by space. No leading dot "."', 'bricks' ), 'cssIdTooltip' => esc_html__( 'No leading pound sign "#"', 'bricks' ), 'cssFilter' => esc_html__( 'CSS filter', 'bricks' ), 'cssFilterDescription' => sprintf( '<a target="_blank" href="https://developer.mozilla.org/en/docs/Web/CSS/filter?v=example">%s</a>', esc_html__( 'Enter CSS filters + value (learn more)', 'bricks' ) ), 'cssSelector' => esc_html__( 'CSS selector', 'bricks' ), 'currentLayout' => esc_html__( 'Current layout', 'bricks' ), 'currentVersionBy' => esc_html__( 'Current version by', 'bricks' ), 'currentWidth' => esc_html__( 'Current width', 'bricks' ), 'custom' => esc_html__( 'Custom', 'bricks' ), 'customCss' => esc_html__( 'Custom CSS', 'bricks' ), 'customFields' => esc_html__( 'Custom fields', 'bricks' ), 'customFont' => esc_html__( 'Custom font', 'bricks' ), 'dashboard' => esc_html__( 'Dashboard', 'bricks' ), 'default' => esc_html__( 'Default', 'bricks' ), 'defaultTemplatesEnabled' => sprintf( esc_html__( '%s. Template conditions precede default templates.', 'bricks' ), '<a href="' . admin_url( 'admin.php?page=bricks-settings#tab-templates' ) . '" target="_blank">' . esc_html__( 'Default templates are enabled', 'bricks' ) . '</a>' ), 'defaultTemplatesDisabled' => sprintf( esc_html__( '%s. Set template conditions or enable default templates.', 'bricks' ), '<a href="' . admin_url( 'admin.php?page=bricks-settings#tab-templates' ) . '" target="_blank">' . esc_html__( 'Default templates are disabled', 'bricks' ) . '</a>' ), 'dashed' => esc_html__( 'dashed', 'bricks' ), 'date' => esc_html__( 'Date', 'bricks' ), 'delete' => esc_html__( 'Delete', 'bricks' ), 'deleted' => esc_html__( 'Deleted', 'bricks' ), 'deprecated' => esc_html__( 'Deprecated', 'bricks' ), 'descending' => esc_html__( 'Descending', 'bricks' ), 'descriptionCustomLayout' => esc_html__( 'Number between 1 - 100 or auto', 'bricks' ), 'descriptionLightboxVideo' => esc_html__( 'YouTube, Vimeo or file URL.', 'bricks' ), 'descriptionParallax' => esc_html__( 'Set to "Fixed" for parallax effect.', 'bricks' ), 'desktop' => esc_html__( 'Desktop', 'bricks' ), 'direction' => esc_html__( 'Direction', 'bricks' ), 'disabled' => esc_html__( 'Disabled', 'bricks' ), 'disableQueryMerge' => esc_html__( 'Disable query merge', 'bricks' ), 'discard' => esc_html__( 'Discard', 'bricks' ), 'div' => 'Div', 'documentation' => esc_html__( 'Documentation', 'bricks' ), 'dots' => esc_html__( 'Dots', 'bricks' ), 'dotted' => esc_html__( 'Dotted', 'bricks' ), 'double' => esc_html__( 'double', 'bricks' ), 'download' => esc_html__( 'Download', 'bricks' ), 'downloaded' => esc_html__( 'Downloaded', 'bricks' ), 'downloading' => esc_html__( 'Downloading', 'bricks' ), 'duplicate' => esc_html__( 'Duplicate', 'bricks' ), 'dynamicData' => esc_html__( 'Dynamic Data', 'bricks' ), 'dynamicDataIsEmpty' => esc_html__( 'Dynamic data is empty.', 'bricks' ), 'dynamicDataSelect' => esc_html__( 'Select dynamic data', 'bricks' ), 'edit' => esc_html__( 'Edit', 'bricks' ), 'edited' => esc_html__( 'Edited', 'bricks' ), 'editTemplate' => esc_html__( 'Edit Template', 'bricks' ), 'editColorPalette' => esc_html__( 'Edit palette', 'bricks' ), 'editing' => esc_html__( 'Editing', 'bricks' ), 'editInWordPress' => esc_html__( 'Edit in WordPress', 'bricks' ), 'effect' => esc_html__( 'Effect', 'bricks' ), 'element' => esc_html__( 'Element', 'bricks' ), 'elements' => esc_html__( 'Elements', 'bricks' ), 'elementClasses' => esc_html__( 'Element classes', 'bricks' ), 'elementId' => esc_html__( 'Element ID', 'bricks' ), 'equal' => esc_html__( 'Equal', 'bricks' ), // x-template element placeholder text 'elementPlaceholder' => [ 'default' => esc_html__( 'No content', 'bricks' ), 'accordion' => esc_html__( 'No accordion item added.', 'bricks' ), 'audio' => esc_html__( 'No audio file selected.', 'bricks' ), 'code' => esc_html__( 'No code found.', 'bricks' ), 'countdown' => esc_html__( 'No date/fields set.', 'bricks' ), 'facebook' => esc_html__( 'No Facebook page URL provided.', 'bricks' ), 'form' => esc_html__( 'No form field added.', 'bricks' ), 'html' => esc_html__( 'No HTML markup defined.', 'bricks' ), 'icon' => esc_html__( 'No icon selected.', 'bricks' ), 'list' => esc_html__( 'No list items defined.', 'bricks' ), 'map' => sprintf( esc_html__( 'Google Maps API key required! Add key in dashboard under: %s', 'bricks' ), '<a href="' . Helpers::settings_url( '#tab-api-keys' ) . '" target="_blank">' . esc_html__( 'Bricks > Settings > API Keys', 'bricks' ) . '</a>' ), 'pricing-table' => esc_html__( 'No pricing table defined.', 'bricks' ), 'progress-bar' => esc_html__( 'No progress bar created.', 'bricks' ), 'slider' => esc_html__( 'No slide added.', 'bricks' ), 'social-icons' => esc_html__( 'No icon selected.', 'bricks' ), 'svg' => esc_html__( 'No SVG selected.', 'bricks' ), 'tabs' => esc_html__( 'No tabs added.', 'bricks' ), 'team-members' => esc_html__( 'No team members added.', 'bricks' ), 'template' => esc_html__( 'No template selected.', 'bricks' ), 'testimonials' => esc_html__( 'No testimonials added.', 'bricks' ), 'text' => esc_html__( 'No text added.', 'bricks' ), 'videoNoFileUrl' => esc_html__( 'No file URL provided.', 'bricks' ), 'videoNoVideo' => esc_html__( 'No video selected.', 'bricks' ), 'videoNoYoutubeId' => esc_html__( 'No YouTube URL provided.', 'bricks' ), 'videoNoVimeoId' => esc_html__( 'No Vimeo URL provided.', 'bricks' ), 'videoNoDynamicData' => esc_html__( 'No dynamic data set.', 'bricks' ), 'videoDynamicDataEmpty' => esc_html__( 'The dynamic data is empty.', 'bricks' ), ], 'emailAddress' => esc_html__( 'Email address', 'bricks' ), 'end' => esc_html__( 'End', 'bricks' ), 'error' => esc_html__( 'Error', 'bricks' ), 'errorBricksAcademy404' => esc_html__( 'Articles could not be loaded. Please visit the official knowledge base:', 'bricks' ), 'errorPage' => esc_html__( '404 Error Page', 'bricks' ), 'excerptLength' => esc_html__( 'Excerpt length', 'bricks' ), 'exclude' => esc_html__( 'Exclude', 'bricks' ), 'excludeCurrent' => esc_html__( 'Exclude current post', 'bricks' ), 'expand' => esc_html__( 'Expand', 'bricks' ), 'expandAll' => esc_html__( 'Expand all', 'bricks' ), 'experimental' => esc_html__( 'experimental', 'bricks' ), 'export' => esc_html__( 'Export', 'bricks' ), 'external' => esc_html__( 'External URL', 'bricks' ), 'extraLarge' => esc_html__( 'Extra large', 'bricks' ), 'extraSmall' => esc_html__( 'Extra small', 'bricks' ), 'fade' => esc_html__( 'Fade', 'bricks' ), 'fallbackFont' => esc_html__( 'Fallback fonts', 'bricks' ), 'false' => esc_html__( 'False', 'bricks' ), 'field' => esc_html__( 'Field', 'bricks' ), 'file' => esc_html__( 'File', 'bricks' ), 'fileImported' => esc_html__( '"%s" imported.', 'bricks' ), 'fileNotImportedAlreadyExists' => esc_html__( 'Import of "%s" failed: Name already exists.', 'bricks' ), 'fileNotImportedWrongFormat' => esc_html__( 'Import of "%s" failed: Wrong format.', 'bricks' ), 'files' => esc_html__( 'Files', 'bricks' ), 'fill' => esc_html__( 'Fill', 'bricks' ), 'noFilesChosen' => esc_html__( 'No files chosen', 'bricks' ), 'fillDark' => esc_html__( 'Fill - Dark', 'bricks' ), 'fillLight' => esc_html__( 'Fill - Light', 'bricks' ), 'fillPrimary' => esc_html__( 'Fill - Primary', 'bricks' ), 'finish' => esc_html__( 'Finish', 'bricks' ), 'fixed' => esc_html__( 'Fixed', 'bricks' ), 'fontFamily' => esc_html__( 'Font family', 'bricks' ), 'fontSize' => esc_html__( 'Font size', 'bricks' ), 'fontStyle' => esc_html__( 'Font style', 'bricks' ), 'fontWeight' => esc_html__( 'Font weight', 'bricks' ), 'fontVariants' => esc_html__( 'Font variants', 'bricks' ), 'footer' => esc_html__( 'Footer', 'bricks' ), 'fullSize' => esc_html__( 'Full size', 'bricks' ), 'galleryLayout' => esc_html__( 'Gallery layout', 'bricks' ), 'general' => esc_html__( 'General', 'bricks' ), 'ghostDark' => esc_html__( 'Outline - Dark', 'bricks' ), 'ghostLight' => esc_html__( 'Outline - Light', 'bricks' ), 'ghostPrimary' => esc_html__( 'Outline - Primary', 'bricks' ), 'globalElement' => esc_html__( 'Global element', 'bricks' ), 'globalClassesActive' => esc_html__( 'Active classes', 'bricks' ), 'globalClassCreated' => esc_html__( 'Global class created', 'bricks' ), 'globalClassDeleted' => esc_html__( 'Global class deleted', 'bricks' ), 'globalClassesImported' => esc_html__( 'Global classes imported', 'bricks' ), 'globalClassesEmptyDescription' => esc_html__( 'Enter the name of your first global CSS class in the field above. Then hit enter to create it.', 'bricks' ) . ' (' . Helpers::article_link( 'global-css-classes', esc_html__( 'Learn more', 'bricks' ) ) . ')', 'globalElements' => esc_html__( 'Global elements', 'bricks' ), 'gradient' => esc_html__( 'Gradient', 'bricks' ), 'gardientColorsDescription' => esc_html__( 'Add at least two colors to create a gradient.', 'bricks' ), 'goToSettingsPanel' => esc_html__( 'Back to settings', 'bricks' ), 'gotIt' => esc_html__( 'Got it', 'bricks' ), 'goTo' => esc_html__( 'Go to', 'bricks' ), 'grid' => esc_html__( 'Grid', 'bricks' ), 'gutter' => esc_html__( 'Spacing', 'bricks' ), 'hasUnexecutedCode' => esc_html__( 'Has unexecuted PHP code', 'bricks' ), 'header' => esc_html__( 'Header', 'bricks' ), 'height' => esc_html__( 'Height', 'bricks' ), 'help' => esc_html__( 'Help', 'bricks' ), 'hidden' => esc_html__( 'Hidden', 'bricks' ), 'hideInfo' => esc_html__( 'Hide info', 'bricks' ), 'history' => esc_html__( 'History', 'bricks' ), 'historyDeleted' => esc_html__( 'History deleted', 'bricks' ), 'home' => esc_html__( 'Home', 'bricks' ), 'homePage' => esc_html__( 'Home page', 'bricks' ), 'horizontal' => esc_html__( 'Horizontal', 'bricks' ), 'howToCreateHeaderTemplate' => esc_html__( 'How to create a header template', 'bricks' ), 'howToCreateFooterTemplate' => esc_html__( 'How to create a footer template', 'bricks' ), 'html5AudioNoBrowserSupport' => esc_html__( 'Your browser does not support the audio tag.', 'bricks' ), 'html5VideoNoBrowserSupport' => esc_html__( 'Your browser does not support the video tag.', 'bricks' ), 'hue' => esc_html__( 'Hue', 'bricks' ), 'icon' => esc_html__( 'Icon', 'bricks' ), 'id' => esc_html__( 'ID', 'bricks' ), 'ignoreStickyPosts' => esc_html__( 'Ignore sticky posts', 'bricks' ), 'image' => esc_html__( 'Image', 'bricks' ), 'imageGalleryDescription' => esc_html__( 'Hold down CMD/CRTL to select multiple images.', 'bricks' ), 'imageNotFound' => esc_html__( 'Image not found', 'bricks' ), 'imageSize' => esc_html__( 'Image size', 'bricks' ), 'import' => esc_html__( 'Import', 'bricks' ), 'importImages' => esc_html__( 'Import images', 'bricks' ), 'importImagesDisabled' => esc_html__( 'Disabled: Show placeholder images.', 'bricks' ), 'importImagesEnabled' => esc_html__( 'Enabled: Download template images to media library.', 'bricks' ), 'importJsonDragAndDrop' => esc_html__( 'Drop JSON file(s) in here', 'bricks' ), 'imports' => esc_html__( 'Imports', 'bricks' ), 'importTemplateDragAndDrop' => esc_html__( 'Drag and drop .JSON or .ZIP template file(s) in here ..', 'bricks' ), 'importTemplate' => esc_html__( 'Import template', 'bricks' ), 'importNote' => esc_html__( 'Valid JSON data required to run the importer', 'bricks' ), 'importTemplateThemeStyle' => esc_html__( 'This template contains a theme style. Would you like to import it?', 'bricks' ), 'importTemplateColorPalette' => esc_html__( 'This template contains a color palette. Would you like to import it?', 'bricks' ), 'include' => esc_html__( 'Include', 'bricks' ), 'includeChildren' => esc_html__( 'Include children', 'bricks' ), 'infinite' => esc_html__( 'Infinite', 'bricks' ), 'infiniteScroll' => esc_html__( 'Infinite scroll', 'bricks' ), 'info' => esc_html__( 'Info', 'bricks' ), 'infoLightbox' => esc_html__( 'Customize lightbox: Settings > Theme Styles > General', 'bricks' ), 'infoFullAccessRequired' => esc_html__( 'Your builder access level doesn\'t allow you modify these settings.', 'bricks' ), 'innerContainer' => esc_html__( 'Inner container', 'bricks' ), 'insert' => esc_html__( 'Insert', 'bricks' ), 'insertAfter' => esc_html__( 'Insert after', 'bricks' ), 'insertMedia' => esc_html__( 'Insert media', 'bricks' ), 'insertLayout' => esc_html__( 'Insert layout', 'bricks' ), 'insertSection' => esc_html__( 'Insert section', 'bricks' ), 'insertTemplate' => esc_html__( 'Insert template', 'bricks' ), 'insertTemplateBelow' => esc_html__( 'Insert template below', 'bricks' ), 'inset' => esc_html__( 'Inset', 'bricks' ), 'interactions' => esc_html__( 'Interactions', 'bricks' ), 'internal' => esc_html__( 'Internal post/page', 'bricks' ), 'invert' => esc_html__( 'Invert', 'bricks' ), 'isArchiveMainQuery' => esc_html__( 'Is main query', 'bricks' ) . ' (' . esc_html__( 'Archive', 'bricks' ) . ')', 'isArchiveMainQueryDescription' => esc_html__( 'Enable if your archive pagination is not working.', 'bricks' ), 'italic' => esc_html__( 'Italic', 'bricks' ), 'item' => esc_html__( 'Item', 'bricks' ), 'joinUs' => esc_html__( 'Join Us', 'bricks' ), 'justify' => esc_html__( 'Justify', 'bricks' ), 'justifyContent' => esc_html__( 'Justify content', 'bricks' ), 'key' => esc_html__( 'Key', 'bricks' ), 'keyboardShortcuts' => esc_html__( 'Keyboard shortcuts', 'bricks' ), 'label' => esc_html__( 'Label', 'bricks' ), 'language' => esc_html__( 'Language', 'bricks' ), 'large' => esc_html__( 'Large', 'bricks' ), 'laptop' => esc_html__( 'Laptop', 'bricks' ), 'lastRefresh' => esc_html__( 'Last refresh', 'bricks' ), 'latest' => esc_html__( 'Latest', 'bricks' ), 'layout' => esc_html__( 'Layout', 'bricks' ), 'learnMore' => esc_html__( 'Learn more', 'bricks' ), 'left' => esc_html__( 'Left', 'bricks' ), 'letterSpacing' => esc_html__( 'Letter spacing', 'bricks' ), 'lightboxId' => esc_html__( 'Lightbox ID', 'bricks' ), 'lightboxImage' => esc_html__( 'Lightbox Image', 'bricks' ), 'lightboxVideo' => esc_html__( 'Lightbox Video', 'bricks' ), 'lightness' => esc_html__( 'Lightness', 'bricks' ), 'lineHeight' => esc_html__( 'Line height', 'bricks' ), 'link' => esc_html__( 'Link', 'bricks' ), 'linked' => esc_html__( 'Linked', 'bricks' ), 'list' => esc_html__( 'List', 'bricks' ), 'loadingTemplates' => esc_html__( 'Loading templates', 'bricks' ), 'loadMore' => esc_html__( 'Load more', 'bricks' ), 'locked' => esc_html__( 'Locked', 'bricks' ), 'lockedUserGoBack' => esc_html__( 'Go back', 'bricks' ), 'lockedUserTakeOver' => esc_html__( 'Take over', 'bricks' ), 'lockedUserTitle' => esc_html__( 'This post is already being edited.', 'bricks' ), 'lockedUserText' => esc_html__( '%s is currently working on this post, which means you cannot make changes, unless you take over.', 'bricks' ), 'login' => esc_html__( 'Login', 'bricks' ), 'loop' => esc_html__( 'Loop', 'bricks' ), 'linkStates' => [ 'unlinked' => esc_html__( 'Unlinked', 'bricks' ), 'opposites' => esc_html__( 'Opposites linked', 'bricks' ), 'all' => esc_html__( 'All sides linked', 'bricks' ), ], 'mainQuery' => esc_html__( 'Main query', 'bricks' ), 'margin' => esc_html__( 'Margin', 'bricks' ), 'masonry' => esc_html__( 'Masonry', 'bricks' ), 'maxUploadSizeInfo' => sprintf( esc_html__( 'Max upload size: %s', 'bricks' ), size_format( wp_max_upload_size() ) ), 'media' => esc_html__( 'Media', 'bricks' ), 'metaKey' => esc_html__( 'Meta key', 'bricks' ), 'metaKeyOrder' => esc_html__( 'Order meta key', 'bricks' ), 'metaValue' => esc_html__( 'Meta value', 'bricks' ), 'metaValueNum' => esc_html__( 'Numeric meta value', 'bricks' ), 'metaQuery' => esc_html__( 'Meta query', 'bricks' ), 'menuOrder' => esc_html__( 'Menu order', 'bricks' ), 'metro' => esc_html__( 'Metro', 'bricks' ), 'mimeType' => esc_html__( 'Mime type', 'bricks' ), 'mimeTypeDesc' => Helpers::article_link( 'query-loop/#media-query', esc_html__( 'Filter media by mime type', 'bricks' ) ), 'mobile' => esc_html__( 'Mobile', 'bricks' ), 'mobileFirst' => esc_html__( 'Mobile first', 'bricks' ), 'mode' => esc_html__( 'Mode', 'bricks' ), 'modified' => esc_html__( 'modified', 'bricks' ), 'modifiedDate' => esc_html__( 'Modified date', 'bricks' ), 'months' => [ esc_html__( 'January', 'bricks' ), esc_html__( 'February', 'bricks' ), esc_html__( 'March', 'bricks' ), esc_html__( 'April', 'bricks' ), esc_html__( 'May', 'bricks' ), esc_html__( 'June', 'bricks' ), esc_html__( 'July', 'bricks' ), esc_html__( 'August', 'bricks' ), esc_html__( 'September', 'bricks' ), esc_html__( 'October', 'bricks' ), esc_html__( 'November', 'bricks' ), esc_html__( 'December', 'bricks' ), ], 'moreLayouts' => esc_html__( 'More layouts', 'bricks' ), 'mostPopular' => esc_html__( 'Most Popular', 'bricks' ), 'move' => esc_html__( 'Move', 'bricks' ), 'moved' => esc_html__( 'Moved', 'bricks' ), 'myTemplates' => esc_html__( 'My templates', 'bricks' ), 'myAccount' => esc_html__( 'My account', 'bricks' ), 'name' => esc_html__( 'Name', 'bricks' ), 'new' => esc_html__( 'New', 'bricks' ), 'newColorPalette' => esc_html__( 'New color palette name', 'bricks' ), 'newColorPaletteCreateFirstColor' => esc_html__( 'Add your first color to this palette by selecting a color value above and then click "Save".', 'bricks' ), 'newImageName' => esc_html__( 'Type name, hit enter', 'bricks' ), 'next' => esc_html__( 'Next', 'bricks' ), 'noConditionsSet' => esc_html__( 'No conditions set. Click the "+" icon to add your render condition.', 'bricks' ), 'noInteractionsSet' => esc_html__( 'No interactions set. Click the "+" icon to add an interaction.', 'bricks' ), 'noContent' => esc_html__( 'No content', 'bricks' ), 'noSearchControlsFound' => esc_html__( 'No matching settings found.', 'bricks' ), 'noFileSelected' => esc_html__( 'No file selected.', 'bricks' ), 'no' => esc_html__( 'No', 'bricks' ), 'none' => esc_html__( 'None', 'bricks' ), 'noRepeat' => esc_html__( 'No-repeat', 'bricks' ), 'noResults' => esc_html__( 'Nothing found. Please try again with a different keyword!', 'bricks' ), 'noResultsQuery' => esc_html__( 'No results', 'bricks' ), 'noRevisions' => esc_html__( 'No revisions.', 'bricks' ), 'noDynamicDataFound' => esc_html__( 'No dynamic data found.', 'bricks' ), 'noTemplatesFound' => esc_html__( 'No templates found.', 'bricks' ), 'notFound' => esc_html__( 'Not found', 'bricks' ), 'nothingFound' => esc_html__( 'Nothing found.', 'bricks' ), 'nothingToCopy' => esc_html__( 'Nothing to copy', 'bricks' ), 'nothingToPaste' => esc_html__( 'Nothing to paste', 'bricks' ), 'notifications' => [ 'autosave' => [ 'button' => esc_html__( 'Preview autosave', 'bricks' ), 'description' => esc_html__( 'There is an autosave more recent than the version you are currently viewing.', 'bricks' ), ], 'svg' => [ 'description' => esc_html__( 'SVG files not imported for security reasons.', 'bricks' ), ], 'templateBundle' => [ 'button' => esc_html__( 'Set template style', 'bricks' ), 'description' => esc_html__( 'Inserted template uses theme style "%s"', 'bricks' ), ], 'populateContent' => [ 'button' => esc_html__( 'Change content', 'bricks' ), 'description' => esc_html__( 'Currently previewing content from "%s".', 'bricks' ), ] ], 'number' => esc_html__( 'Number', 'bricks' ), 'numberedlist' => esc_html__( 'Numbered list', 'bricks' ), 'offset' => esc_html__( 'Offset', 'bricks' ), 'oldest' => esc_html__( 'Oldest', 'bricks' ), 'opacity' => esc_html__( 'Opacity', 'bricks' ), 'openInNewTab' => esc_html__( 'Open in new tab', 'bricks' ), 'or' => esc_html__( 'Or', 'bricks' ), 'order' => esc_html__( 'Order', 'bricks' ), 'orderBy' => esc_html__( 'Order by', 'bricks' ), 'otherClasses' => esc_html__( 'Other classes', 'bricks' ), 'overlay' => esc_html__( 'Overlay', 'bricks' ), 'overwrite' => esc_html__( 'Overwrite', 'bricks' ), 'padding' => esc_html__( 'Padding', 'bricks' ), 'page' => esc_html__( 'Page', 'bricks' ), 'pages' => esc_html__( 'Pages' ), 'pageSettings' => esc_html__( 'Page settings', 'bricks' ), 'panelRevisionsInfo' => esc_html__( 'Select any revision to preview it. Click "Apply" to continue editing the selected revision. Click "Discard" to continue editing the current revision.', 'bricks' ), 'parent' => esc_html__( 'Parent', 'bricks' ), 'postParentId' => esc_html__( 'Insert post parent ID', 'bricks' ), 'paste' => esc_html__( 'Paste', 'bricks' ), 'pasted' => esc_html__( 'Pasted', 'bricks' ), 'pasteStyles' => esc_html__( 'Paste styles', 'bricks' ), 'paused' => esc_html__( 'Paused', 'bricks' ), 'pin' => esc_html__( 'Pin', 'bricks' ), 'pinnedElements' => esc_html__( 'Pinned elements', 'bricks' ), 'placeholderEmptyCanvas' => esc_html__( 'Click on any element to add it to your canvas.', 'bricks' ), 'placeholderEmptyPopup' => esc_html__( 'Click on any element to add it to your popup.', 'bricks' ), 'placeholderFormMessage' => esc_html__( 'Your message goes here. The more details, the better ;)', 'bricks' ), 'placeholderImageInfo' => esc_html__( 'Placeholder image shown.', 'bricks' ), 'placeholderTitle' => esc_html__( 'Type title and hit enter', 'bricks' ), 'placeholderTemplateName' => esc_html__( 'Enter new template name', 'bricks' ), 'placeholderSearchDocumentation' => esc_html__( 'Search documentation', 'bricks' ), 'placeholderSelectPost' => esc_html__( 'Select post/page', 'bricks' ), 'placeholderSelectLinkType' => esc_html__( 'Select link type', 'bricks' ), 'placeholderYourName' => esc_html__( 'Your name (optional)', 'bricks' ), 'playInteraction' => esc_html__( 'Play interaction', 'bricks' ), 'popular' => esc_html__( 'Popular', 'bricks' ), 'popup' => esc_html__( 'Popup', 'bricks' ), 'position' => esc_html__( 'Position', 'bricks' ), 'post' => esc_html__( 'Post', 'bricks' ), 'posts' => esc_html__( 'Posts', 'bricks' ), 'postsOffsetDescription' => esc_html__( 'Ignored when posts per page set to "-1".', 'bricks' ), 'postsPerPage' => esc_html__( 'Posts per page', 'bricks' ), 'postType' => esc_html__( 'Post type', 'bricks' ), 'poweredByUnsplash' => sprintf( esc_html__( 'Powered by %s', 'bricks' ), '<a href="https://unsplash.com/?ref=bricksbuilderio" target="_blank">Unsplash</a>' ), 'prev' => esc_html__( 'Prev', 'bricks' ), 'preview' => esc_html__( 'Preview', 'bricks' ), 'previewMode' => esc_html__( 'Preview mode', 'bricks' ), 'previewTemplate' => esc_html__( 'Preview template', 'bricks' ), 'pseudoClassActive' => esc_html__( 'Active pseudo-class', 'bricks' ), 'pseudoClassCreated' => esc_html__( 'Pseudo-class created', 'bricks' ), 'pseudoClassDeleted' => esc_html__( 'Pseudo-class deleted', 'bricks' ), 'pseudoClassPlaceholder' => esc_html__( 'Select or create pseudo-class', 'bricks' ), 'pseudoClassTooltip' => esc_html__( 'States (pseudo-classes)', 'bricks' ), 'pseudoElementCreated' => esc_html__( 'Pseudo-element created', 'bricks' ), 'pseudoElementDeleted' => esc_html__( 'Pseudo-element deleted', 'bricks' ), 'publish' => esc_html__( 'Publish', 'bricks' ), 'published' => esc_html__( 'Published', 'bricks' ), 'publishedDate' => esc_html__( 'Published date', 'bricks' ), 'queryLoop' => esc_html__( 'Query loop', 'bricks' ), 'quickNav' => esc_html__( 'Quick nav', 'bricks' ), 'radius' => esc_html__( 'Radius', 'bricks' ), 'random' => esc_html__( 'Random', 'bricks' ), 'randomSeedTtl' => esc_html__( 'Random seed TTL', 'bricks' ), 'randomSeedTtlDescription' => esc_html__( 'Time in minutes that the random seed will last. Avoid duplicate posts when using random order.', 'bricks' ), 'raw' => esc_html__( 'Raw', 'bricks' ), 'redo' => esc_html__( 'Redo', 'bricks' ), 'reloadCanvas' => esc_html__( 'Reload canvas', 'bricks' ), 'remote' => esc_html__( 'Remote', 'bricks' ), 'remoteTemplates' => esc_html__( 'Remote templates', 'bricks' ), 'remove' => esc_html__( 'Remove', 'bricks' ), 'removeFile' => esc_html__( 'Remove file', 'bricks' ), 'rename' => esc_html__( 'Rename', 'bricks' ), 'renameImages' => esc_html__( 'Rename images', 'bricks' ), 'renameImagesDisabled' => esc_html__( 'Disabled: Keep original image filename.', 'bricks' ), 'renameImagesEnabled' => esc_html__( 'Enabled: Rename image before download.', 'bricks' ), 'linkRenderedAs' => esc_html__( 'Link rendered as', 'bricks' ), 'repeat' => esc_html__( 'Repeat', 'bricks' ), 'relation' => esc_html__( 'Relation', 'bricks' ), 'replaceContent' => esc_html__( 'Replace content', 'bricks' ), 'replaceContentDisabled' => esc_html__( 'Disabled: Insert below existing content.', 'bricks' ), 'replaceContentEnabled' => esc_html__( 'Enabled: Replace existing content with template data.', 'bricks' ), 'responsiveBreakpoints' => esc_html__( 'Responsive breakpoints', 'bricks' ), 'reset' => esc_html__( 'Reset', 'bricks' ), 'resetBreakpointsDescription' => esc_html__( 'Resetting all breakpoints deletes all custom breakpoints and resets all default breakpoints.', 'bricks' ), 'resetStyles' => esc_html__( 'Reset styles', 'bricks' ), 'resetDynamicData' => esc_html__( 'Clear non-existing dynamic data', 'bricks' ), 'results' => esc_html__( 'Results', 'bricks' ), 'resultsFor' => esc_html__( 'results for:', 'bricks' ), 'reverse' => esc_html__( 'Reverse', 'bricks' ), 'revisionBy' => esc_html__( 'Revision by', 'bricks' ), 'revisionDeleted' => esc_html__( 'Revision deleted', 'bricks' ), 'revisionApplied' => esc_html__( 'Revision applied', 'bricks' ), 'revisionDiscarded' => esc_html__( 'Revision discarded', 'bricks' ), 'revisions' => esc_html__( 'Revisions', 'bricks' ), 'revisionsDeleted' => esc_html__( 'All revisions deleted', 'bricks' ), 'right' => esc_html__( 'Right', 'bricks' ), 'roles' => esc_html__( 'Roles', 'bricks' ), 'runCode' => esc_html__( 'Run code', 'bricks' ), 'saturation' => esc_html__( 'Saturation', 'bricks' ), 'save' => esc_html__( 'Save', 'bricks' ), 'saveDraft' => esc_html__( 'Save draft', 'bricks' ), 'saveAsGlobalElement' => esc_html__( 'Save as global element', 'bricks' ), 'saveAsTemplate' => esc_html__( 'Save as template', 'bricks' ), 'saveNewStyle' => esc_html__( 'Save new style', 'bricks' ), 'saveStyle' => esc_html__( 'Save style', 'bricks' ), 'saved' => esc_html__( 'Saved', 'bricks' ), 'savedAsTemplate' => esc_html__( 'Saved as template', 'bricks' ), 'scale' => esc_html__( 'Scale', 'bricks' ), 'scroll' => esc_html__( 'Scroll', 'bricks' ), 'searchElements' => esc_html__( 'Search elements ..', 'bricks' ), 'searchFor' => esc_html__( 'Search for ..', 'bricks' ), 'searchSettings' => esc_html__( 'Search settings', 'bricks' ), 'search' => esc_html__( 'Search', 'bricks' ), 'searchByTitle' => esc_html__( 'Search by title', 'bricks' ), 'searchPages' => esc_html__( 'Search pages ..', 'bricks' ), 'searchTemplates' => esc_html__( 'Search templates ..', 'bricks' ), 'searchTag' => esc_html__( 'Search tag', 'bricks' ), 'section' => esc_html__( 'Section', 'bricks' ), 'select' => esc_html__( 'Select', 'bricks' ), 'selectColorPalette' => esc_html__( 'Select color palette', 'bricks' ), 'setTemplateConditions' => esc_html__( 'Set conditions', 'bricks' ), 'selectFile' => esc_html__( 'Select file', 'bricks' ), 'selectFilesToImport' => esc_html__( 'Select file(s) to import', 'bricks' ), 'selectIcon' => esc_html__( 'Select icon', 'bricks' ), 'selectImage' => esc_html__( 'Select image', 'bricks' ), 'selectLibrary' => esc_html__( 'Select library', 'bricks' ), 'selectPostType' => esc_html__( 'Select post type', 'bricks' ), 'selectPosts' => esc_html__( 'Select posts', 'bricks' ), 'selectTaxonomies' => esc_html__( 'Select taxonomies', 'bricks' ), 'selectTemplate' => esc_html__( 'Select template', 'bricks' ), 'selectTemplateTags' => esc_html__( 'Select template tags', 'bricks' ), 'selectTemplateType' => esc_html__( 'Select template type', 'bricks' ), 'selectTemplateToUpdate' => esc_html__( 'Select template to update', 'bricks' ), 'selectTerms' => esc_html__( 'Select terms', 'bricks' ), 'send' => esc_html__( 'Send', 'bricks' ), 'sepia' => esc_html__( 'Sepia', 'bricks' ), 'settings' => esc_html__( 'Settings', 'bricks' ), 'settingsImported' => esc_html__( 'Settings imported', 'bricks' ), 'settingsResetted' => esc_html__( 'Settings resetted', 'bricks' ), 'solid' => esc_html__( 'Solid', 'bricks' ), 'settings' => esc_html__( 'Settings', 'bricks' ), 'showAuthor' => esc_html__( 'Show author', 'bricks' ), 'showDate' => esc_html__( 'Show date', 'bricks' ), 'showEmpty' => esc_html__( 'Show empty', 'bricks' ), 'showExcerpt' => sprintf( '<a href="https://codex.wordpress.org/Excerpt" target="_blank">%s</a>', esc_html__( 'Show excerpt', 'bricks' ) ), 'showInfo' => esc_html__( 'Show info', 'bricks' ), 'showFullscreen' => esc_html__( 'Show fullscreen', 'bricks' ), 'showTitle' => esc_html__( 'Show title', 'bricks' ), 'single' => esc_html__( 'Single', 'bricks' ), 'site' => esc_html__( 'Site', 'bricks' ), 'size' => esc_html__( 'Size', 'bricks' ), 'skip' => esc_html__( 'Skip', 'bricks' ), 'slide' => esc_html__( 'Slide', 'bricks' ), 'slider-nested' => esc_html__( 'Slide', 'bricks' ), // ActionAdd.vue tooltip 'small' => esc_html__( 'Small', 'bricks' ), 'spaceBetween' => esc_html__( 'Space between', 'bricks' ), 'spaceAround' => esc_html__( 'Space around', 'bricks' ), 'spaceEvenly' => esc_html__( 'Space evenly', 'bricks' ), 'spread' => esc_html__( 'Spread', 'bricks' ), 'square' => esc_html__( 'Square', 'bricks' ), 'start' => esc_html__( 'Start', 'bricks' ), 'stretch' => esc_html__( 'Stretch', 'bricks' ), 'strike' => esc_html__( 'Strike', 'bricks' ), 'strokeColor' => esc_html__( 'Stroke color', 'bricks' ), 'strokeWidth' => esc_html__( 'Stroke width', 'bricks' ), 'structure' => esc_html__( 'Structure', 'bricks' ), 'style' => esc_html__( 'Style', 'bricks' ), 'styles' => esc_html__( 'Styles', 'bricks' ), 'subject' => esc_html__( 'Subject', 'bricks' ), 'sure' => esc_html__( 'Sure?', 'bricks' ), 'switchTo' => esc_html__( 'Switch to', 'bricks' ), 'svgUploadNotAllowed' => esc_html__( 'You are not allowed to uploads SVG files.', 'bricks' ), 'tablet' => esc_html__( 'Tablet', 'bricks' ), 'tag' => esc_html__( 'Tag', 'bricks' ), 'taxonomy' => esc_html__( 'Taxonomy', 'bricks' ), 'taxonomies' => esc_html__( 'Taxonomies', 'bricks' ), 'taxQuery' => esc_html__( 'Taxonomy query', 'bricks' ), 'template' => esc_html__( 'Template', 'bricks' ), 'templateBundle' => esc_html__( 'Template bundle', 'bricks' ), 'templateCreated' => esc_html__( 'Template created', 'bricks' ), 'templateDeleted' => esc_html__( 'Template deleted', 'bricks' ), 'templateImportHint' => esc_html__( 'Inserting any template overwrites your data. We recommend to save your changes first.', 'bricks' ), 'templateImported' => esc_html__( 'Template imported', 'bricks' ), 'templateInserted' => esc_html__( 'Template inserted', 'bricks' ), 'templateInsertErrorNoData' => esc_html__( 'Template insert failed: This template has no data', 'bricks' ), 'templateOverridden' => esc_html__( 'Template overridden', 'bricks' ), 'templateReleaseAfterCancellation' => esc_html__( 'Released after you cancelled', 'bricks' ), 'templateReleaseSinceCancellation' => esc_html__( 'new templates have been released since you cancelled Bricks.', 'bricks' ), 'templateSaved' => esc_html__( 'Template saved', 'bricks' ), 'templateSettings' => esc_html__( 'Template settings', 'bricks' ), 'templateTag' => esc_html__( 'Template tag', 'bricks' ), 'templateTags' => esc_html__( 'Template tags', 'bricks' ), 'templateType' => esc_html__( 'Template type', 'bricks' ), 'templateTypeDescription' => esc_html__( 'Select the type of template you want to create:', 'bricks' ), 'templates' => esc_html__( 'Templates', 'bricks' ), 'terms' => esc_html__( 'Terms', 'bricks' ), 'text' => esc_html__( 'Text', 'bricks' ), 'textAlign' => esc_html__( 'Text align', 'bricks' ), 'textDecoration' => esc_html__( 'Text decoration', 'bricks' ), 'textShadow' => esc_html__( 'Text shadow', 'bricks' ), 'textTransform' => esc_html__( 'Text transform', 'bricks' ), 'themeStyles' => esc_html__( 'Theme Styles', 'bricks' ), 'themeStyleActive' => esc_html__( 'Active style', 'bricks' ), 'themeStyleActiveInfo' => esc_html__( 'Set condition(s) to apply selected theme style to your entire website or certain areas.', 'bricks' ), 'themeStyleNameExists' => esc_html__( 'The style name entered already exists. Please choose a different name.', 'bricks' ), 'themeStyleSelectInfo' => sprintf( esc_html__( 'Select a theme style or create a new one to style your website (%s).', 'bricks' ), Helpers::article_link( 'theme-styles', esc_html__( 'learn more', 'bricks' ) ) ), 'themeStyleCreated' => esc_html__( 'Theme style created', 'bricks' ), 'themeStyleDeleted' => esc_html__( 'Theme style deleted', 'bricks' ), 'themeStyleNewName' => esc_html__( 'New theme style name', 'bricks' ), 'themeStyleSaved' => esc_html__( 'Style saved', 'bricks' ), 'title' => esc_html__( 'Title', 'bricks' ), 'top' => esc_html__( 'Top', 'bricks' ), 'topLeft' => esc_html__( 'Top left', 'bricks' ), 'topCenter' => esc_html__( 'Top center', 'bricks' ), 'topRight' => esc_html__( 'Top right', 'bricks' ), 'thumbnail' => esc_html__( 'Thumbnail', 'bricks' ), 'true' => esc_html__( 'True', 'bricks' ), 'type' => esc_html__( 'Type', 'bricks' ), 'typography' => esc_html__( 'Typography', 'bricks' ), 'transform' => [ 'translateX' => esc_html__( 'Translate X', 'bricks' ), 'translateY' => esc_html__( 'Translate Y', 'bricks' ), 'scaleX' => esc_html__( 'Scale X', 'bricks' ), 'scaleY' => esc_html__( 'Scale Y', 'bricks' ), 'rotateX' => esc_html__( 'Rotate X', 'bricks' ), 'rotateY' => esc_html__( 'Rotate Y', 'bricks' ), 'rotateZ' => esc_html__( 'Rotate Z', 'bricks' ), 'skewX' => esc_html__( 'Skew X', 'bricks' ), 'skewY' => esc_html__( 'Skew Y', 'bricks' ), ], 'underline' => esc_html__( 'Underline', 'bricks' ), 'undo' => esc_html__( 'Undo', 'bricks' ), 'unlink' => esc_html__( 'Unlink', 'bricks' ), 'unlinked' => esc_html__( 'Unlinked', 'bricks' ), 'unlocked' => esc_html__( 'Unlocked', 'bricks' ), 'unsplashErrorInvalidApiKey' => esc_html__( 'Your Unsplash API key is not valid.', 'bricks' ), 'unsplashErrorNoApiKey' => sprintf( esc_html__( 'Unsplash API key required! Add key in dashboard under: %s', 'bricks' ), '<a href="' . Helpers::settings_url( '#tab-api-keys' ) . '" target="_blank">' . esc_html__( 'Bricks > Settings > API Keys', 'bricks' ) . '</a>' ), 'unsplashErrorRateLimitReached' => esc_html__( 'Rate limit for this hour reached. Please wait until the next full hour for it to be resetted.', 'bricks' ), 'unsplashSearchPlaceholder' => esc_html__( 'Type keyword, hit enter.', 'bricks' ), 'uncategorized' => esc_html__( 'Uncategorized', 'bricks' ), 'understandingTheLayout' => esc_html__( 'Understanding the layout', 'bricks' ), 'unitTooltip' => esc_html__( 'Select/enter unit', 'bricks' ), 'unpin' => esc_html__( 'Unpin', 'bricks' ), 'unsplashSetApiKey' => '<a href="' . Helpers::settings_url( '#tab-api-keys' ) . '" class="button" target="_blank">' . esc_html__( 'Set Unsplash API Key', 'bricks' ) . '</a>', 'update' => esc_html__( 'Update', 'bricks' ), 'uppercase' => esc_html__( 'Uppercase', 'bricks' ), 'url' => esc_html__( 'URL', 'bricks' ), 'userProfile' => esc_html__( 'User profile', 'bricks' ), 'vertical' => esc_html__( 'Vertical', 'bricks' ), 'verticalAlignment' => esc_html__( 'Vertical alignment', 'bricks' ), 'video' => esc_html__( 'Video', 'bricks' ), 'videoUrl' => esc_html__( 'Video URL', 'bricks' ), 'viewOnFrontend' => esc_html__( 'View on frontend', 'bricks' ), 'visitBricksAcademy' => esc_html__( 'Visit Bricks Academy', 'bricks' ), 'visitDocs' => esc_html__( 'Visit docs', 'bricks' ), 'width' => esc_html__( 'Width', 'bricks' ), 'woocommerce_product' => esc_html__( 'Product', 'bricks' ), 'wordpress' => esc_html__( 'WordPress', 'bricks' ), 'wrap' => esc_html__( 'Wrap', 'bricks' ), 'nowrap' => esc_html__( 'No wrap', 'bricks' ), 'wrap-reverse' => esc_html__( 'Wrap reverse', 'bricks' ), 'xAxis' => esc_html__( 'X axis', 'bricks' ), 'yAxis' => esc_html__( 'Y axis', 'bricks' ), 'yes' => esc_html__( 'Yes', 'bricks' ), 'youAreMissingOut' => esc_html__( 'You are missing out!', 'bricks' ), 'zIndex' => esc_html__( 'Z-index', 'bricks' ), ]; return apply_filters( 'bricks/builder/i18n', $i18n ); } /** * Custom save messages * * @since 1.0 * * @return array */ function save_messages() { $messages = [ esc_html__( 'All right', 'bricks' ), esc_html__( 'Amazing', 'bricks' ), esc_html__( 'Aye', 'bricks' ), esc_html__( 'Beautiful', 'bricks' ), esc_html__( 'Brilliant', 'bricks' ), esc_html__( 'Champ', 'bricks' ), esc_html__( 'Cool', 'bricks' ), esc_html__( 'Congrats', 'bricks' ), esc_html__( 'Done', 'bricks' ), esc_html__( 'Excellent', 'bricks' ), esc_html__( 'Exceptional', 'bricks' ), esc_html__( 'Exquisite', 'bricks' ), esc_html__( 'Enjoy', 'bricks' ), esc_html__( 'Fantastic', 'bricks' ), esc_html__( 'Fine', 'bricks' ), esc_html__( 'Good', 'bricks' ), esc_html__( 'Grand', 'bricks' ), esc_html__( 'Impressive', 'bricks' ), esc_html__( 'Incredible', 'bricks' ), esc_html__( 'Magnificent', 'bricks' ), esc_html__( 'Marvelous', 'bricks' ), esc_html__( 'Neat', 'bricks' ), esc_html__( 'Nice job', 'bricks' ), esc_html__( 'Okay', 'bricks' ), esc_html__( 'Outstanding', 'bricks' ), esc_html__( 'Remarkable', 'bricks' ), esc_html__( 'Saved', 'bricks' ), esc_html__( 'Skillful', 'bricks' ), esc_html__( 'Stunning', 'bricks' ), esc_html__( 'Superb', 'bricks' ), esc_html__( 'Sure thing', 'bricks' ), esc_html__( 'Sweet', 'bricks' ), esc_html__( 'Top', 'bricks' ), esc_html__( 'Very well', 'bricks' ), esc_html__( 'Woohoo', 'bricks' ), esc_html__( 'Wonderful', 'bricks' ), esc_html__( 'Yeah', 'bricks' ), esc_html__( 'Yep', 'bricks' ), esc_html__( 'Yes', 'bricks' ), ]; $messages = apply_filters( 'bricks/builder/save_messages', $messages ); return $messages; } /** * Get icon font classes * * @since 1.0 * * @return array */ public static function get_icon_font_classes() { return [ 'close' => 'ion-md-close', 'undo' => 'ion-ios-undo', 'redo' => 'ion-ios-redo', 'arrowRight' => 'ion-ios-arrow-forward', 'arrowDown' => 'ion-ios-arrow-down', 'arrowLeft' => 'ion-ios-arrow-back', 'arrowUp' => 'ion-ios-arrow-up', 'preview' => 'ion-ios-eye', 'settings' => 'ion-md-settings', 'structure' => 'ion-ios-albums', 'publish' => 'ion-ios-power', 'templates' => 'ion-ios-folder-open', 'page' => 'ion-md-document', 'desktop' => 'ion-md-desktop', 'mobile' => 'ion-md-phone-portrait', 'globe' => 'ion-md-globe', 'documentation' => 'ion-ios-help-buoy', 'panelMaximize' => 'ion-ios-qr-scanner', 'panelMinimize' => 'ion-ios-qr-scanner', 'add' => 'ion-md-add', 'addTi' => 'ti-plus', 'remove' => 'ion-md-remove', 'edit' => 'ion-md-create', 'clone' => 'ion-ios-copy', 'move' => 'ion-md-move', 'save' => 'ion-md-save', 'check' => 'ion-md-checkmark', 'trash' => 'ion-md-trash', 'trashTi' => 'ti-trash', 'newTab' => 'ti-new-window', 'brush' => 'ion-md-brush', 'image' => 'ion-ios-image', 'video' => 'ion-md-videocam', 'cssFilter' => 'ion-md-color-filter', 'faceSad' => 'ti-face-sad', 'heart' => 'ion-md-heart', 'refresh' => 'ti-reload', 'help' => 'ti-help-alt', 'helpIon' => 'ion-md-help-circle', 'hover' => 'ti-hand-point-up', 'more' => 'ti-more-alt', 'notifications' => 'ti-bell', 'revisions' => 'ion-md-time', 'link' => 'ion-ios-link', 'docs' => 'ti-agenda', 'email' => 'ion-ios-mail', 'search' => 'ti-search', 'wordpress' => 'ti-wordpress', 'import' => 'ti-import', 'export' => 'ti-export', 'download' => 'ti-download', 'zoomIn' => 'ti-zoom-in', ]; } /** * Based on post_type or template type select the first elements category to show up on builder. * * @return void */ public function get_first_elements_category( $post_id = 0 ) { $post_type = get_post_type( $post_id ); // NOTE: Undocumented $category = apply_filters( 'bricks/builder/first_element_category', false, $post_id, $post_type ); if ( $category ) { return $category; } if ( 'page' !== $post_type ) { return 'single'; } return ''; } /** * Default color palette (https://www.materialui.co/colors) * * Only used if no custom colorPalette is saved in db. * * @since 1.0 * * @return array */ public static function default_color_palette() { $colors = [ // Grey [ 'hex' => '#f5f5f5' ], [ 'hex' => '#e0e0e0' ], [ 'hex' => '#9e9e9e' ], [ 'hex' => '#616161' ], [ 'hex' => '#424242' ], [ 'hex' => '#212121' ], // A200 [ 'hex' => '#ffeb3b' ], [ 'hex' => '#ffc107' ], [ 'hex' => '#ff9800' ], [ 'hex' => '#ff5722' ], [ 'hex' => '#f44336' ], [ 'hex' => '#9c27b0' ], [ 'hex' => '#2196f3' ], [ 'hex' => '#03a9f4' ], [ 'hex' => '#81D4FA' ], [ 'hex' => '#4caf50' ], [ 'hex' => '#8bc34a' ], [ 'hex' => '#cddc39' ], ]; $colors = apply_filters( 'bricks/builder/color_palette', $colors ); foreach ( $colors as $key => $color ) { $colors[ $key ]['id'] = Helpers::generate_random_id( false ); $colors[ $key ]['name'] = sprintf( esc_html__( 'Color #%s', 'bricks' ), $key + 1 ); } $palettes[] = [ 'id' => Helpers::generate_random_id( false ), 'name' => esc_html__( 'Default', 'bricks' ), 'colors' => $colors, ]; return $palettes; } /** * Check permissions for a certain user to access the Bricks builder * * @since 1.0 */ public function template_redirect() { // Redirect non-logged-in visitors to login page if ( ! is_user_logged_in() ) { auth_redirect(); } // 1/3: Check for valid license $license_is_valid = License::license_is_valid(); if ( ! $license_is_valid ) { wp_redirect( admin_url( 'admin.php?page=bricks-license' ) ); } // 2/3: Check if current user can edit post if ( ! Capabilities::current_user_can_use_builder() ) { // Redirect users without builder capabilities back to WordPress admin area wp_redirect( admin_url( '/?action=edit&bricks_notice=error_role_manager' ) ); die(); } // NOTE: Don't check for template if ( is_home() || ( function_exists( 'is_shop' ) && is_shop() ) ) { return; } // 3/3: Check admin settings if post type is supported $current_post_type = get_post_type(); $supported_post_types = Database::get_setting( 'postTypes', [] ); // Bricks templates always have builder support if ( $current_post_type === BRICKS_DB_TEMPLATE_SLUG ) { $supported_post_types[] = BRICKS_DB_TEMPLATE_SLUG; } // NOTE: Undocumented $supported_post_types = apply_filters( 'bricks/builder/supported_post_types', $supported_post_types, $current_post_type ); if ( ! in_array( $current_post_type, $supported_post_types ) ) { wp_redirect( admin_url( "/edit.php?post_type={$current_post_type}&bricks_notice=error_post_type" ) ); } } /** * Get page data for builder * * @since 1.0 * * @return array */ public static function builder_data( $post_id ) { $global_data = Database::$global_data; $page_data = Database::$page_data; $theme_styles = Theme_Styles::$styles; $theme_style_active = Theme_Styles::$active_id; $template_settings = Helpers::get_template_settings( $post_id ); $template_preview_post_id = ! empty( $template_settings['templatePreviewPostId'] ) ? $template_settings['templatePreviewPostId'] : 0; $load_data = [ 'fullAccess' => Capabilities::current_user_has_full_access(), 'breakpoints' => Breakpoints::$breakpoints, 'breakpointActive' => Breakpoints::$base_key, 'themeStyles' => $theme_styles, 'themeStyleActive' => $theme_style_active, 'pinnedElements' => get_option( BRICKS_DB_PINNED_ELEMENTS, [] ), ]; // Add color palettes to load_data if ( ! empty( $global_data['colorPalette'] ) && is_array( $global_data['colorPalette'] ) ) { $load_data['colorPalette'] = $global_data['colorPalette']; } else { $load_data['colorPalette'] = self::default_color_palette(); } // Add global classes if ( ! empty( $global_data['globalClasses'] ) ) { $load_data['globalClasses'] = $global_data['globalClasses']; } // Add global classes locked if ( ! empty( $global_data['globalClassesLocked'] ) ) { $load_data['globalClassesLocked'] = $global_data['globalClassesLocked']; } // Add pseudo classes if ( ! empty( $global_data['pseudoClasses'] ) ) { $load_data['pseudoClasses'] = $global_data['pseudoClasses']; } else { $load_data['pseudoClasses'] = [ ':hover', ':active', ':focus', ]; } // Add elements & global settings if ( ! empty( $global_data['elements'] ) ) { $load_data['globalElements'] = $global_data['elements']; } if ( ! empty( $global_data['settings'] ) ) { $load_data['globalSettings'] = $global_data['settings']; } // Add page data to load_data if ( ! empty( $page_data['header'] ) ) { $load_data['header'] = $page_data['header']; } else { // Check for header template $template_header_id = Database::$active_templates['header']; $header_template = $template_header_id ? Database::get_data( $template_header_id, 'header' ) : Database::get_data( $post_id, 'header' ); if ( ! empty( $header_template ) ) { $load_data['header'] = $header_template; // Sticky header, header postition etc. $load_data['templateHeaderSettings'] = Helpers::get_template_settings( $template_header_id ); } } // Content $template_content_id = Database::$active_templates['content']; if ( count( $page_data['content'] ) ) { $load_data['content'] = $page_data['content']; } // If content still not populated, check if populated content was set to preview it if ( empty( $load_data['content'] ) && $template_preview_post_id ) { // Template preview $content = get_post_meta( $template_preview_post_id, BRICKS_DB_PAGE_CONTENT, true ); $load_data['content'] = empty( $content ) ? [] : $content; } // Last resort for getting content: WP blocks if ( empty( $load_data['content'] ) && Database::get_setting( 'wp_to_bricks' ) ) { $template_preview_post_id = $template_preview_post_id ? $template_preview_post_id : $post_id; // Convert Gutenberg blocks to Bricks element $converter = new Blocks(); $content_from_blocks = $converter->convert_blocks_to_bricks( $template_preview_post_id ); if ( is_array( $content_from_blocks ) ) { $load_data['content'] = $content_from_blocks; // DEV_ONLY $post = get_post( $template_content_id ); $blocks = parse_blocks( $post->post_content ); $load_data['blocks'] = $blocks; } } // Footer if ( ! empty( $page_data['footer'] ) ) { $load_data['footer'] = $page_data['footer']; } else { $template_footer_id = Database::$active_templates['footer']; // Check for footer template $footer_template = $template_footer_id ? Database::get_data( $template_footer_id, 'footer' ) : []; if ( ! empty( $footer_template ) ) { $load_data['footer'] = $footer_template; } } if ( ! empty( $page_data['settings'] ) ) { $load_data['pageSettings'] = $page_data['settings']; } // Template type $template_type = Templates::get_template_type( $post_id ); // @since 1.7.1 - Default template type is 'content' (so listenHistory in builder can work properly) $load_data['templateType'] = ! empty( $template_type ) ? $template_type : 'content'; // Template settings if ( $template_settings ) { $load_data['templateSettings'] = $template_settings; } // Parse elements to replace dynamic data (needed for background image) $template_preview_post_id = $template_preview_post_id ? $template_preview_post_id : $post_id; if ( $template_type !== 'header' && ! empty( $load_data['header'] ) && is_array( $load_data['header'] ) ) { $load_data['header'] = self::render_dynamic_data_on_elements( $load_data['header'], $template_preview_post_id ); } if ( ! empty( $load_data['content'] ) && is_array( $load_data['content'] ) ) { $load_data['content'] = self::render_dynamic_data_on_elements( $load_data['content'], $template_preview_post_id ); } if ( $template_type !== 'footer' && ! empty( $load_data['footer'] ) && is_array( $load_data['footer'] ) ) { $load_data['footer'] = self::render_dynamic_data_on_elements( $load_data['footer'], $template_preview_post_id ); } // Generate element HTML strings in PHP for fast initial render (individual element HTML AJAX calls in builder are too slow) // Only load for dynamic data (not static areas) $load_data['elementsHtml'] = []; // Remove setting in builder to get 'elementsHtml' with element ID for all PHP elements (@since 1.7) unset( Database::$global_settings['elementAttsAsNeeded'] ); if ( $template_type === 'header' && isset( $load_data['header'] ) && is_array( $load_data['header'] ) ) { $load_data['elementsHtml'] = array_merge( $load_data['elementsHtml'], self::query_content_type_for_elements_html( $load_data['header'], $template_preview_post_id ) ); } if ( ! in_array( $template_type, [ 'header', 'footer' ] ) && isset( $load_data['content'] ) && is_array( $load_data['content'] ) ) { $load_data['elementsHtml'] = array_merge( $load_data['elementsHtml'], self::query_content_type_for_elements_html( $load_data['content'], $template_preview_post_id ) ); } if ( $template_type === 'footer' && isset( $load_data['footer'] ) && is_array( $load_data['footer'] ) ) { $load_data['elementsHtml'] = array_merge( $load_data['elementsHtml'], self::query_content_type_for_elements_html( $load_data['footer'], $template_preview_post_id ) ); } /** * STEP: Pre-populate dynamic data to minimize AJAX requests on builder load * * Only if Bricks builder setting 'enableDynamicDataPreview' is enabled, we pre-populate. * * @see render_dynamic_data_on_elements * * @since 1.7.1 */ if ( Database::get_setting( 'enableDynamicDataPreview', false ) && is_array( self::$dynamic_data ) && count( self::$dynamic_data ) ) { $load_data['dynamicData'] = self::$dynamic_data; } return $load_data; } /** * Return array with HTML string of every single element for initial fast builder render * * @since 1.0 */ public static function query_content_type_for_elements_html( $elements, $post_id ) { $elements_html = []; foreach ( $elements as $element ) { $element_name = ! empty( $element['name'] ) ? $element['name'] : ''; // Skip generating HTML for certain elements if ( $element_name === 'code' || // To prevent critical errors with code execution enabled when loading the builder $element_name === 'template' // To render template inline CSS in builder ) { continue; } // STEP: Pre-populate dynamic data for all elements (@since 1.7.1) if ( Database::get_setting( 'enableDynamicDataPreview', false ) && ! empty( $element['settings'] ) ) { $settings_string = json_encode( $element['settings'] ); // Get all dynamic data tags inside element settings preg_match_all( '/\{([^{}"]+)\}/', $settings_string, $matches ); $dynamic_data_tags = $matches[1]; foreach ( $dynamic_data_tags as $dynamic_data_tag ) { $dynamic_data_value = \Bricks\Integrations\Dynamic_Data\Providers::render_tag( $dynamic_data_tag, $post_id ); if ( $dynamic_data_value ) { self::$dynamic_data[ "{$dynamic_data_tag}" ] = $dynamic_data_value; } } } $element_class_name = isset( Elements::$elements[ $element_name ]['class'] ) ? Elements::$elements[ $element_name ]['class'] : false; if ( ! $element_class_name || ! class_exists( $element_class_name ) ) { continue; } $element_instance = new $element_class_name( $element ); // Skip nestable elements if ( $element_instance->nestable ) { unset( $element_instance ); continue; } // Check for and populate global element settings (@since 1.2.1) foreach ( Database::$global_data['elements'] as $index => $global_element ) { if ( ! empty( $global_element['global'] ) && ! empty( $element['global'] ) && $global_element['global'] === $element['global'] ) { unset( $element['settings'] ); $element['settings'] = $global_element['settings']; } // Pre 1.2.1: Use 'id' instead of 'global' property elseif ( ! empty( $global_element['id'] ) && $global_element['id'] === $element['id'] ) { unset( $element['settings'] ); $element['settings'] = $global_element['settings']; } // Last global element checked: The global element doesn't exist in this installation: Remove element.global property elseif ( $index + 1 === count( Database::$global_data['elements'] ) ) { unset( $element['global'] ); } } $elements_html[ $element['id'] ] = Ajax::render_element( $element ); } return $elements_html; } /** * Screens all elements and try to convert dynamic data to enhance builder experience * * @param array $elements * @param int $post_id * @return void */ public static function render_dynamic_data_on_elements( $elements, $post_id ) { if ( strpos( json_encode( $elements ), 'useDynamicData' ) === false ) { return $elements; } foreach ( $elements as $index => $element ) { $elements[ $index ]['settings'] = self::render_dynamic_data_on_settings( $element['settings'], $post_id ); } return $elements; } /** * On the settings array, if _background exists and is set to image, get the image URL * Needed when setting element background image * * @param array $settings * @param int $post_id * @return void */ public static function render_dynamic_data_on_settings( $settings, $post_id ) { // Return: Do not render dynamic data for elements inside a loop if ( isset( $settings['hasLoop'] ) ) { return $settings; } $background_image_dd_tag = ! empty( $settings['_background']['image']['useDynamicData'] ) ? $settings['_background']['image']['useDynamicData'] : false; if ( ! $background_image_dd_tag ) { return $settings; } $size = ! empty( $settings['_background']['image']['size'] ) ? $settings['_background']['image']['size'] : BRICKS_DEFAULT_IMAGE_SIZE; $images = Integrations\Dynamic_Data\Providers::render_tag( $background_image_dd_tag, $post_id, 'image', [ 'size' => $size ] ); $image_id = ! empty( $images[0] ) ? $images[0] : false; if ( ! $image_id ) { unset( $settings['_background']['image']['id'], $settings['_background']['image']['url'] ); return $settings; } if ( is_numeric( $image_id ) ) { $settings['_background']['image']['id'] = $image_id; $settings['_background']['image']['size'] = $size; $settings['_background']['image']['url'] = wp_get_attachment_image_url( $image_id, $size ); } else { $settings['_background']['image']['url'] = $image_id; } return $settings; } /** * Builder: Force Bricks template to avoid conflicts with other builders (Elementor PRO, etc.) */ public function template_include( $template ) { if ( bricks_is_builder() ) { $template = BRICKS_PATH . 'template-parts/builder.php'; } return $template; } /** * Helper function to check if a AJAX or REST API call comes from inside the builder * * NOTE: Use bricks_is_builder_call() to check if AJAX/REST API call inside the builder * * @since 1.5.5 * * @return boolean */ public static function is_builder_call() { /** * STEP: Builder AJAX call: Check data for 'bricks-is-builder' * * @since 1.5.5 */ if ( bricks_is_ajax_call() ) { $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : ''; $is_builder = isset( $_REQUEST['bricks-is-builder'] ); if ( $is_builder ) { return true; } // Check if call action starts with 'bricks_' if ( strpos( $action, 'bricks_' ) === 0 ) { return true; } } /** * STEP: REST API call * * Is default builder render. */ if ( bricks_is_rest_call() ) { return ! empty( $_SERVER['HTTP_X_BRICKS_IS_BUILDER'] ); } /** * STEP: Builder frontend preview (window opened via builder toolbar preview icon) * * Check needed as referrer check below is the builder. * * @since 1.6.2 */ if ( isset( $_GET['bricks_preview'] ) ) { return false; } // STEP: Check query string of referer URL (@since 1.5.5) $referer = ! empty( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : wp_get_referer(); $url_parsed = $referer ? wp_parse_url( $referer ) : ''; $url_query_string = isset( $url_parsed['query'] ) ? $url_parsed['query'] : ''; if ( $url_query_string && strpos( $url_query_string, 'bricks=run' ) !== false ) { return true; } return false; } }