Web de Gure Ametsa Bi Lagun en WordPress para Dokploy

- Docker Compose (WordPress + MariaDB) listo para Dokploy, con instalación
  automática por etapas: idiomas, páginas, menús y plugins recomendados.
- Web bilingüe castellano / euskera con Polylang.
- Tema propio «gure-ametsa»: diseño inspirado en Beargrass Animal Rescue,
  personalizable desde Apariencia → Personalizar (paletas, tipografías,
  secciones de portada ordenables) y patrones de bloques propios.
- Plugin mu «gure-ametsa-core»: animales en adopción con ficha y filtros,
  carrusel y formulario de contacto/adopción.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-24 16:21:26 +02:00
parent 97b8c1be31
commit 0b2c9f271f
64 changed files with 4561 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
<?php
/**
* Tarjeta de animal (dentro del loop).
*/
$id = get_the_ID();
$meta = array_filter( array(
ga_get( $id, 'raza' ) ?: ga_species(),
ga_age( $id ),
ga_label( $id, 'tamano' ),
) );
$compatible = ga_label( $id, 'compatible' ) ?: array();
?>
<article class="ga-card">
<?php ga_status_badge(); ?>
<div class="ga-card__img"><?php ga_animal_photo(); ?></div>
<div class="ga-card__body">
<h3 class="ga-card__title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<?php if ( $meta ) : ?>
<p class="ga-card__meta"><?php echo esc_html( implode( ' · ', $meta ) ); ?></p>
<?php endif; ?>
<?php if ( $compatible ) : ?>
<ul class="ga-badges">
<?php foreach ( $compatible as $c ) : ?>
<li><?php echo esc_html( ga_compat_label( $c ) ); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<span class="ga-card__more"><?php ga_e( 'Ver ficha', 'Ikusi fitxa' ); ?> <?php echo ga_icon( 'arrow' ); ?></span>
</div>
</article>

View File

@@ -0,0 +1,18 @@
<?php
$button = ga_opt( 'animals', 'button' )
? sprintf( '<a class="ga-btn ga-btn--primary" href="%s">%s %s</a>', esc_url( get_post_type_archive_link( 'animal' ) ), esc_html( ga_opt( 'animals', 'button' ) ), ga_icon( 'arrow' ) )
: '';
?>
<section class="ga-section" id="animales">
<div class="ga-wrap">
<?php ga_section_head( 'animals', array( 'extra' => $button ) ); ?>
<?php
echo do_shortcode( sprintf(
'[ga_animales numero="%d" estado="%s" vista="%s"]',
max( 1, (int) ga_opt( 'animals', 'count' ) ),
esc_attr( ga_opt( 'animals', 'filter' ) ),
esc_attr( ga_opt( 'animals', 'view' ) )
) );
?>
</div>
</section>

View File

@@ -0,0 +1,11 @@
<?php
/* Contenido de la página «Inicio» / «Hasiera» hecho con el editor de bloques. */
while ( have_posts() ) :
the_post();
if ( trim( get_the_content() ) ) :
?>
<section class="ga-content"><?php the_content(); ?></section>
<?php
endif;
endwhile;
rewind_posts();

View File

@@ -0,0 +1,24 @@
<?php
$items = array();
for ( $i = 1; $i <= 5; $i++ ) {
if ( ga_opt( 'faq', "q$i" ) ) {
$items[] = array( ga_opt( 'faq', "q$i" ), ga_opt( 'faq', "a$i" ) );
}
}
if ( ! $items ) {
return;
}
?>
<section class="ga-section">
<div class="ga-narrow">
<?php ga_section_head( 'faq', array( 'center' => true ) ); ?>
<div class="ga-faq">
<?php foreach ( $items as [ $q, $a ] ) : ?>
<details>
<summary><?php echo esc_html( $q ); ?></summary>
<p><?php echo esc_html( $a ); ?></p>
</details>
<?php endforeach; ?>
</div>
</div>
</section>

View File

