add_content_filter(); $this->init_swiper_settings(); // Hack to avoid enqueue post CSS while it's a `the_excerpt` call. add_filter( 'get_the_excerpt', [ $this, 'start_excerpt_flag' ], 1 ); add_filter( 'get_the_excerpt', [ $this, 'end_excerpt_flag' ], 20 ); } /** * Get module name. * * Retrieve the module name. * * @since 2.3.0 * @access public * * @return string Module name. */ public function get_name() { return 'frontend'; } /** * Init render mode manager. */ public function init_render_mode() { if ( Plugin::$instance->editor->is_edit_mode() ) { return; } $this->render_mode_manager = new Render_Mode_Manager(); } /** * Init. * * Initialize Elementor front end. Hooks the needed actions to run Elementor * in the front end, including script and style registration. * * Fired by `template_redirect` action. * * @since 1.0.0 * @access public */ public function init() { if ( Plugin::$instance->editor->is_edit_mode() ) { return; } add_filter( 'body_class', [ $this, 'body_class' ] ); if ( Plugin::$instance->preview->is_preview_mode() ) { return; } if ( current_user_can( 'manage_options' ) ) { Plugin::$instance->init_common(); } $this->post_id = get_the_ID(); $document = Plugin::$instance->documents->get( $this->post_id ); if ( is_singular() && $document && $document->is_built_with_elementor() ) { add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_styles' ], self::ENQUEUED_STYLES_PRIORITY ); } // Priority 7 to allow google fonts in header template to load in
tag add_action( 'wp_head', [ $this, 'print_fonts_links' ], 7 ); add_action( 'wp_head', [ $this, 'print_google_fonts_preconnect_tag' ], 8 ); add_action( 'wp_head', [ $this, 'add_theme_color_meta_tag' ] ); add_action( 'wp_footer', [ $this, 'wp_footer' ] ); } public function print_google_fonts_preconnect_tag() { if ( 0 >= $this->google_fonts_index ) { return; } echo ''; } /** * @since 2.0.12 * @access public * @param string|array $class */ public function add_body_class( $class ) { if ( is_array( $class ) ) { $this->body_classes = array_merge( $this->body_classes, $class ); } else { $this->body_classes[] = $class; } } /** * Add Theme Color Meta Tag * * @since 3.0.0 * @access public */ public function add_theme_color_meta_tag() { $kit = Plugin::$instance->kits_manager->get_active_kit_for_frontend(); $mobile_theme_color = $kit->get_settings( 'mobile_browser_background' ); if ( ! empty( $mobile_theme_color ) ) { ?> body_classes ); $id = get_the_ID(); $document = Plugin::$instance->documents->get( $id ); if ( is_singular() && $document && $document->is_built_with_elementor() ) { $classes[] = 'elementor-page elementor-page-' . $id; } if ( Plugin::$instance->preview->is_preview_mode() ) { $editor_preferences = SettingsManager::get_settings_managers( 'editorPreferences' ); $show_hidden_elements = $editor_preferences->get_model()->get_settings( 'show_hidden_elements' ); if ( 'yes' === $show_hidden_elements ) { $classes[] = 'e-preview--show-hidden-elements'; } } return $classes; } /** * Add content filter. * * Remove plain content and render the content generated by Elementor. * * @since 1.8.0 * @access public */ public function add_content_filter() { add_filter( 'the_content', [ $this, 'apply_builder_in_content' ], self::THE_CONTENT_FILTER_PRIORITY ); } public function init_swiper_settings() { $e_swiper_latest = Plugin::$instance->experiments->is_feature_active( 'e_swiper_latest' ); $this->e_swiper_asset_path = $e_swiper_latest ? 'assets/lib/swiper/v8/' : 'assets/lib/swiper/'; $this->e_swiper_version = $e_swiper_latest ? '8.4.5' : '5.3.6'; } /** * Remove content filter. * * When the Elementor generated content rendered, we remove the filter to prevent multiple * accuracies. This way we make sure Elementor renders the content only once. * * @since 1.8.0 * @access public */ public function remove_content_filter() { remove_filter( 'the_content', [ $this, 'apply_builder_in_content' ], self::THE_CONTENT_FILTER_PRIORITY ); } /** * Registers scripts. * * Registers all the frontend scripts. * * Fired by `wp_enqueue_scripts` action. * * @since 1.2.1 * @access public */ public function register_scripts() { /** * Before frontend register scripts. * * Fires before Elementor frontend scripts are registered. * * @since 1.2.1 */ do_action( 'elementor/frontend/before_register_scripts' ); wp_register_script( 'elementor-webpack-runtime', $this->get_js_assets_url( 'webpack.runtime', 'assets/js/' ), [], ELEMENTOR_VERSION, true ); wp_register_script( 'elementor-frontend-modules', $this->get_js_assets_url( 'frontend-modules' ), [ 'elementor-webpack-runtime', 'jquery', ], ELEMENTOR_VERSION, true ); wp_register_script( 'flatpickr', $this->get_js_assets_url( 'flatpickr', 'assets/lib/flatpickr/' ), [ 'jquery', ], '4.1.4', true ); wp_register_script( 'imagesloaded', $this->get_js_assets_url( 'imagesloaded', 'assets/lib/imagesloaded/' ), [ 'jquery', ], '4.1.0', true ); wp_register_script( 'jquery-numerator', $this->get_js_assets_url( 'jquery-numerator', 'assets/lib/jquery-numerator/' ), [ 'jquery', ], '0.2.1', true ); wp_register_script( 'elementor-dialog', $this->get_js_assets_url( 'dialog', 'assets/lib/dialog/' ), [ 'jquery-ui-position', ], '4.9.3', true ); wp_register_script( 'elementor-gallery', $this->get_js_assets_url( 'e-gallery', 'assets/lib/e-gallery/js/' ), [ 'jquery', ], '1.2.0', true ); wp_register_script( 'share-link', $this->get_js_assets_url( 'share-link', 'assets/lib/share-link/' ), [ 'jquery', ], ELEMENTOR_VERSION, true ); wp_register_script( 'elementor-frontend', $this->get_js_assets_url( 'frontend' ), [ 'elementor-frontend-modules', 'jquery-ui-position', ], ELEMENTOR_VERSION, true ); /** * After frontend register scripts. * * Fires after Elementor frontend scripts are registered. * * @since 1.2.1 */ do_action( 'elementor/frontend/after_register_scripts' ); } /** * Registers styles. * * Registers all the frontend styles. * * Fired by `wp_enqueue_scripts` action. * * @since 1.2.0 * @access public */ public function register_styles() { $min_suffix = Utils::is_script_debug() ? '' : '.min'; $direction_suffix = is_rtl() ? '-rtl' : ''; $has_custom_breakpoints = Plugin::$instance->breakpoints->has_custom_breakpoints(); /** * Before frontend register styles. * * Fires before Elementor frontend styles are registered. * * @since 1.2.0 */ do_action( 'elementor/frontend/before_register_styles' ); wp_register_style( 'font-awesome', $this->get_css_assets_url( 'font-awesome', 'assets/lib/font-awesome/css/' ), [], '4.7.0' ); wp_register_style( 'elementor-icons', $this->get_css_assets_url( 'elementor-icons', 'assets/lib/eicons/css/' ), [], Icons_Manager::ELEMENTOR_ICONS_VERSION ); wp_register_style( 'flatpickr', $this->get_css_assets_url( 'flatpickr', 'assets/lib/flatpickr/' ), [], '4.1.4' ); wp_register_style( 'elementor-gallery', $this->get_css_assets_url( 'e-gallery', 'assets/lib/e-gallery/css/' ), [], '1.2.0' ); wp_register_style( 'e-apple-webkit', $this->get_frontend_file_url( 'apple-webkit.min.css', $has_custom_breakpoints, 'conditionals/' ), [], $has_custom_breakpoints ? null : ELEMENTOR_VERSION ); wp_register_style( 'e-swiper', $this->get_css_assets_url( 'e-swiper', 'assets/css/conditionals/' ), [ 'swiper' ], ELEMENTOR_VERSION ); wp_register_style( 'swiper', $this->get_css_assets_url( 'swiper', $this->e_swiper_asset_path . 'css/' ), [], $this->e_swiper_version ); wp_register_style( 'elementor-wp-admin-bar', $this->get_css_assets_url( 'admin-bar', 'assets/css/' ), [], ELEMENTOR_VERSION ); wp_register_style( 'e-lightbox', $this->get_frontend_file_url( 'lightbox.min.css', $has_custom_breakpoints, 'conditionals/' ), [], $has_custom_breakpoints ? null : ELEMENTOR_VERSION ); wp_register_style( 'elementor-frontend', $this->get_frontend_file_url( "frontend{$direction_suffix}{$min_suffix}.css", $has_custom_breakpoints ), [], $has_custom_breakpoints ? null : ELEMENTOR_VERSION ); $widgets_with_styles = Plugin::$instance->widgets_manager->widgets_with_styles(); foreach ( $widgets_with_styles as $widget_name ) { wp_register_style( "widget-{$widget_name}", $this->get_css_assets_url( "widget-{$widget_name}", null, true, true ), [ 'elementor-frontend' ], ELEMENTOR_VERSION ); } $widgets_with_responsive_styles = Plugin::$instance->widgets_manager->widgets_with_responsive_styles(); foreach ( $widgets_with_responsive_styles as $widget_name ) { wp_register_style( "widget-{$widget_name}", $this->get_frontend_file_url( "widget-{$widget_name}{$direction_suffix}.min.css", $has_custom_breakpoints ), [ 'elementor-frontend' ], $has_custom_breakpoints ? null : ELEMENTOR_VERSION ); } /** * After frontend register styles. * * Fires after Elementor frontend styles are registered. * * @since 1.2.0 */ do_action( 'elementor/frontend/after_register_styles' ); } /** * Enqueue scripts. * * Enqueue all the frontend scripts. * * @since 1.0.0 * @access public */ public function enqueue_scripts() { /** * Before frontend enqueue scripts. * * Fires before Elementor frontend scripts are enqueued. * * @since 1.0.0 */ do_action( 'elementor/frontend/before_enqueue_scripts' ); wp_enqueue_script( 'elementor-frontend' ); $this->print_config(); $this->enqueue_conditional_assets(); /** * After frontend enqueue scripts. * * Fires after Elementor frontend scripts are enqueued. * * @since 1.0.0 */ do_action( 'elementor/frontend/after_enqueue_scripts' ); } /** * Enqueue styles. * * Enqueue all the frontend styles. * * Fired by `wp_enqueue_scripts` action. * * @since 1.0.0 * @access public */ public function enqueue_styles() { static $is_enqueue_styles_already_triggered; if ( ! $is_enqueue_styles_already_triggered ) { $is_enqueue_styles_already_triggered = true; /** * Before frontend styles enqueued. * * Fires before Elementor frontend styles are enqueued. * * @since 1.0.0 */ do_action( 'elementor/frontend/before_enqueue_styles' ); // The e-icons are needed in preview mode for the editor icons (plus-icon for new section, folder-icon for the templates library etc.). if ( ! Plugin::$instance->experiments->is_feature_active( 'e_font_icon_svg' ) || Plugin::$instance->preview->is_preview_mode() ) { wp_enqueue_style( 'elementor-icons' ); } wp_enqueue_style( 'elementor-frontend' ); // TODO: Update in version 3.26.0 [ED-15471] if ( ! Plugin::$instance->experiments->is_feature_active( 'e_swiper_css_conditional_loading' ) ) { wp_enqueue_style( 'e-swiper' ); } if ( is_admin_bar_showing() ) { wp_enqueue_style( 'elementor-wp-admin-bar' ); } /** * After frontend styles enqueued. * * Fires after Elementor frontend styles are enqueued. * * @since 1.0.0 */ do_action( 'elementor/frontend/after_enqueue_styles' ); if ( ! Plugin::$instance->preview->is_preview_mode() ) { $post_id = get_the_ID(); // Check $post_id for virtual pages. check is singular because the $post_id is set to the first post on archive pages. if ( $post_id && is_singular() ) { $page_assets = get_post_meta( $post_id, Assets::ASSETS_META_KEY, true ); if ( ! empty( $page_assets ) ) { Plugin::$instance->assets_loader->enable_assets( $page_assets ); } $css_file = Post_CSS::create( get_the_ID() ); $css_file->enqueue(); } } } } /** * Get Frontend File URL * * Returns the URL for the CSS file to be loaded in the front end. If requested via the second parameter, a custom * file is generated based on a passed template file name. Otherwise, the URL for the default CSS file is returned. * * @since 3.4.5 * * @access public * * @param string $frontend_file_name * @param boolean $custom_file * * @return string frontend file URL */ public function get_frontend_file_url( $frontend_file_name, $custom_file, $css_subfolder = '' ) { if ( $custom_file ) { $frontend_file = $this->get_frontend_file( $frontend_file_name ); $frontend_file_url = $frontend_file->get_url(); } else { $frontend_file_url = ELEMENTOR_ASSETS_URL . 'css/' . $css_subfolder . $frontend_file_name; } return $frontend_file_url; } /** * Get Frontend File Path * * Returns the path for the CSS file to be loaded in the front end. If requested via the second parameter, a custom * file is generated based on a passed template file name. Otherwise, the path for the default CSS file is returned. * * @since 3.5.0 * @access public * * @param string $frontend_file_name * @param boolean $custom_file * * @return string frontend file path */ public function get_frontend_file_path( $frontend_file_name, $custom_file ) { if ( $custom_file ) { $frontend_file = $this->get_frontend_file( $frontend_file_name ); $frontend_file_path = $frontend_file->get_path(); } else { $frontend_file_path = ELEMENTOR_ASSETS_PATH . 'css/' . $frontend_file_name; } return $frontend_file_path; } /** * Get Frontend File * * Returns a frontend file instance. * * @since 3.5.0 * @access public * * @param string $frontend_file_name * @param string $file_prefix * @param string $template_file_path * * @return FrontendFile */ public function get_frontend_file( $frontend_file_name, $file_prefix = 'custom-', $template_file_path = '' ) { static $cached_frontend_files = []; $file_name = $file_prefix . $frontend_file_name; if ( isset( $cached_frontend_files[ $file_name ] ) ) { return $cached_frontend_files[ $file_name ]; } if ( ! $template_file_path ) { $template_file_path = Breakpoints_Manager::get_stylesheet_templates_path() . $frontend_file_name; } $frontend_file = new FrontendFile( $file_name, $template_file_path ); $time = $frontend_file->get_meta( 'time' ); if ( ! $time ) { $frontend_file->update(); } $cached_frontend_files[ $file_name ] = $frontend_file; return $frontend_file; } /** * Enqueue assets conditionally. * * Enqueue all assets that were pre-enabled. * * @since 3.3.0 * @access private */ private function enqueue_conditional_assets() { Plugin::$instance->assets_loader->enqueue_assets(); } /** * Elementor footer scripts and styles. * * Handle styles and scripts that are not printed in the header. * * Fired by `wp_footer` action. * * @since 1.0.11 * @access public */ public function wp_footer() { if ( ! $this->_has_elementor_in_page ) { return; } $this->enqueue_styles(); $this->enqueue_scripts(); $this->print_fonts_links(); } /** * @return array|array[] */ public function get_list_of_google_fonts_by_type(): array { $google_fonts = [ 'google' => [], 'early' => [], ]; foreach ( $this->fonts_to_enqueue as $key => $font ) { $font_type = Fonts::get_font_type( $font ); switch ( $font_type ) { case Fonts::GOOGLE: $google_fonts['google'][] = $font; break; case Fonts::EARLYACCESS: $google_fonts['early'][] = $font; break; case false: $this->maybe_enqueue_icon_font( $font ); break; default: /** * Print font links. * * Fires when Elementor frontend fonts are printed on the HEAD tag. * * The dynamic portion of the hook name, `$font_type`, refers to the font type. * * @since 2.0.0 * * @param string $font Font name. */ do_action( "elementor/fonts/print_font_links/{$font_type}", $font ); } } $this->fonts_to_enqueue = []; return $google_fonts; } /** * Print fonts links. * * Enqueue all the frontend fonts by url. * * Fired by `wp_head` action. * * @since 1.9.4 * @access public */ public function print_fonts_links() { $google_fonts = $this->get_list_of_google_fonts_by_type(); $this->enqueue_google_fonts( $google_fonts ); $this->enqueue_icon_fonts(); } private function maybe_enqueue_icon_font( $icon_font_type ) { if ( ! Icons_Manager::is_migration_allowed() ) { return; } $icons_types = Icons_Manager::get_icon_manager_tabs(); if ( ! isset( $icons_types[ $icon_font_type ] ) ) { return; } $icon_type = $icons_types[ $icon_font_type ]; if ( isset( $icon_type['url'] ) ) { $this->icon_fonts_to_enqueue[ $icon_font_type ] = [ $icon_type['url'] ]; } } private function enqueue_icon_fonts() { if ( empty( $this->icon_fonts_to_enqueue ) || ! Icons_Manager::is_migration_allowed() ) { return; } foreach ( $this->icon_fonts_to_enqueue as $icon_type => $css_url ) { wp_enqueue_style( 'elementor-icons-' . $icon_type ); $this->enqueued_icon_fonts[] = $css_url; } //clear enqueued icons $this->icon_fonts_to_enqueue = []; } /** * @param array $fonts Stable google fonts ($google_fonts['google']). * @return string */ public function get_stable_google_fonts_url( array $fonts ): string { foreach ( $fonts as &$font ) { $font = str_replace( ' ', '+', $font ) . ':100,100italic,200,200italic,300,300italic,400,400italic,500,500italic,600,600italic,700,700italic,800,800italic,900,900italic'; } // Defining a font-display type to google fonts. $font_display_url_str = '&display=' . Fonts::get_font_display_setting(); $fonts_url = sprintf( 'https://fonts.googleapis.com/css?family=%1$s%2$s', implode( rawurlencode( '|' ), $fonts ), $font_display_url_str ); $subsets = [ 'ru_RU' => 'cyrillic', 'bg_BG' => 'cyrillic', 'he_IL' => 'hebrew', 'el' => 'greek', 'vi' => 'vietnamese', 'uk' => 'cyrillic', 'cs_CZ' => 'latin-ext', 'ro_RO' => 'latin-ext', 'pl_PL' => 'latin-ext', 'hr_HR' => 'latin-ext', 'hu_HU' => 'latin-ext', 'sk_SK' => 'latin-ext', 'tr_TR' => 'latin-ext', 'lt_LT' => 'latin-ext', ]; /** * Google font subsets. * * Filters the list of Google font subsets from which locale will be enqueued in frontend. * * @since 1.0.0 * * @param array $subsets A list of font subsets. */ $subsets = apply_filters( 'elementor/frontend/google_font_subsets', $subsets ); $locale = get_locale(); if ( isset( $subsets[ $locale ] ) ) { $fonts_url .= '&subset=' . $subsets[ $locale ]; } return $fonts_url; } /** * @param array $fonts Early Access google fonts ($google_fonts['early']). * @return array */ public function get_early_access_google_font_urls( array $fonts ): array { $font_urls = []; foreach ( $fonts as $font ) { $font_urls[] = sprintf( 'https://fonts.googleapis.com/earlyaccess/%s.css', strtolower( str_replace( ' ', '', $font ) ) ); } return $font_urls; } /** * Print Google fonts. * * Enqueue all the frontend Google fonts. * * Fired by `wp_head` action. * * @since 1.0.0 * @access private * * @param array $google_fonts Optional. Google fonts to print in the frontend. * Default is an empty array. */ private function enqueue_google_fonts( $google_fonts = [] ) { $print_google_fonts = Fonts::is_google_fonts_enabled(); /** * Print frontend google fonts. * * Filters whether to enqueue Google fonts in the frontend. * * @since 1.0.0 * * @param bool $print_google_fonts Whether to enqueue Google fonts. Default is true. */ $print_google_fonts = apply_filters( 'elementor/frontend/print_google_fonts', $print_google_fonts ); if ( ! $print_google_fonts ) { return; } // Print used fonts if ( ! empty( $google_fonts['google'] ) ) { $this->google_fonts_index++; $fonts_url = $this->get_stable_google_fonts_url( $google_fonts['google'] ); wp_enqueue_style( 'google-fonts-' . $this->google_fonts_index, $fonts_url ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion } if ( ! empty( $google_fonts['early'] ) ) { $early_access_font_urls = $this->get_early_access_google_font_urls( $google_fonts['early'] ); foreach ( $early_access_font_urls as $ea_font_url ) { $this->google_fonts_index++; //printf( '', strtolower( str_replace( ' ', '', $current_font ) ) ); wp_enqueue_style( 'google-earlyaccess-' . $this->google_fonts_index, $ea_font_url ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion } } } /** * Enqueue fonts. * * Enqueue all the frontend fonts. * * @since 1.2.0 * @access public * * @param array $font Fonts to enqueue in the frontend. */ public function enqueue_font( $font ) { if ( in_array( $font, $this->registered_fonts ) ) { return; } $this->fonts_to_enqueue[] = $font; $this->registered_fonts[] = $font; } /** * Apply builder in content. * * Used to apply the Elementor page editor on the post content. * * @since 1.0.0 * @access public * * @param string $content The post content. * * @return string The post content. */ public function apply_builder_in_content( $content ) { $this->restore_content_filters(); if ( Plugin::$instance->preview->is_preview_mode() || $this->_is_excerpt ) { return $content; } // Remove the filter itself in order to allow other `the_content` in the elements $this->remove_content_filter(); $post_id = get_the_ID(); $builder_content = $this->get_builder_content( $post_id ); if ( ! empty( $builder_content ) ) { $content = $builder_content; $this->remove_content_filters(); } // Add the filter again for other `the_content` calls $this->add_content_filter(); return $content; } /** * Retrieve builder content. * * Used to render and return the post content with all the Elementor elements. * * Note that this method is an internal method, please use `get_builder_content_for_display()`. * * @since 1.0.0 * @access public * * @param int $post_id The post ID. * @param bool $with_css Optional. Whether to retrieve the content with CSS * or not. Default is false. * * @return string The post content. */ public function get_builder_content( $post_id, $with_css = false ) { if ( post_password_required( $post_id ) ) { return ''; } $document = Plugin::$instance->documents->get_doc_for_frontend( $post_id ); if ( ! $document || ! $document->is_built_with_elementor() ) { return ''; } // Change the current post, so widgets can use `documents->get_current`. Plugin::$instance->documents->switch_to_document( $document ); $data = $document->get_elements_data(); /** * Frontend builder content data. * * Filters the builder content in the frontend. * * @since 1.0.0 * * @param array $data The builder content. * @param int $post_id The post ID. */ $data = apply_filters( 'elementor/frontend/builder_content_data', $data, $post_id ); do_action( 'elementor/frontend/before_get_builder_content', $document, $this->_is_excerpt ); if ( empty( $data ) ) { Plugin::$instance->documents->restore_document(); return ''; } if ( ! $this->_is_excerpt ) { if ( $document->is_autosave() ) { $css_file = Post_Preview::create( $document->get_post()->ID ); } else { $css_file = Post_CSS::create( $post_id ); } /** * Builder Content - Before Enqueue CSS File * * Allows intervening with a document's CSS file before it is enqueued. * * @param $css_file Post_CSS|Post_Preview */ $css_file = apply_filters( 'elementor/frontend/builder_content/before_enqueue_css_file', $css_file ); $css_file->enqueue(); } ob_start(); // Handle JS and Customizer requests, with CSS inline. if ( is_customize_preview() || wp_doing_ajax() ) { $with_css = true; } /** * Builder Content - With CSS * * Allows overriding the `$with_css` parameter which is a factor in determining whether to print the document's * CSS and font links inline in a `style` tag above the document's markup. * * @param $with_css boolean */ $with_css = apply_filters( 'elementor/frontend/builder_content/before_print_css', $with_css ); if ( ! empty( $css_file ) && $with_css ) { $css_file->print_css(); } $document->print_elements_with_wrapper( $data ); $content = ob_get_clean(); $content = $this->process_more_tag( $content ); /** * Frontend content. * * Filters the content in the frontend. * * @since 1.0.0 * * @param string $content The content. */ $content = apply_filters( 'elementor/frontend/the_content', $content ); if ( ! empty( $content ) ) { $this->_has_elementor_in_page = true; } Plugin::$instance->documents->restore_document(); // BC // TODO: use Deprecation::do_deprecated_action() in 3.1.0 do_action( 'elementor/frontend/get_builder_content', $document, $this->_is_excerpt, $with_css ); return $content; } /** * Retrieve builder content for display. * * Used to render and return the post content with all the Elementor elements. * * @since 1.0.0 * @access public * * @param int $post_id The post ID. * * @param bool $with_css Optional. Whether to retrieve the content with CSS * or not. Default is false. * * @return string The post content. */ public function get_builder_content_for_display( $post_id, $with_css = false ) { if ( ! get_post( $post_id ) ) { return ''; } $editor = Plugin::$instance->editor; // Avoid recursion if ( get_the_ID() === (int) $post_id ) { $content = ''; if ( $editor->is_edit_mode() ) { $content = '