From b94e6b0bfb2a46ce243a1587151c5aa0385c8603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20V=C3=A4nttinen?= Date: Sun, 19 May 2024 22:46:12 +0300 Subject: [PATCH 1/4] TMS-1028: Add social media link-list block, component & footer section --- CHANGELOG.MD | 2 + assets/icons/index.js | 6 + assets/icons/instagram.svg | 3 + assets/icons/snapchat.svg | 3 + assets/icons/spotify.svg | 3 + assets/icons/threads.svg | 3 + assets/icons/tiktok.svg | 3 + assets/icons/twitter.svg | 6 +- assets/icons/youtube.svg | 3 + lib/ACF/Fields/Settings/FooterSettingsTab.php | 84 ++++++++++-- lib/ACF/Fields/SomeLinkListFields.php | 124 ++++++++++++++++++ lib/ACF/FrontPageGroup.php | 1 + lib/ACF/Layouts/SomeLinkListLayout.php | 56 ++++++++ lib/ACF/PageGroup.php | 1 + lib/Blocks/SomeLinkListBlock.php | 84 ++++++++++++ lib/BlocksController.php | 11 +- models/shared/footer.php | 22 ++++ partials/blocks/block-some-link-list.dust | 30 +++++ partials/layouts/layout-some-link-list.dust | 9 ++ partials/shared/footer-inner.dust | 61 ++++++--- 20 files changed, 480 insertions(+), 35 deletions(-) create mode 100644 assets/icons/instagram.svg create mode 100644 assets/icons/snapchat.svg create mode 100644 assets/icons/spotify.svg create mode 100644 assets/icons/threads.svg create mode 100644 assets/icons/tiktok.svg create mode 100644 assets/icons/youtube.svg create mode 100644 lib/ACF/Fields/SomeLinkListFields.php create mode 100644 lib/ACF/Layouts/SomeLinkListLayout.php create mode 100644 lib/Blocks/SomeLinkListBlock.php create mode 100644 partials/blocks/block-some-link-list.dust create mode 100644 partials/layouts/layout-some-link-list.dust diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 602509e8..fa724078 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +- TMS-1028: Add social media link-list block, component & footer section + ## [1.8.12] - 2024-05-14 - TMS-1029: Change contacts-blocks width diff --git a/assets/icons/index.js b/assets/icons/index.js index 6bbc609d..fb126878 100644 --- a/assets/icons/index.js +++ b/assets/icons/index.js @@ -112,3 +112,9 @@ import './place.svg'; import './date-range.svg'; import './save.svg'; import './user.svg'; +import './instagram.svg'; +import './youtube.svg'; +import './tiktok.svg'; +import './snapchat.svg'; +import './spotify.svg'; +import './threads.svg'; diff --git a/assets/icons/instagram.svg b/assets/icons/instagram.svg new file mode 100644 index 00000000..ef7f492c --- /dev/null +++ b/assets/icons/instagram.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/icons/snapchat.svg b/assets/icons/snapchat.svg new file mode 100644 index 00000000..73cc0f45 --- /dev/null +++ b/assets/icons/snapchat.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/icons/spotify.svg b/assets/icons/spotify.svg new file mode 100644 index 00000000..ecb50c28 --- /dev/null +++ b/assets/icons/spotify.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/icons/threads.svg b/assets/icons/threads.svg new file mode 100644 index 00000000..a2371300 --- /dev/null +++ b/assets/icons/threads.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/icons/tiktok.svg b/assets/icons/tiktok.svg new file mode 100644 index 00000000..456a5351 --- /dev/null +++ b/assets/icons/tiktok.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/icons/twitter.svg b/assets/icons/twitter.svg index 4d9a1c5f..c1afc109 100644 --- a/assets/icons/twitter.svg +++ b/assets/icons/twitter.svg @@ -1,3 +1,3 @@ - - - + + + \ No newline at end of file diff --git a/assets/icons/youtube.svg b/assets/icons/youtube.svg new file mode 100644 index 00000000..092443c8 --- /dev/null +++ b/assets/icons/youtube.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/lib/ACF/Fields/Settings/FooterSettingsTab.php b/lib/ACF/Fields/Settings/FooterSettingsTab.php index 51d863d0..f1e498ca 100644 --- a/lib/ACF/Fields/Settings/FooterSettingsTab.php +++ b/lib/ACF/Fields/Settings/FooterSettingsTab.php @@ -69,6 +69,15 @@ class FooterSettingsTab extends Tab { 'title' => 'Linkki', 'instructions' => '', ], + 'some_link_column' => [ + 'title' => 'Some-linkkipalsta', + 'instructions' => '', + 'button_label' => 'Lisää linkki', + ], + 'some_icon' => [ + 'title' => 'Some-ikoni', + 'instructions' => '', + ], 'privacy_links' => [ 'title' => 'Tietosuojalinkit', 'instructions' => 'Saavutettavuusselosteet ja tietosuojalinkit', @@ -113,39 +122,39 @@ public function sub_fields( $key ) { try { $logo_field = ( new Field\Image( $strings['footer_logo']['title'] ) ) - ->set_key( "${key}_footer_logo" ) + ->set_key( "{$key}_footer_logo" ) ->set_name( 'footer_logo' ) ->set_return_format( 'id' ) ->set_wrapper_width( 50 ) ->set_instructions( $strings['footer_logo']['instructions'] ); $contact_title_field = ( new Field\Text( $strings['contact_title']['title'] ) ) - ->set_key( "${key}_contact_title" ) + ->set_key( "{$key}_contact_title" ) ->set_name( 'contact_title' ) ->set_wrapper_width( 50 ) ->set_instructions( $strings['contact_title']['instructions'] ); $address_field = ( new Field\Textarea( $strings['address']['title'] ) ) - ->set_key( "${key}_address" ) + ->set_key( "{$key}_address" ) ->set_name( 'address' ) ->set_new_lines( 'wpautop' ) ->set_wrapper_width( 50 ) ->set_instructions( $strings['address']['instructions'] ); $email_field = ( new Field\Email( $strings['email']['title'] ) ) - ->set_key( "${key}_email" ) + ->set_key( "{$key}_email" ) ->set_name( 'email' ) ->set_wrapper_width( 50 ) ->set_instructions( $strings['email']['instructions'] ); $phone_field = ( new Field\Text( $strings['phone']['title'] ) ) - ->set_key( "${key}_phone" ) + ->set_key( "{$key}_phone" ) ->set_name( 'phone' ) ->set_wrapper_width( 50 ) ->set_instructions( $strings['phone']['instructions'] ); $link_columns_field = ( new Field\Repeater( $strings['link_columns']['title'] ) ) - ->set_key( "${key}_link_columns" ) + ->set_key( "{$key}_link_columns" ) ->set_name( 'link_columns' ) ->set_layout( 'block' ) ->set_max( 3 ) @@ -153,14 +162,14 @@ public function sub_fields( $key ) { ->set_instructions( $strings['link_columns']['instructions'] ); $column_title_field = ( new Field\Text( $strings['column_title']['title'] ) ) - ->set_key( "${key}_column_title" ) + ->set_key( "{$key}_column_title" ) ->set_name( 'column_title' ) ->set_instructions( $strings['column_title']['instructions'] ); $link_columns_field->add_field( $column_title_field ); $link_column_field = ( new Field\Repeater( $strings['link_column']['title'] ) ) - ->set_key( "${key}_link_column" ) + ->set_key( "{$key}_link_column" ) ->set_name( 'link_column' ) ->set_button_label( $strings['link_column']['button_label'] ) ->set_instructions( $strings['link_column']['instructions'] ); @@ -168,32 +177,80 @@ public function sub_fields( $key ) { $link_columns_field->add_field( $link_column_field ); $link_field = ( new Field\Link( $strings['link']['title'] ) ) - ->set_key( "${key}_link" ) + ->set_key( "{$key}_link" ) ->set_name( 'link' ) ->set_instructions( $strings['link']['instructions'] ); $link_column_field->add_field( $link_field ); + $some_link_columns_field = ( new Field\Group( $strings['some_link_column']['title'] ) ) + ->set_key( "{$key}_some_link_columns" ) + ->set_name( 'some_link_columns' ) + ->set_instructions( $strings['some_link_column']['instructions'] ); + + $some_link_column_field = ( new Field\Repeater( $strings['some_link_column']['title'] ) ) + ->set_key( "{$key}_some_link_column" ) + ->set_name( 'some_link_column' ) + ->set_layout( 'block' ) + ->set_button_label( $strings['some_link_column']['button_label'] ) + ->set_instructions( $strings['some_link_column']['instructions'] ); + + $some_icon = ( new Field\Select( $strings['some_icon']['title'] ) ) + ->set_key( "{$key}_some_icon" ) + ->set_name( 'some_icon' ) + ->set_choices( [ + 'facebook' => 'Facebook', + 'instagram' => 'Instagram', + 'twitter' => 'X (Twitter)', + 'youtube' => 'YouTube', + 'linkedin' => 'LinkedIn', + 'tiktok' => 'TikTok', + 'snapchat' => 'Snapchat', + 'spotify' => 'Spotify', + 'threads' => 'Threads', + ] ) + ->set_default_value( 'facebook' ) + ->set_required() + ->set_wrapper_width( 50 ) + ->set_instructions( $strings['some_icon']['instructions'] ); + + $some_link = ( new Field\Link( $strings['link']['title'] ) ) + ->set_key( "{$key}_some_link" ) + ->set_name( 'some_link' ) + ->set_required() + ->set_wrapper_width( 50 ) + ->set_instructions( $strings['link']['instructions'] ); + + $some_link_column_field->add_fields( [ + $some_icon, + $some_link, + ] ); + + $some_link_columns_field->add_fields( [ + $column_title_field, + $some_link_column_field, + ] ); + $privacy_links_field = ( new Field\Repeater( $strings['privacy_links']['title'] ) ) - ->set_key( "${key}_privacy_links" ) + ->set_key( "{$key}_privacy_links" ) ->set_name( 'privacy_links' ) ->set_button_label( $strings['privacy_links']['button_label'] ) ->set_instructions( $strings['privacy_links']['instructions'] ); $privacy_link_field = ( new Field\Link( $strings['privacy_link']['title'] ) ) - ->set_key( "${key}_privacy_link" ) + ->set_key( "{$key}_privacy_link" ) ->set_name( 'privacy_link' ) ->set_instructions( $strings['privacy_link']['instructions'] ); $privacy_links_field->add_field( $privacy_link_field ); $hero_credits_field = ( new Field\Text( $strings['hero_credits']['title'] ) ) - ->set_key( "${key}_hero_credits" ) + ->set_key( "{$key}_hero_credits" ) ->set_name( 'hero_credits' ) ->set_instructions( $strings['hero_credits']['instructions'] ); $copyright_field = ( new Field\Text( $strings['copyright']['title'] ) ) - ->set_key( "${key}_copyright" ) + ->set_key( "{$key}_copyright" ) ->set_name( 'copyright' ) ->set_instructions( $strings['copyright']['instructions'] ); @@ -204,6 +261,7 @@ public function sub_fields( $key ) { $email_field, $phone_field, $link_columns_field, + $some_link_columns_field, $privacy_links_field, $hero_credits_field, $copyright_field, diff --git a/lib/ACF/Fields/SomeLinkListFields.php b/lib/ACF/Fields/SomeLinkListFields.php new file mode 100644 index 00000000..e64c9d09 --- /dev/null +++ b/lib/ACF/Fields/SomeLinkListFields.php @@ -0,0 +1,124 @@ +add_fields( $this->sub_fields() ); + } + catch ( \Exception $e ) { + ( new Logger() )->error( $e->getMessage(), $e->getTrace() ); + } + } + + /** + * This returns all sub fields of the parent groupable. + * + * @return array + * @throws Exception In case of invalid ACF option. + */ + protected function sub_fields() : array { + $strings = [ + 'title' => [ + 'label' => 'Otsikko', + 'instructions' => '', + ], + 'description' => [ + 'label' => 'Kuvaus', + 'instructions' => '', + ], + 'links' => [ + 'label' => 'Some-linkit', + 'instructions' => '', + 'button' => 'Lisää linkki', + ], + 'icon' => [ + 'label' => 'Ikoni', + 'instructions' => '', + ], + 'link' => [ + 'label' => 'Linkki', + 'instructions' => 'Linkkiteksti on pakollinen, muuten linkkiä ei näytetä.', + ], + ]; + + $key = $this->get_key(); + + $title_field = ( new Field\Text( $strings['title']['label'] ) ) + ->set_key( "{$key}_title" ) + ->set_name( 'title' ) + ->set_instructions( $strings['title']['instructions'] ); + + $description_field = ( new Field\ExtendedWysiwyg( $strings['description']['label'] ) ) + ->set_key( "{$key}_description" ) + ->set_name( 'description' ) + ->set_tabs( 'visual' ) + ->set_toolbar( 'tms-minimal' ) + ->disable_media_upload() + ->set_height( 100 ) + ->set_instructions( $strings['description']['instructions'] ); + + $links_field = ( new Field\Repeater( $strings['links']['label'] ) ) + ->set_key( "{$key}_links" ) + ->set_name( 'links' ) + ->set_layout( 'block' ) + ->set_button_label( $strings['links']['button'] ) + ->set_instructions( $strings['links']['instructions'] ); + + $icon_field = ( new Field\Select( $strings['icon']['label'] ) ) + ->set_key( "{$key}_icon" ) + ->set_name( 'icon' ) + ->set_choices( [ + 'facebook' => 'Facebook', + 'instagram' => 'Instagram', + 'twitter' => 'X (Twitter)', + 'youtube' => 'YouTube', + 'linkedin' => 'LinkedIn', + 'tiktok' => 'TikTok', + 'snapchat' => 'Snapchat', + 'spotify' => 'Spotify', + 'threads' => 'Threads', + ] ) + ->set_default_value( 'facebook' ) + ->set_required() + ->set_wrapper_width( 50 ) + ->set_instructions( $strings['link']['instructions'] ); + + $link_field = ( new Field\Link( $strings['link']['label'] ) ) + ->set_key( "{$key}_link" ) + ->set_name( 'link' ) + ->set_required() + ->set_wrapper_width( 50 ) + ->set_instructions( $strings['link']['instructions'] ); + + $links_field->add_fields( [ + $icon_field, + $link_field, + ] ); + + return [ + $title_field, + $description_field, + $links_field, + ]; + } +} diff --git a/lib/ACF/FrontPageGroup.php b/lib/ACF/FrontPageGroup.php index 62914c2c..ab9b7683 100644 --- a/lib/ACF/FrontPageGroup.php +++ b/lib/ACF/FrontPageGroup.php @@ -124,6 +124,7 @@ protected function get_components_field( string $key ) : Field\FlexibleContent { Layouts\ShareLinksLayout::class, Layouts\TreduEventsLayout::class, Layouts\VideoLayout::class, + Layouts\SomeLinkListLayout::class, ], $key ); diff --git a/lib/ACF/Layouts/SomeLinkListLayout.php b/lib/ACF/Layouts/SomeLinkListLayout.php new file mode 100644 index 00000000..90e4c192 --- /dev/null +++ b/lib/ACF/Layouts/SomeLinkListLayout.php @@ -0,0 +1,56 @@ +add_layout_fields(); + } + + /** + * Add layout fields + * + * @return void + */ + private function add_layout_fields() : void { + $fields = new SomeLinkListFields( + $this->get_label(), + $this->get_key(), + $this->get_name() + ); + + try { + $this->add_fields( + $this->filter_layout_fields( $fields->get_fields(), $this->get_key(), self::KEY ) + ); + } + catch ( Exception $e ) { + ( new Logger() )->error( $e->getMessage(), $e->getTrace() ); + } + } +} diff --git a/lib/ACF/PageGroup.php b/lib/ACF/PageGroup.php index 0f987ef1..c4df0663 100644 --- a/lib/ACF/PageGroup.php +++ b/lib/ACF/PageGroup.php @@ -191,6 +191,7 @@ protected function get_components_field( string $key ) : Field\FlexibleContent { Layouts\ProgramLayout::class, Layouts\TreduEventsLayout::class, Layouts\VideoLayout::class, + Layouts\SomeLinkListLayout::class, ], $key ); diff --git a/lib/Blocks/SomeLinkListBlock.php b/lib/Blocks/SomeLinkListBlock.php new file mode 100644 index 00000000..9dc3d1d5 --- /dev/null +++ b/lib/Blocks/SomeLinkListBlock.php @@ -0,0 +1,84 @@ +title = 'Some-linkkilista'; + + parent::__construct(); + } + + /** + * Create block fields. + * + * @return array + */ + protected function fields() : array { + $group = new SomeLinkListFields( $this->title, self::NAME ); + + return \apply_filters( + 'tms/block/' . self::KEY . '/fields', + $group->get_fields(), + self::KEY + ); + } + + /** + * This filters the block ACF data. + * + * @param array $data Block's ACF data. + * @param Block $instance The block instance. + * @param array $block The original ACF block array. + * @param string $content The HTML content. + * @param bool $is_preview A flag that shows if we're in preview. + * @param int $post_id The parent post's ID. + * + * @return array The block data. + */ + public function filter_data( $data, $instance, $block, $content, $is_preview, $post_id ) : array { // phpcs:ignore + if ( empty( $data['links'] ) ) { + return $data; + } + + // Filter out empty links + $data['links'] = array_filter( $data['links'], function ( $item ) { + return ! empty( $item['link']['title'] ); + } ); + + return \apply_filters( 'tms/acf/block/' . self::KEY . '/data', $data ); + } + +} diff --git a/lib/BlocksController.php b/lib/BlocksController.php index 08a2e954..10c47894 100644 --- a/lib/BlocksController.php +++ b/lib/BlocksController.php @@ -180,7 +180,16 @@ private function allowed_block_types( $allowed_blocks, $context ) { PostType\Project::SLUG, ], ], - + 'acf/some-link-list' => [ + 'post_types' => [ + PostType\Page::SLUG, + PostType\DialTredu::SLUG, + PostType\Post::SLUG, + PostType\BlogArticle::SLUG, + PostType\Program::SLUG, + PostType\Project::SLUG, + ], + ], 'acf/quote' => [ 'post_types' => [ PostType\Page::SLUG, diff --git a/models/shared/footer.php b/models/shared/footer.php index 3c91461a..cadb92d9 100644 --- a/models/shared/footer.php +++ b/models/shared/footer.php @@ -41,8 +41,10 @@ public function brand_logo_url() : string { public function column_class() : string { $contact_info = $this->contact_info(); $columns = $this->link_columns(); + $some_column = $this->some_link_columns(); $count = empty( $columns ) ? 0 : count( $columns ); $count = empty( $contact_info ) ? $count : ++ $count; + $count = empty( $some_column ) ? $count : ++ $count; return $count <= 3 ? 'is-6 is-4-widescreen' @@ -93,6 +95,26 @@ public function link_columns() { return $columns; } + /** + * Get social media link column + * + * @return mixed|null + */ + public function some_link_columns() { + $columns = Settings::get_setting( 'some_link_columns' ) ?? null; + + if ( empty( $columns['some_link_column'] ) ) { + return null; + } + + // Filter out empty links + $columns['some_link_column'] = array_filter( $columns['some_link_column'], function ( $item ) { + return ! empty( $item['some_link']['title'] ); + } ); + + return $columns; + } + /** * Get privacy links * diff --git a/partials/blocks/block-some-link-list.dust b/partials/blocks/block-some-link-list.dust new file mode 100644 index 00000000..56c87643 --- /dev/null +++ b/partials/blocks/block-some-link-list.dust @@ -0,0 +1,30 @@ + diff --git a/partials/layouts/layout-some-link-list.dust b/partials/layouts/layout-some-link-list.dust new file mode 100644 index 00000000..0779075d --- /dev/null +++ b/partials/layouts/layout-some-link-list.dust @@ -0,0 +1,9 @@ + diff --git a/partials/shared/footer-inner.dust b/partials/shared/footer-inner.dust index 10d2652b..fc736e99 100644 --- a/partials/shared/footer-inner.dust +++ b/partials/shared/footer-inner.dust @@ -1,5 +1,5 @@ {#Footer} -