@@ -0,0 +1,35 @@
<?php
$image = (int) ga_opt( 'foster', 'image' );
$items = ga_lines( ga_opt( 'foster', 'list' ) );
$url = add_query_arg( 'motivo', 'acogida', ga_page_url( 'contacto' ) ) . '#formulario';
?>
<section class="ga-section" id="acogida">
<div class="ga-wrap ga-split">
<div>
<?php ga_section_head( 'foster' ); ?>
<?php if ( $items ) : ?>
<?php if ( ga_opt( 'foster', 'list_title' ) ) : ?>
<h3 class="ga-list-title"><?php ga_opt_e( 'foster', 'list_title' ); ?></h3>
<?php endif; ?>
<ul class="ga-checklist">
<?php foreach ( $items as $item ) : ?>
<li><?php echo ga_icon( 'check' ); ?><span><?php echo esc_html( $item ); ?></span></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php if ( ga_opt( 'foster', 'button' ) ) : ?>
<p class="ga-section__cta"><a class="ga-btn ga-btn--primary" href="<?php echo esc_url( $url ); ?>"><?php ga_opt_e( 'foster', 'button' ); ?> <?php echo ga_icon( 'arrow' ); ?></a></p>
<?php endif; ?>
</div>
<figure class="ga-photo">
<?php if ( $image ) : ?>
<?php echo wp_get_attachment_image( $image, 'large', false, array( 'loading' => 'lazy' ) ); ?>
<?php else : ?>
<div class="ga-photo__placeholder"><?php echo ga_icon( 'paw' ); ?></div>
<?php endif; ?>
<?php if ( ga_opt( 'foster', 'caption' ) ) : ?>
<figcaption><?php ga_opt_e( 'foster', 'caption' ); ?></figcaption>
<?php endif; ?>
</figure>
</div>
</section>

View File

@@ -0,0 +1,33 @@
<?php
$needs = ga_lines( ga_opt( 'give', 'needs' ) );
$shortcode = trim( (string) ga_opt( 'give', 'shortcode' ) );
$url = add_query_arg( 'motivo', 'donaciones', ga_page_url( 'contacto' ) ) . '#formulario';
?>
<section class="ga-section ga-section--sand" id="dona">
<div class="ga-wrap">
<?php ga_section_head( 'give' ); ?>
<div class="ga-give">
<div class="ga-panel">
<?php if ( $shortcode && preg_match( '/^\[[a-z_]+[^\]]*\]$/i', $shortcode ) ) : ?>
<?php echo do_shortcode( $shortcode ); ?>
<?php else : ?>
<h3><?php ga_opt_e( 'give', 'card_title' ); ?></h3>
<p><?php ga_opt_e( 'give', 'card_text' ); ?></p>
<?php if ( ga_opt( 'give', 'button' ) ) : ?>
<a class="ga-btn ga-btn--accent ga-btn--block" href="<?php echo esc_url( $url ); ?>"><?php ga_opt_e( 'give', 'button' ); ?> <?php echo ga_icon( 'arrow' ); ?></a>
<?php endif; ?>
<?php endif; ?>
</div>
<?php if ( $needs ) : ?>
<div class="ga-panel ga-panel--dark">
<h3><?php ga_opt_e( 'give', 'needs_title' ); ?></h3>
<ul class="ga-needs">
<?php foreach ( $needs as $i => $need ) : ?>
<li><strong><?php echo (int) $i + 1; ?></strong><span><?php echo esc_html( $need ); ?></span></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
</div>
</div>
</section>

View File

