feat: initial ACRIB WordPress deployment

- WordPress 6.9.4 (es_ES) with Kadence theme
- Homepage: Hero, La Asociación, Pilares, Beneficios, Eventos, Miembros, Hazte Miembro, Contacto
- Brand identity: #13294b navy, #a12932 burgundy, #c69c48 gold
- Fonts: Raleway (headings) + Source Sans 3 (body) + Lato (UI)
- Plugins: Kadence Blocks, Polylang, Contact Form 7
- Custom CSS with full brand styling and responsive layout
- HTTPS enforced via wp-config.php proxy detection
This commit is contained in:
Malin
2026-05-19 19:25:59 +02:00
commit f3ff7b7186
6119 changed files with 1984255 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
<?php declare( strict_types=1 );
namespace KadenceWP\KadenceBlocks\Optimizer\Lazy_Load;
use KadenceWP\KadenceBlocks\Asset\Asset;
use KadenceWP\KadenceBlocks\Optimizer\Analysis_Registry;
use WP_HTML_Tag_Processor;
/**
* Handles setting up the Kadence Row Layout Block for background image
* lazy loading.
*/
final class Background_Lazy_Loader {
private Asset $asset;
private Analysis_Registry $registry;
public function __construct(
Asset $asset,
Analysis_Registry $registry
) {
$this->asset = $asset;
$this->registry = $registry;
}
/**
* Add lazy loading attributes to the row layout block's wrapper div.
*
* @filter kadence_blocks_row_wrapper_args
*
* @note Video posters come in as a bgImg as well.
*
* @param array<string, mixed> $attrs The wrapper div HTML attributes.
* @param array<string, mixed> $attributes The current block attributes.
*
* @return array<string, mixed>
*/
public function lazy_load_row_background_images( array $attrs, array $attributes ): array {
$bg = $attributes['bgImg'] ?? '';
$classes = (string) ( $attrs['class'] ?? '' );
if ( ! $bg ) {
return $attrs;
}
if ( ! $this->registry->is_optimized() ) {
return $attrs;
}
$background_images = $this->registry->get_background_images();
if ( $background_images ) {
$lookup = array_flip( $background_images );
// Exclude above the fold background images.
if ( isset( $lookup[ $bg ] ) ) {
return $attrs;
}
}
$is_inline = $attributes['backgroundInline'] ?? false;
// Add lazy loading data attributes for CSS backgrounds.
if ( $classes ) {
$attrs['data-kadence-lazy-class'] = $classes;
$attrs['data-kadence-lazy-trigger'] = 'viewport';
$attrs['data-kadence-lazy-attrs'] = 'class';
unset( $attrs['class'] );
}
// Add lazy loading data attributes for inline style background images.
if ( $is_inline ) {
$attrs['data-kadence-lazy-style'] = $attrs['style'] ?? '';
$attrs['data-kadence-lazy-trigger'] ??= 'viewport';
if ( ! empty( $attrs['data-kadence-lazy-attrs'] ) ) {
$attrs['data-kadence-lazy-attrs'] .= ',style';
} else {
$attrs['data-kadence-lazy-attrs'] = 'style';
}
unset( $attrs['style'] );
}
// Enqueue the lazy loader script if we found a bg.
$this->enqueue_scripts();
return $attrs;
}
/**
* Lazy load columns with background images.
*
* @filter kadence_blocks_column_html
*
* @param string $html The kadence/column html.
* @param array $attributes The block attributes.
*
* @return string
*/
public function lazy_load_column_backgrounds( string $html, array $attributes ): string {
$bg = $attributes['backgroundImg'][0]['bgImg'] ?? false;
if ( ! $bg ) {
return $html;
}
if ( ! $this->registry->is_optimized() ) {
return $html;
}
$background_images = $this->registry->get_background_images();
if ( $background_images ) {
$lookup = array_flip( $background_images );
// Exclude above the fold background images.
if ( isset( $lookup[ $bg ] ) ) {
return $html;
}
}
$p = new WP_HTML_Tag_Processor( $html );
if ( ! $p->next_tag( [ 'class_name' => 'wp-block-kadence-column' ] ) ) {
return $html;
}
$class_attr = $p->get_attribute( 'class' );
if ( ! $class_attr ) {
return $html;
}
$p->set_attribute( 'data-kadence-lazy-class', $class_attr );
$p->set_attribute( 'data-kadence-lazy-trigger', 'viewport' );
$p->set_attribute( 'data-kadence-lazy-attrs', 'class' );
$p->remove_attribute( 'class' );
// Enqueue the lazy loader script if we found a bg.
$this->enqueue_scripts();
return $p->get_updated_html();
}
/**
* Enqueue the lazy loading frontend script.
*
* @return void
*/
private function enqueue_scripts(): void {
$this->asset->enqueue_script( 'lazy-loader', 'dist/lazy-loader' );
}
}

