Blog Ana Sayfası

Şimdi son gönderileri gösteren bir ana sayfa oluşturacağız.

Başlamadan önce, Model-View-Presenter tasarım deseninin (MVC benzeri) en azından temellerini bilmek gerekir:

  • Model – verilerle çalışan katman. Uygulamanın geri kalanından tamamen ayrılmıştır. Yalnızca presenter ile iletişim kurar.
  • View – ön uç katmanı. İstenen verileri şablonlar kullanarak oluşturur ve kullanıcıya gösterir.
  • Presenter (veya Controller) – bağlantı katmanı. Presenter, Model ve View'u birbirine bağlar. İstekleri işler, Model'den veri sorgular ve bunları View'a geri döndürür.

Blogumuz gibi basit uygulamalar durumunda, tüm model katmanı yalnızca veritabanı sorgularından oluşacaktır – bunun için henüz ekstra koda ihtiyacımız yok. Başlangıç olarak, yalnızca presenter'ları ve şablonları oluşturacağız. Nette'de her presenter'ın kendi şablonları vardır, bu yüzden onları aynı anda oluşturacağız.

Adminer Kullanarak Veritabanı Oluşturma

Verileri depolamak için MySQL veritabanını kullanacağız, çünkü web uygulaması programcıları arasında en yaygın olanıdır. Ancak kullanmak istemiyorsanız, kendi seçiminize göre bir veritabanı seçmekten çekinmeyin.

Şimdi blogumuzun makalelerinin saklanacağı veritabanı yapısını hazırlayacağız. Çok basit başlayacağız – yalnızca gönderiler için bir tablo oluşturacağız.

Veritabanını oluşturmak için Adminer'ı veya veritabanlarını yönetmek için favori aracınızı indirebiliriz.

Adminer'ı açalım ve quickstart adında yeni bir veritabanı oluşturalım.

posts adında yeni bir tablo ve şu sütunlarla oluşturalım:

  • id int, autoincrement (AI) işaretleyin
  • title varchar, uzunluk 255
  • content text
  • created_at timestamp

Sonuç yapısı şöyle görünmelidir:

CREATE TABLE `posts` (
	`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
	`title` varchar(255) NOT NULL,
	`content` text NOT NULL,
	`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB CHARSET=utf8;

InnoDB depolama alanını kullanmak gerçekten önemlidir. Birazdan nedenini göstereceğiz. Şimdilik, sadece seçin ve kaydet'e tıklayın.

Uygulama aracılığıyla veritabanına makale ekleme seçeneği oluşturmadan önce, bloga manuel olarak birkaç örnek makale ekleyin.

INSERT INTO `posts` (`id`, `title`, `content`, `created_at`) VALUES
(1,	'Article One',	'Lorem ipusm dolor one',	CURRENT_TIMESTAMP),
(2,	'Article Two',	'Lorem ipsum dolor two',	CURRENT_TIMESTAMP),
(3,	'Article Three',	'Lorem ipsum dolor three',	CURRENT_TIMESTAMP);

Veritabanına Bağlanma

Veritabanı oluşturulduğuna ve içinde birkaç makale sakladığımıza göre, onları güzel yeni sayfamızda göstermenin tam zamanı.

Öncelikle uygulamaya hangi veritabanını kullanacağını söylemeliyiz. Veritabanı bağlantısını config/common.neon dosyasında DSN ve giriş bilgileri kullanarak ayarlayacağız. Şöyle görünmelidir:

database:
	dsn: 'mysql:host=127.0.0.1;dbname=quickstart'
	user: *buraya kullanıcı adını girin*
	password: *buraya veritabanı şifresini girin*

Bu dosyayı düzenlerken satır girintisine dikkat edin. NEON formatı hem boşluklarla hem de sekmelerle girintiyi kabul eder, ancak ikisini aynı anda kabul etmez. Web Projesi'ndeki varsayılan yapılandırma dosyası sekmeleri kullanır.

Veritabanı Bağlantısını Aktarma

Makalelerin listelenmesinden sorumlu olacak HomePresenter, veritabanına bir bağlantıya ihtiyaç duyar. Bunu elde etmek için, şöyle görünecek bir yapıcı kullanacağız:

<?php
namespace App\Presentation\Home;

use Nette;

final class HomePresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}

	// ...
}

