Mobil Menü

Python ile Kişisel Websitesi Projesi

Bu website; yalnızca yazılım, tasarım ve teknoloji dünyasına dair içerikler sunmakla kalmıyor, aynı zamanda Flask gibi modern web teknolojileri kullanılarak geliştirilmiş dinamik bir platform. Sitenin arka planında çalışan kod yapısını ve teknik detaylarını sizlerle paylaşmak istiyorum.

Sitenin Teknik Altyapısı

Site, aşağıdaki teknolojiler kullanılarak geliştirildi:

  • Flask: Python tabanlı hafif ve esnek bir web framework’ü. Flask, sitenin backend (arka plan) işlemlerini yönetiyor.
  • HTML/CSS: Sitenin frontend (kullanıcı arayüzü) kısmı, modern HTML5 ve CSS3 standartlarına uygun olarak tasarlandı.
  • JSON Veri Saklama: Blog gönderileri, bir JSON dosyasında saklanıyor. Bu sayede, veritabanı kullanmadan bile dinamik içerik yönetimi sağlanıyor.
  • Responsive Tasarım: Sitem, mobil cihazlarda da sorunsuz çalışacak şekilde responsive tasarım ilkelerine uygun olarak geliştirildi.

Kod Yapısı ve Özellikler

Sitenin kod yapısı, basit ancak etkili bir şekilde tasarlandı. İşte sitenin temel özellikleri ve nasıl çalıştığı:

  1. Ana Sayfa (Anasayfa):
    • Flask’ın render_template fonksiyonu kullanılarak, kullanıcıya hoş geldiniz mesajı ve site hakkında genel bilgiler sunuluyor.
    • SEO uyumlu meta etiketleri ve açıklamalar içeriyor.
  2. Blog Sayfası:
    • Blog gönderileri, data/blog_posts.json dosyasında saklanıyor.
    • Yeni gönderi eklemek için bir form bulunuyor. Bu form, Flask’ın request modülü ile işleniyor ve JSON dosyasına kaydediliyor.
    • Gönderiler, tarih ve yazar bilgileriyle birlikte listeleniyor.
    • Gönderi silme özelliği ile kullanıcılar, eski gönderileri silebiliyor.
  3. Projeler Sayfası:
    • Yaptığım projeler, kartlar halinde sunuluyor. Her kart, proje başlığı, açıklaması ve detaylar butonu içeriyor.
    • HTML ve CSS kullanılarak, proje kartları responsive hale getirildi.
  4. Galeri Sayfası:
    • Galeri sayfası, static/images/ klasöründe bulunan resimleri gösteriyor.
    • CSS ile resimler, kullanıcı dostu bir şekilde düzenlendi.
  5. Hakkımda Sayfası:
    • Kişisel bilgilerim ve yeteneklerim, düzenli bir şekilde listeleniyor.
    • Sosyal medya bağlantıları ile iletişim kolaylaştırıldı.
  6. İletişim Sayfası:
    • İletişim formu, Flask’ın POST metodu ile işleniyor.
    • Form gönderildiğinde, kullanıcıya başarı mesajı gösteriliyor.
    • Google Maps entegrasyonu ile konum bilgisi paylaşılıyor.

JSON ile Veri Yönetimi

Blog gönderileri, bir JSON dosyasında saklanıyor. Bu dosya, Flask tarafından okunuyor ve güncelleniyor. Örnek bir JSON yapısı şu şekilde:

[
    {
        "id": 1,
        "title": "Python ile Web Geliştirme",
        "content": "Flask kullanarak nasıl hızlı bir şekilde web uygulamaları geliştirebileceğinizi öğrenin.",
        "author": "Admin",
        "date": "25/10/2023 14:30"
    },
    {
        "id": 2,
        "title": "React Native'e Giriş",
        "content": "Mobil uygulama geliştirme dünyasına adım atın.",
        "author": "Admin",
        "date": "26/10/2023 10:15"
    }
]

SEO Optimizasyonu