View File

@@ -0,0 +1,139 @@
<?php declare( strict_types=1 );
namespace KadenceWP\KadenceBlocks\Optimizer\Lazy_Load;
use KadenceWP\KadenceBlocks\Optimizer\Lazy_Load\Sections\Lazy_Render_Decider;
use WP_HTML_Tag_Processor;
/**
* Process section Optimization data to set content visibility on the Kadence row layout and column
* block.
*
* @phpstan-type HtmlClassHeightMap array<string, float> Class attribute => height in pixels.
*/
final class Element_Lazy_Loader {
private const CONTENT_VISIBILITY = 'content-visibility';
private const CONTAIN_INTRINSIC_SIZE = 'contain-intrinsic-size';
private Lazy_Render_Decider $decider;
public function __construct(
Lazy_Render_Decider $decider
) {
$this->decider = $decider;
}
/**
* Add content-visibility CSS to below the fold Kadence row elements.
*
* @filter kadence_blocks_row_wrapper_args
*
* @param array<string, mixed> $args The wrapper div HTML attributes.
* @param array<string, mixed> $attributes The current block attributes.
*
* @return array<string, mixed>
*/
public function set_content_visibility_for_row( array $args, array $attributes ): array {
$unique_id = $attributes['uniqueID'] ?? false;
if ( ! $unique_id ) {
return $args;
}
$classes = (string) ( $args['class'] ?? '' );
// Explode class string into array for exact matching.
$class_list = array_filter( preg_split( '/\s+/', $classes ) );
// Bypass lazy rendering if we find an excluded class (exact match only).
if ( ! $this->decider->should_lazy_render( $class_list ) ) {
return $args;
}
$height = $this->decider->get_section_height_by_unique_id( $unique_id );
if ( $height <= 0 ) {
return $args;
}
$current_style = (string) ( $args['style'] ?? '' );
if ( $this->has_content_visibility( $current_style ) ) {
return $args;
}
$args['style'] = $this->prepend_style( $height, $current_style );
return $args;
}
/**
* Set content visibility on found kadence/column sections.
*
* @filter kadence_blocks_column_html
*
* @param string $html The kadence/column html.
*
* @return string
*/
public function modify_column_html( string $html ): string {
$p = new WP_HTML_Tag_Processor( $html );
if ( ! $p->next_tag( [ 'class_name' => 'wp-block-kadence-column' ] ) ) {
return $html;
}
$class_attr = $p->get_attribute( 'class' );
if ( ! $class_attr ) {
return $html;
}
$height = $this->decider->get_section_height_by_class_attr( $class_attr );
if ( $height <= 0 ) {
return $html;
}
$current_style = (string) $p->get_attribute( 'style' );
if ( $this->has_content_visibility( $current_style ) ) {
return $html;
}
$p->set_attribute( 'style', $this->prepend_style( $height, $current_style ) );
return $p->get_updated_html();
}
/**
* Check if a style attribute already has content-visibility.
*
* @param string $current_style The current style attribute value.
*
* @return bool
*/
private function has_content_visibility( string $current_style ): bool {
return str_contains( $current_style, self::CONTENT_VISIBILITY ) ||
str_contains( $current_style, self::CONTAIN_INTRINSIC_SIZE );
}
/**
* Prepend the content-visibility styles to an existing style string.
*
* @param float $height The section height.
* @param string $current_style The current style.
*
* @return string
*/
private function prepend_style( float $height, string $current_style ): string {
return sprintf(
'%s: auto;%s: auto %dpx;%s',
self::CONTENT_VISIBILITY,
self::CONTAIN_INTRINSIC_SIZE,
$height,
trim( $current_style )
);
}
}

