文件操作 - container.php
返回文件管理
返回主菜单
删除本文件
文件: /storage/v12552/stanleysteamer/public_html/wp-content/themes/bricks/includes/elements/container.php
编辑文件内容
<?php namespace Bricks; if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly class Element_Container extends Element { public $category = 'layout'; public $name = 'container'; public $icon = 'ti-layout-width-default'; public $vue_component = 'bricks-nestable'; public $nestable = true; public function get_label() { return esc_html__( 'Container', 'bricks' ); } public function get_keywords() { return [ 'query', 'loop', 'repeater', 'nestable' ]; } public function set_controls() { if ( bricks_is_builder() && ! Builder_Permissions::user_has_permission( 'access_element_content' ) ) { $this->controls['infoNoAccess'] = [ 'type' => 'info', 'content' => esc_html__( 'Your builder capability doesn\'t allow you to access these settings.', 'bricks' ), 'fullAccess' => false, ]; } /** * Grid item * * Show controls if parent uses display "grid" * * Check via control startsWith '_gridItem' * * @see PanelControl.vue 'settings' watcher * @since 1.6.1 */ $this->controls['_gridItemSeparator'] = [ 'type' => 'separator', 'label' => esc_html__( 'Grid item', 'bricks' ), ]; $this->controls['_gridItemColumnSpan'] = [ 'label' => esc_html__( 'Grid column', 'bricks' ), 'type' => 'text', 'inline' => true, 'hasDynamicData' => false, 'css' => [ [ 'property' => 'grid-column', ], ], ]; $this->controls['_gridItemRowSpan'] = [ 'label' => esc_html__( 'Grid row', 'bricks' ), 'type' => 'text', 'hasDynamicData' => false, 'inline' => true, 'css' => [ [ 'property' => 'grid-row', ], ], ]; $this->controls['_gridItemJustifySelf'] = [ 'label' => esc_html__( 'Justify self', 'bricks' ), 'type' => 'align-items', 'hasDynamicData' => false, 'css' => [ [ 'property' => 'justify-self', ], ], ]; $this->controls['_gridItemSeparatorAfter'] = [ 'type' => 'separator', ]; /** * Loop Builder * * Enable for elements: Container, Block, Div and Section (@since 1.8) */ if ( bricks_is_builder() && Builder_Permissions::user_has_permission( 'access_query_loop_builder' ) && in_array( $this->name, [ 'section', 'container', 'block', 'div' ] ) ) { $this->controls = array_replace_recursive( $this->controls, $this->get_loop_builder_controls() ); $this->controls['loopSeparator'] = [ 'type' => 'separator', ]; } $this->controls['link'] = [ 'label' => esc_html__( 'Link', 'bricks' ), 'type' => 'link', 'placeholder' => esc_html__( 'Select link type', 'bricks' ), 'required' => [ 'tag', '=', 'a' ], ]; $this->controls['linkInfo'] = [ 'type' => 'info', 'content' => esc_html__( 'Make sure there are no elements with links inside your linked container (nested links).', 'bricks' ), 'required' => [ [ 'tag', '=', 'a' ], [ 'link', '!=', '' ], ], ]; // Masonry active info (@since 1.11.1) $this->controls['_useMasonryInfo'] = [ 'type' => 'info', // translators: %s: Masonry layout is active. 'content' => sprintf( '%s (%s > %s). %s', sprintf( esc_html__( '%s layout is active' ), esc_html__( 'Masonry', 'bricks' ) ), esc_html__( 'Style', 'bricks' ), esc_html__( 'Layout', 'bricks' ), esc_html__( 'Ensure that no conflicting CSS styles are applied to this element and that a width is defined, especially when using a Div element.', 'bricks' ) ), 'required' => [ '_useMasonry', '=', true ], ]; $this->controls['tag'] = [ 'label' => esc_html__( 'HTML tag', 'bricks' ), 'type' => 'select', 'options' => [ 'div' => 'div', 'section' => 'section', 'a' => 'a [' . esc_html__( 'Link', 'bricks' ) . ']', 'article' => 'article', 'nav' => 'nav', 'ol' => 'ol', 'ul' => 'ul', 'li' => 'li', 'aside' => 'aside', 'address' => 'address', 'figure' => 'figure', 'custom' => esc_html__( 'Custom', 'bricks' ), ], 'lowercase' => true, 'inline' => true, 'placeholder' => $this->tag ? $this->tag : 'div', 'fullAccess' => true, ]; $this->controls['customTag'] = [ 'label' => esc_html__( 'Custom tag', 'bricks' ), 'info' => esc_html__( 'Without attributes', 'bricks' ), 'type' => 'text', 'inline' => true, 'hasDynamicData' => false, 'placeholder' => 'div', 'required' => [ 'tag', '=', 'custom' ], ]; // Display $this->controls['_display'] = [ 'label' => esc_html__( 'Display', 'bricks' ), 'type' => 'select', 'options' => [ 'flex' => 'flex', 'grid' => 'grid', 'block' => 'block', 'inline-block' => 'inline-block', 'inline' => 'inline', 'none' => 'none', ], 'add' => true, 'inline' => true, 'lowercase' => true, 'css' => [ [ 'property' => 'display', 'selector' => '', ], /** * Use 'required' property to add CSS rule if display is set to 'grid' * * @prev 1.7.2: Used .brx-grid class on nestable to set align-items to initial. * * @since 1.7.2 */ [ 'selector' => '', 'property' => 'align-items', 'value' => 'initial', 'required' => 'grid', ], ], ]; // Display: grid $this->controls['_gridGap'] = [ 'label' => esc_html__( 'Gap', 'bricks' ), 'type' => 'number', 'units' => true, 'css' => [ [ 'property' => 'grid-gap', // '{column-gap} {row-gap}' e.g. '20px 40px' 'selector' => '', ], ], 'placeholder' => '', 'required' => [ '_display', '=', 'grid' ], ]; $this->controls['_gridTemplateColumns'] = [ 'label' => esc_html__( 'Grid template columns', 'bricks' ), 'type' => 'text', 'hasDynamicData' => false, 'hasVariables' => true, 'css' => [ [ 'property' => 'grid-template-columns', 'selector' => '', ], ], 'placeholder' => '', 'required' => [ '_display', '=', 'grid' ], ]; $this->controls['_gridTemplateRows'] = [ 'label' => esc_html__( 'Grid template rows', 'bricks' ), 'type' => 'text', 'hasDynamicData' => false, 'hasVariables' => true, 'css' => [ [ 'property' => 'grid-template-rows', 'selector' => '', ], ], 'placeholder' => '', 'required' => [ '_display', '=', 'grid' ], ]; $this->controls['_gridAutoColumns'] = [ 'label' => esc_html__( 'Grid auto columns', 'bricks' ), 'type' => 'text', 'hasDynamicData' => false, 'hasVariables' => true, 'css' => [ [ 'property' => 'grid-auto-columns', 'selector' => '', ], ], 'required' => [ '_display', '=', 'grid' ], ]; $this->controls['_gridAutoRows'] = [ 'label' => esc_html__( 'Grid auto rows', 'bricks' ), 'type' => 'text', 'hasDynamicData' => false, 'hasVariables' => true, 'css' => [ [ 'property' => 'grid-auto-rows', 'selector' => '', ], ], 'required' => [ '_display', '=', 'grid' ], ]; $this->controls['_gridAutoFlow'] = [ 'label' => esc_html__( 'Grid auto flow', 'bricks' ), 'type' => 'select', 'options' => [ 'row' => 'row', 'column' => 'column', 'dense' => 'dense', ], 'css' => [ [ 'property' => 'grid-auto-flow', 'selector' => '', ], ], 'required' => [ '_display', '=', 'grid' ], ]; $this->controls['_justifyItemsGrid'] = [ 'label' => esc_html__( 'Justify items', 'bricks' ), 'type' => 'justify-content', 'direction' => 'row', 'css' => [ [ 'property' => 'justify-items', ], ], 'required' => [ '_display', '=', 'grid' ], ]; $this->controls['_alignItemsGrid'] = [ 'label' => esc_html__( 'Align items', 'bricks' ), 'type' => 'align-items', 'direction' => 'row', 'css' => [ [ 'property' => 'align-items', ], ], 'required' => [ '_display', '=', 'grid' ], ]; $this->controls['_justifyContentGrid'] = [ 'label' => esc_html__( 'Justify content', 'bricks' ), 'type' => 'justify-content', 'direction' => 'row', 'css' => [ [ 'property' => 'justify-content', ], ], 'required' => [ '_display', '=', 'grid' ], ]; $this->controls['_alignContentGrid'] = [ 'label' => esc_html__( 'Align content', 'bricks' ), 'type' => 'align-items', 'direction' => 'row', 'css' => [ [ 'property' => 'align-content', ], ], 'required' => [ '_display', '=', 'grid' ], ]; // Display: flex // Flex controls $this->controls['_flexWrap'] = [ 'label' => esc_html__( 'Flex wrap', 'bricks' ), 'type' => 'select', 'options' => [ 'nowrap' => esc_html__( 'No wrap', 'bricks' ), 'wrap' => esc_html__( 'Wrap', 'bricks' ), 'wrap-reverse' => esc_html__( 'Wrap reverse', 'bricks' ), ], 'inline' => true, 'css' => [ [ 'property' => 'flex-wrap', ], ], 'required' => [ '_display', '=', 'flex' ], ]; $this->controls['_direction'] = [ 'label' => esc_html__( 'Direction', 'bricks' ), 'type' => 'direction', 'css' => [ [ 'property' => 'flex-direction', ], ], 'inline' => true, 'rerender' => true, 'required' => [ '_display', '=', 'flex' ], ]; $this->controls['_alignSelf'] = [ 'label' => esc_html__( 'Align self', 'bricks' ), 'type' => 'align-items', 'css' => [ [ 'property' => 'align-self', 'important' => true, ], [ 'selector' => '', 'property' => 'width', 'value' => '100%', 'required' => 'stretch', // NOTE: Undocumented (@since 1.4) ], ], 'required' => [ '_display', '=', 'flex' ], ]; $this->controls['_justifyContent'] = [ 'label' => esc_html__( 'Align main axis', 'bricks' ), 'type' => 'justify-content', 'css' => [ [ 'property' => 'justify-content', ], ], 'required' => [ '_display', '=', 'flex' ], ]; $this->controls['_alignItems'] = [ 'label' => esc_html__( 'Align cross axis', 'bricks' ), 'type' => 'align-items', 'css' => [ [ 'property' => 'align-items', ], ], 'required' => [ '_display', '=', 'flex' ], ]; $this->controls['_columnGap'] = [ 'label' => esc_html__( 'Column gap', 'bricks' ), 'type' => 'number', 'units' => true, 'css' => [ [ 'property' => 'column-gap', ], ], 'required' => [ '_display', '=', 'flex' ], ]; $this->controls['_rowGap'] = [ 'label' => esc_html__( 'Row gap', 'bricks' ), 'type' => 'number', 'units' => true, 'css' => [ [ 'property' => 'row-gap', ], ], 'required' => [ '_display', '=', 'flex' ], ]; $this->controls['_flexGrow'] = [ 'label' => esc_html__( 'Flex grow', 'bricks' ), 'type' => 'number', 'min' => 0, 'css' => [ [ 'property' => 'flex-grow', ], ], 'placeholder' => 0, 'required' => [ '_display', '=', 'flex' ], ]; $this->controls['_flexShrink'] = [ 'label' => esc_html__( 'Flex shrink', 'bricks' ), 'type' => 'number', 'min' => 0, 'css' => [ [ 'property' => 'flex-shrink', ], ], 'placeholder' => 1, 'required' => [ '_display', '=', 'flex' ], ]; $this->controls['_flexBasis'] = [ 'label' => esc_html__( 'Flex basis', 'bricks' ), 'type' => 'text', 'css' => [ [ 'property' => 'flex-basis', ], ], 'inline' => true, 'placeholder' => 'auto', 'hasDynamicData' => false, 'hasVariables' => true, 'required' => [ '_display', '=', 'flex' ], ]; // Misc $this->controls['_order'] = [ 'label' => esc_html__( 'Order', 'bricks' ), 'type' => 'number', 'min' => -999, 'css' => [ [ 'property' => 'order', ], ], 'placeholder' => 0, 'required' => [ '_display', '!=', 'none' ], ]; // TAB: STYLE // Inner container (direct children) $this->controls['_innerContainerSeparator'] = [ 'type' => 'separator', 'label' => esc_html__( 'Inner container', 'bricks' ) . ' / div', 'tab' => 'style', 'group' => '_layout', 'deprecated' => true, // @since 1.10 ]; $this->controls['_innerContainerMargin'] = [ 'tab' => 'style', 'group' => '_layout', 'info' => esc_html__( 'Inner container', 'bricks' ) . ' / div', 'label' => esc_html__( 'Margin', 'bricks' ), 'type' => 'spacing', 'css' => [ [ 'property' => 'margin', 'selector' => '> .brxe-container', ], [ 'property' => 'margin', 'selector' => '> .brxe-block', ], [ 'property' => 'margin', 'selector' => '> .brxe-div', ], ], 'deprecated' => true, // @since 1.10 ]; $this->controls['_innerContainerPadding'] = [ 'tab' => 'style', 'group' => '_layout', 'info' => esc_html__( 'Inner container', 'bricks' ) . ' / div', 'label' => esc_html__( 'Padding', 'bricks' ), 'type' => 'spacing', 'css' => [ [ 'property' => 'padding', 'selector' => '> .brxe-container', ], [ 'property' => 'padding', 'selector' => '> .brxe-block', ], [ 'property' => 'padding', 'selector' => '> .brxe-div', ], ], 'deprecated' => true, // @since 1.10 ]; } /** * Return shape divider HTML */ public static function get_shape_divider_html( $settings = [] ) { $shape_dividers = ! empty( $settings['_shapeDividers'] ) && is_array( $settings['_shapeDividers'] ) ? $settings['_shapeDividers'] : []; $output = ''; foreach ( $shape_dividers as $shape ) { $shape_name = ! empty( $shape['shape'] ) ? $shape['shape'] : false; // Skip: No shape set if ( ! $shape_name ) { continue; } $svg = ''; // Custom shape from attachment ID (@since 1.8.6) if ( $shape_name === 'custom' ) { $svg_path = ! empty( $shape['shapeCustom']['id'] ) ? get_attached_file( $shape['shapeCustom']['id'] ) : false; $svg = $svg_path ? Helpers::file_get_contents( $svg_path ) : false; } // Shape from file else { $svg = Helpers::file_get_contents( BRICKS_PATH_ASSETS . "svg/shapes/{$shape_name}.svg" ); } // Skip: SVG file doesn't exist if ( ! $svg ) { continue; } $shape_classes = [ 'bricks-shape-divider' ]; $shape_styles = []; // Shape classes if ( isset( $shape['front'] ) ) { $shape_classes[] = 'front'; } if ( isset( $shape['flipHorizontal'] ) ) { $shape_classes[] = 'flip-horizontal'; } if ( isset( $shape['flipVertical'] ) ) { $shape_classes[] = 'flip-vertical'; } if ( isset( $shape['overflow'] ) ) { $shape_classes[] = 'overflow'; } // Shape styles if ( isset( $shape['horizontalAlign'] ) ) { $shape_styles[] = "justify-content: {$shape['horizontalAlign']}"; } if ( isset( $shape['verticalAlign'] ) ) { $shape_styles[] = "align-items: {$shape['verticalAlign']}"; } // Shape inner styles $shape_inner_styles = []; $shape_css_properties = [ 'height', 'width', 'top', 'right', 'bottom', 'left', ]; foreach ( $shape_css_properties as $property ) { $value = isset( $shape[ $property ] ) ? $shape[ $property ] : null; if ( $value !== null ) { // Append default unit if ( is_numeric( $value ) ) { $value .= 'px'; } $shape_inner_styles[] = "{$property}: {$value}"; } } if ( isset( $shape['rotate'] ) ) { $rotate = intval( $shape['rotate'] ); $shape_inner_styles[] = "transform: rotate({$rotate}deg)"; } $output .= '<div class="' . join( ' ', $shape_classes ) . '" style="' . join( '; ', $shape_styles ) . '">'; $output .= '<div class="bricks-shape-divider-inner" style="' . join( '; ', $shape_inner_styles ) . '">'; $dom = new \DOMDocument(); libxml_use_internal_errors( true ); $dom->loadXML( $svg ); libxml_clear_errors(); // SVG styles $svg_styles = []; if ( isset( $shape['fill']['raw'] ) ) { $svg_styles[] = "fill: {$shape['fill']['raw']}"; } elseif ( isset( $shape['fill']['rgb'] ) ) { $svg_styles[] = "fill: {$shape['fill']['rgb']}"; } elseif ( isset( $shape['fill']['hex'] ) ) { $svg_styles[] = "fill: {$shape['fill']['hex']}"; } foreach ( $dom->getElementsByTagName( 'svg' ) as $element ) { $element->setAttribute( 'style', join( '; ', $svg_styles ) ); } $svg = $dom->saveXML(); $output .= str_replace( '<?xml version="1.0"?>', '', $svg ); $output .= '</div>'; $output .= '</div>'; } return $output; } /** * Parses video URL or ID * * Input: Video ID: Return ID as is * Input: Video URL: Return escaped URL * * @since 1.12.2 */ private function parse_video_url_or_id( $input ) { // Remove whitespace $input = trim( $input ); // Return video URL if ( filter_var( $input, FILTER_VALIDATE_URL ) ) { return esc_url( $input ); } // Return video ID return esc_attr( $input ); } /** * Return background video HTML */ public function get_background_video_html( $settings ) { // Loop over all breakpoints foreach ( Breakpoints::$breakpoints as $breakpoint ) { $setting_key = $breakpoint['key'] === 'desktop' ? '_background' : "_background:{$breakpoint['key']}"; $background = ! empty( $settings[ $setting_key ] ) ? $settings[ $setting_key ] : false; $video_url = ! empty( $background['videoUrl'] ) ? $background['videoUrl'] : false; $video_attributes = []; if ( strpos( $video_url, '{' ) !== false ) { $video_url = bricks_render_dynamic_data( $video_url, $this->post_id, 'link' ); } if ( $video_url ) { $video_url = $this->parse_video_url_or_id( $video_url ); $attributes[] = 'class="bricks-background-video-wrapper bricks-lazy-video"'; $attributes[] = 'data-background-video-url="' . $video_url . '"'; if ( ! empty( $background['videoScale'] ) ) { $attributes[] = 'data-background-video-scale="' . $background['videoScale'] . '"'; } if ( ! empty( $background['videoAspectRatio'] ) ) { $attributes[] = 'data-background-video-ratio="' . $background['videoAspectRatio'] . '"'; } if ( ! empty( $background['videoStartTime'] ) ) { $attributes[] = 'data-background-video-start="' . $background['videoStartTime'] . '"'; } if ( ! empty( $background['videoEndTime'] ) ) { $attributes[] = 'data-background-video-end="' . $background['videoEndTime'] . '"'; } if ( empty( $background['videoPlayOnce'] ) ) { $attributes[] = 'data-background-video-loop="1"'; } if ( ! empty( $background['videoShowAtBreakpoint'] ) ) { $breakpoint = Breakpoints::get_breakpoint_by( 'key', $background['videoShowAtBreakpoint'] ); $width = isset( $breakpoint['width'] ) ? $breakpoint['width'] : null; // Is base breakpoint if ( isset( $breakpoint['base'] ) ) { $breakpoints = Breakpoints::$breakpoints; foreach ( $breakpoints as $index => $bp ) { // Is first breakpoint if ( $bp['key'] === $breakpoint['key'] && $index === 0 ) { // Get 'width' of next breakpoint $next_breakpoint = isset( $breakpoints[ $index + 1 ] ) ? $breakpoints[ $index + 1 ] : null; if ( $next_breakpoint ) { $width = Breakpoints::$is_mobile_first ? 0 : $next_breakpoint['width'] + 1; } } } } if ( $width ) { $attributes[] = 'data-background-video-show-at-breakpoint="' . $width . '"'; } } // Video poster (@since 1.11) if ( ! empty( $background['videoPoster'] ) ) { $poster_url = $this->extract_background_video_poster_url( $background['videoPoster'] ); $video_attributes[] = 'poster="' . $poster_url . '"'; $attributes[] = 'data-background-video-poster="' . $poster_url . '"'; } // YouTube video poster (@since 1.11) if ( ! empty( $background['videoPosterYouTube'] ) ) { $youtube_poster_size = $background['videoPosterYouTubeSize'] ?? 'maxresdefault'; $attributes[] = 'data-background-video-poster-yt-size="' . $youtube_poster_size . '"'; } $attributes = join( ' ', $attributes ); $video_attributes = join( ' ', $video_attributes ); // @since 1.4: Chrome doesn't play the .mp4 background video if the <video> tag is injected programmatically using JavaScript return "<div $attributes><video autoplay loop playsinline muted $video_attributes></video></div>"; } } } public function render() { $element = $this->element; $settings = $this->settings ?? []; $output = ''; // Bricks Query Loop if ( isset( $settings['hasLoop'] ) ) { // Hold the component to first unset 'hasLoop' and then add back 'hasLoop' after the query->render (@since 1.12) $original_component = Helpers::get_component( $element ); // Hold the global element to first unset 'hasLoop' and then add back 'hasLoop' after the query->render $global_element = Helpers::get_global_element( $element ); // STEP: Query add_filter( 'bricks/posts/query_vars', [ $this, 'maybe_set_preview_query' ], 10, 3 ); /** * Is component: Generate random ID for component instance (@since 1.12) * * Component instances inserted as direct slot payloads are already unique local * elements. Keep their local ID so their own slots can find the right slotChildren. * (#86c82k2b3; @since 2.3.8) */ $is_direct_slot_component = ! empty( $element['slotInstanceId'] ); if ( ! empty( $element['instanceId'] ) && ! empty( $element['parentComponent'] ) && ! $is_direct_slot_component ) { $element['id'] .= '-' . $element['instanceId']; // Use dash instead of colon (@since 1.12.2) } $query = new \Bricks\Query( $element ); remove_filter( 'bricks/posts/query_vars', [ $this, 'maybe_set_preview_query' ], 10, 3 ); // Prevent endless loop (@since 2.0; #86c3qwrm6) $element['looped'] = true; // Prevent condition execution when looping (@since 1.12.2) unset( $element['settings']['_conditions'] ); // Maybe add li node for children elements (@since 2.0) add_filter( 'bricks/frontend/render_element', [ $this, 'maybe_wrap_nav_link' ], 0, 2 ); // STEP: Render loop $output = $query->render( 'Bricks\Frontend::render_element', compact( 'element' ) ); // Maybe add li node for children elements (@since 2.0) remove_filter( 'bricks/frontend/render_element', [ $this, 'maybe_wrap_nav_link' ], 0, 2 ); // NOTE: Undocumented: For builder to collect first query loop node if query located inside component (@since 2.0) $output = apply_filters( 'bricks/frontend/render_loop', $output, $element, $this ); echo $output; // STEP: Infinite scroll $this->render_query_loop_trail( $query ); // Destroy Query to explicitly remove it from global store $query->destroy(); unset( $query ); return; } // Render the video wrapper first so we know it before adding the has-bg-video class $video_wrapper_html = $this->get_background_video_html( $settings ); // No background video set on element ID: Loop over element global classes if ( ! $video_wrapper_html ) { /** * Ensure global classes IDs are an array * * If "Multiple options" is not enabled, the selected class is stored as a string. * * @since 2.0 */ if ( ! empty( $settings['_cssGlobalClasses'] ) ) { $elements_class_ids = $settings['_cssGlobalClasses']; if ( is_string( $elements_class_ids ) ) { $elements_class_ids = explode( ' ', $elements_class_ids ); } if ( is_array( $elements_class_ids ) && count( $elements_class_ids ) ) { $global_classes = Database::$global_data['globalClasses']; foreach ( $global_classes as $global_class ) { $global_class_id = ! empty( $global_class['id'] ) ? $global_class['id'] : ''; if ( ! $video_wrapper_html && in_array( $global_class_id, $elements_class_ids ) ) { if ( ! empty( $global_class['settings'] ) ) { $video_wrapper_html = $this->get_background_video_html( $global_class['settings'] ); } } } } } } // Add .has-bg-video to set z-index: 1 (#2g9ge90) if ( ! empty( $video_wrapper_html ) ) { $this->set_attribute( '_root', 'class', 'has-bg-video' ); } // Add .has-shape to set position: relative (#2t7w2bq) if ( ! empty( $settings['_shapeDividers'] ) ) { $this->set_attribute( '_root', 'class', 'has-shape' ); } // Non-megamenu dropdown content: Set tag to 'ul' $parent_id = ! empty( $element['parent'] ) ? $element['parent'] : false; $parent_element = ! empty( Frontend::$elements[ $parent_id ] ) ? Frontend::$elements[ $parent_id ] : false; if ( $parent_element && $parent_element['name'] === 'dropdown' && ! isset( $parent_element['settings']['megaMenu'] ) ) { $this->tag = 'ul'; } /** * Live search wrapper * * Add 'data-brx-ls-wrapper' to hide live search wrapper on page load. * * @since 1.9.6 */ if ( count( Frontend::$live_search_wrapper_selectors ) ) { foreach ( Frontend::$live_search_wrapper_selectors as $live_search_query_id => $live_search_wrapper_selector ) { /** * 1. Last six-characters of live search results selector match element.id * 2. Live search results selector matches custom element ID */ $match_default_id = "#brxe-{$element['id']}" === $live_search_wrapper_selector; $match_custom_id = ! empty( $element['settings']['_cssId'] ) && "#{$element['settings']['_cssId']}" === $live_search_wrapper_selector; if ( $match_default_id || $match_custom_id ) { unset( Frontend::$live_search_wrapper_selectors[ $live_search_query_id ] ); $this->set_attribute( '_root', 'data-brx-ls-wrapper', $live_search_query_id ); // Ensure setting element 'id' to target the live search wrapper with CSS. Could be omittied, if the elment doesn't has_css_settings. if ( empty( $this->attributes['_root']['id'] ) ) { $this->set_attribute( '_root', 'id', $this->get_element_attribute_id() ); } } } } // Default: Non-query loop $output .= "<{$this->tag} {$this->render_attributes( '_root' )}>"; $output .= self::get_shape_divider_html( $settings ); $output .= $video_wrapper_html; // Maybe add li node for children elements (@since 2.0) add_filter( 'bricks/frontend/render_element', [ $this, 'maybe_wrap_nav_link' ], 0, 2 ); if ( ! empty( $element['children'] ) && is_array( $element['children'] ) ) { foreach ( $element['children'] as $child_id ) { $child_element = Frontend::$elements[ $child_id ] ?? false; /** * Skip element: Component with this 'cid' doesn't exist in database * * @since 1.12 */ if ( ! empty( $child_element['cid'] ) && ! Helpers::get_component_by_cid( $child_element['cid'] ) ) { continue; } // Render element children $child_html = $child_element ? Frontend::render_element( $child_element ) : false; // Recursive $output .= $child_html; } } // Maybe add li node for children elements (@since 2.0) remove_filter( 'bricks/frontend/render_element', [ $this, 'maybe_wrap_nav_link' ], 0, 2 ); /** * STEP: Add masonry trail nodes * * Suppose add these nodes inside base.php but no perfect hook yet. * Any custom element has to run this method manually in the render method. * * @since 1.11.1 */ $output .= $this->maybe_masonry_trail_nodes(); $output .= "</{$this->tag}>"; echo $output; } /** * Modify html for element instance * - Wrap nav link in <li> if inside nav items or dropdown content * - Priority: 0 to run before other filters that might modify the HTML before this function * * @since 2.0 */ public function maybe_wrap_nav_link( $html, $element_instance ) { if ( empty( $html ) ) { return $html; } // Nav items is parent element: Wrap this nav link in <li> (@since 1.8) $element = $element_instance->element ?? false; $parent_id = $element['parent'] ?? false; if ( ! $parent_id ) { return $html; } $parent_element = ! empty( Frontend::$elements[ $parent_id ] ) ? Frontend::$elements[ $parent_id ] : false; $inside_nav_items = ! empty( $parent_element['settings']['_hidden']['_cssClasses'] ) ? $parent_element['settings']['_hidden']['_cssClasses'] === 'brx-nav-nested-items' : false; $inside_dropdown_content = ! empty( $parent_element['settings']['_hidden']['_cssClasses'] ) ? $parent_element['settings']['_hidden']['_cssClasses'] === 'brx-dropdown-content' : false; // Wrap in <li> if child HTML does not start with an 'li' tag (e.g. non-megamenu dropdown) if ( ( $inside_nav_items || $inside_dropdown_content ) && ( strpos( $html, '<li' ) === false || strpos( $html, '<li' ) !== 0 ) ) { $dropdown_id = $parent_element['parent'] ?? false; $dropdown_element = isset( Frontend::$elements[ $dropdown_id ] ) && ! empty( Frontend::$elements[ $dropdown_id ] ) ? Frontend::$elements[ $dropdown_id ] : false; // Megamenu: Don't wrap dropdown item in <li> if ( isset( $dropdown_element['settings']['megaMenu'] ) ) { return $html; } // Wrap menu item in <li> else { $html = '<li class="menu-item">' . $html . '</li>'; } } return $html; } /** * Extract Video poster from background settings * * @param array $background Background video poster settings * @return string Video poster URL * @since 2.2 */ public function extract_background_video_poster_url( $video_poster ) { // If it contains 'url' key, return as is if ( isset( $video_poster['url'] ) ) { return $video_poster['url']; } $video_poster['size'] = ! empty( $video_poster['size'] ) ? $video_poster['size'] : BRICKS_DEFAULT_IMAGE_SIZE; // If it's "useDynamicData", then render dynamic tag if ( ! empty( $video_poster['useDynamicData'] ) ) { $dynamic_image = $this->render_dynamic_data_tag( $video_poster['useDynamicData'], 'image', [ 'size' => $video_poster['size'] ] ); if ( ! empty( $dynamic_image[0] ) ) { if ( is_numeric( $dynamic_image[0] ) ) { // Use the image ID to populate and set $dynamic_image['url'] return wp_get_attachment_image_url( $dynamic_image[0], $video_poster['size'] ); } else { return $dynamic_image[0]; } } else { return ''; } } return ''; } }
修改文件时间
将文件时间修改为当前时间的前一年
删除文件