Javascript ile Basit Timeline Websitesi
Timeline Web Sitesi Projesi
JSON, HTML, CSS, Javascript kullanarak basit bir zaman çizgisi web sitesi yapıyoruz. Buradaki amacımız, JSON ve Javascript yapılarının çalışma mantığını kavrayabilmektir.
Proje Hedefleri
- JavaScript ile JSON üzerinden veri fetch etmek
- Javascript ile alınan öğeleri web sayfası üzerinde HTML Element yapılarına dönüştürmek
- HTTP Server ve yardımcı araçlar kullanarak projedeki verilerin otomatik olarak güncellenmesini sağlamak
Proje Gereksinimleri
Projede kullanacağımız veri yapıları ve diller aşağıda listelenmiştir.
- Python : Geçici olarak bir http server yapısı kurabilmek için built-in Python kütüphanelerinden faydalanacağız.
- Javascript : Projemizdeki fetch işlemleri için script yapılarımızı tutacağız.
- HTML : Projemizin omurgasını oluşturacak yapı olacaktır.
- CSS : Projemize görsellik ekleyeceğiz.
- JSON : Projemizdeki verileri API response'ları benzeri JSON listeleri halinde tutacağız.
HTML Dosyasının Yazımı
HTML dosyasını yazarken dikkat edeceğimiz en önemli husus id=timeline
olan bir öğe oluşturmaktır.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Turkish History</title>
</head>
<body>
<h1>Turkey Historical Timeline</h1>
<div id="timeline"></div>
<!-- the components here -->
<script src="script.js"></script>
</body>
</html>
Yukarıdaki HTML dosyasında <body>
içerisinde bir <div ="timeline">
oluşturuyoruz. Script yazım aşamasında öğelerimizi bu div içerisinde görüntüleyeceğiz.
JSON Verileri
Burada kendimize göre bir veri yazım formatı belirledikten sonra JSON array içerisinde verilerimizi görüntüleyeceğiz.
[
{
"year": "527",
"event": "Justinian I Become Emperor",
"description": "Justinian I ascends to the throne and begins his reign."
},
{
"year": "541",
"event": "Plague of Justinian",
"description": "A deadly pandemic sweeps through the Byzantine Empire"
},
{
"year": "565",
"event": "Death of Justinian I",
"description": "End of Justinian I’s rule and transition of power."
},
{
"year": "532",
"event": "Hagia Sophia builded!",
"description": "Hagia Sophia Builded under the rule of Justinian I"
}
]
JavaScript Fonksiyonları
Bu aşamada JSON verilerimize bağlanıp bu verileri sistemde görüntüleyeceğiz.
// INFO: DOMContentLoaded -> DOM içerikleri yüklendiği anda fonksiyonu devreye alacak bir EventListener ekliyoruz
document.addEventListener("DOMContentLoaded", loadTimeline);
//INFO: Fonksiyonumuzu tanımlıyoruz.
function loadTimeline() {
// data.json isimli dosyadan verileri fetch ediyoruz
fetch("data.json")
.then((response) => response.json())
.then((data) => renderTimeline(data))
.catch((error) => console.error("Error loading JSON:", error));
}
// INFO: data ile ilgili işlemleri yapmak üzere _renderTimeline_ isimli bir fonksiyon daha tanımlıyoruz.
function renderTimeline(data) {
const timeline = document.getElementById("timeline");
// INFO: data.json verilerini tarihlere gore sıralar
data.sort((a, b) => parseInt(a.year) - parseInt(b.year));
// INFO: data içerisinde yer alan her öğe için aşağıdaki işlemleri gerçekleştir diye forEach döngüsü oluşturuyoruz.
data.forEach((event) => {
const eventDiv = document.createElement("div");
eventDiv.classList.add("timeline-item");
eventDiv.innerHTML = `<h3>${event.year}</h3><p><strong>${event.event}</strong></p><p>${event.description}</p>`;
timeline.appendChild(eventDiv);
});
}
Yukarıdaki JavaScript dosyamızı script.js
ismiyle proje klasörümüze oluşturup kaydediyoruz. Yorum satılarında hangi kısmın ne işe yaradığını anlatmaya çalıştım. Çalışma prensibine ait diyagram aşağıdadır:
graph TD;
loadTimeline --> | adds results to _Event Listener_ trigger | EventListener;
data.json --> | fetch data to _script.js_ | loadTimeline;
renderTimeline --> | creates HTML elements using **innerHTML** and puts data as _Child_ element | loadTimeline;
EventListener --> | sends data to _main.html_ using trigger _DomContentLoaded_ | main.html;
CSS - Görsel Düzenlemeler
Bu aşamada projede yapacağımız görsel düzenlemeler yer alıyor. Burada tasarım yeteneklerinize bağlı olarak dosya içeriğini düzenleyebilirsiniz.
Projenin Çalıştırılması ve Test Edilmesi
Bu aşamada HTTP Server kullanarak testler gerçekleştireceğiz.
Python ile Web Server Kurmak
Projemizi doğrudan Firefox, Chrome benzeri tarayıcılardan açmak istediğimizde F12 ile console
yapısına erişim sağladığımızda hata mesajı ile karşılıyoruz. Bu hata mesajının sebebi, CORS isimli sistemin header yüklemesi sırasında data.json
dosyasını yüklemediğimiz için bir aracıya ihtiyac duymasıdır.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at file:///home/gokayburuc/Documents/ws/web_development/turkey-timeline-project/data.json. (Reason: CORS request not http).
Hata mesajı olarak bu tarz bir mesajla karşılaşıyoruz.
Reason: CORS request not HTTP
[[CORS-Javascript]] kısaca cross-origin iletilerinde nelerin görüntülenip görüntülenmeyeceğini denetleyen yapıdır. JSON dosyasındaki verileri görüntüleyebilmek için bir HTTP Server üzerinden derlememiz gerektiği konusunda bizi uyarıyor.
graph TD;
main_html -->|"Served by"| PythonHTTPServer;
script_js -->|"Served by"| PythonHTTPServer;
data_json -->|"Fetched by"| script_js;
style_css -->|"Served by"| PythonHTTPServer;
PythonHTTPServer -->|"Renders in"| WebBrowser;
Çözüm için birden fazla alternatif var ilk olarak Python ile olan çözümü paylaşıyorum.
Terminal üzerinden aşağıdaki komutu yazın:
pyhon3 -m http.server 8000
Sonrasında tarayıcınızın arama çubuğuna aşağıdaki metni yazın:
localhost:8000
Rust ile Web Server Kurmak
Eğer Python ile arayüz kullanmak istemezseniz Rust ile de aynı işlemi gerçekliştirebilirsiniz.
Öncelikle bir rust crate'i olan miniserve indiriyoruz.
cargo install miniserve
Daha sonra ise miniserve
ile 8000 numaralı portta local klasördeki her şeyi görüntülüyoruz.
miniserve . --port 8000
Kişisel olarak Rust ile kurulan HTTP Server yapılarını diğer yapılara nazaran daha iyi buluyorum.
Eğer kurulum ve çalıştırmayı birleştirmek istiyorsanız &&
ampersand işaretleri ile sıralı hale edebilirsiniz.
cargo install miniserve && miniserve . --port 8080
Eğer tüm değişimleri anlık olarak ekranı yenilemeden görmek istiyorsanız Live Server özelliğine ihtiyacınız olacaktır. VSCode içerisinde eklenti olarak gelen bu özellik, Rust Programlama dilinde watchexec-cli isimli bir paket sayesinde gerçekleştirilir.
Node.js ile Web Server Kurmak
Node ile proje klasöründeyken aşağıdaki komutla yine bir HTTP Server başlatabilirsiniz.
npx http-server -p 8080
Eğer sisteminizde http-server
yüklü değilse ilk olarak sistem genelinde -g
seçeneği ile yüklemeniz gerekir.
npm install -g http-server
GO ile Web Server Kurmak
GO ile HTTP Server kurmak için benzer bir yol izliyoruz. Fakat bu sefer ya main.go isimli bir dosya oluşturuyoruz ya da aşağıdaki kodu proje klasörümüzde çalıştırıyoruz.
go run -e 'package main; import . "net/http"; func main() { ListenAndServe(":8080", FileServer(Dir("."))) }'
eğer go ile projenizde bir HTTP Server çalıştırmak istiyorsanız:
# timeline/http-server isimli bir go projesi başlatıyoruz.
go mod init timeline/http-server
burada main.go
isimli bir dosya oluşturup aşağıdaki kodu giriyoruz.
package main
import . "net/http"
func main(){
ListenAndServe(":8080",FileServer(Dir(".")))
}
Script dosyamızı kaydettikten sonra çalıştırmak için :
go run main.go
Projenin Uygulaması
Geliştirmeye Açık Özellikler
Projemiz temel seviye bir proje olup çeşitli özellikler eklenerek geliştirilmeye açıktır:
- Auto Refresh: Belirli aralıklarla
data.json
üzerindeki değişiklikleri kontrol eden bir fonksiyon yazılabilir. - Dasboard: JSON üzerindeki değişiklikleri görüntüleyebilecek bir Dasboard
- Middleware: JSON dosyamıza veri girişini yönetebileceğimiz JavaScript, Python, Rust, GO gibi dillerle yazılmış bir middleware (Alternatif olarak Olay Ekle ve Sil butonları da kullanılabilir)
- CSS: Görsellik açısından bir tasarım belirlenip responsive bir hale getirilebilir.
- Date Sort: data.json dosyası düzenlenerek ve script.js dosyası güncellenerek, gün ay yıl olarak sıralama yaptırılabilir. Ayrıca öğeler
h2
yıl öğeleri altında gruplandırılmış olarak görüntülenebilir.