# Shortcode amb views

Per fer un plugin més net i escalable, cal **separar la lògica del codi HTML de presentació**. En lloc de retornar un *string* directament des de la funció del *shortcode*, farem que la funció inclogui un altre fitxer PHP que contindrà l'estructura HTML. En aquest cas ampliarem l'estructura del plugin **"Banner Personalitzat"** per utilitzar aquesta tècnica.

## Estructura de fitxers

Afegirem una carpeta i un fitxer per al nostre *template* (plantilla):

<div _ngcontent-ng-c1868495127="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-carpeta%2Ffitxer-prop%C3%B2" inline-copy-host=""><table><thead><tr><td>**Carpeta/Fitxer**</td><td>**Propòsit**</td></tr></thead><tbody><tr><td>**`banner-personalitzat/`**</td><td>Carpeta arrel.</td></tr><tr><td>`banner-personalitzat/`**`includes/`**</td><td>Lògica PHP.</td></tr><tr><td>`banner-personalitzat/includes/`**`shortcode.php`**</td><td>Conté la funció PHP que processa els paràmetres i carrega el template.</td></tr><tr><td>**`banner-personalitzat/templates/`**</td><td>**NOVA CARPETA:** Conté els fitxers de presentació.</td></tr><tr><td>`banner-personalitzat/templates/`**`banner-template.php`**</td><td>**NOU FITXER:** Conté l'HTML pur del banner.</td></tr><tr><td>`banner-personalitzat/assets/`</td><td>Estils i scripts.</td></tr></tbody></table>

</div>## Lògica del shortcode `includes/shortcode.php`

La funció del *shortcode* ara s'encarregarà de **preparar les dades** i **carregar el fitxer de plantilla**. Utilitzarem una tècnica de *buffer* de sortida de PHP (`ob_start`, `ob_get_clean`) per capturar l'HTML del fitxer inclòs i retornar-lo com a *string* al lloc on s'ha utilitzat el *shortcode*.

<div _ngcontent-ng-c1868495127="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-" inline-copy-host=""></div><div _ngcontent-ng-c1663689211="" class="code-block ng-tns-c1663689211-81 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-php" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_195d4914994f79e2","c_c37ff72b56e6a11c",null,"rc_6bc69a766e875e43",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c1663689211="" class="code-block-decoration header-formatted gds-title-s ng-tns-c1663689211-81 ng-star-inserted"><span class="ng-tns-c1663689211-81">PHP</span><div _ngcontent-ng-c1663689211="" class="buttons ng-tns-c1663689211-81 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c1663689211-81 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c1663689211="" class="formatted-code-block-internal-container ng-tns-c1663689211-81"><div _ngcontent-ng-c1663689211="" class="animated-opacity ng-tns-c1663689211-81">  
</div></div></div>```php
<?php
/**
 * Funció que processa el shortcode [banner]
 * @param array $atts Paràmetres passats pel shortcode
 * @param string $content Contingut tancat dins el shortcode
 * @return string HTML del banner carregat des del template
 */
function bp_shortcode_banner( $atts, $content = null ) {
    
    // 1. Definir els valors per defecte i processar paràmetres
    $params = shortcode_atts( 
        array(
            'titol'   => 'Benvingut!', 
            'tipus'   => 'informatiu', 
            'color'   => '#0073aa', 
        ), 
        $atts, 
        'banner' 
    );
    
    // Extreure els paràmetres per utilitzar-los com a variables al template
    // Les variables $titol, $tipus, $color, $content estaran disponibles al template.
    extract( $params );
    
    // Afegir el contingut del shortcode a la variable $content si existeix
    $content = do_shortcode( $content ); 

    // 2. Iniciar el Buffer de Sortida de PHP
    ob_start();
    
    // 3. Incloure el template
    // Aquest fitxer tindrà accés a totes les variables que hem extret (p.ex., $titol, $color)
    include BP_PATH . 'templates/banner-template.php'; 
    
    // 4. Capturar el contingut del buffer i netejar-lo
    // El contingut HTML generat pel template.php es guarda a $output
    $output = ob_get_clean();

    // 5. Retornar l'HTML
    return $output;
}

// Enregistrem el shortcode
add_shortcode( 'banner', 'bp_shortcode_banner' );

```

<div _ngcontent-ng-c1663689211="" class="code-block ng-tns-c1663689211-81 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_195d4914994f79e2","c_c37ff72b56e6a11c",null,"rc_6bc69a766e875e43",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c1663689211="" class="formatted-code-block-internal-container ng-tns-c1663689211-81"><div _ngcontent-ng-c1663689211="" class="animated-opacity ng-tns-c1663689211-81"></div></div></div>### Output buffer

Les funcions **`ob_start()`** i **`ob_get_clean()`** de PHP s'utilitzen per gestionar el **Buffer de Sortida (*Output Buffer*)**. Aquesta tècnica és crucial en entorns com WordPress per capturar la sortida d'un codi (normalment HTML) en lloc d'enviar-la directament al navegador, permetent-te manipular-la o, com en el teu cas, retornar-la.