@@ -0,0 +1,27 @@
<?php
/* Variante en tarjetas de las «puertas» (usa los textos de Portada principal). */
$colabora = ga_page_url( 'colabora' );
$links = array(
1 => get_post_type_archive_link( 'animal' ),
2 => $colabora . '#acogida',
3 => $colabora . '#voluntariado',
4 => $colabora . '#donaciones',
);
?>
<section class="ga-section ga-section--sand">
<div class="ga-wrap">
<?php ga_section_head( 'help' ); ?>
<div class="ga-doors__grid ga-doors__grid--static">
<?php foreach ( $links as $n => $href ) : ?>
<?php if ( ga_opt( 'hero', "door{$n}_title" ) ) : ?>
<a class="ga-door ga-door--<?php echo (int) $n; ?>" href="<?php echo esc_url( $href ); ?>">
<span class="ga-door__kicker"><?php ga_opt_e( 'hero', "door{$n}_kicker" ); ?></span>
<span class="ga-door__title"><?php ga_opt_e( 'hero', "door{$n}_title" ); ?></span>
<span class="ga-door__text"><?php ga_opt_e( 'hero', "door{$n}_text" ); ?></span>
<span class="ga-door__link"><?php ga_opt_e( 'hero', "door{$n}_link" ); ?> <?php echo ga_icon( 'arrow' ); ?></span>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
</section>

View File

@@ -0,0 +1,88 @@
<?php
$image = (int) ga_opt( 'hero', 'image' );
$video = (int) ga_opt( 'hero', 'video' );
$full = 'full' === ga_opt( 'hero', 'layout' );
$overlay = min( 95, (int) ga_opt( 'hero', 'overlay' ) ) / 100;
$btn1 = ga_link( ga_opt( 'hero', 'btn1_url' ), get_post_type_archive_link( 'animal' ) );
$btn2 = ga_link( ga_opt( 'hero', 'btn2_url' ), ga_page_url( 'contacto', '#formulario' ) );
$doors = ga_opt( 'hero', 'doors' );
$colabora = ga_page_url( 'colabora' );
$door_links = array(
1 => get_post_type_archive_link( 'animal' ),
2 => $colabora . '#acogida',
3 => $colabora . '#voluntariado',
4 => $colabora . '#donaciones',
);
$classes = array( 'ga-hero', $full ? 'ga-hero--full' : 'ga-hero--split' );
if ( $full && ( $image || $video ) ) {
$classes[] = 'has-media';
}
if ( $doors ) {
$classes[] = 'has-doors';
}
?>
<section class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>" style="--ga-overlay:<?php echo esc_attr( $overlay ); ?>">
<?php if ( $full && ( $image || $video ) ) : ?>
<div class="ga-hero__bg" aria-hidden="true">
<?php if ( $video && wp_get_attachment_url( $video ) ) : ?>
<video autoplay muted loop playsinline preload="metadata"
<?php echo $image ? 'poster="' . esc_url( wp_get_attachment_image_url( $image, 'full' ) ) . '"' : ''; ?>>
<source src="<?php echo esc_url( wp_get_attachment_url( $video ) ); ?>" type="<?php echo esc_attr( get_post_mime_type( $video ) ); ?>">
</video>
<?php else : ?>
<?php echo wp_get_attachment_image( $image, 'full', false, array( 'fetchpriority' => 'high', 'alt' => '' ) ); ?>
<?php endif; ?>
</div>
<?php elseif ( $full ) : ?>
<div class="ga-hero__paw" aria-hidden="true"><?php echo ga_icon( 'paw' ); ?></div>
<?php endif; ?>
<div class="ga-wrap ga-hero__inner">
<div class="ga-hero__text">
<?php if ( ga_opt( 'hero', 'eyebrow' ) ) : ?>
<span class="ga-pill"><?php ga_opt_e( 'hero', 'eyebrow' ); ?></span>
<?php endif; ?>
<h1><?php echo ga_highlight( ga_opt( 'hero', 'title' ) ); // Escapado en la función. ?></h1>
<?php if ( ga_opt( 'hero', 'lead' ) ) : ?>
<p class="ga-hero__lead"><?php ga_opt_e( 'hero', 'lead' ); ?></p>
<?php endif; ?>
<div class="ga-hero__actions">
<?php if ( ga_opt( 'hero', 'btn1' ) ) : ?>
<a class="ga-btn ga-btn--accent" href="<?php echo esc_url( $btn1 ); ?>"><?php ga_opt_e( 'hero', 'btn1' ); ?> <?php echo ga_icon( 'arrow' ); ?></a>
<?php endif; ?>
<?php if ( ga_opt( 'hero', 'btn2' ) ) : ?>
<a class="ga-btn ga-btn--ghost" href="<?php echo esc_url( $btn2 ); ?>"><?php ga_opt_e( 'hero', 'btn2' ); ?></a>
<?php endif; ?>
</div>
</div>
<?php if ( ! $full ) : ?>
<div class="ga-hero__media">
<?php if ( $image ) : ?>
<?php echo wp_get_attachment_image( $image, 'large', false, array( 'fetchpriority' => 'high' ) ); ?>
<?php else : ?>
<div class="ga-hero__art"><?php echo ga_icon( 'paw' ); ?></div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</section>
<?php if ( $doors ) : ?>
<nav class="ga-doors" aria-label="<?php echo esc_attr( ga__( 'Formas de ayudar', 'Laguntzeko moduak' ) ); ?>">
<div class="ga-wrap ga-doors__grid">
<?php foreach ( $door_links as $n => $href ) : ?>
<?php if ( ga_opt( 'hero', "door{$n}_title" ) ) : ?>
<a class="ga-door ga-door--<?php echo (int) $n; ?>" href="<?php echo esc_url( $href ); ?>">
<span class="ga-door__kicker"><?php ga_opt_e( 'hero', "door{$n}_kicker" ); ?></span>
<span class="ga-door__title"><?php ga_opt_e( 'hero', "door{$n}_title" ); ?></span>
<span class="ga-door__text"><?php ga_opt_e( 'hero', "door{$n}_text" ); ?></span>
<span class="ga-door__link"><?php ga_opt_e( 'hero', "door{$n}_link" ); ?> <?php echo ga_icon( 'arrow' ); ?></span>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</nav>
<?php endif; ?>

