$elementor = Plugin::$instance;
- $elementor->widgets_manager->register_widget_type( new Widgets\BackgroundImage() );
$elementor->widgets_manager->register_widget_type( new Widgets\TextBlock() );
+ $elementor->widgets_manager->register_widget_type( new Widgets\BackgroundImage() );
$elementor->widgets_manager->register_widget_type( new Widgets\HeaderSlideshow() );
$elementor->widgets_manager->register_widget_type( new Widgets\NewsBanner() );
$elementor->widgets_manager->register_widget_type( new Widgets\LinkCarousel() );
$elementor->widgets_manager->register_widget_type( new Widgets\PictoGrid() );
+ $elementor->widgets_manager->register_widget_type( new Widgets\PeopleGrid() );
}
protected function _customise_sections() {
$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 .'%';
+
+ if (is_numeric($image['id'])) {
+ $meta = wp_get_attachment_metadata($image['id']);
+ $ratio = $meta['height'] / $meta['width'] * 100 . '%';
+ } else {
+ // No image set, use fallback
+ $image['url'] = Utils::get_placeholder_image_src();
+ $ratio = '100%';
+ }
echo '<div class="bg-image" style="background-image: url('. $image['url'] .'); background-position: '. $bg_position .'"><div class="bg-image-sizer" style="padding-bottom: '. $ratio .'"></div></div>';
--- /dev/null
+<?php
+
+namespace Cube\Elementor\Widgets;
+
+use Elementor\Controls_Manager;
+use Elementor\Utils;
+
+use function Roots\view;
+
+
+class PeopleGrid extends _Base {
+
+ // Widget name / ID
+ public function get_name() {
+ return 'cube-people-grid';
+ }
+
+ // Elementor widget title
+ public function get_title() {
+ return __( 'People Grid', 'cube' );
+ }
+
+ // Elementor interface icon
+ public function get_icon() {
+ return 'eicon-posts-grid';
+ }
+
+ /**
+ * List of scripts the widget depends on.
+ * Used to set scripts dependencies required to run the widget.
+ *
+ * @since 1.0.0
+ * @access public
+ * @return array Widget scripts dependencies.
+ */
+ public function get_script_depends() {
+ return [];
+ }
+ /**
+ * Register the widget controls.
+ * Adds different input fields to allow the user to change and customize the widget settings.
+ *
+ * @since 1.0.0
+ * @access protected
+ */
+ protected function _register_controls() {
+
+ $this->start_controls_section(
+ 'section_content',
+ [
+ 'label' => __( 'People Grid', 'cube' ),
+ ]
+ );
+
+ $this->add_control(
+ 'people',
+ [
+ 'label' => __( 'People', 'cube' ),
+ 'type' => Controls_Manager::REPEATER,
+ 'fields' => [
+ [
+ 'name' => 'photo',
+ 'label' => __('Photo', 'cube'),
+ 'label_block' => true,
+ 'type' => Controls_Manager::MEDIA,
+ 'default' => [
+ 'url' => Utils::get_placeholder_image_src(),
+ ],
+ ],
+ [
+ 'name' => 'name',
+ 'label' => __( 'Nom', 'cube' ),
+ 'type' => Controls_Manager::TEXTAREA,
+ 'label_block' => true,
+ 'default' => '',
+ ],
+ [
+ 'name' => 'details',
+ 'label' => __( 'Détails', 'cube' ),
+ 'type' => Controls_Manager::TEXTAREA,
+ 'label_block' => true,
+ 'default' => '',
+ ],
+ ],
+ 'title_field' => '{{{ name }}}',
+ ]
+ );
+ $this->end_controls_section();
+
+ $this->common_controls();
+ }
+ /**
+ * 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() {
+ $people = $this->get_settings('people');
+ echo view('widgets/people-grid', compact('people'));
+ }
+}
'label' => __( 'Description', 'cube' ),
'type' => Controls_Manager::TEXTAREA,
'label_block' => true,
+ 'default' => '',
],
],
'title_field' => '{{{ description }}}',
@import 'common/mixins'
@import 'common/debug'
@import 'common/global'
+@import 'common/admin'
@import 'common/layout'
@import 'common/spacing'
@import 'common/animations'
--- /dev/null
+// Tiny MCE editor styles in Elementor editor
+// Most styles for editor set in text-block.styl body...
+#tinymce
+ @apply font-body p-3
+
+ // Normally the lists have no margin and the bullet > image sits
+ // in the spacing gutter created by the text-block. In the context
+ // of the editor, it would be hidden so we indent it to make it
+ // visible while editing...
+ ul
+ margin-left: 1.3em
.container,
.elementor-section-boxed > .elementor-container
- //horizontal-spacing()
center($content-max-width)
- // Account for the extra padding Elementor adds with the "extended" column gap (15px)
- &.elementor-column-gap-extended
- padding-left: s('calc(%s - 15px)', $horizontal-gutter)
- padding-right: @padding-left
-
// Nested containers should have no padding
.elementor-container, &.elementor-column-gap-no
padding-left: 0
.elementor-column-gap-default > .elementor-row > .elementor-column > .elementor-element-populated
padding: 0
-.elementor-column-gap-wide > .elementor-row > .elementor-column > .elementor-element-populated
- +below(450px)
- padding-left: 0
- padding-right: 0
+.elementor-section-boxed > .elementor-column-gap-wide
+ horizontal-spacing(-2.5vw, margin) // Negative margins to pull back horizontal padding added to child columns below
+ > .elementor-row > .elementor-column > .elementor-element-populated
+ horizontal-spacing(2.5vw)
+ padding-top: 0
+ padding-bottom: 0
+ //+below(450px)
+ // padding-left: 0
+ // padding-right: 0
// Buttons
-.btn
+.btn,
+.elementor-widget-button a.elementor-button
@apply relative inline-block overflow-hidden
- @apply bg-pink text-white
+ @apply bg-pink text-white rounded-none
@apply font-bold text-xs uppercase
@apply px-10 py-3
font-smoothing()
&:hover
@apply bg-teal
- &-text
- @apply z-10 relative
+ &.elementor-size-sm
+ @apply text-sm
+ &.elementor-size-md
+ @apply text-base
+ &.elementor-size-lg
+ @apply text-lg
+ &.elementor-size-xl
+ @apply text-xl
+
+ //&-text
+ // @apply z-10 relative
//&-no-hover:before
// display: none
--- /dev/null
+// Elementor Image Widget overrides
+.elementor-image
+ .wp-caption
+ display: flex
+ flex-direction: column-reverse
+ align-items: flex-start
+
+ .wp-caption-text
+ @apply text-lg mb-2 flex items-center
+ color: currentColor
+
+ &:before
+ @apply inline-block bg-pink mr-2
+ content: ''
+ constrain(width, 2.5vw)
+ height: 4px
--- /dev/null
+.people-grid
+ display: grid
+ grid-template-columns: repeat(3, 1fr)
+ constrain(grid-gap, 5vw)
+
+ +below(768px)
+ grid-template-columns: repeat(2, 1fr)
+ +below(500px)
+ grid-template-columns: 1fr
+
+ &-item
+ @apply text-center
+
+ &-photo
+ @apply bg-light bg-cover bg-center bg-no-repeat rounded-full mx-auto
+ max-width: 288px
+
+ &-sizer
+ padding-bottom: 100% // Ratio based sizing to make a square
+
+ &-name
+ @apply font-body text-lg mt-4
+
+ &-details
+ @apply mx-auto
+ max-width: 280px
display: grid
grid-template-columns: repeat(4, 1fr)
constrain(grid-gap, 5vw)
- horizontal-spacing(5vw, margin)
+below(900px)
grid-template-columns: repeat(3, 1fr)
max-height: 40%
margin-bottom: 0.5em
+ // Allow image to be bigger if there's no title below it
+ &:last-child
+ max-height: none
+ margin-bottom: 0
+
&-title
flex: 0 0 auto
color: #fff
//&:last-child
// margin-bottom: 0
- &-body
- font-weight: 300
- //margin-top: r(40px)
+ &-cta
+ @apply antialiased
+ margin-top: r(30px)
- // If the body is the first child, there's no title
- // so we don't want the top margin...
- //&:first-child
- // margin-top: 0
+ // 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
- > * + * // Automatic spacing between direct child elements
- margin-top: 1.5em
+// Not nested so that we can share these styles with TinyMCE
+.text-block-body, #tinymce
+ font-weight: 300
+ //margin-top: r(40px)
- h3
- @apply font-body font-medium text-lg
+ // If the body is the first child, there's no title
+ // so we don't want the top margin...
+ //&:first-child
+ // margin-top: 0
- a
- @apply text-pink
+ > * + * // Automatic spacing between direct child elements
+ margin-top: 1.5em
- &:hover
- @apply text-teal
+ h3
+ @apply font-body font-medium text-lg
- b, strong
- font-weight: 400
+ a
+ @apply text-pink
- li
- position: relative
+ &:hover
+ @apply text-teal
- &:before
- content: ''
- position: absolute
- top: 0.4em
- left: -1.3em
- width: 7px
- height: 13px
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='14' viewBox='0 0 8 14'%3E%3Cpath stroke='%23ff078b' stroke-width='2' stroke-linecap='round' d='M1 1l6 6M1 13l6-6'/%3E%3C/svg%3E")
- background-repeat: no-repeat
- background-size: contain
+ b, strong
+ font-weight: 400
- &-cta
- @apply antialiased
- margin-top: r(30px)
+ li
+ position: relative
- // 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
+ &:before
+ content: ''
+ position: absolute
+ top: 0.4em
+ left: -1.3em
+ width: 7px
+ height: 13px
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='14' viewBox='0 0 8 14'%3E%3Cpath stroke='%23ff078b' stroke-width='2' stroke-linecap='round' d='M1 1l6 6M1 13l6-6'/%3E%3C/svg%3E")
+ background-repeat: no-repeat
+ background-size: contain
--- /dev/null
+{{-- PEOPLE GRID --}}
+<div class="people-grid">
+ @foreach ($people as $person)
+ <div class="people-grid-item">
+ <div class="people-grid-photo" style="background-image:url({{ $person['photo']['url'] }})">
+ <div class="people-grid-photo-sizer"></div>
+ </div>
+ <h3 class="people-grid-name">{!! $person['name'] !!}</h3>
+ @if ($person['details'])
+ <p class="people-grid-details">{!! nl2br($person['details']) !!}</p>
+ @endif
+ </div>
+ @endforeach
+</div>
<img class="picto-grid-image" src="{{ $item['image']['url'] }}" alt="">
@endif
@if ($item['title'])
- <p class="picto-grid-title">{{ $item['title'] }}</p>
+ <p class="picto-grid-title">{!! nl2br($item['title']) !!}</p>
@endif
</div>
</div>
- <p class="picto-grid-description">{{ $item['description'] }}</p>
+ <p class="picto-grid-description">{!! nl2br($item['description']) !!}</p>
</div>
@endforeach
</div>