From: Stephen Cameron Date: Mon, 30 Sep 2019 16:38:26 +0000 (+0200) Subject: WIP #3053 @7.5 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=47188f0f8ac80ba34f2601498bead938c64be4c7;p=ccv-wordpress.git WIP #3053 @7.5 --- diff --git a/wp-content/mu-plugins/cube-loader.php b/wp-content/mu-plugins/cube-loader.php new file mode 100644 index 0000000..ede46dd --- /dev/null +++ b/wp-content/mu-plugins/cube-loader.php @@ -0,0 +1,30 @@ +register_customisations(); + + // Register widgets with Elementor + add_action('elementor/widgets/widgets_registered', [$this, 'register_widgets']); + } + + + public function register_customisations() { + + $this->_customise_sections(); + $this->_customise_image_widget(); + + } + + + public function register_widgets() { + + $elementor = Plugin::$instance; + + $elementor->widgets_manager->register_widget_type( new Widgets\BackgroundImage() ); + $elementor->widgets_manager->register_widget_type( new Widgets\TextBlock() ); + } + + protected function _customise_sections() { + + // Override the main Elementor section element to allow custom controls to be added to the editor + // This allows us to set specific CSS classes on the section wrapper, thereby centralising control + // of necessary settings for each section layout (column width, padding etc) + // + // References: + // https://www.ibenic.com/extending-elementor-custom-button-field-skin/ + // https://blogs.devforum.ro/customizing-elementor-default-widgets/ + // https://github.com/pojome/elementor/issues/3495 + + // Add controls to section element in editor + add_action( 'elementor/element/section/section_layout/after_section_start', function( $element, $args ) { + /** @var \Elementor\Element_Base $element */ + $element->add_control( + 'block_layout', + [ + 'label' => __('Custom Layout', 'cube'), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'layout-default' => __( 'Default', 'cube' ), + 'layout-overlap-above' => __( 'Overlap Above', 'cube' ), + 'layout-overlap-below' => __( 'Overlap Below', 'cube' ), + ], + 'default' => 'layout-default', + 'prefix_class' => '', // Use the full value as the classname (too late to change values after many pages have been built) + ] + ); + + $element->add_control( + 'layout_reversed', + [ + 'label' => __('Reverse layout?', 'cube'), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'return_value' => 'layout-reversed', + 'prefix_class' => '', + ] + ); + + $element->add_control( + 'padding_top', + [ + 'label' => __('Disable padding top', 'cube'), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'return_value' => 'pt0', + 'prefix_class' => '', + ] + ); + + $element->add_control( + 'padding_bottom', + [ + 'label' => __('Disable padding bottom', 'cube'), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'return_value' => 'pb0', + 'prefix_class' => '', + ] + ); + + $element->add_control( + 'stacking_margins', + [ + 'label' => __('Disable margins when stacking columns?', 'cube'), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'return_value' => 'no-column-stacking-gap', + 'prefix_class' => '', + ] + ); + + }, 10, 2 ); + + + //--- Section shape divider + // Add a CSS class based on the shape divider type so we can style accordingly + // (extra padding needed when a divider is present) + add_action( 'elementor/element/section/section_shape_divider/before_section_end', function( $element, $args ) { + $elementor = Plugin::instance(); + + // Get the shape divider controls for updating + $divider_top = $elementor->controls_manager->get_control_from_stack( $element->get_name(), 'shape_divider_top' ); + $divider_bottom = $elementor->controls_manager->get_control_from_stack( $element->get_name(), 'shape_divider_bottom' ); + + if (is_wp_error($divider_top) || is_wp_error($divider_top)) { + return; + } + + // Add a prefix class so section will have a class that matches the divider type(s) + $divider_top['prefix_class'] = 'divider-top-'; + $divider_top['render_type'] = 'template'; // Needed so class will be applied immediately in the editor + $element->update_control( 'shape_divider_top', $divider_top ); + $divider_bottom['prefix_class'] = 'divider-bottom-'; + $divider_bottom['render_type'] = 'template'; // Needed so class will be applied immediately in the editor + $element->update_control( 'shape_divider_bottom', $divider_bottom ); + }, 10, 2); + + } + + protected function _customise_image_widget() { + + // Add controls to image widget in editor + add_action( 'elementor/element/image/section_image/before_section_end', function( $element, $args ) { + + /** @var \Elementor\Element_Base $element */ + $element->add_control( + 'link_icon', + [ + 'label' => __( 'Link Icon', 'cube' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => __( 'None', 'cube' ), + 'tour-360' => __( '360 Tour', 'cube' ), + 'enlarge' => __( 'Enlarge', 'cube' ), + ], + 'default' => '', + 'prefix_class' => 'icon-', + 'condition' => [ + 'link_to!' => 'none', + ], + ] + ); + }, 10, 2); + + } + +} diff --git a/wp-content/mu-plugins/cube/src/Elementor/Widgets/BackgroundImage.php b/wp-content/mu-plugins/cube/src/Elementor/Widgets/BackgroundImage.php new file mode 100644 index 0000000..34780f9 --- /dev/null +++ b/wp-content/mu-plugins/cube/src/Elementor/Widgets/BackgroundImage.php @@ -0,0 +1,109 @@ +start_controls_section( + 'section_image', + [ + 'label' => __( 'Flexible Background Image', 'cube' ), + ] + ); + + $this->add_control( + 'image', + [ + 'label' => __( 'Choose Image', 'elementor' ), + 'type' => Controls_Manager::MEDIA, + 'default' => [ + 'url' => Utils::get_placeholder_image_src(), + ], + ] + ); + + $this->add_control( + 'background_position', + [ + 'label' => __( 'Background Position', 'cube' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'center', + 'options' => [ + 'top left' => __( 'Top Left', 'cube' ), + 'top center' => __( 'Top Center', 'cube' ), + 'top right' => __( 'Top Right', 'cube' ), + 'center' => __( 'Center', 'cube' ), + 'bottom left' => __( 'Bottom Left', 'cube' ), + 'bottom center' => __( 'Bottom Center', 'cube' ), + 'bottom right' => __( 'Bottom Right', 'cube' ), + ], + ] + ); + + $this->end_controls_section(); + } + /** + * Render the widget output on the frontend. + * Written in PHP and used to generate the final HTML. + * + * @since 1.0.0 + * @access protected + */ + protected function render() { + + $image = $this->get_settings('image'); + $bg_position = $this->get_settings('background_position'); + $meta = wp_get_attachment_metadata($image['id']); + $ratio = $meta['height'] / $meta['width'] * 100 .'%'; + + echo '
'; + + } +} diff --git a/wp-content/mu-plugins/cube/src/Elementor/Widgets/TextBlock.php b/wp-content/mu-plugins/cube/src/Elementor/Widgets/TextBlock.php new file mode 100644 index 0000000..d551029 --- /dev/null +++ b/wp-content/mu-plugins/cube/src/Elementor/Widgets/TextBlock.php @@ -0,0 +1,323 @@ +start_controls_section( + 'section_content', + [ + 'label' => __( 'Content', 'cube' ), + ] + ); + + $this->add_control( + 'title', + [ + 'label' => __( 'Title', 'elementor' ), + 'type' => Controls_Manager::TEXTAREA, + 'placeholder' => __( 'Enter your title', 'elementor' ), + 'default' => '', + ] + ); + + $this->add_control( + 'body', + [ + 'label' => __('Body', 'cube'), + 'type' => Controls_Manager::WYSIWYG, + 'default' => '', + ] + ); + + $this->add_control( + 'cta_text', + [ + 'label' => __('Call to Action text', 'cube'), + 'type' => Controls_Manager::TEXT, + 'default' => '' + ] + ); + + $this->add_control( + 'cta_link', + [ + 'label' => __('Call to Action link', 'cube'), + 'type' => Controls_Manager::URL, + 'default' => [ + 'url' => '', + 'is_external' => false, + ], + 'show_external' => true + ] + ); + + $this->end_controls_section(); + + + $this->start_controls_section( + 'section_formatting', + [ + 'label' => __( 'Colours & Formatting', 'cube' ), + ] + ); + + $this->add_control( + 'padding_top', + [ + 'label' => __('Disable padding top', 'cube'), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'return_value' => 'pt-0', + 'prefix_class' => '', + ] + ); + + $this->add_control( + 'padding_bottom', + [ + 'label' => __('Disable padding bottom', 'cube'), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'return_value' => 'pb-0', + 'prefix_class' => '', + ] + ); + + $this->add_control( + 'title_size', + [ + 'label' => __( 'Title Size', 'cube' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => __( 'Default', 'cube' ), + 'medium' => __( 'Medium', 'cube' ), + ], + 'default' => '', + ] + ); + + $this->add_control( + 'title_color', + [ + 'label' => __( 'Title Colour', 'cube' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .text-block-title' => 'color: {{VALUE}};', + ], + ] + ); + + + $this->add_control( + 'body_color', + [ + 'label' => __( 'Body Colour', 'cube' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .text-block-body' => 'color: {{VALUE}};', + ], + ] + ); + + + $this->add_responsive_control( + 'align', + [ + 'label' => __( 'Alignment', 'elementor' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => __( 'Left', 'elementor' ), + 'icon' => 'fa fa-align-left', + ], + 'center' => [ + 'title' => __( 'Center', 'elementor' ), + 'icon' => 'fa fa-align-center', + ], + 'right' => [ + 'title' => __( 'Right', 'elementor' ), + 'icon' => 'fa fa-align-right', + ], + 'justify' => [ + 'title' => __( 'Justified', 'elementor' ), + 'icon' => 'fa fa-align-justify', + ], + ], + 'default' => '', + 'selectors' => [ + '{{WRAPPER}}' => 'text-align: {{VALUE}}; margin: 0 auto;', + ], + ] + ); + + $this->add_control( + 'max_width', + [ + 'label' => __( 'Maximum Width', 'cube' ), + 'type' => Controls_Manager::SLIDER, + // 'default' => [ + // 'size' => 400, + // ], + 'range' => [ + 'px' => [ + 'min' => 400, + 'max' => 1600, + 'step' => 10, + ], + '%' => [ + 'min' => 0, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .text-block' => 'max-width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + } + /** + * Render the widget output on the frontend. + * Written in PHP and used to generate the final HTML. + * + * @since 1.0.0 + * @access protected + */ + protected function render() { + + $title = $this->get_settings('title'); + $title_size = $this->get_settings('title_size'); + $body = $this->parse_text_editor($this->get_settings('body')); + $cta_text = $this->get_settings('cta_text'); + $cta_link = $this->get_settings('cta_link'); + + if ( ! empty( $cta_link['url'] ) ) { + $this->add_render_attribute( 'cta_text', 'href', $cta_link['url'] ); + + if ( $cta_link['is_external'] ) { + $this->add_render_attribute( 'cta_text', 'target', '_blank' ); + } + + if ( $cta_link['nofollow'] ) { + $this->add_render_attribute( 'cta_text', 'rel', 'nofollow' ); + } + } + + // Inline Editing settings + $this->add_inline_editing_attributes('title', 'none'); + $this->add_inline_editing_attributes('body', 'advanced'); + $this->add_inline_editing_attributes('cta_text', 'none'); + + // CSS Classes for elements + $this->add_render_attribute('title', 'class', ['text-block-title h2 decorated']); + $this->add_render_attribute('body', 'class', ['text-block-body']); + $this->add_render_attribute('cta_text', 'class', ['text-block-cta arrow-link']); + + if (!empty($title_size)) { + $this->add_render_attribute('title', 'class', ["text-block-title-size-{$title_size}"]); + } + + // Rendered content + echo '
'; + if (!empty($title)) echo "

get_render_attribute_string('title')}>$title

"; + if (!empty($body)) echo "
get_render_attribute_string('body')}>$body
"; + if (!empty($cta_text)) { + echo 'get_render_attribute_string('cta_text') .'>'; + echo $cta_text; + echo ''; + } + echo '
'; + } + + /** + * Render text editor widget output in the editor. + * + * Written as a Backbone JavaScript template and used to generate the live preview. + * + * @since 1.0.0 + * @access protected + */ + protected function _content_template() { + ?> + <# + view.addRenderAttribute( 'title', 'class', ['text-block-title h2 decorated']); + view.addRenderAttribute( 'body', 'class', ['text-block-body']); + view.addRenderAttribute( 'cta_text', 'class', ['text-block-cta arrow-link']); + + if ('' !== settings.title_size) { + view.addRenderAttribute('title', 'class', ['text-block-title-size-' + settings.title_size]); + } + + view.addInlineEditingAttributes( 'title', 'none' ); + view.addInlineEditingAttributes( 'body', 'advanced' ); + view.addInlineEditingAttributes( 'cta_text', 'none' ); + #> +
+ + <# if ('' !== settings.title) { #> +

{{{ settings.title }}}

+ <# } #> + + <# if ('' !== settings.body) { #> +
{{{ settings.body }}}
+ <# } #> + + <# if ('' !== settings.cta_text) { #> + + {{{ settings.cta_text }}} + + <# } #> + +
+ register(); + } + } + } + + /** + * @param class $class Class from the services array + * @return class instance New instance of the class + */ + private static function instantiate($class) { + return new $class(); + } +} diff --git a/wp-content/themes/CCV/app/setup.php b/wp-content/themes/CCV/app/setup.php index 9785ff0..7e15ea6 100755 --- a/wp-content/themes/CCV/app/setup.php +++ b/wp-content/themes/CCV/app/setup.php @@ -88,7 +88,7 @@ add_action('widgets_init', function () { $config = [ 'before_widget' => '
', 'after_widget' => '
', - 'before_title' => '

', + 'before_title' => '

', 'after_title' => '

' ]; diff --git a/wp-content/themes/CCV/resources/assets/styles/app.styl b/wp-content/themes/CCV/resources/assets/styles/app.styl index d3bcac7..8dc5522 100644 --- a/wp-content/themes/CCV/resources/assets/styles/app.styl +++ b/wp-content/themes/CCV/resources/assets/styles/app.styl @@ -12,6 +12,7 @@ // Extracted components or custom styles that can't be done with utilities @import 'components/*' +@import 'widgets/*' //@import 'pages/*' // Utilities go last in source order so they can diff --git a/wp-content/themes/CCV/resources/assets/styles/components/buttons.styl b/wp-content/themes/CCV/resources/assets/styles/components/buttons.styl new file mode 100644 index 0000000..8527e28 --- /dev/null +++ b/wp-content/themes/CCV/resources/assets/styles/components/buttons.styl @@ -0,0 +1,52 @@ +// Buttons + +.btn + @apply relative inline-block overflow-hidden + @apply bg-pink text-white + @apply font-bold text-xs uppercase + @apply px-10 py-3 + font-smoothing() + + &-text + @apply z-10 relative + + &-no-hover:before + display: none + + &:hover:before + transform: scaleX(1) + opacity: 1 + + //&:before + // content: '' + // position: absolute + // top: 0 + // left: 0 + // width: 100% + // height: 100% + // z-index: 1 + // background-color: rgba(#fff, 0.2) + // transform: scaleX(0) + // transform-origin: left + // transition: transform 0.2s ease-out + + // Circle hover effect + &:hover:before + transform: scale(1.1) translateY(-50%) + opacity: 1 + + &:before + content: '' + position: absolute + top: 50% + left: 0 + z-index: 1 + background-color: rgba(#fff, 0.15) + width: 100% + padding-bottom: 100% + border-radius: 50% + transform: scale(0) translateY(-50%) + transform-origin: top center + transition: all 0.2s ease-out + opacity: 0 + diff --git a/wp-content/themes/CCV/resources/assets/styles/components/headings.styl b/wp-content/themes/CCV/resources/assets/styles/components/headings.styl new file mode 100644 index 0000000..1e0272f --- /dev/null +++ b/wp-content/themes/CCV/resources/assets/styles/components/headings.styl @@ -0,0 +1,34 @@ +h1, .h1, h2, .h2 + @apply font-display font-medium mb-2 uppercase + line-height: 1.1 + +h1, .h1 + @apply text-3xl + +h2, .h2 + @apply text-2xl + +// Pink dash +h1, .h1, h2, .h2, .decorated + @apply relative + + &:before + content: '' + display: block + position: absolute + top: 0.6em + constrain(left, -5vw) + constrain(width, 2.5vw) + height: 5px + background: theme('colors.pink') + + +h3, .h3, h4, .h4 + @apply font-medium + line-height: 1.4 + +h3, .h3 + @apply font-display text-xl + +h4, .h4 + @apply text-lg diff --git a/wp-content/themes/CCV/resources/assets/styles/widgets/background-image.styl b/wp-content/themes/CCV/resources/assets/styles/widgets/background-image.styl new file mode 100644 index 0000000..8600bbf --- /dev/null +++ b/wp-content/themes/CCV/resources/assets/styles/widgets/background-image.styl @@ -0,0 +1,15 @@ +.bg-image + background-size: cover + background-repeat: no-repeat + background-position: center + + &-sizer + // The sizer is only needed when in one column mode. + // The rest of the time it should just fill the height + // required by the other column's content... + +above($breakpoint-columns) + display: none + +// Ensure full height on element so the image always covers the full area +.elementor-widget-cube-bg-image, .elementor-widget-container, .bg-image + height: 100% diff --git a/wp-content/themes/CCV/resources/assets/styles/widgets/text-block.styl b/wp-content/themes/CCV/resources/assets/styles/widgets/text-block.styl new file mode 100644 index 0000000..e0b987a --- /dev/null +++ b/wp-content/themes/CCV/resources/assets/styles/widgets/text-block.styl @@ -0,0 +1,51 @@ +// Text block widget (Elementor defaults) +.elementor-widget-cube-text //.elementor-widget-container + vertical-spacing(5vw) + constrain(padding-left, 10vw) + constrain(padding-right, 7.5vw) + max-width: 640px + width: 100% + box-sizing: content-box // So padding doesn't influence max-width + + +below(450px) + horizontal-spacing(2.5vw) + +.text-block + + &-title + @apply text-2xl antialiased + white-space: pre-line + + +below(1600px) + white-space: normal // Avoid strange gaps caused by pre-line breaks wrapping + font-size: 4.25vw // Using vw units so headings scale instead of wrapping further + +below(795px) // Cap font size to medium once the vw size matches medium size + @apply text-xl // Note: also affected by the base HTML font size since it is converted rems + + // No bottom margin if it's the last element (ie. no body below) + &:last-child + margin-bottom: 0 + + &-body + font-weight: 400 + margin-top: r(40px) + + // If the body is the first child, there's no title + // so we don't want the top margin... + &:first-child + margin-top: 0 + + h3 + @apply font-medium text-lg + + a + color: theme('colors.pink') + + &-cta + @apply antialiased + margin-top: r(30px) + + // If the CTA is the first child, it means it is the only element + // in the text block so we don't want the top margin... + &:first-child + margin-top: 0 diff --git a/wp-content/themes/CCV/resources/views/partials/footer.blade.php b/wp-content/themes/CCV/resources/views/partials/footer.blade.php index e9dd92a..90a450a 100644 --- a/wp-content/themes/CCV/resources/views/partials/footer.blade.php +++ b/wp-content/themes/CCV/resources/views/partials/footer.blade.php @@ -1,16 +1,16 @@ -