Add social profiles as a block and rebuild Elektro Bernhard in 1.12.0
Social profiles are maintained once under settings (one HTTPS address per network, SocialProfiles::NETWORKS) and shown by the new `social` block (document schema v23) wherever it stands: size, shape, layout, labels, new tab and an optional subset of networks on the block; colour, hover, spacing and alignment through the free block styles. The addresses also feed sameAs in the structured data. Icons are own outline drawings in the style of the existing icon set. ADR 093. Elektro Bernhard is rebuilt with a dark hero over the team photo, a transparent header that turns white on scroll, Lato, cards with shadows and hover lift, a review slider with six real Google reviews, a dark solar band, page headers on every subpage and staggered entrance effects. Social profiles sit in the top bar and the footer. The site is a second local reference installation next to the Kant-IT pilot (var/elektro-bernhard.db, launch config on port 8088); the seed script rebuilds it from scratch. Checked: PHP suite 492 tests (only the documented old failure remains), 33 JS tests, Twig lint, PHP style, full editor browser check with axe. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
30e4b3eb2e
commit
fd4cb75548
19 files changed
+1202
-12
No files matched your search
@@ -3568,6 +3568,64 @@ final class CmsTest extends TestCase
|
||||
yield 'slider missing a device' => ['slider', ['desktopVisible' => 3, 'tabletVisible' => 2, 'snap' => true]];
|
||||
}
|
||||
|
||||
public function testSocialProfilesAreMaintainedOnceAndShownWhereverTheBlockStands(): void
|
||||
{
|
||||
$this->site->save(['country' => 'DE', 'homePath' => 'home', 'sameAs' => 'https://kant-it.de', 'social' => [
|
||||
'instagram' => 'https://www.instagram.com/elektrobernhardgmbh/', 'facebook' => 'https://www.facebook.com/elektrobernhardgmbh',
|
||||
'x' => '',
|
||||
]]);
|
||||
self::assertSame(['facebook' => 'https://www.facebook.com/elektrobernhardgmbh', 'instagram' => 'https://www.instagram.com/elektrobernhardgmbh/'], $this->site->load()['social']);
|
||||
|
||||
$document = DemoContent::starter('Mit Profilen');
|
||||
$document['schemaVersion'] = 23;
|
||||
$document['blocks'][] = ['id' => 'so1', 'type' => 'social', 'props' => ['size' => 32, 'shape' => 'circle', 'layout' => 'horizontal', 'labels' => false, 'networks' => []]];
|
||||
$document['blocks'][] = ['id' => 'so2', 'type' => 'social', 'props' => ['size' => 20, 'shape' => 'plain', 'layout' => 'vertical', 'labels' => true, 'networks' => ['instagram'], 'newTab' => false]];
|
||||
$this->pages->publish('page-1', $this->pages->saveDraft('page-1', $document, 0), 1);
|
||||
$html = $this->request('/')->getContent();
|
||||
// Die Reihenfolge ist die der festen Liste, nicht die der Eingabe; jeder Link trägt seinen Namen.
|
||||
self::assertMatchesRegularExpression('#<ul id="so1" class="block-social social-horizontal social-shape-circle social-size-32"[^>]*>.*facebook\.com.*instagram\.com.*</ul>#s', $html);
|
||||
self::assertStringContainsString('<span class="visually-hidden">Facebook</span>', $html);
|
||||
self::assertStringContainsString('href="https://www.facebook.com/elektrobernhardgmbh" target="_blank" rel="noopener"', $html);
|
||||
// Der zweite Block zeigt nur Instagram, beschriftet, im selben Tab.
|
||||
preg_match('#<ul id="so2"[^>]*>(.*?)</ul>#s', $html, $second);
|
||||
self::assertStringNotContainsString('facebook', $second[1]);
|
||||
self::assertStringContainsString('<span>Instagram</span>', $second[1]);
|
||||
self::assertStringNotContainsString('target="_blank"', $second[1]);
|
||||
self::assertStringContainsString('social-labels', $html);
|
||||
// Und die Profile stehen ohne zweite Pflege in den strukturierten Daten.
|
||||
$this->site->save(['country' => 'DE', 'homePath' => 'home', 'legalName' => 'Elektro Bernhard GmbH', 'sameAs' => 'https://kant-it.de', 'social' => ['facebook' => 'https://www.facebook.com/elektrobernhardgmbh']]);
|
||||
preg_match('#<script type="application/ld\+json">(.*?)</script>#s', $this->request('/')->getContent(), $match);
|
||||
self::assertSame(['https://kant-it.de', 'https://www.facebook.com/elektrobernhardgmbh'], json_decode(html_entity_decode($match[1], ENT_QUOTES), true)['sameAs']);
|
||||
// Ohne Profile bleibt die Seite still: kein leerer Baustein, keine Liste.
|
||||
$this->site->save(['country' => 'DE', 'homePath' => 'home']);
|
||||
self::assertStringNotContainsString('block-social', $this->request('/')->getContent());
|
||||
}
|
||||
|
||||
/** @return iterable<string, array{array<string, mixed>}> */
|
||||
public static function refusedSocialBlocks(): iterable
|
||||
{
|
||||
yield 'size off the list' => [['size' => 30, 'shape' => 'plain', 'layout' => 'horizontal', 'labels' => false, 'networks' => []]];
|
||||
yield 'unknown shape' => [['size' => 24, 'shape' => 'hexagon', 'layout' => 'horizontal', 'labels' => false, 'networks' => []]];
|
||||
yield 'unknown network' => [['size' => 24, 'shape' => 'plain', 'layout' => 'horizontal', 'labels' => false, 'networks' => ['myspace']]];
|
||||
yield 'labels as text' => [['size' => 24, 'shape' => 'plain', 'layout' => 'horizontal', 'labels' => 'ja', 'networks' => []]];
|
||||
}
|
||||
|
||||
#[DataProvider('refusedSocialBlocks')]
|
||||
public function testASocialBlockOnlyStoresWhatTheRendererKnows(array $props): void
|
||||
{
|
||||
$document = DemoContent::starter('Profile');
|
||||
$document['schemaVersion'] = 23;
|
||||
$document['blocks'][] = ['id' => 'so1', 'type' => 'social', 'props' => $props];
|
||||
$this->expectException(InvalidDocument::class);
|
||||
$this->pages->saveDraft('page-1', $document, 0);
|
||||
}
|
||||
|
||||
public function testASocialProfileMustBeAnHttpsAddress(): void
|
||||
{
|
||||
$this->expectException(InvalidPage::class);
|
||||
$this->site->save(['country' => 'DE', 'homePath' => 'home', 'social' => ['facebook' => 'http://facebook.com/x']]);
|
||||
}
|
||||
|
||||
#[DataProvider('refusedNewBlocks')]
|
||||
public function testRefusedNewBlocksNeverReachADocument(string $type, array $props): void
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user