View File

@@ -0,0 +1,28 @@
<?php
$cases = array();
for ( $i = 1; $i <= 3; $i++ ) {
if ( ga_opt( 'intake', "caso{$i}_title" ) ) {
$cases[] = array( ga_opt( 'intake', "caso{$i}_title" ), ga_opt( 'intake', "caso{$i}_text" ) );
}
}
if ( ! $cases ) {
return;
}
?>
<section class="ga-section ga-section--sand" id="ayuda">
<div class="ga-wrap">
<?php ga_section_head( 'intake' ); ?>
<div class="ga-cases">
<?php foreach ( $cases as [ $title, $text ] ) : ?>
<div class="ga-case">
<h3><?php echo esc_html( $title ); ?></h3>
<p><?php echo esc_html( $text ); ?></p>
</div>
<?php endforeach; ?>
</div>
<p class="ga-cases__phone">
<?php ga_e( '¿Es urgente? Llámanos:', 'Premiazkoa da? Deitu iezaguzu:' ); ?>
<a href="<?php echo esc_attr( ga_tel_link() ); ?>"><?php echo ga_icon( 'phone' ); ?> <?php echo esc_html( ga_info( 'telefono' ) ); ?></a>
</p>
</div>
</section>

View File

@@ -0,0 +1,35 @@
<?php
/* Accesos grandes a perros y gatos (inspirado en «Meet our dogs / Meet our cats»). */
$tiles = array();
foreach ( array( 'dog' => 'perro', 'cat' => 'gato' ) as $key => $slug ) {
$term = get_term_by( 'slug', $slug, 'especie' );
if ( $term && function_exists( 'pll_get_term' ) ) {
$translated = pll_get_term( $term->term_id, ga_lang() );
$term = $translated ? get_term( $translated, 'especie' ) : $term;
}
$tiles[ $key ] = array(
'url' => $term && ! is_wp_error( $term ) ? get_term_link( $term ) : get_post_type_archive_link( 'animal' ),
'label' => ga_opt( 'species', "{$key}_label" ),
'image' => (int) ga_opt( 'species', "{$key}_image" ),
);
}
?>
<section class="ga-section ga-species-section">
<div class="ga-wrap">
<?php if ( ga_opt( 'species', 'title' ) ) : ?>
<h2 class="ga-center"><?php ga_opt_e( 'species', 'title' ); ?></h2>
<?php endif; ?>
<div class="ga-species">
<?php foreach ( $tiles as $key => $tile ) : ?>
<a class="ga-species__tile ga-species__tile--<?php echo esc_attr( $key ); ?>" href="<?php echo esc_url( $tile['url'] ); ?>">
<?php if ( $tile['image'] ) : ?>
<?php echo wp_get_attachment_image( $tile['image'], 'large', false, array( 'loading' => 'lazy', 'alt' => '' ) ); ?>
<?php else : ?>
<span class="ga-species__paw"><?php echo ga_icon( 'paw' ); ?></span>
<?php endif; ?>
<span class="ga-species__label"><?php echo esc_html( $tile['label'] ); ?> <span aria-hidden="true">→</span></span>
</a>
<?php endforeach; ?>
</div>
</div>
</section>