View File

@@ -0,0 +1,127 @@
<?php declare( strict_types=1 );
namespace KadenceWP\KadenceBlocks\Optimizer\Lazy_Load;
use KadenceWP\KadenceBlocks\Optimizer\Analysis_Registry;
use KadenceWP\KadenceBlocks\Optimizer\Lazy_Load\Sections\Lazy_Render_Decider;
use KadenceWP\KadenceBlocks\Optimizer\Request\Request;
use KadenceWP\KadenceBlocks\StellarWP\ProphecyMonorepo\Container\Contracts\Provider as Provider_Contract;
use KadenceWP\KadenceBlocks\Traits\Viewport_Trait;
final class Provider extends Provider_Contract {
use Viewport_Trait;
public function register(): void {
$this->register_analysis_registry();
$this->register_element_lazy_loader();
$this->register_slider_lazy_loader();
$this->register_video_poster_lazy_loader();
$this->register_background_lazy_loader();
}
private function register_analysis_registry(): void {
$this->container->singleton( Analysis_Registry::class, Analysis_Registry::class );
$this->container->when( Analysis_Registry::class )
->needs( '$is_mobile' )
->give( fn(): bool => $this->is_mobile() );
}
private function register_element_lazy_loader(): void {
$this->container->singleton( Lazy_Render_Decider::class, Lazy_Render_Decider::class );
$this->container->singleton( Element_Lazy_Loader::class, Element_Lazy_Loader::class );
/**
* Filters the list of CSS classes that should be excluded from lazy loading for
* section elements.
*
* @param string[] $excluded_classes An array of CSS class names. If a row has one
* of these classes, it will be excluded from lazy loading.
*/
$excluded_classes = apply_filters(
'kadence_blocks_optimizer_section_lazy_load_excluded_classes',
[
'kt-jarallax',
]
);
$this->container->when( Lazy_Render_Decider::class )
->needs( '$excluded_classes' )
->give( static fn(): array => $excluded_classes );
// Do not perform element lazy loading on optimizer requests.
if ( $this->container->get( Request::class )->is_optimizer_request() ) {
return;
}
add_filter(
'kadence_blocks_row_wrapper_args',
$this->container->callback( Element_Lazy_Loader::class, 'set_content_visibility_for_row' ),
10,
2
);
add_filter(
'kadence_blocks_column_html',
$this->container->callback( Element_Lazy_Loader::class, 'modify_column_html' ),
10,
1
);
}
private function register_slider_lazy_loader(): void {
$this->container->singleton( Slider_Lazy_Loader::class, Slider_Lazy_Loader::class );
// Do not perform slider lazy loading on optimizer requests.
if ( $this->container->get( Request::class )->is_optimizer_request() ) {
return;
}
add_filter(
'kadence_blocks_row_slider_attrs',
$this->container->callback( Slider_Lazy_Loader::class, 'lazy_load_row_slider' ),
10,
2
);
}
private function register_video_poster_lazy_loader(): void {
$this->container->singleton( Video_Poster_Lazy_Loader::class, Video_Poster_Lazy_Loader::class );
// Do not perform slider lazy loading on optimizer requests.
if ( $this->container->get( Request::class )->is_optimizer_request() ) {
return;
}
add_filter(
'kadence_blocks_row_video_attrs',
$this->container->callback( Video_Poster_Lazy_Loader::class, 'lazy_load_row_video_poster' ),
10,
1
);
}
private function register_background_lazy_loader(): void {
$this->container->singleton( Background_Lazy_Loader::class, Background_Lazy_Loader::class );
// Do not perform background lazy loading on optimizer requests.
if ( $this->container->get( Request::class )->is_optimizer_request() ) {
return;
}
add_filter(
'kadence_blocks_row_wrapper_args',
$this->container->callback( Background_Lazy_Loader::class, 'lazy_load_row_background_images' ),
20,
2
);
add_filter(
'kadence_blocks_column_html',
$this->container->callback( Background_Lazy_Loader::class, 'lazy_load_column_backgrounds' ),
20,
2
);
}
}