#### `ob_start()` (Output buffer start)

<div _ngcontent-ng-c1868495127="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-qu%C3%A8-fa%3A-activa-el-bu" inline-copy-host="">- **Què fa:** Activa el *buffer* de sortida. A partir d'aquest moment, **tota la sortida** generada (amb `echo`, `print`, o HTML pur inclòs) no s'envia al navegador.
- **On va la sortida:** En lloc d'això, s'emmagatzema internament en una memòria intermèdia (el *buffer*).

</div>#### `ob_get_clean()` (Output buffer get and clean)

<div _ngcontent-ng-c1868495127="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-qu%C3%A8-fa%3A-t%C3%A9-dues-acci" inline-copy-host="">- **Què fa:** Té dues accions clau:
    
    
    1. **Obté:** Recupera tot el contingut que s'ha emmagatzemat al *buffer* des de l'últim `ob_start()`.
    2. **Neteja:** Elimina i descarta la memòria intermèdia, i la desactiva.
- **Resultat:** La funció **retorna** tot el contingut capturat com una **cadena de text (`string`)**.

</div>#### Que fa dins el plugin?

En el plugin, s'utilitza de la següent manera:

<div _ngcontent-ng-c1868495127="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-la-funci%C3%B3-del-shortc" inline-copy-host="">1. La funció del *shortcode* fa `ob_start()`.
2. Després, fa un **`include`** del fitxer de plantilla (`banner-template.php`). L'HTML d'aquesta plantilla es queda al *buffer*.
3. Finalment, fa un **`ob_get_clean()`**. Això recupera l'HTML de la plantilla com a *string* i desactiva el *buffer*.
4. Aquesta *string* es retorna amb **`return $output;`**, que és el format que WordPress espera d'un *shortcode* per inserir el contingut al lloc correcte de la pàgina.

</div>En essència, és com posar tot el codi de presentació en una "caixa virtual" i després tancar la tapa per obtenir el resultat final com un paquet compacte que es pot moure i retornar.

<div _ngcontent-ng-c1868495127="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2" inline-copy-host=""></div>## L'arxiu presentació (`templates/banner-template.php`)

Aquest fitxer **només conté HTML i referències a les variables** que hem preparat a `shortcode.php`. És molt més fàcil de llegir, mantenir i modificar per a dissenyadors sense trencar la lògica PHP. Hem de considerar que les variables `$titol`, `$color`, `$tipus` i `$content` provenen de la funció `bp_shortcode_banner` que ha utilitzat `extract()`.

<div _ngcontent-ng-c1868495127="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3" inline-copy-host=""></div><div _ngcontent-ng-c1663689211="" class="code-block ng-tns-c1663689211-82 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-php-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_195d4914994f79e2","c_c37ff72b56e6a11c",null,"rc_6bc69a766e875e43",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c1663689211="" class="code-block-decoration header-formatted gds-title-s ng-tns-c1663689211-82 ng-star-inserted"><span class="ng-tns-c1663689211-82">PHP</span><div _ngcontent-ng-c1663689211="" class="buttons ng-tns-c1663689211-82 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c1663689211-82 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c1663689211="" class="formatted-code-block-internal-container ng-tns-c1663689211-82"><div _ngcontent-ng-c1663689211="" class="animated-opacity ng-tns-c1663689211-82">  
</div></div></div>```php
<?php 
// Per seguretat, evitem l'accés directe al fitxer de template
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

// Preparem la classe CSS
$classe_css = 'bp-banner bp-' . sanitize_html_class( $tipus );
?>

<div class="<?php echo $classe_css; ?>" style="border-left-color: <?php echo esc_attr($color); ?>;">
    
    <h3><?php echo esc_html( $titol ); ?></h3>
    
    <?php if ( ! empty( $content ) ) : ?>
        <p><?php echo $content; ?></p>
    <?php else : ?>
        <p>Aquest és un missatge de banner per defecte.</p>
    <?php endif; ?>
    
    <button class="bp-tanca-btn">Tanca Banner &times;</button>
    
</div>
```

<div _ngcontent-ng-c1663689211="" class="code-block ng-tns-c1663689211-82 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_195d4914994f79e2","c_c37ff72b56e6a11c",null,"rc_6bc69a766e875e43",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c1663689211="" class="formatted-code-block-internal-container ng-tns-c1663689211-82"><div _ngcontent-ng-c1663689211="" class="animated-opacity ng-tns-c1663689211-82"></div></div></div><div _ngcontent-ng-c1868495127="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5" inline-copy-host=""></div>Amb aquesta tècnica, has millorat significativament l'arquitectura del teu plugin, separant responsabilitats i facilitant futurs canvis en el disseny (HTML/CSS) sense haver de tocar la lògica de processament dels paràmetres (PHP).

<div _ngcontent-ng-c1868495127="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6" inline-copy-host=""></div>