Sitem, arama motoru optimizasyonu (SEO) kurallarına uygun olarak geliştirildi. Her sayfa, ilgili anahtar kelimelerle zenginleştirilmiş içerikler ve meta etiketleri içeriyor. Bu sayede, Google gibi arama motorlarında daha iyi sıralanmayı hedefliyor.


Proje Yapısı

Proje klasörünüz şu şekilde olacak:

my_blog/
│
├── app.py
├── requirements.txt
├── static/
│   ├── css/
│   │   └── styles.css
│   └── images/
│       ├── image1.jpg
│       ├── image2.jpg
│       └── image3.jpg
├── templates/
│   ├── base.html
│   ├── index.html
│   ├── blog.html
│   ├── projects.html
│   ├── gallery.html
│   ├── about.html
│   └── contact.html
└── data/
    └── blog_posts.json

1. app.py

Flask uygulamasının ana dosyası:

from flask import Flask, render_template, request, redirect, url_for
import json
import os
from datetime import datetime

app = Flask(__name__)

# Blog gönderilerini yükleme
def load_blog_posts():
    if os.path.exists('data/blog_posts.json'):
        with open('data/blog_posts.json', 'r') as file:
            return json.load(file)
    return []

# Blog gönderilerini kaydetme
def save_blog_posts(posts):
    with open('data/blog_posts.json', 'w') as file:
        json.dump(posts, file, indent=4)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/blog')
def blog():
    posts = load_blog_posts()
    return render_template('blog.html', posts=posts)

@app.route('/add_post', methods=['POST'])
def add_post():
    title = request.form['title']
    content = request.form['content']
    author = "Admin"  # Varsayılan yazar adı
    date = datetime.now().strftime("%d/%m/%Y %H:%M")  # Şu anki tarih ve saat
    posts = load_blog_posts()
    posts.append({'title': title, 'content': content, 'author': author, 'date': date})
    save_blog_posts(posts)
    return redirect(url_for('blog'))

@app.route('/projects')
def projects():
    return render_template('projects.html')

@app.route('/gallery')
def gallery():
    return render_template('gallery.html')

@app.route('/about')
def about():
    return render_template('about.html')

@app.route('/contact', methods=['GET', 'POST'])
def contact():
    if request.method == 'POST':
        name = request.form['name']
        email = request.form['email']
        message = request.form['message']
        # Burada form verilerini işleyebilirsiniz (örneğin, e-posta gönderme).
        return render_template('contact.html', message="Mesajınız gönderildi! Teşekkür ederiz.")
    return render_template('contact.html')

if __name__ == '__main__':
    app.run(debug=True)

2. requirements.txt

Gerekli Python kütüphaneleri:

Flask==2.3.2

3. static/css/styles.css

CSS stil dosyası:

/*
body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f4f4f4;
}

header {
    background-color: #333;
    color: #fff;
    padding: 10px 0;
}

header h1 {
    text-align: center;
}

nav ul {
    list-style-type: none;
    padding: 0;
    text-align: center;
}

nav ul li {
    display: inline;
    margin: 0 15px;
}

nav ul li a {
    color: #fff;
    text-decoration: none;
}

.container {
    width: 80%;
    margin: 0 auto;
    padding: 20px;
    background-color: #fff;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

footer {
    background-color: #333;
    color: #fff;
    text-align: center;
    padding: 10px 0;
    position: fixed;
    width: 100%;
    bottom: 0;
}

form label {
    display: block;
    margin-top: 10px;
}

form input, form textarea {
    width: 100%;
    padding: 10px;
    margin-top: 5px;
}

form button {
    margin-top: 10px;
    padding: 10px 20px;
    background-color: #333;
    color: #fff;
    border: none;
    cursor: pointer;
}

form button:hover {
    background-color: #555;
}

.posts {
    margin-top: 20px;
}

.post {
    background-color: #f9f9f9;
    padding: 15px;
    margin-bottom: 10px;
    border-left: 5px solid #333;
}

.cta-buttons {
    margin-top: 20px;
}

.btn {
    display: inline-block;
    padding: 10px 20px;
    background-color: #333;
    color: #fff;
    text-decoration: none;
    border-radius: 5px;
    margin-right: 10px;
}

.btn:hover {
    background-color: #555;
}

.projects {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
}

.project-card {
    background-color: #f9f9f9;
    padding: 15px;
    border: 1px solid #ddd;
    border-radius: 5px;
    width: 300px;
}

.project-card h3 {
    margin-top: 0;
}

.project-card a {
    display: inline-block;
    margin-top: 10px;
    color: #333;
    text-decoration: none;
    font-weight: bold;
}

.project-card a:hover {
    text-decoration: underline;
}

.gallery {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.gallery img {
    width: 200px;
    height: auto;
    border: 2px solid #333;
    border-radius: 5px;
}

.gallery-item {
    text-align: center;
    margin-bottom: 20px;
}

.gallery-item img {
    width: 100%;
    max-width: 300px;
    border-radius: 10px;
}

.gallery-item p {
    margin-top: 10px;
    font-style: italic;
}

.skills {
    margin-top: 20px;
}

.skills ul {
    list-style-type: square;
    padding-left: 20px;
}

.skills li {
    margin-bottom: 10px;
}

.contact-info {
    margin-bottom: 20px;
}

.map {
    margin-bottom: 20px;
}

.success-message {
    color: green;
    font-weight: bold;
}

@media (max-width: 768px) {
    nav ul li {
        display: block;
        margin: 10px 0;
    }

    .container {
        width: 95%;
    }

    .gallery img {
        width: 100%;
    }

    .projects {
        flex-direction: column;
    }

    .project-card {
        width: 100%;
    }
}
*/

4. HTML Şablonları

templates/base.html

<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Kişisel Blog</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
</head>
<body>
    <header>
        <div class="container">
            <h1>Kişisel Blog</h1>
            <nav>
                <ul>
                    <li><a href="{{ url_for('index') }}">Anasayfa</a></li>
                    <li><a href="{{ url_for('blog') }}">Blog</a></li>
                    <li><a href="{{ url_for('projects') }}">Projeler</a></li>
                    <li><a href="{{ url_for('gallery') }}">Galeri</a></li>
                    <li><a href="{{ url_for('about') }}">Hakkımda</a></li>
                    <li><a href="{{ url_for('contact') }}">İletişim</a></li>
                </ul>
            </nav>
        </div>
    </header>
    <main>
        {% block content %}{% endblock %}
    </main>
    <footer>
        <div class="container">
            <p>&copy; 2023 Kişisel Blog. Tüm hakları saklıdır.</p>
        </div>
    </footer>
</body>
</html>

templates/index.html

{% extends "base.html" %}

{% block content %}
<div class="container">
    <h2>Hoş Geldiniz!</h2>
    <p>Merhaba, ben [Adınız]. Yazılım geliştirme, tasarım ve teknoloji hakkında tutkulu biriyim. Bu blogda, deneyimlerimi, projelerimi ve öğrendiklerimi sizlerle paylaşıyorum.</p>
    <p>Eğer yazılım dünyasına ilgi duyuyorsanız, <a href="{{ url_for('blog') }}">blog yazılarımı</a> okuyabilir veya <a href="{{ url_for('projects') }}">projelerime</a> göz atabilirsiniz.</p>
    <div class="cta-buttons">
        <a href="{{ url_for('blog') }}" class="btn">Blog Yazılarım</a>
        <a href="{{ url_for('contact') }}" class="btn">İletişime Geçin</a>
    </div>
</div>
{% endblock %}

templates/blog.html

{% extends "base.html" %}

{% block content %}
<div class="container">
    <h2>Blog</h2>
    <p>Burada yazılım, tasarım ve teknoloji hakkındaki düşüncelerimi paylaşıyorum.</p>
    <form action="{{ url_for('add_post') }}" method="post">
        <label for="title">Başlık:</label>
        <input type="text" id="title" name="title" required>
        <label for="content">İçerik:</label>
        <textarea id="content" name="content" required></textarea>
        <button type="submit" class="btn">Gönder</button>
    </form>
    <div class="posts">
        {% for post in posts %}
        <div class="post">
            <h3>{{ post.title }}</h3>
            <p><small>{{ post.date }} - {{ post.author }}</small></p>
            <p>{{ post.content }}</p>
        </div>
        {% endfor %}
    </div>