View File

@@ -0,0 +1,73 @@
<?php declare( strict_types=1 );
namespace KadenceWP\KadenceBlocks\Optimizer\Lazy_Load\Sections;
use KadenceWP\KadenceBlocks\Optimizer\Analysis_Registry;
/**
* Decide whether we should lazy render a section or not.
*/
class Lazy_Render_Decider {
private Analysis_Registry $registry;
/**
* A list of CSS classes that will bypass lazy rendering.
*
* @var string[]
*/
private array $excluded_classes;
public function __construct(
Analysis_Registry $registry,
array $excluded_classes
) {
$this->registry = $registry;
$this->excluded_classes = $excluded_classes;
}
/**
* Whether we should lazy load a section.
*
* @param string[] $class_list The class of classes to check.
*
* @return bool
*/
public function should_lazy_render( array $class_list ): bool {
foreach ( $this->excluded_classes as $excluded_class ) {
if ( in_array( $excluded_class, $class_list, true ) ) {
return false;
}
}
return true;
}
/**
* Get a section's height by a Kadence unique ID.
*
* @param string $unique_id The unique ID, e.g. 1722_f1b7a6-ea.
*
* @return float
*/
public function get_section_height_by_unique_id( string $unique_id ): float {
foreach ( $this->registry->get_valid_sections() as $class_attr => $height ) {
if ( str_contains( $class_attr, $unique_id ) ) {
return $height;
}
}
return 0.0;
}
/**
* Get a section's height by matching the complete class attribute value.
*
* @param string $class_attr The class attribute, e.g. `kb-row-layout-wrap kb-row-layout-id1722_ab152a-75 alignfull`.
*
* @return float
*/
public function get_section_height_by_class_attr( string $class_attr ): float {
return $this->registry->get_valid_sections()[ $class_attr ] ?? 0.0;
}
}

View File

@@ -0,0 +1,53 @@
<?php declare( strict_types=1 );
namespace KadenceWP\KadenceBlocks\Optimizer\Lazy_Load;
use KadenceWP\KadenceBlocks\Optimizer\Analysis_Registry;
final class Slider_Lazy_Loader {
private Analysis_Registry $registry;
public function __construct( Analysis_Registry $registry ) {
$this->registry = $registry;
}
/**
* Lazy load the row slider background image.
*
* @filter kadence_blocks_row_slider_attrs
*
* @param array<string, mixed> $attrs The HTML attributes.
* @param array<string, mixed> $attributes The row block's attributes.
*
* @return array<string, mixed>
*/
public function lazy_load_row_slider( array $attrs, array $attributes ): array {
if ( ! $this->registry->is_optimized() ) {
return $attrs;
}
$sliders = $attributes['backgroundSlider'] ?? [];
// Exclude sliders with above the fold background images.
if ( $sliders ) {
$background_images = $this->registry->get_background_images();
if ( $background_images ) {
$lookup = array_flip( $background_images );
foreach ( $sliders as $slide ) {
$bg = $slide['bgImg'] ?? '';
if ( $bg && isset( $lookup[ $bg ] ) ) {
return $attrs;
}
}
}
}
$attrs['class'] = trim( ( $attrs['class'] ?? '' ) . ' kb-lazy-bg-pending' );
return $attrs;
}
}

