diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 2839aa63..b94a8ce0 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.54.9] - 2024-04-18 - TMS-1031: Fix event-component recurring manual-event dates diff --git a/assets/icons/index.js b/assets/icons/index.js index 5cb83d6a..cba819d1 100644 --- a/assets/icons/index.js +++ b/assets/icons/index.js @@ -99,3 +99,9 @@ import './veistospuisto.svg'; import './vkontakte.svg'; import './whatsapp.svg'; import './accessibility'; +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 f1ca115a..20060bef 100644 --- a/lib/ACF/Fields/Settings/FooterSettingsTab.php +++ b/lib/ACF/Fields/Settings/FooterSettingsTab.php @@ -30,59 +30,68 @@ class FooterSettingsTab extends Tab { * @var array */ protected $strings = [ - 'tab' => 'Alatunniste', - 'footer_logo' => [ + 'tab' => 'Alatunniste', + 'footer_logo' => [ 'title' => 'Logo', 'instructions' => '', ], - 'contact_title' => [ + 'contact_title' => [ 'title' => 'Yhteystietojen otsikko', 'instructions' => '', ], - 'address' => [ + 'address' => [ 'title' => 'Osoite', 'instructions' => '', ], - 'email' => [ + 'email' => [ 'title' => 'Sähköposti', 'instructions' => '', ], - 'phone' => [ + 'phone' => [ 'title' => 'Puhelinnumero', 'instructions' => '', ], - 'link_columns' => [ + 'link_columns' => [ 'title' => 'Linkkipalstat', 'instructions' => '', 'button_label' => 'Lisää linkkipalsta', ], - 'column_title' => [ + 'column_title' => [ 'title' => 'Otsikko', 'instructions' => '', ], - 'link_column' => [ + 'link_column' => [ 'title' => 'Linkkipalsta', 'instructions' => '', 'button_label' => 'Lisää linkki', ], - 'link' => [ + 'link' => [ 'title' => 'Linkki', 'instructions' => '', ], - 'privacy_links' => [ + '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', 'button_label' => 'Lisää linkki', ], - 'privacy_link' => [ + 'privacy_link' => [ 'title' => 'Linkki', 'instructions' => '', ], - 'hero_credits' => [ + 'hero_credits' => [ 'title' => 'Etusivun hero-kuvan tekijätieto tai kuvaajan nimi', 'instructions' => '', ], - 'copyright' => [ + 'copyright' => [ 'title' => 'Copyright-teksti', 'instructions' => '© ja vuosi lisätään automaattisesti syötettyä tekstiä ennen', ], @@ -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..9b101c84 --- /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 15382527..8d8d0c75 100644 --- a/lib/ACF/FrontPageGroup.php +++ b/lib/ACF/FrontPageGroup.php @@ -122,6 +122,7 @@ protected function get_components_field( string $key ) : Field\FlexibleContent { Layouts\ShareLinksLayout::class, Layouts\CountdownLayout::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..0af7d600 --- /dev/null +++ b/lib/ACF/Layouts/SomeLinkListLayout.php @@ -0,0 +1,60 @@ +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 ae0c5d64..38b19f00 100644 --- a/lib/ACF/PageGroup.php +++ b/lib/ACF/PageGroup.php @@ -174,6 +174,7 @@ protected function get_components_field( string $key ) : Field\FlexibleContent { Layouts\ShareLinksLayout::class, Layouts\CountdownLayout::class, Layouts\VideoLayout::class, + Layouts\SomeLinkListLayout::class, ], $key ); @@ -212,6 +213,7 @@ private function add_anchor_fields() : void { 'share_links', 'countdown', 'video', + 'some_link_list', ]; foreach ( $keys as $component ) { diff --git a/lib/Blocks/SomeLinkListBlock.php b/lib/Blocks/SomeLinkListBlock.php new file mode 100644 index 00000000..20b9ad83 --- /dev/null +++ b/lib/Blocks/SomeLinkListBlock.php @@ -0,0 +1,88 @@ +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; + } + + $home_url = defined( 'DPT_PLL_ACTIVE' ) && DPT_PLL_ACTIVE + ? \pll_home_url() + : \home_url(); + + // 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 fb2e0d8e..82d22f10 100644 --- a/lib/BlocksController.php +++ b/lib/BlocksController.php @@ -167,6 +167,14 @@ private function allowed_block_types( $allowed_blocks, $context ) { PostType\DynamicEvent::SLUG, ], ], + 'acf/some-link-list' => [ + 'post_types' => [ + PostType\Page::SLUG, + PostType\Post::SLUG, + PostType\BlogArticle::SLUG, + PostType\DynamicEvent::SLUG, + ], + ], 'acf/quote' => [ 'post_types' => [ PostType\Page::SLUG, diff --git a/models/shared/footer.php b/models/shared/footer.php index d3882c2c..f3215ed9 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 1fcbfebe..161bd0ee 100644 --- a/partials/shared/footer-inner.dust +++ b/partials/shared/footer-inner.dust @@ -1,5 +1,5 @@ {#Footer} -