</div>
{% endblock %}

templates/projects.html

{% extends "base.html" %}

{% block content %}
<div class="container">
    <h2>Projeler</h2>
    <p>İşte şimdiye kadar üzerinde çalıştığım bazı projeler:</p>
    <div class="projects">
        <div class="project-card">
            <h3>Kişisel Blog Sitesi</h3>
            <p>Flask ve Python kullanarak geliştirdiğim bu blog sitesi, kişisel deneyimlerimi paylaşmamı sağlıyor.</p>
            <a href="#" class="btn">Detaylar</a>
        </div>
        <div class="project-card">
            <h3>Mobil Uygulama: ToDo List</h3>
            <p>React Native ile geliştirdiğim bu mobil uygulama, kullanıcıların günlük görevlerini takip etmelerine yardımcı oluyor.</p>
            <a href="#" class="btn">Detaylar</a>
        </div>
        <div class="project-card">
            <h3>E-ticaret Sitesi</h3>
            <p>Django ve React kullanarak geliştirdiğim bu e-ticaret sitesi, kullanıcıların ürün satın almalarını sağlıyor.</p>
            <a href="#" class="btn">Detaylar</a>
        </div>
    </div>
</div>
{% endblock %}

templates/gallery.html

{% extends "base.html" %}

{% block content %}
<div class="container">
    <h2>Galeri</h2>
    <p>İşte benim çektiğim bazı fotoğraflar:</p>
    <div class="gallery">
        <div class="gallery-item">
            <img src="{{ url_for('static', filename='images/image1.jpg') }}" alt="Resim 1">
            <p>Manzara Fotoğrafı</p>
        </div>
        <div class="gallery-item">
            <img src="{{ url_for('static', filename='images/image2.jpg') }}" alt="Resim 2">
            <p>Şehir Manzarası</p>
        </div>
        <div class="gallery-item">
            <img src="{{ url_for('static', filename='images/image3.jpg') }}" alt="Resim 3">
            <p>Doğa Yürüyüşü</p>
        </div>
    </div>
</div>
{% endblock %}

templates/about.html

{% extends "base.html" %}

{% block content %}
<div class="container">
    <h2>Hakkımda</h2>
    <p>Merhaba, ben [Adınız]. [Yaşınız] yaşındayım ve [Şehir]'de yaşıyorum. Yazılım geliştirme ve teknoloji benim için bir tutku. Özellikle Python, JavaScript ve mobil uygulama geliştirme alanlarında kendimi geliştiriyorum.</p>
    <p>Şu anda [İş/Okul]'da çalışıyorum/okuyorum ve bu süreçte edindiğim deneyimleri bu blog aracılığıyla sizlerle paylaşıyorum.</p>
    <div class="skills">
        <h3>Yeteneklerim</h3>
        <ul>
            <li>Python</li>
            <li>JavaScript</li>
            <li>React Native</li>
            <li>Flask</li>
            <li>HTML/CSS</li>
        </ul>
    </div>
</div>
{% endblock %}

templates/contact.html

{% extends "base.html" %}

{% block content %}
<div class="container">
    <h2>İletişim</h2>
    {% if message %}
    <p class="success-message">{{ message }}</p>
    {% endif %}
    <p>Bana ulaşmak için aşağıdaki formu kullanabilir veya doğrudan e-posta gönderebilirsiniz.</p>
    <div class="contact-info">
        <p><strong>E-posta:</strong> ornek@email.com</p>
        <p><strong>Telefon:</strong> +90 555 555 55 55</p>
        <p><strong>Adres:</strong> [Şehir], [Ülke]</p>
    </div>
    <div class="map">
        <iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3010.279567726852!2d28.978858315411997!3d41.00846297930046!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x14cab9e7a7777c43%3A0x4c76cf3dcc8b330b!2s%C4%B0stanbul%2C%20T%C3%BCrkiye!5e0!3m2!1str!2s!4v1622549400000!5m2!1str!2s" width="100%" height="300" style="border:0;" allowfullscreen="" loading="lazy"></iframe>
    </div>
    <form method="POST">
        <label for="name">Adınız:</label>
        <input type="text" id="name" name="name" required>
        <label for="email">E-posta:</label>
        <input type="email" id="email" name="email" required>
        <label for="message">Mesajınız:</label>
        <textarea id="message" name="message" required></textarea>
        <button type="submit" class="btn">Gönder</button>
    </form>
