# Site Menüleri

https://dev.wisecp.com/tr/site-menuleri

Beş menü grubunun ağacını kuran, sıralayan ve düzenleyen yedi uç.

## Genel Bakış

Site menüleri **beş ayrı grupta** yaşar: üst menü, alt menü, müşteri paneli, mobil ve kenar çubuğu. Her grup kendi ağacıdır ve öğeler gruplar arasında taşınmaz.

Bir öğe ya **bir sayfaya bağlanır** ya da bağlantısı elle yazılır. Sayfaya bağlanan öğe sayfanın adresi değiştiğinde onu izler; elle yazılan bağlantı olduğu gibi kalır.

Başlık, açıklama, rozet ve mega menü içeriği **dil başına** tutulur. Sıra ve iç içe yerleşim ise ayrı bir uçtan, tek çağrıda yazılır.

## Referans

### Menü Ağacını Getirme

get/api/v1/admin/website/menus

`Website/GetMenus` admin

Bir menü grubunun tamamını iç içe ağaç olarak döndürür.

Sorgu 1

groupstringHangi menü: `header`, `footer`, `mobile`, `sidebar`. `clientArea` hâlâ yanıt verir ama kullanımdan kaldırıldı: hiçbir tema göstermez, yanıt `meta.deprecation` taşır. Öntanımlı olarak üst menü.

Dönen alanlar data[] — 11 + meta — 3

idintÖğenin numarası.

parentintÜst öğe. Sıfır, öğenin en üst düzeyde olduğunu söyler.

typestringÖğenin bulunduğu menü grubu.

iconstringÖğenin simgesi.

rankintKardeşleri arasındaki sırası.

targetboolBağlantının yeni sekmede açılıp açılmayacağı.

statusstringÖğe yayında mı.

pagestringBağlandığı sayfa. Boşsa bağlantı elle yazılmıştır.

only_client_areaboolÖğenin yalnız müşteri panelinde görünüp görünmediği.

languagesobjectDil başına başlık, bağlantı, açıklama, rozet ve mega menü içeriği.

childrenarrayAlt öğeler. Aynı şekli taşır ve iç içe devam eder.

groupstringİstenen menü grubu. Meta altında döner.

countintEn üst düzeydeki öğe sayısı.

deprecationobjectYalnız kullanımdan kaldırılan `clientArea` grubunda: `field`, `value` ve hiçbir temanın göstermediğini söyleyen `message`. Öğe uçları o gruptaki öğe için aynı uyarıyı taşır.

Hatalar 2

invalid_group422Menü grubu tanınmıyor.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl 'https://panel.ornek.com/api/v1/admin/website/menus?group=header' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const url = new URL('https://panel.ornek.com/api/v1/admin/website/menus');
url.searchParams.set('group', 'header');