Veritabanından Gönderileri Yükleme

Şimdi gönderileri veritabanından yükleyeceğiz ve onları HTML kodu olarak oluşturacak olan şablona göndereceğiz. Bunun için render metodu olarak adlandırılan metot kullanılır:

public function renderDefault(): void
{
	$this->template->posts = $this->database
		->table('posts')
		->order('created_at DESC')
		->limit(5);
}

Presenter şimdi veritabanından verileri şablona (View) aktaran bir render metodu renderDefault() içerir. Şablonlar app/Presentation/{PresenterName}/{viewName}.latte içinde bulunur, bu yüzden bu durumda şablon app/Presentation/Home/default.latte içinde bulunur. Şablonda şimdi veritabanından alınan gönderileri içeren $posts değişkeni mevcut olacaktır.

Şablon

Tüm web sitesi için ana bir şablonumuz (adı layout, başlık, stiller, altbilgi,… içerir) ve her görünüm (View) için belirli şablonlarımız (örneğin, blogdaki gönderileri görüntülemek için) vardır, bunlar ana şablonun bazı bölümlerini geçersiz kılabilir.

Varsayılan olarak, layout şablonu app/Presentation/@layout.latte içinde bulunur ve şunları içerir:

...
{include content}
...

{include content} ifadesi, ana şablona content adlı bloğu ekler. Bunu bireysel görünümlerin (View) şablonlarında tanımlayacağız. Bizim durumumuzda, Home/default.latte dosyasını aşağıdaki gibi düzenleyeceğiz:

{block content}
	Merhaba Dünya
{/block}

Bununla, ana layout'a eklenecek olan content bloğunu tanımladık. Tarayıcıyı tekrar yenilersek, “Merhaba Dünya” metnini içeren bir sayfa göreceğiz (@layout.latte içinde tanımlanan HTML başlığı ve altbilgisi ile kaynak kodunda).

Blog gönderilerini görüntüleyelim – şablonu aşağıdaki gibi düzenleyeceğiz:

{block content}
	<h1>Blogum</h1>

	{foreach $posts as $post}
	<div class="post">
		<div class="date">{$post->created_at|date:'F j, Y'}</div>

		<h2>{$post->title}</h2>

		<div>{$post->content|truncate:256}</div>
	</div>
	{/foreach}
{/block}

Tarayıcıyı yenilersek, tüm gönderilerin bir listesini göreceğiz. Liste henüz pek güzel veya renkli değil, bu yüzden www/css/style.css dosyasına birkaç CSS stili ekleyebilir ve layout'ta bağlayabiliriz:

	...
	<link rel="stylesheet" href="{$basePath}/css/style.css">
</head>
...

{foreach} etiketi, $posts değişkeninde şablona aktardığımız tüm gönderiler üzerinde yinelenir ve her biri için verilen HTML parçasını oluşturur. Tam olarak PHP kodu gibi davranır.

|date: ifadesine filtre diyoruz. Filtreler çıktıyı biçimlendirmek için tasarlanmıştır. Bu özel filtre, tarihi (örneğin 2013-04-12) daha okunabilir bir biçime (April 12, 2013) dönüştürür. |truncate filtresi, dizeyi belirtilen maksimum uzunluğa kırpar ve dize kısaltılırsa sonuna üç nokta ekler. Bu bir önizleme olduğundan, makalenin tüm içeriğini göstermenin bir anlamı yoktur. Diğer varsayılan filtreleri belgelerde bulabiliriz veya gerektiğinde kendi filtrelerimizi oluşturabiliriz.

Bir şey daha var. Önceki kodu kısaltabilir ve basitleştirebiliriz. Bunu Latte etiketlerini n:attributelerle değiştirerek başarırız:

{block content}
	<h1>Blogum</h1>

	<div n:foreach="$posts as $post" class="post">
		<div class="date">{$post->created_at|date:'F j, Y'}</div>

		<h2>{$post->title}</h2>

		<div>{$post->content|truncate:256}</div>
	</div>
{/block}

n:foreach niteliği, div bloğunu foreach ile sarar (önceki kodla tamamen aynı şekilde çalışır).

Özet

Şimdi birkaç gönderi içeren çok basit bir MySQL veritabanımız var. Uygulama bu veritabanına bağlanır ve bu gönderilerin basit bir listesini şablonda görüntüler.