View File

@@ -0,0 +1,21 @@
<?php
$items = array();
for ( $i = 1; $i <= 4; $i++ ) {
if ( '' !== trim( (string) ga_opt( 'stats', "num$i" ) ) ) {
$items[] = array( ga_opt( 'stats', "num$i" ), ga_opt( 'stats', "label$i" ) );
}
}
if ( ! $items ) {
return;
}
?>
<section class="ga-section ga-section--dark">
<div class="ga-wrap">
<?php ga_section_head( 'stats' ); ?>
<ul class="ga-stats">
<?php foreach ( $items as [ $num, $label ] ) : ?>
<li><strong><?php echo esc_html( $num ); ?></strong><span><?php echo esc_html( $label ); ?></span></li>
<?php endforeach; ?>
</ul>
</div>
</section>

View File

@@ -0,0 +1,18 @@
<section class="ga-section ga-section--sand" id="como-adoptar">
<div class="ga-wrap">
<?php ga_section_head( 'steps' ); ?>
<ol class="ga-steps">
<?php for ( $i = 1; $i <= 4; $i++ ) : ?>
<?php if ( ga_opt( 'steps', "step{$i}_title" ) ) : ?>
<li class="ga-step">
<h3><?php ga_opt_e( 'steps', "step{$i}_title" ); ?></h3>
<p><?php ga_opt_e( 'steps', "step{$i}_text" ); ?></p>
</li>
<?php endif; ?>
<?php endfor; ?>
</ol>
<?php if ( ga_opt( 'steps', 'button' ) ) : ?>
<p class="ga-section__cta"><a class="ga-btn ga-btn--primary" href="<?php echo esc_url( ga_page_url( 'contacto', '#formulario' ) ); ?>"><?php ga_opt_e( 'steps', 'button' ); ?> <?php echo ga_icon( 'arrow' ); ?></a></p>
<?php endif; ?>
</div>
</section>

View File

@@ -0,0 +1,25 @@
<?php
/* Últimos animales adoptados: se oculta si todavía no hay ninguno. */
$adopted = ga_query_animals( array(
'numero' => max( 1, (int) ga_opt( 'stories', 'count' ) ),
'estado' => 'adoptado',
) );
if ( ! $adopted->have_posts() ) {
return;
}
?>
<section class="ga-section">
<div class="ga-wrap">
<?php ga_section_head( 'stories', array( 'center' => true ) ); ?>
<?php
$carousel = 'carrusel' === ga_opt( 'stories', 'view' );
$carousel ? ga_carousel_open( ga_opt( 'stories', 'title' ) ) : print( '<div class="ga-grid">' );
while ( $adopted->have_posts() ) :
$adopted->the_post();
get_template_part( 'template-parts/animal-card' );
endwhile;
wp_reset_postdata();
$carousel ? ga_carousel_close() : print( '</div>' );
?>
</div>
</section>

View File