</div>
{% endblock %}

5. data/blog_posts.json

Blog gönderilerini saklamak için JSON dosyası:

[]

6. static/images/

Galeri sayfasında kullanılacak resimleri static/images/ klasörüne ekleyin. Örneğin:

  • image1.jpg
  • image2.jpg
  • image3.jpg

Bu resimler, galeri sayfasında gösterilecektir. Eğer resimleriniz yoksa, örnek resimler bulup bu klasöre ekleyebilirsiniz.


7. requirements.txt

Flask’ı yüklemek için gerekli kütüphaneyi belirtin:

Flask==2.3.2

8. Projeyi Çalıştırma Adımları

Projeyi bilgisayarınızda çalıştırmak için aşağıdaki adımları takip edin:

Adım 1: Proje Klasörüne Gidin

Terminalde proje klasörünüze gidin:

cd my_blog

Adım 2: Sanal Ortam Oluşturun (Opsiyonel)

Sanal ortam oluşturarak bağımlılıkları yönetebilirsiniz:

python -m venv venv

Adım 3: Sanal Ortamı Etkinleştirin

  • Windows:
  venv\Scripts\activate
  • macOS/Linux:
  source venv/bin/activate

Adım 4: Gerekli Kütüphaneleri Yükleyin

requirements.txt dosyasındaki kütüphaneleri yükleyin:

pip install -r requirements.txt

Adım 5: Uygulamayı Başlatın

Flask uygulamasını çalıştırın:

python app.py

Adım 6: Tarayıcıda Görüntüleyin

Tarayıcınızda http://127.0.0.1:5000/ adresine giderek sitenizi görüntüleyin.


9. Projenin Çalışır Haldeki Özellikleri

  • Anasayfa: Hoş geldiniz mesajı ve blog/projeler sayfalarına yönlendiren butonlar.
  • Blog Sayfası: Yeni blog gönderileri ekleyebilir ve mevcut gönderileri görüntüleyebilirsiniz.
  • Projeler Sayfası: Proje kartları ve detaylar.
  • Galeri Sayfası: Resimler ve açıklamalar.
  • Hakkımda Sayfası: Kişisel bilgiler ve yetenekler.
  • İletişim Sayfası: İletişim formu ve harita.

10. Ek Özellikler (Opsiyonel)

Projeyi daha da geliştirmek için aşağıdaki özellikleri ekleyebilirsiniz:

a) Kullanıcı Girişi ve Yönetim Paneli

  • Flask-Login veya Flask-User gibi kütüphanelerle kullanıcı girişi ekleyebilirsiniz.
  • Yalnızca yetkili kullanıcıların blog gönderisi eklemesine izin verebilirsiniz.

b) Yorum Sistemi

  • Blog gönderilerine yorum ekleyebilirsiniz.
  • Yorumları veritabanında saklayabilirsiniz.

c) Veritabanı Entegrasyonu

  • SQLite, PostgreSQL veya MySQL gibi bir veritabanı kullanarak verileri kalıcı hale getirebilirsiniz.
  • Flask-SQLAlchemy gibi bir ORM kütüphanesi kullanabilirsiniz.

d) Dosya Yükleme Sistemi

  • Galeri sayfasına resim yükleme özelliği ekleyebilirsiniz.
  • Flask-Uploads gibi bir kütüphane kullanabilirsiniz.

e) SEO Optimizasyonu

  • Meta etiketleri ve açıklamalar ekleyerek sitenizin arama motorlarında daha iyi sıralanmasını sağlayabilirsiniz.

Osman Bayrak
Osman Bayrak

Yazılım Mühendisiyim. Teknoloji ve yazılıma meraklıyım.

Articles: 154