# Elementor: hiányzó tartalom, linkek és saját widgetek

> Mi jelenik meg magától a fordítószerkesztőben, hogyan regisztrálj hiányzó mezőt, mi történik az ismétlődő elemek linkjeivel, és hogyan tehetsz saját widgetet fordíthatóvá.

Ez a fejezet az [Elementor-oldalak fordítása](https://hub.hellowp.io/hu/plugins/sitepress-multilingual-cms/oldalepitok-elementor/) folytatása: azt írja le, mit olvas be a WPML magától, mit kell kézzel regisztrálni, hogyan kezeli a lista típusú widgetek linkjeit, és hogyan lehet saját widgetet fordíthatóvá tenni.

## Ami magától megjelenik a fordítószerkesztőben

Az Advanced Translation Editor (ATE) beállítás nélkül listázza ezeket:

- **Heading**: a címsor szövege.
- **Text Editor**: a bekezdés a benne lévő linkekkel.
- **Button**: a gomb szövege és a linkje.
- **Image**: a képaláírás és a képlink.
- **Container link**: ha a konténer HTML-címkéje `a`, és be van állítva a linkje, a link külön **Link URL** sorként jelenik meg. A konténer mást nem ad a fordításhoz.
- **Kiegészítő widgetek**: a WPML beolvassa a widget vezérlőit, és felsorolja a szöveg-, szövegterület-, vizuális szerkesztő- és linkmezőket, a listák elemeivel együtt. A legtöbb kiegészítő saját `wpml-config.xml` fájlt is mellékel, amit a WPML szintén beolvas.

Az Icon List, a Slides és a Price Table bejegyzéseinek linkjei is megjelennek (lásd lejjebb).

## A hiányzó mező megkeresése

1. Nyisd meg az oldal fordítását: **WPML → Translations**, **Translation Jobs** fül. Az oldal sorában kattints a **Review** (vagy **Continue reviewing**) gombra, majd a lefordított oldal feletti sávban az **Edit translation** hivatkozásra. Ha a WPML felülvizsgálat nélkül teszi közzé az automatikus fordításokat, a sorban a ceruza ikon (**Edit Translation**) van. Ugyanide visz az **Oldalak → Összes oldal** lista nyelvoszlopaiban látható ikon is.
2. Keresd meg a mezőt. A szerkesztő widgetenként csoportosít, például a **Link URL** sor a **Button** csoportban van. Ha egy szöveg vagy link nincs a listán, akkor olyan vezérlőben van, amit a WPML nem olvas: általában egy kiegészítő által egy konténerhez vagy oszlophoz adott vezérlőben.

## Hiányzó mező regisztrálása az egyedi XML-konfigurációban

A konténerhez vagy oszlophoz adott vezérlő nem widgetvezérlő, ezért a WPML nem olvassa magától. A példában egy oszlopot kattinthatóvá tevő kiegészítő a konténerekhez egy **Container Link** vezérlőt ad (link és linkszöveg). A régi oszlopoknál ez a **Column Link**.

1. Nyisd meg a **WPML → Settings** oldalt, és keresd meg a **Custom XML Configuration** részt.
2. Illeszd be a konfigurációt a kódszerkesztőbe. A `name` az elem neve az Elementorban, a mezők pedig a vezérlők kulcsai.

```xml
<wpml-config>
  <elementor-widgets>
    <widget name="container">
      <fields>
        <field type="Container: Link URL" editor_type="LINK">link&gt;url</field>
        <field type="Container: Column link (Make Column Clickable)" editor_type="LINK">column_link&gt;url</field>
        <field type="Container: Column link text (Make Column Clickable)" editor_type="LINE">column_link_text</field>
      </fields>
    </widget>
  </elementor-widgets>
</wpml-config>
```

3. Kattints a **Save** gombra. A **Configuration saved.** üzenet jelenik meg.

Ha `container` bejegyzést adsz meg, hagyd benne az Elementor saját konténerlink-sorát (`link>url`) is, mint a példában, hogy a WPML továbbra is regisztrálja a beépített linket.

### Az oldal frissítése és az új mezők fordítása

1. Mentsd újra az oldalt Elementorban: szerkeszd, módosíts egy szöveget, és kattints a **Publish** gombra. A WPML ekkor újra regisztrálja az oldal sztringjeit.
2. Nyisd meg újra a fordítószerkesztőt. Az új sorok az XML-ben megadott neveket viselik.
3. Fordítsd le a linkszöveget, a link URL-jét hagyd meg, és kattints a **Save and Complete** gombra. A lefordított oldalon a konténerlink a lefordított oldalra mutat.

### Mezők regisztrálása wpml-config.xml fájlban

Ugyanez az XML működik egy `wpml-config.xml` fájlban is, a kiegészítő vagy a téma gyökérmappájában. A WPML ebben a sorrendben egyesíti a konfigurációkat: a saját Elementor-widgetlistája, a népszerű kiegészítőkhöz szolgáltatott konfiguráció, a kiegészítő saját `wpml-config.xml` fájlja, végül a te egyedi XML-ed, ami mindent felülír.

### Automatikus fordítás

Ha a **Translate Everything Automatically** be van kapcsolva, a WPML az oldalt, a widgeteket és a regisztrált mezőket is lefordítja közzétételkor vagy frissítéskor, a WPML AI-fordításával. A regisztrált konténerlink ilyenkor is a lefordított oldalra mutat. Az eredményt az ATE-ben nézheted át. Az oldal nyelvenként egyszer számít fel, a későbbi szerkesztés csak az oldal növekedésével járó szavakat.

### Ha a mező még mindig nem jelenik meg

- Regisztráltad, de nem látszik: mentsd újra az oldalt Elementorban, és nyisd meg újra a szerkesztőt. Ellenőrizd, hogy a **Configuration saved.** üzenet megjelent-e, és hogy a widget neve és a mezőkulcs egyezik-e a kiegészítő vezérlőjével.
- A vezérlő nem szöveg, szövegterület, vizuális szerkesztő (WYSIWYG) vagy URL típusú: regisztráld PHP-val (lásd lejjebb).
- Egy kiegészítő widgetének szövege vagy linkje hiányzik: a kiegészítő saját `wpml-config.xml` fájlja kihagyhatta, és az az irányadó a widgetjeire. Add hozzá a mezőt az egyedi XML-konfigurációban, amit a WPML rá egyesít.
- A mező megjelenik, de a lefordított link az eredeti nyelvre mutat: a céloldal még nincs lefordítva. Fordítsd le, és a link követi.

## Linkek az ismétlődő elemekben (Icon List, Slides, Price Table)

Az Icon List, a Slides és a Price Table widget bejegyzéslistát tartalmaz, és minden bejegyzésnek saját **Link** mezője van (a placeholder: „Type or paste your URL”).

| Widget | Hol van a link |
|---|---|
| Icon List (Elementor, **General** kategória) | **Edit Icon List → Content → Items**: minden elemnek van **Text**, **Icon** és **Link** mezője. |
| Slides (Elementor Pro) | **Edit Slides → Content → Slides**: minden dia **Content** fülén van **Title**, **Description**, **Button Text** és **Link**. Az **Apply Link On** dönti el, hogy az egész dia vagy csak a gomb kattintható. |
| Price Table (Elementor Pro) | **Edit Price Table → Content → Footer**, a **Button Text** alatt. A funkciósoroknak nincs linkjük. |

Az egyetlen mezőben megadott linkek (Button, képlink, Text Editor bekezdésben lévő link) ugyanígy fordulnak. A menülinkek a menü fordítását követik.

### Mit csinál a WPML a linkekkel

- **Belső linkek** (a webhely oldalaira, bejegyzéseire, termékeire): a lefordított oldalon a lefordított célra mutatnak, akármelyik oldalt fordítod előbb. Amíg a célnak nincs fordítása, a link az eredetire mutat, és a fordítás közzétételekor átáll. Nincs mit karbantartani.
- **Külső linkek** (másik webhelyre): változatlanok maradnak, az „új ablakban nyílik” beállítással együtt. A WPML nem tudhatja, van-e a másik webhelynek fordított oldala, ezért az ATE minden linket külön sorként mutat a bejegyzés szövege mellett, ahol átírhatod.

A linkek megtekintése vagy egy külső link módosítása:

1. Nyisd meg a fordítást: **WPML → Translations**, **Translation Jobs** fül, **Review**, majd **Edit translation** (lásd fent).
2. Keresd meg a link sorokat. Minden bejegyzés két sorban jelenik meg: **Text** és **Link URL** az Icon List és a Slides csoportban; a Price Table **Button Link** sort mutat. A belső link az eredeti címet mutatja, a lefordított címet a WPML az oldal megjelenítésekor számolja ki.
3. A belső linkeket hagyd, a külsőt átírhatod. Fordítsd le a szövegeket, és kattints a **Save and Complete** gombra. A lefordított oldalon például az „About” link a francia „About” oldalra mutat.

### Új elem felvétele fordítás után

Ha később új elemet adsz az eredeti oldalhoz, az új elem és a linkje bekerül a fordításba, a már elkészült fordítások megmaradnak.

1. Szerkeszd az eredeti oldalt Elementorral, jelöld ki az Icon List widgetet, és az **Items** alatt kattints az **+ Add Item** gombra. Add meg a szöveget és a linket.
2. Kattints a **Publish** gombra (az Elementor ezt a feliratot tartja meg már közzétett oldalaknál is).
3. Nyisd meg újra a fordítást a **WPML → Translations** oldalról. Az új elem szövege és linkje sorként megjelenik. Fordítsd le a szöveget, és kattints a **Save and Complete** gombra.

### Ha a lefordított link az eredeti nyelvre mutat

- A céloldalnak még nincs fordítása: amint közzéteszed, a link átáll.
- Egy kiegészítő widget linkje nincs a szerkesztőben: a WPML még nem ismeri a vezérlőt. Regisztráld a hiányzó mezőt (lásd fent), és fordítsd újra az oldalt.
- Egy külső link másik webhely lefordított oldalára kellene mutasson: ezt a WPML nem tudhatja, írd át a bejegyzés sorában.

### Fejlesztőknek: linkmezők a wpml-config.xml-ben

Az Elementor az elemlistát ismétlő (repeater) vezérlőnek nevezi. A WPML minden bejegyzés linkvezérlőjét `LINK` mezőtípussal regisztrálja. A kiegészítő widget a linkvezérlőit a saját `wpml-config.xml` fájljában deklarálja `editor_type="LINK"` megadással.

## Saját Elementor-widget fordíthatóvá tétele PHP-val

Kétféle saját widget van:

- **Egyszerű widget**: nincs benne ismétlő mező. A WPML Multilingual Tools bővítményével PHP-kód nélkül is regisztrálható.
- **Összetett widget**: bonyolultabb szerkezetű, egy vagy több ismétlő mezővel.

Az összetett widgetet kétféleképpen teheted fordíthatóvá: ajánlottan a `wpml-config.xml` konfigurációs fájllal, vagy kézzel, PHP-kóddal. A PHP-s módszer lépései:

### 1. WPML-szűrő a widgethez

Minden saját widget bővítményben add hozzá a `wpml_elementor_widgets_to_translate` szűrőt az `init` akció alatt. A WPML ebből tudja meg, mely szövegeket kell fordítani.

```php
add_filter( 'wpml_elementor_widgets_to_translate', [ $this, 'wpml_widgets_to_translate_filter' ] );
```

A szűrő átadja a fordítandó widgettípusok tömbjét (az Elementor alapelemeivel együtt). Az új widgettípusokat ebbe a tömbbe kell felvenni:

```php
public function wpml_widgets_to_translate_filter( $widgets ) {
  $widgets[ $this->get_name() ] = [
     'conditions' => [ 'widgetType' => $this->get_name() ],
     'fields'     => [
        [
           'field'       => 'title',
           'type'        => __( 'Hello World Title', 'hello-world' ),
           'editor_type' => 'LINE'
        ],
     ],
  ];

  return $widgets;
}
```

A `fields` tömb elemei:

| Elem | Jelentés |
|---|---|
| `field` | A mező azonosítója, ugyanaz, mint a vezérlő hozzáadásakor (`Control_stack::add_control`). |
| `type` | A mező típusa: ez a szöveg látszik a fordítószerkesztőben, hogy a fordító tudja, mit fordít. |
| `editor_type` | A szerkesztő mezőtípusa: `LINE` (egy sor), `AREA` (több sor), `VISUAL` (vizuális szerkesztő). Linkhez `LINK`. |

### 2. Saját osztály a fordításokhoz

Bonyolultabb widgetnél hozz létre egy osztályt, és add meg a nevét az `integration-class` mezőben:

```php
public function wpml_widgets_to_translate_filter( $widgets ) {
  $widgets[ $this->get_name() ] = [
     'conditions' => [ 'widgetType' => $this->get_name() ],
     'fields'     => [],
     'integration-class' => 'My_Custom_Widget_WPML_Support',
  ];

  return $widgets;
}
```

### 3. Az IWPML_Page_Builders_Module interfész

Az integrációs osztálynak két függvényt kell megvalósítania. A `get` visszaadja a fordítandó sztringek listáját, az `update` pedig frissíti az Elementor-adatokat, amikor fordítás érkezik.

```php
interface IWPML_Page_Builders_Module {
  public function get( $node_id, $element, $strings );
  public function update( $node_id, $element, WPML_PB_String $string );
}
```

### 4. Ugyanaz a mező többször egy blokkban: field_id

Ha ugyanaz a mező többször szerepel egy blokkban, a `field_id` különbözteti meg az előfordulásokat:

```php
'fields' => [
   'title_1' => [
      'field'       => 'title',
      'field_id'    => 'title_1',
      'type'        => __( 'Hello World Title', 'hello-world' ),
      'editor_type' => 'LINE'
   ],
   'title_2' => [
      'field'       => 'title',
      'field_id'    => 'title_2',
      'type'        => __( 'Hello World Title', 'hello-world' ),
      'editor_type' => 'LINE'
   ],
],
```

### 5. Elemlistát tartalmazó widget: WPML_Elementor_Module_With_Items

Egyes widgetek (például a Slides) elemlistát tartalmaznak, mondjuk több diát címsorral és gombbal. Ha a saját widgeted is ilyen, terjeszd ki a `WPML_Elementor_Module_With_Items` osztályt, és az egyes elemeket külön fordíthatod:

```php
class WPML_Elementor_Slides extends WPML_Elementor_Module_With_Items {

  public function get_items_field() {
     return 'slides';
  }

  public function get_fields() {
     return array( 'heading', 'description', 'button_text' );
  }

  protected function get_title( $field ) {
     switch( $field ) {
        case 'heading':
           return esc_html__( 'Slides: heading', 'wpml-string-translation' );
        case 'description':
           return esc_html__( 'Slides: description', 'wpml-string-translation' );
        case 'button_text':
           return esc_html__( 'Slides: button text', 'wpml-string-translation' );
        default:
           return '';
     }
  }

  protected function get_editor_type( $field ) {
     switch( $field ) {
        case 'heading':
        case 'button_text':
           return 'LINE';
        case 'description':
           return 'VISUAL';
        default:
           return '';
     }
  }
}
```

További példák a WPML core bővítmény `addons/wpml-page-builders/classes/Integrations/Elementor/modules/` mappájában vannak. Az osztályokat az `init` horogra töltsd be: a WPML 4.5-től az `init` előtti betöltés végzetes hibát okoz.