View File

@@ -0,0 +1,62 @@
<?php declare( strict_types=1 );
namespace KadenceWP\KadenceBlocks\Optimizer\Lazy_Load;
use KadenceWP\KadenceBlocks\Asset\Asset;
use KadenceWP\KadenceBlocks\Optimizer\Analysis_Registry;
final class Video_Poster_Lazy_Loader {
private Asset $asset;
private Analysis_Registry $registry;
public function __construct(
Asset $asset,
Analysis_Registry $registry
) {
$this->asset = $asset;
$this->registry = $registry;
}
/**
* Lazy load video posters.
*
* @example `<video poster="https://wordpress.test/some-image.jpg">`
*
* @filter kadence_blocks_row_video_attrs
*
* @param array<string, mixed> $attrs The HTML attributes.
*
* @return array<string, mixed>
*/
public function lazy_load_row_video_poster( array $attrs ): array {
$poster = $attrs['poster'] ?? '';
if ( ! $poster ) {
return $attrs;
}
if ( ! $this->registry->is_optimized() ) {
return $attrs;
}
$critical_images = $this->registry->get_background_images();
$lookup = array_flip( $critical_images );
// Bypass above the fold images.
if ( isset( $lookup[ $poster ] ) ) {
return $attrs;
}
$attrs['data-kadence-lazy-poster'] = $poster;
$attrs['data-kadence-lazy-trigger'] = 'viewport';
$attrs['data-kadence-lazy-attrs'] = 'poster';
unset( $attrs['poster'] );
// Enqueue the frontend lazy loader script.
$this->asset->enqueue_script( 'lazy-loader', 'dist/lazy-loader' );
return $attrs;
}
}

View File

@@ -0,0 +1,4 @@
import { createLazyLoader } from './lazy-loader';
const lazyLoader = createLazyLoader();
lazyLoader.observeElements();

View File

@@ -0,0 +1,60 @@
/**
* Use the IntersectionObserver to replace our lazy load attributes with the originals
* when the element comes into the viewport.
*
* @param {IntersectionObserverInit} options The IntersectionObserver options.
*/
export const createLazyLoader = (options = { rootMargin: '300px 0px' }) => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (e.isIntersecting) {
observer.unobserve(e.target);
// Get the attributes to replace: data-kadence-lazy-attrs.
const lazyAttributes = e.target.dataset.kadenceLazyAttrs;
// Merge or copy the attribute values back to their original attributes.
if (lazyAttributes) {
lazyAttributes.split(',').forEach((attributeName) => {
const lazyValue = e.target.getAttribute(`data-kadence-lazy-${attributeName}`);
if (lazyValue) {
const existingValue = e.target.getAttribute(attributeName);
if (attributeName === 'class') {
// Merge class names.
e.target.classList.add(...lazyValue.trim().split(/\s+/));
} else {
// Merge or set values if the attribute already exists.
const mergedValue = existingValue
? `${existingValue.trim()} ${lazyValue}`.trim()
: lazyValue;
e.target.setAttribute(attributeName, mergedValue);
}
}
});
// Clean up the lazy data attributes.
[...e.target.attributes]
.filter((attr) => attr.name.startsWith('data-kadence-lazy'))
.forEach((attr) => e.target.removeAttribute(attr.name));
// Fire an event so other JS scripts can hook into this and re-run their initialization.
window.dispatchEvent(
new CustomEvent('kadence-lazy-loaded', {
detail: { element: e.target },
})
);
}
}
});
}, options);
const observeElements = (selector = "[data-kadence-lazy-trigger='viewport']") => {
const elements = document.querySelectorAll(selector);
elements.forEach((e) => observer.observe(e));
};
return { observeElements };
};