3, 'editor_script' => 'vimine-blocks', 'attributes' => [ 'label' => [ 'type' => 'string', 'default' => '' ], 'returnTo' => [ 'type' => 'string', 'default' => '' ], 'scope' => [ 'type' => 'string', 'default' => '' ] ], 'render_callback' => static fn( array $a ): string => self::wrap( Vimine_Shortcodes::signin( [ 'label' => $a['label'] ?? '', 'return_to' => $a['returnTo'] ?? '', 'scope' => $a['scope'] ?? '' ] ) ), ] ); register_block_type( 'vimine/card', [ 'api_version' => 3, 'editor_script' => 'vimine-blocks', 'render_callback' => static fn(): string => self::wrap( Vimine_Shortcodes::card( [] ) ), ] ); // The look (`scheme`, `accent`, `background`, `font`): empty is Settings → Vimine's, as for the shortcode. $look = [ 'scheme', 'accent', 'background', 'font' ]; register_block_type( 'vimine/enroll', [ 'api_version' => 3, 'editor_script' => 'vimine-blocks', 'attributes' => [ 'slug' => [ 'type' => 'string', 'default' => '' ], 'height' => [ 'type' => 'string', 'default' => '900' ], 'lang' => [ 'type' => 'string', 'default' => '' ] ] + array_fill_keys( $look, [ 'type' => 'string', 'default' => '' ] ), 'render_callback' => static fn( array $a ): string => self::wrap( Vimine_Shortcodes::enroll( [ 'slug' => $a['slug'] ?? '', 'height' => $a['height'] ?? '900', 'lang' => $a['lang'] ?? '' ] + array_intersect_key( $a, array_flip( $look ) ) ) ), ] ); register_block_type( 'vimine/events', [ 'api_version' => 3, 'editor_script' => 'vimine-blocks', 'attributes' => [ 'slug' => [ 'type' => 'string', 'default' => '' ], 'filter' => [ 'type' => 'string', 'default' => 'upcoming' ], 'limit' => [ 'type' => 'string', 'default' => '10' ] ], 'render_callback' => static fn( array $a ): string => self::wrap( Vimine_Shortcodes::events( [ 'slug' => $a['slug'] ?? '', 'filter' => $a['filter'] ?? 'upcoming', 'limit' => $a['limit'] ?? '10' ] ) ), ] ); } /** * A block's markup inside the block's own wrapper: a block theme's layout places the wrapper in the content column, * and what the shortcode draws keeps its own width inside it. Unwrapped, the sign-in link (an inline element) sat at * the page's left edge, and the card, narrower than the column, was centred in it. Nothing to show stays nothing. */ private static function wrap( string $html ): string { return '' !== $html ? '