@@ -0,0 +1,25 @@
<section class="ga-section ga-section--dark" id="contacto">
<div class="ga-wrap ga-talk">
<div>
<?php ga_section_head( 'talk' ); ?>
<ul class="ga-iconlist ga-iconlist--big">
<?php if ( ga_info( 'telefono' ) ) : ?>
<li><?php echo ga_icon( 'phone' ); ?><span><strong><?php ga_e( 'Teléfono', 'Telefonoa' ); ?></strong><a href="<?php echo esc_attr( ga_tel_link() ); ?>"><?php echo esc_html( ga_info( 'telefono' ) ); ?></a></span></li>
<?php endif; ?>
<?php if ( ga_info( 'email' ) ) : ?>
<li><?php echo ga_icon( 'mail' ); ?><span><strong>Email</strong><a href="mailto:<?php echo esc_attr( ga_info( 'email' ) ); ?>"><?php echo esc_html( ga_info( 'email' ) ); ?></a></span></li>
<?php endif; ?>
<?php if ( ga_info( 'direccion' ) ) : ?>
<li><?php echo ga_icon( 'pin' ); ?><span><strong><?php ga_e( 'Dirección', 'Helbidea' ); ?></strong><?php echo esc_html( ga_info( 'direccion' ) ); ?></span></li>
<?php endif; ?>
<?php if ( ga_info( 'horario' ) ) : ?>
<li><?php echo ga_icon( 'clock' ); ?><span><strong><?php ga_e( 'Horario', 'Ordutegia' ); ?></strong><?php echo esc_html( ga_info( 'horario' ) ); ?></span></li>
<?php endif; ?>
</ul>
</div>
<div class="ga-panel ga-panel--form" id="formulario">
<h3><?php ga_opt_e( 'talk', 'form_title' ); ?></h3>
<?php echo do_shortcode( '[ga_contacto]' ); ?>
</div>
</div>
</section>

View File

@@ -0,0 +1,39 @@
<?php
$image = (int) ga_opt( 'visit', 'image' );
?>
<section class="ga-section ga-section--sand" id="visitanos">
<div class="ga-wrap">
<?php ga_section_head( 'visit' ); ?>
<div class="ga-location">
<div class="ga-location__photo">
<?php if ( $image ) : ?>
<?php echo wp_get_attachment_image( $image, 'large', false, array( 'loading' => 'lazy' ) ); ?>
<?php else : ?>
<div class="ga-photo__placeholder"><?php echo ga_icon( 'paw' ); ?></div>
<?php endif; ?>
</div>
<div class="ga-location__info">
<h3><?php echo esc_html( ga_opt( 'header', 'brand_line1' ) . ' ' . ga_opt( 'header', 'brand_line2' ) ); ?></h3>
<ul class="ga-iconlist">
<?php if ( ga_info( 'direccion' ) ) : ?>
<li><?php echo ga_icon( 'pin' ); ?><span><?php echo esc_html( ga_info( 'direccion' ) ); ?></span></li>
<?php endif; ?>
<?php if ( ga_info( 'horario' ) ) : ?>
<li><?php echo ga_icon( 'clock' ); ?><span><?php echo esc_html( ga_info( 'horario' ) ); ?></span></li>
<?php endif; ?>
<?php if ( ga_info( 'telefono' ) ) : ?>
<li><?php echo ga_icon( 'phone' ); ?><a href="<?php echo esc_attr( ga_tel_link() ); ?>"><?php echo esc_html( ga_info( 'telefono' ) ); ?></a></li>
<?php endif; ?>
</ul>
<div class="ga-location__actions">
<?php if ( ga_info( 'maps' ) ) : ?>
<a class="ga-btn ga-btn--primary" href="<?php echo esc_url( ga_info( 'maps' ) ); ?>" target="_blank" rel="noopener"><?php ga_e( 'Cómo llegar', 'Nola iritsi' ); ?> <?php echo ga_icon( 'arrow' ); ?></a>
<?php endif; ?>
<?php if ( ga_opt( 'visit', 'button' ) ) : ?>
<a class="ga-btn ga-btn--outline" href="<?php echo esc_url( ga_page_url( 'hotel' ) ); ?>"><?php ga_opt_e( 'visit', 'button' ); ?></a>
<?php endif; ?>
</div>
</div>
</div>
</div>
</section>