const res  = await fetch(url, {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/website/menus?' . http_build_query(['group' => 'header']));
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Her grup AYRI bir agactir; hepsini gormek icin bes cagri gerekir.
$header = Api::Website()->GetMenus([], ['group' => 'header'])['data'];
$footer = Api::Website()->GetMenus([], ['group' => 'footer'])['data'];
```

### Sayfa Seçeneklerini Getirme

get/api/v1/admin/website/menus/page-options

`Website/GetMenuPageOptions` admin

Menü öğesinin bağlanabileceği sayfaları döndürür.

Dönen alanlar data

dataarrayBağlanılabilir sayfaların listesi. Sayfa alanına yazılacak anahtarlar buradan alınır.

Hatalar 1

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl 'https://panel.ornek.com/api/v1/admin/website/menus/page-options' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res  = await fetch('https://panel.ornek.com/api/v1/admin/website/menus/page-options', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/website/menus/page-options');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Anahtarlari koda gomme: liste kurulumun sayfalarina gore degisir.
$options = Api::Website()->GetMenuPageOptions()['data'];
```

### Menüyü Yeniden Sıralama

put/api/v1/admin/website/menus/reorder

`Website/ReorderMenus` admin sıra ve üst öğe birlikte

Menü öğelerinin sırasını ve iç içe yerleşimini tek çağrıda yazar.

Gövde 1

ordersarrayreqÖğelerin yeni yerleşimi. Her girdi numarayı, konumu ve üst öğeyi taşır; alt öğeler kendi listesiyle iç içe verilir.

Dönen alanlar data — 1

reorderedintKaç öğenin yazıldığı. Alt öğeler de sayılır.

Hatalar 2

orders_required422Hiç öğe gönderilmedi.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X PUT 'https://panel.ornek.com/api/v1/admin/website/menus/reorder' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"orders":[{"id":10,"position":0,"parentId":0,"submenuOrder":[{"id":11,"position":0,"parentId":10}]}]}'
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/website/menus/reorder', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    orders: [
      {
        id: 10,
        position: 0,
        parentId: 0,
        submenuOrder: [{ id: 11, position: 0, parentId: 10 }],
      },
    ],
  }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/website/menus/reorder');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'orders' => [[
            'id'           => 10,
            'position'     => 0,
            'parentId'     => 0,
            'submenuOrder' => [['id' => 11, 'position' => 0, 'parentId' => 10]],
        ]],
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Gonderilmeyen oge OLDUGU YERDE kalir: eksik liste agaci yari-tasinmis birakabilir.
$r = Api::Website()->ReorderMenus(['orders' => $tree]);
$written = $r['data']['reordered'];
```

### Menü Öğesi Detayı

get/api/v1/admin/website/menus/{id}

`Website/GetMenu` admin

Tek bir menü öğesini dilleriyle döndürür.

Dönen alanlar data — 11

idintÖğenin numarası.

parentintÜst öğe. Sıfır, öğenin en üst düzeyde olduğunu söyler.

typestringÖğenin bulunduğu menü grubu.

iconstringÖğenin simgesi.

rankintKardeşleri arasındaki sırası.

targetboolBağlantının yeni sekmede açılıp açılmayacağı.

statusstringÖğe yayında mı.

pagestringBağlandığı sayfa. Boşsa bağlantı elle yazılmıştır.

only_client_areaboolÖğenin yalnız müşteri panelinde görünüp görünmediği.

languagesobjectDil başına başlık, bağlantı, açıklama, rozet ve mega menü içeriği.

childrenarrayAlt öğeler. Aynı şekli taşır ve iç içe devam eder.

Hatalar 2

menu_not_found404Menü öğesi bulunamadı.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl 'https://panel.ornek.com/api/v1/admin/website/menus/10' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res  = await fetch(`https://panel.ornek.com/api/v1/admin/website/menus/${id}`, {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/website/menus/' . $id);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Alt ogeler listesi burada BOS gelir; agaci gormek icin grup ucunu kullanin.
$item = Api::Website()->GetMenu(['id' => $id])['data'];
```

### Menü Öğesi Ekleme

post/api/v1/admin/website/menus

`Website/CreateMenu` admin

Bir menüye yeni öğe ekler.

Gövde 7

groupstringreqÖğenin gireceği menü: `header`, `footer`, `mobile`, `sidebar`. `clientArea` kullanımdan kaldırıldı: öğe kaydedilir ama hiçbir yerde görünmez, yanıt `meta.deprecation` taşır ve API v2 bu grubu reddedecek. Müşteri paneli menüsüne bağlantı eklemek için eklentinize müşteri sayfası verin ya da `ui:client.subnav.items` kancasını kullanın.

parentintÜst öğe. Verilmezse öğe en üst düzeye girer.

pagestringBağlanacak sayfa. Boş bırakılırsa bağlantıyı dil alanına elle yazarsınız.

iconstringÖğenin simgesi.

targetintBağlantıyı yeni sekmede açar.

rankintKardeşleri arasındaki sırası.

languagesobjectDil başına içerik: başlık, bağlantı, açıklama, rozet metni ile renkleri ve mega menü içeriği.

Dönen alanlar 201 — data — 11

dataobjectOluşan menü öğesi. Detay ucuyla aynı şekildedir.

Hatalar 3

invalid_group422Menü grubu tanınmıyor.

create_failed500Öğe oluşturulamadı.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X POST 'https://panel.ornek.com/api/v1/admin/website/menus' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"group":"header","page":"home","languages":{"tr":{"title":"Ana Sayfa"}}}'
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/website/menus', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    group: 'header',
    page: 'home',
    languages: {
      en: { title: 'Home', description: 'Back to homepage', label: 'New' },
    },
  }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/website/menus');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'group'     => 'header',
        'page'      => 'home',
        'languages' => ['en' => ['title' => 'Home']],
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Baslik DIL BASINA yazilir; eksik biraktiginiz dilde oge bos etiketle gorunur.
Api::Website()->CreateMenu([
    'group'     => 'header',
    'page'      => 'home',
    'languages' => ['en' => ['title' => 'Home'], 'tr' => ['title' => 'Ana Sayfa']],
]);
```

### Menü Öğesini Güncelleme

patch/api/v1/admin/website/menus/{id}

`Website/UpdateMenu` admin

Menü öğesinin gönderdiğiniz alanlarını değiştirir.

Gövde 6

iconstringÖğenin simgesi.

pagestringBağlanacak sayfa.

