# Fluid Template: Yazım Kuralları

TYPO3 v13 için kapsamlı Fluid Template sözdizimi ve yazım kuralları rehberi.

---

## İçindekiler

1. [Giriş](#giriş)
2. [Temel Sözdizimi](#temel-sözdizimi)
3. [Değişkenler ve Veri Tipleri](#değişkenler-ve-veri-tipleri)
4. [ViewHelper'lar](#viewhelperlar)
5. [Koşullar (Conditions)](#koşullar-conditions)
6. [Döngüler (Loops)](#döngüler-loops)
7. [Layout ve Template Yapısı](#layout-ve-template-yapısı)
8. [Partial'lar](#partialler)
9. [Section'lar](#sectionlar)
10. [Namespace Tanımlamaları](#namespace-tanımlamaları)
11. [Format ViewHelper'ları](#format-viewhelperlari)
12. [Escaping ve Güvenlik](#escaping-ve-güvenlik)
13. [En İyi Uygulamalar](#en-iyi-uygulamalar)

---

## Giriş

Fluid, TYPO3'ün modern template motorudur. PHP tabanlı ama XML benzeri bir sözdizimi kullanır. Fluid, MVC (Model-View-Controller) mimarisinin "View" katmanını oluşturur ve HTML çıktısı üretmek için kullanılır.

### Fluid'in Avantajları

- 🎯 **Temiz Sözdizimi**: HTML'e yakın, okunması kolay
- ⚡ **Performanslı**: Compiled template desteği
- 🔧 **Esnek**: ViewHelper'lar ile genişletilebilir
- 🛡️ **Güvenli**: Otomatik XSS koruması

---

## Temel Sözdizimi

### Değişken Çıktısı

Değişkenler süslü parantezler `{}` içinde yazılır:

```html
<h1>{title}</h1>
<p>{content}</p>
```

### Nesne Özelliklerine Erişim

Nokta notasyonu ile nesne özelliklerine erişilir:

```html
<p>Yazar: {post.author.name}</p>
<p>E-posta: {post.author.email}</p>
```

### Dizi Elemanlarına Erişim

```html
<p>İlk Eleman: {myArray.0}</p>
<p>İkinci Eleman: {myArray.1}</p>
```

---

## Değişkenler ve Veri Tipleri

### String (Metin)

```html
{myString}
```

### Integer (Tam Sayı)

```html
{myNumber}
```

### Boolean (Mantıksal)

Fluid 4.0+ ile `{true}` ve `{false}` literal değerleri kullanılabilir:

```html
<f:render section="MySection" optional="{true}" />

{f:render(section: 'MySection', optional: true)}
```

### Array (Dizi)

```html
<!-- Inline dizi tanımlama -->
{f:render(partial: 'MyPartial', arguments: {foo: 'bar', baz: 123})}
```

### NULL Değeri

```html
{f:variable(name: 'myVar', value: null)}
```

---

## ViewHelper'lar

ViewHelper'lar Fluid'in en güçlü özelliğidir. İki farklı sözdizimi ile kullanılabilirler:

### Tag Sözdizimi (Tag Syntax)

XML/HTML benzeri etiketler kullanılır:

```html
<!-- Self-closing (Kendini kapatan) -->
<f:constant name="\Vendor\Package\Class::CONSTANT" />

<!-- İçerikli -->
<f:format.case mode="upper">lowercase</f:format.case>

<!-- İç içe ViewHelper'lar -->
<f:format.trim>
  <f:replace search="foo" replace="bar">
    <f:format.case mode="upper"> {myString} </f:format.case>
  </f:replace>
</f:format.trim>
```

### Inline Sözdizimi (Inline Syntax)

Süslü parantezler içinde kullanılır:

```html
<!-- Basit çağrı -->
{f:constant(name: '\Vendor\Package\Class::CONSTANT')}

<!-- Değer dönüştürme -->
{f:format.case(value: 'lowercase', mode: 'upper')}

<!-- Pipe (Boru) operatörü ile zincirleme -->
{myVariable -> f:format.case(mode: 'upper')}

<!-- Çoklu zincirleme -->
{myString -> f:format.case(mode: 'upper') -> f:replace(search: 'foo', replace:
'bar') -> f:format.trim()}
```

### Çok Satırlı Inline Sözdizimi

Okunabilirlik için trailing comma desteği:

```html
{f:render( partial: 'MyPartial', arguments: { foo: 'bar', baz: 123, }, )}
```

---

## Koşullar (Conditions)

### Temel If Yapısı

```html
<f:if condition="{myObject}"> Bu içerik myObject truthy ise gösterilir </f:if>
```

### Then ve Else Blokları

```html
<f:if condition="{myVar} == 'test'">
  <f:then> Variable is test </f:then>
  <f:else> Variable is something else </f:else>
</f:if>
```

### Sadece Else Bloğu

```html
<f:if condition="{myVar} == 'test'">
  <f:else>Variable is NOT test</f:else>
</f:if>
```

### Çoklu Else-If (Elseif)

```html
<f:if condition="{myVar} == 'test'">
  <f:then>Variable is test</f:then>
  <f:else if="{myVar} == 'foo'">Variable is foo</f:else>
  <f:else if="{myVar} == 'bar'">Variable is bar</f:else>
  <f:else>Variable is something else</f:else>
</f:if>
```

### Switch-Case Yapısı

```html
<f:switch expression="{myVariable}">
  <f:case value="foo">Variable is foo</f:case>
  <f:case value="bar">Variable is bar</f:case>
  <f:defaultCase>Variable is something else</f:defaultCase>
</f:switch>
```

### Karşılaştırma Operatörleri

| Operatör | Açıklama        |
| -------- | --------------- |
| `==`     | Eşitlik         |
| `!=`     | Eşit değil      |
| `>`      | Büyüktür        |
| `<`      | Küçüktür        |
| `>=`     | Büyük veya eşit |
| `<=`     | Küçük veya eşit |
| `%`      | Modulo (Kalan)  |

### Mantıksal Operatörler

| Operatör | Açıklama    |
| -------- | ----------- |
| `&&`     | VE (AND)    |
| `\|\|`   | VEYA (OR)   |
| `!`      | DEĞİL (NOT) |

### Karmaşık Koşullar

```html
<f:if condition="{myNumber} > 3 || {otherNumber} || {somethingElse}">
  <f:then> Koşullardan en az biri doğru </f:then>
  <f:else> Hiçbiri doğru değil </f:else>
</f:if>
```

### Inline Koşul

Özellikle attribute değerlerinde kullanışlıdır:

```html
<div
  class="{f:if(condition: blog.posts, then: 'blogPostsAvailable', else: 'noPosts')}"
>
  ...
</div>
```

### ViewHelper Attribute'larında Boolean Koşul

```html
<my:custom showLabel="{myString} === 'something'"> ... </my:custom>
```

---

## Döngüler (Loops)

### For Döngüsü

```html
<f:for each="{items}" as="item">
  <p>{item.name}</p>
</f:for>
```

### Iterator Kullanımı

```html
<f:for each="{items}" as="item" iteration="iterator">
  <p>
    Index: {iterator.index} | Cycle: {iterator.cycle} | Total: {iterator.total}
    | İlk mi: {iterator.isFirst} | Son mu: {iterator.isLast} | Tek mi:
    {iterator.isOdd} | Çift mi: {iterator.isEven}
  </p>
</f:for>
```

### Iterator Özellikleri

| Özellik   | Açıklama                                  |
| --------- | ----------------------------------------- |
| `index`   | Sıfırdan başlayan index (0, 1, 2...)      |
| `cycle`   | Birden başlayan döngü sayacı (1, 2, 3...) |
| `total`   | Toplam eleman sayısı                      |
| `isFirst` | İlk eleman mı? (boolean)                  |
| `isLast`  | Son eleman mı? (boolean)                  |
| `isOdd`   | Tek sayılı mı? (boolean)                  |
| `isEven`  | Çift sayılı mı? (boolean)                 |

### Key ile For Döngüsü

```html
<f:for each="{items}" as="item" key="itemKey">
  <p>Key: {itemKey} - Value: {item}</p>
</f:for>
```

### Reverse (Ters) Döngü

```html
<f:for each="{items}" as="item" reverse="true">
  <p>{item.name}</p>
</f:for>
```

---

## Layout ve Template Yapısı

### Dizin Yapısı

```
Resources/Private/
├── Layouts/
│   └── PageLayout.html
├── Templates/
│   └── Default.html
└── Partials/
    ├── Header.html
    ├── Footer.html
    └── Content/
        └── Element.html
```

### Layout Dosyası

Layout, sayfanın genel yapısını tanımlar:

```html
<!-- Resources/Private/Layouts/PageLayout.html -->
<!DOCTYPE html>
<html lang="tr">
  <head>
    <title>{pageTitle}</title>
    <f:render section="HeaderAssets" optional="true" />
  </head>
  <body>
    <header>
      <f:render partial="Header" />
    </header>

    <main>
      <f:render section="Main" />
    </main>

    <footer>
      <f:render partial="Footer" />
    </footer>

    <f:render section="FooterAssets" optional="true" />
  </body>
</html>
```

### Template Dosyası

Template, layout'u kullanarak içerik sağlar:

```html
<!-- Resources/Private/Templates/Default.html -->
<f:layout name="PageLayout" />

<f:section name="Main">
  <div id="content">
    <f:render partial="Content" />
  </div>
</f:section>

<f:section name="HeaderAssets">
  <link rel="stylesheet" href="custom.css" />
</f:section>
```

---

## Partial'lar

Partial'lar tekrar kullanılabilir template parçalarıdır.

### Partial Oluşturma

```html
<!-- Resources/Private/Partials/Tags.html -->
<ul class="tags">
  <f:for each="{tags}" as="tag">
    <li>{tag.name}</li>
  </f:for>
</ul>
```

### Partial Çağırma

```html
<f:render partial="Tags" arguments="{tags: post.tags}" />
```

### Tüm Değişkenleri Aktarma

```html
<f:render partial="MyPartial" arguments="{_all}" />
```

### Section İçeren Partial

```html
<!-- Partial with section -->
<f:render
  partial="MyPartial"
  section="SpecificSection"
  arguments="{data: myData}"
/>
```

### Alt Dizindeki Partial

```html
<f:render
  partial="Content/Element"
  arguments="{contentObject: contentObject}"
/>
```

---

## Section'lar

Section'lar template içinde yeniden kullanılabilir bloklar tanımlar.

### Section Tanımlama

```html
<f:section name="MySectionName">
  <p>Bu bir section içeriğidir.</p>
</f:section>
```

### Section Render Etme

```html
<!-- Mevcut template'deki section -->
<f:render section="MySectionName" />

<!-- Arguments ile -->
<f:render section="MySectionName" arguments="{title: 'Başlık'}" />

<!-- Opsiyonel section (yoksa hata vermez) -->
<f:render section="OptionalSection" optional="true" />
```

### Partial İçindeki Section

```html
<f:render partial="MyPartial" section="SpecificSection" />
```

---

## Namespace Tanımlamaları

### Varsayılan Fluid Namespace

`f:` namespace'i varsayılan olarak mevcuttur.

### HTML Attribute ile Tanımlama

```html
<html
  xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
  xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers"
  data-namespace-typo3-fluid="true"
></html>
```

### Inline Namespace Tanımlama

```html
{namespace blog=MyVendor\BlogExample\ViewHelpers}
```

### Namespace Kullanımı

```html
<!-- Varsayılan f: namespace -->
<f:if condition="{myVar}">...</f:if>

<!-- Özel namespace -->
<blog:latestPosts limit="5" />

<!-- TYPO3 Core namespace -->
<core:icon identifier="actions-view-go" />
```

### Yaygın TYPO3 Namespace'leri

| Namespace | Açıklama                   |
| --------- | -------------------------- |
| `f:`      | TYPO3 Fluid ViewHelpers    |
| `core:`   | TYPO3 Core ViewHelpers     |
| `be:`     | Backend ViewHelpers        |
| `fe:`     | Frontend ViewHelpers       |
| `form:`   | Form Framework ViewHelpers |

---

## Format ViewHelper'ları

### f:format.html

Raw HTML çıktısı (escaping kapalı):

```html
<f:format.html>{rawHtmlContent}</f:format.html>
```

### f:format.raw

Ham veri çıktısı:

```html
<f:format.raw>{content}</f:format.raw>
```

### f:format.case

Büyük/küçük harf dönüşümü:

```html
<!-- Büyük harf -->
<f:format.case mode="upper">{myText}</f:format.case>

<!-- Küçük harf -->
<f:format.case mode="lower">{myText}</f:format.case>

<!-- İlk harf büyük -->
<f:format.case mode="capital">{myText}</f:format.case>

<!-- Her kelimenin ilk harfi büyük -->
<f:format.case mode="capitalWords">{myText}</f:format.case>
```

### f:format.trim

Boşlukları temizleme:

```html
<f:format.trim>{myText}</f:format.trim>

<!-- Inline -->
{myText -> f:format.trim()}
```

### f:format.crop

Metni kırpma:

```html
<f:format.crop maxCharacters="100" append="...">{longText}</f:format.crop>
```

### f:format.date

Tarih formatlama:

```html
<f:format.date format="d.m.Y H:i">{dateObject}</f:format.date>

<!-- Türkçe tarih formatı -->
<f:format.date format="d F Y">{dateObject}</f:format.date>
```

### f:format.currency

Para birimi formatlama:

```html
<f:format.currency currencySign="₺" decimalSeparator="," thousandsSeparator="."
  >{price}</f:format.currency
>
```

### f:format.number

Sayı formatlama:

```html
<f:format.number decimals="2" decimalSeparator="," thousandsSeparator="."
  >{number}</f:format.number
>
```

---

## Escaping ve Güvenlik

### Otomatik Escaping

Fluid varsayılan olarak tüm çıktıları escape eder (XSS koruması):

```html
<!-- Otomatik escape edilir -->
{potentiallyDangerousContent}
```

### Escaping'i Devre Dışı Bırakma

> ⚠️ **Dikkat**: Sadece güvenilir içerik için kullanın!

```html
<!-- f:format.raw ile -->
<f:format.raw>{trustedHtmlContent}</f:format.raw>

<!-- f:format.html ile -->
<f:format.html>{trustedHtmlContent}</f:format.html>
```

### Inline Escaping Kontrolü

```html
{trustedContent -> f:format.raw()}
```

---

## En İyi Uygulamalar

### 1. Okunabilirlik

```html
<!-- ❌ Kötü: Tek satırda karmaşık ifade -->
<f:if condition="{a}"><f:then>{b}</f:then><f:else>{c}</f:else></f:if>

<!-- ✅ İyi: Düzgün girintileme -->
<f:if condition="{a}">
  <f:then> {b} </f:then>
  <f:else> {c} </f:else>
</f:if>
```

### 2. Partial Kullanımı

Tekrar eden kod bloklarını partial'lara taşıyın:

```html
<!-- ❌ Kötü: Aynı kod birden fazla yerde -->
<div class="card">
  <h3>{post1.title}</h3>
  <p>{post1.content}</p>
</div>
<div class="card">
  <h3>{post2.title}</h3>
  <p>{post2.content}</p>
</div>

<!-- ✅ İyi: Partial kullanımı -->
<f:for each="{posts}" as="post">
  <f:render partial="Card" arguments="{post: post}" />
</f:for>
```

### 3. Mantık Template'de Olmamalı

Karmaşık mantık PHP tarafında (Controller, ViewHelper) kalmalı:

```html
<!-- ❌ Kötü: Karmaşık mantık template'de -->
<f:if condition="{user.age} > 18 && {user.verified} && {user.subscribed}">
  ...
</f:if>

<!-- ✅ İyi: Controller'da hazırlanmış değişken -->
<f:if condition="{userCanAccess}"> ... </f:if>
```

### 4. Anlamlı Değişken İsimleri

```html
<!-- ❌ Kötü -->
{a} {x} {data.item}

<!-- ✅ İyi -->
{userName} {articleCount} {blogPost.title}
```

### 5. Namespace Organizasyonu

```html
<!-- Template başında tüm namespace'leri tanımlayın -->
{namespace blog=MyVendor\BlogExample\ViewHelpers} {namespace
utils=MyVendor\Utils\ViewHelpers}

<!-- Sonra kullanın -->
<blog:latestPosts />
<utils:formatPrice value="{price}" />
```

### 6. Yorum Kullanımı

```html
<!-- Bu bir Fluid yorumudur ve HTML çıktısında görünmez -->
<f:comment>
  Bu blok tamamen yok sayılır. {expensiveOperation} çalıştırılmaz.
</f:comment>
```

### 7. Debug Modu

Geliştirme sırasında değişkenleri inceleme:

```html
<f:debug>{myVariable}</f:debug>

<!-- İnline -->
{myVariable -> f:debug()}
```

---

## Sık Yapılan Hatalar

### 1. Boşluk Hatası

```html
<!-- ❌ Hatalı: Süslü parantezlerde boşluk -->
{ myVariable }

<!-- ✅ Doğru -->
{myVariable}
```

### 2. Attribute Değerlerinde Tırnak

```html
<!-- ❌ Hatalı: Karışık tırnak kullanımı -->
<f:link.page pageUid="{settings.pageUid}">
  <!-- ✅ Doğru: Tutarlı kullanım -->
  <f:link.page pageUid="{settings.pageUid}"></f:link.page
></f:link.page>
```

### 3. İç İçe Süslü Parantez

```html
<!-- ❌ Hatalı: İç içe değişken erişimi -->
{{myObject}.property}

<!-- ✅ Doğru: Nokta notasyonu -->
{myObject.property}
```

### 4. Inline Sözdiziminde Hata

```html
<!-- ❌ Hatalı: Yanlış parantez -->
{f:format.case(value: myVar, mode: 'upper')}

<!-- ✅ Doğru: Değişken süslü parantez içinde -->
{f:format.case(value: '{myVar}', mode: 'upper')}

<!-- veya pipe operatörü ile -->
{myVar -> f:format.case(mode: 'upper')}
```

---

## Örnek Proje Yapısı

```
my_sitepackage/
├── Configuration/
│   └── TypoScript/
│       └── setup.typoscript
└── Resources/
    └── Private/
        ├── Language/
        │   └── locallang.xlf
        ├── Layouts/
        │   ├── Default.html
        │   └── TwoColumn.html
        ├── Partials/
        │   ├── Navigation/
        │   │   ├── Main.html
        │   │   └── Footer.html
        │   ├── Content/
        │   │   └── Element.html
        │   └── Shared/
        │       └── Pagination.html
        └── Templates/
            ├── Page/
            │   ├── Default.html
            │   └── Home.html
            └── Content/
                ├── Text.html
                └── Image.html
```

---

## TypoScript Yapılandırması

Fluid template yollarını TypoScript ile tanımlama:

```typoscript
module.tx_core.view {
    templateRootPaths {
        0 = EXT:my_sitepackage/Resources/Private/Templates/
    }
    partialRootPaths {
        0 = EXT:my_sitepackage/Resources/Private/Partials/
    }
    layoutRootPaths {
        0 = EXT:my_sitepackage/Resources/Private/Layouts/
    }
}
```

---

## Sonuç

Fluid Template Engine, TYPO3'ün güçlü ve esnek bir parçasıdır. Bu dokümantasyondaki kuralları takip ederek:

- ✅ Okunabilir ve bakımı kolay template'ler yazabilirsiniz
- ✅ Güvenli web sayfaları oluşturabilirsiniz
- ✅ Kodunuzu yeniden kullanılabilir parçalara ayırabilirsiniz
- ✅ TYPO3 topluluğunun standartlarına uygun çalışabilirsiniz

---

## Kaynaklar

- [TYPO3 Fluid Resmi Dokümantasyonu](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Fluid/Index.html)
- [TYPO3 ViewHelper Referansı](https://docs.typo3.org/other/typo3/view-helper-reference/main/en-us/)
- [Fluid GitHub Repository](https://github.com/TYPO3/Fluid)

---