targetintBağlantıyı yeni sekmede açar.

rankintKardeşleri arasındaki sırası.

parentintÜst öğe. Öğeyi ağacın başka bir dalına taşır.

languagesobjectDil başına içerik: başlık, bağlantı, açıklama, rozet metni ile renkleri ve mega menü içeriği. Göndermediğiniz alan değerini korur; boş değer onu temizler.

Dönen alanlar data — 11

dataobjectGüncel menü öğesi. Detay ucuyla aynı şekildedir.

Hatalar 2

menu_not_found404Menü öğesi bulunamadı.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X PATCH 'https://panel.ornek.com/api/v1/admin/website/menus/10' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"rank":1,"languages":{"tr":{"title":"Anasayfa"}}}'
```

```javascript
const res = await fetch(`https://panel.ornek.com/api/v1/admin/website/menus/${id}`, {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    rank: 1,
    languages: { en: { title: 'Homepage' } },
  }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/website/menus/' . $id);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'rank'      => 1,
        'languages' => ['en' => ['title' => 'Homepage']],
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Oge baska bir GRUBA tasinamaz; grup alani yalniz olusturmada verilir.
Api::Website()->UpdateMenu(['id' => $id, 'parent' => $newParent]);
```

### Menü Öğesini Silme

delete/api/v1/admin/website/menus/{id}

`Website/DeleteMenu` admin alt öğeler de gider

Menü öğesini ve altındaki bütün öğeleri kaldırır.

Dönen alanlar data — 3

deletedboolSilme çalıştı mı.

idintSilinen öğenin numarası.

removedarraySilinen bütün numaralar. Alt öğeler de bu listede yer alır.

Hatalar 2

menu_not_found404Menü öğesi bulunamadı.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X DELETE 'https://panel.ornek.com/api/v1/admin/website/menus/10' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch(`https://panel.ornek.com/api/v1/admin/website/menus/${id}`, {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const { data } = await res.json();
console.log(data.removed);   // [10, 11]
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/website/menus/' . $id);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Ust ogeyi silmek ALT MENUYU de goturur; once cocuklari baska bir ogeye tasiyin.
$gone = Api::Website()->DeleteMenu(['id' => $id])['data']['removed'];
```

## Tuzaklar

> **Silme alt menüyü de götürür**
> 
> Bir menü öğesini silmek **altındaki bütün öğeleri** de siler. Üst düzey bir başlığı kaldırmak, altındaki bütün bağlantıları menüden çıkarır. Yanıttaki silinenler listesi gerçekte ne gittiğini söyler; alt öğeleri korumak istiyorsanız önce onları başka bir öğenin altına taşıyın.

> **Öğe grup değiştiremez**
> 
> Menü grubu **yalnız oluştururken** verilir; güncelleme onu almaz. Üst menüdeki bir bağlantıyı alt menüye taşımak, onu yeni grupta yeniden oluşturup eskisini silmek demektir. Aynısı yeniden sıralama ucu için de geçerlidir: o yalnız aynı ağaç içinde yer değiştirir.

> **Yeniden sıralama gönderdiğinizle sınırlıdır**
> 
> Sıralama ucu **yalnız listedeki öğeleri** yazar; göndermedikleriniz eski yerinde kalır. Ağacın bir kısmını gönderip gerisini atlamak, menüyü yarı taşınmış bir durumda bırakabilir. Yazılan öğe sayısını dönen değerden okuyup beklediğinizle karşılaştırın.

> **Başlık dil başınadır**
> 
> Menü başlığı her dilde ayrı yazılır. Bir dili atlarsanız öğe o dilde **boş bir etiketle** görünür; kaybolmaz, adsız durur. Yeni bir dil açtığınızda mevcut menü öğelerinin hiçbiri o dilde başlık taşımaz, hepsini gezmeniz gerekir.

> **Sayfa bağı ile elle yazılan bağlantı farklıdır**
> 
> Sayfaya bağlanan bir öğe, sayfanın adresi değiştiğinde onu **kendiliğinden izler**. Elle yazılan bir bağlantı ise olduğu yerde kalır ve sayfa taşınınca kırılır. Kendi sitenizin bir sayfasına gidiyorsanız adresi elle yazmak yerine sayfa alanını kullanın; geçerli anahtarları sayfa seçenekleri ucu verir.

## İlgili Makaleler

- [Site Sayfaları](https://dev.wisecp.com/tr/site-sayfalari)
- [Site Kategorileri](https://dev.wisecp.com/tr/site-kategorileri)
- [Gelen Mesaj Kutusu](https://dev.wisecp.com/tr/gelen-mesaj-kutusu)
