27 Haziran 2014 Cuma

Bootstrap



  Bootstrap web uygulamalarımızı ekran boyutundan bağımsız bir şekilde yazmamızı sağlayan bir çatı. Yani uygulamayı tek bir web çatısı kullanarak yazıyoruz ve küçük ekran telefonlardan geniş ekran bilgisayarlara kadar her yerde görünümü bozulmadan kullanabiliyoruz. Bu yazımda bir önceki yazımda Flask ile yazdığım basit blog uygulamasının Bootstrapla iyileştirilme aşamalarını anlatacağım.

  Bootstrap'ın Flask için yazılmış bir modülüde mevcut "pip install flask-bootstrap" diyerek kurup öyle kullanılıyor.  Ama bunu kullanmak yazacağımız uygulamanın kullanım alanını daraltabilir. Örneğin eğer uygulama kararlı depoyu kullanan bir sunucu yada bilgisayarda kullanılacaksa yazacağımız uygulamayı buralarda kullanmak istemeyeceklerdir.

  Bootstrap'ın çok fazla bileşeni olduğundan sadece bloğumuz için gerekli olanlardan bahsedeceğim daha ayrıntılı bilgiyi buradan bulabilisiniz.

  Bootstrap'ı uygulayacağımız blog uygulamasını buradan bulabilirsiniz.

*  Öncelikle linkten Bootstrap için gerekli dosyaları indirmeliyiz. İndirdiğiniz dosyayı açarak uygulamamızın içindeki static dizini altına taşımalıyız.

*  .../templates/layout.html dosyasının başına şu satırı ekleyerek kullanacağımız css dosyasının yolunu belirtmiş oluyoruz:

     <link rel=stylesheet type=text/css href="{{ url_for('static', filename='bootstrap-3.1.1-\
dist/css/bootstrap.min.css') }}">

*  Şimdi bootstrap'ın  her ekran boyutunda düzgün görünmesini sağlayan layout özelliğini ekleyeceğiz. Bootstrap uygulamamızı 12 kolon'a kadar ölçekleyebilir. Biz ekranımızı şekilde görüldüğü gibi bölerek orta kolonu kullanacağız.

  Bunun için Bootstrap içindeki .col-md-* sınıfını kullanacağız. Daha küçük ekranlardaki görünümü için .col-xs-* sınıfını kullanacağız. Yine layout.html dosyasına şu kodu ekleyeceğiz:

<div class="row">
  <div class="col-md-4"> İlk bölme </div>
  <div class="col-xs-12 col-md-4"> Orta bölme </div>
  <div class="col-md-4"> Son bölme</div>
</div> 

*  İlk ve son bölmeyi boş bırakacağız. Orta bölmeye kodun layout kısmını içinde kullanıcıya göstereceğimiz kısmı koyacağız. 

* Aynı yerde "log in" ve "log out " butonlarınıda iyileştirmek için  butonların bulunduğu satırı şu şekilde değiştirelim:

 <a class="btn btn-primary btn-lg" role="button" href="{{ url_for('login') }}">log in</a>
 <a class="btn btn-primary btn-lg" role="button" href="{{ url_for('logout') }}">log out</a>

*  .../template/login.html dosyasını açalım ve oradaki kullanıcı adı ve parola kısımlarını ve submit butonunun görünümünü Bootstraptaki sınıfları kullanarak iyileştirmek için form etiketleri arasını aşağıdaki kod ile değiştirelim.

<form action="{{ url_for('login') }}" method=post role="form">
  <div class="form-group">
    <label for="exampleInputEmail1">User name</label>
      <input type="text" name="username" class="form-control"  placeholder="Enter user name please">
  </div>
  <div class="form-group">
    <label for="exampleInputPassword1">Password</label>
      <input type="password" name="password" class="form-control" placeholder="Enter password please">
  </div>
  <div class="metanav">
      <button type="submit" class="btn btn-primary btn-sm">Submit</button>
  </div>
  </form>

*  .../template/show_entries.html dosyasını açalım Yine aynı şekilde formun ve butonların görünümünü iyileştirmek için aşağıdaki form etiketleri içindeki kodu aşağıdaki kod parçasıyla değiştirelim.

  <form action="{{ url_for('add_entry') }}" method=post role="form">
    <div class="form-group">
      <label>Title</label>
        <input type="text" name="title" size=30 class="form-control"  placeholder="Enter title please">
    </div>
    <div class="form-group">
      <label>Text</label>
        <textarea name="text" row=5 cols=40 class="form-control" placeholder="Enter password please"></textarea>
    </div>
    <button type="submit" class="btn btn-primary btn-sm">Submit</button>
  </form>

* Aynı dosya içinde daha önce yazılmış bloglar liste şeklinde görünüyordu. Onların göürünümünü iyileştirmek için tablo kullanmayı tercih ettim. O kısmıda şu şekilde değiştirebiliriz:

<table class="table table-hover">
{% for entry in entries %}
  <tr class="info text-center"><td><h3>{{ entry.title }}</h3>{{ entry.text|safe }}</td></tr>
{% else %}
  <tr class="info text-center"><td><em>Unbelievable. No entries here so far</em></td></tr>
{% endfor %}
</table>

  Artık dosyayı kaydedip bloğu çalıştırdığımızda pencere küçülterek görüntünün bozulmadığını ve bloğun eskisinden daha iyi göründüğünü görebiliriz.

Ek olarak:

  Belki ileride işimiz yarayabilecek bir bileşen "navbar" bileşeni. Hızlıca nasıl çalıştığını layout.html dosyasının başına şu kodu eklediğimizde hızlıca görebiliriz:

<div>
  <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Brand</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Link</a></li>
        <li><a href="#">Link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li><a href="#">Separated link</a></li>
            <li class="divider"></li>
            <li><a href="#">One more separated link</a></li>
          </ul>
        </li>
      </ul>
      <form class="navbar-form navbar-left" role="search">
        <div class="form-group">
          <input type="text" class="form-control" placeholder="Search">
        </div>
        <button type="submit" class="btn btn-default">Submit</button>
      </form>
      <ul class="nav navbar-nav navbar-right">
        <li><a href="#">Link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li><a href="#">Separated link</a></li>
          </ul>
        </li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
  </nav>
</div>



23 Haziran 2014 Pazartesi

Flask ile Blog Uygulaması





Önceki yazımda Flask'ın kurulumunu anlatmıştım. Şimdi Flask kullanarak basitçe bir blog nasıl yazılır adım adım anlatmaya çalışacağım.

  $ mkdir flaskr
  $ cd flaskr
  $ vim schema.sql

  Açılan dosya içine şu satırları ekleyelim:

  drop table if exists entries;
  create table entries (
          id integer primary key autoincrement,
          title text not null,
          text text not null
   );

  Kaydedip çıkalım. Database olarak sqlite3 kullanacağız. Yukarıda blog bilgilerimizi ( id, başlık, gövde ) tutacak basit bir tablo oluşturmak için kullanacağımız dosyayı yazdık. id bilgisi primary key dir ve otomatik olarak artar. Devam edelim.

  $ vim flaskr.py

  Açtığımız dosyaya şu satırları ekliyoruz:

  # Gerekli modülleri dahil ettik
  import os
  import sqlite3
  from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash

  # app adında küçük bir uygulama oluşturduk.
  app = Flask(__name__)
  app.config.from_object(__name__)

  # Uygulama için gerekli yapılandırma bilgilerini ekledik.
  app.config.update(dict(
          DATABASE='/tmp/flaskr.db',
          DEBUG=True,
          SECRET_KEY=’development key’,
          USERNAME=’admin’,
          PASSWORD=’default’
  ))
  app.config.from_envvar(’FLASKR_SETTINGS’, silent=True)

# Özel bir veritabanına bağlantı yapmak için     def connect_db():
          rv = sqlite3.connect(app.config[’DATABASE’])
          rv.row_factory = sqlite3.Row
          return rv

# Veritabanı bağlantısı için gerekli kısım.
  def get_db():
  if not hasattr(g, ’sqlite_db’):
          g.sqlite_db = connect_db()
   return g.sqlite_db

  @app.teardown_appcontext
  def close_db(error):
  if hasattr(g, ’sqlite_db’):
          g.sqlite_db.close()

  # Veritabanını başlatacak kısım
  def init_db():
          with app.app_context():
                  db = get_db()
                  with app.open_resource(’schema.sql’, mode=’r’) as f:
                          db.cursor().executescript(f.read())
                  db.commit()

  # Yazılmış olan blog yazılarını ve başlıklarını görüntüleyecek kısım.
  @app.route(’/’)
  def show_entries():
          db = get_db()
          cur = db.execute(’select title, text from entries order by id desc’)
          entries = cur.fetchall()
          return render_template(’show_entries.html’, entries=entries)

  # Yeni bir blog girdisinin veritabanına girişini sağlayan kısım.
  @app.route(’/add’, methods=[’POST’])
  def add_entry():
          if not session.get(’logged_in’):
                  abort(401)
          db = get_db()
          db.execute(’insert into entries (title, text) values (?, ?)’, [request.form[’title’], request.form[’text’]])
          db.commit()
          flash(’New entry was successfully posted’)
          return redirect(url_for(’show_entries’))

  # Giriş yapmayı sağlayan kısım
  @app.route(’/login’, methods=[’GET’, ’POST’])
  def login():
          error = None
          if request.method == ’POST’:
                  if request.form[’username’] != app.config[’USERNAME’]:
                          error = ’Invalid username’
                  elif request.form[’password’] != app.config[’PASSWORD’]:
                          error = ’Invalid password’
                  else:
                          session[’logged_in’] = True
                          flash(’You were logged in’)
                          return redirect(url_for(’show_entries’))
          return render_template(’login.html’, error=error)


  # Çıkış yapmayı sağlayan kısım
  @app.route(’/logout’)
  def logout():
          session.pop(’logged_in’, None)
          flash(’You were logged out’)
          return redirect(url_for(’show_entries’))

  # Uygulamayı başlatan kısım
  if __name__ == ’__main__’:
          app.run()

    Bu dosyayı kaydedip çıkıyoruz. Komut satırında veri tabanınındaki tablomuzun oluşması için şu komutu  veriyoruz:

  $ sqlite3 /tmp/flaskr.db < schema.sql

  Veri tabanını başlatmak için python kabuğunda şu komutları veriyoruz:

  $ python
  >>> from flaskr import init_db
  >>> init_db()


  Şimdi gereken şablonları ekleyelim:

  $ mkdir templates
  $ cd templates
  $ vim layout.html

  Açılan dosyaya şu satırları ekleyelim:

  <!doctype html>
 <title>Flaskr</title>
 <link rel=stylesheet type=text/css href="{{ url_for(’static’, filename=’style.css’) }}">
 <div class=page>
   <h1>Flaskr</h1>
     <div class=metanav>
     {% if not session.logged_in %}
       <a href="{{ url_for(’login’) }}">log in</a>
     {% else %}
       <a href="{{ url_for(’logout’) }}">log out</a>
     {% endif %}
     </div>
     {% for message in get_flashed_messages() %}
       <div class=flash>{{ message }}</div>
     {% endfor %}
     {% block body %}{% endblock %}
   </div>

  Kaydedip çıkalım. Blog girdilerini göstermek için bir şablon ekleyelim

  $ vim show_entries.html

  Açılan dosyaya şu satırları ekleyelim:

  {% extends "layout.html" %}
  {% block body %}
    {% if session.logged_in %}
       <form action="{{ url_for(’add_entry’) }}" method=post class=add-entry>
       <dl>
         <dt>Title:
           <dd><input type=text size=30 name=title>
         <dt>Text:
           <dd><textarea name=text rows=5 cols=40></textarea>
           <dd><input type=submit value=Share>
       </dl> 
     </form>
  {% endif %}
  <ul class=entries>
  {% for entry in entries %}
     <li><h2>{{ entry.title }}</h2>{{ entry.text|safe }}
  {% else %}
     <li><em>Unbelievable. No entries here so far</em>
  {% endfor %}
   </ul>
{% endblock %}

  Kaydedip çıkalım. Şimdi giriş için bir şablon ekleyelim:

  $ vim login.html

  Açılan dosyaya şunları ekleyelim:

  {% extends "layout.html" %}
  {% block body %}
    <h2>Login</h2>
    {% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
     <form action="{{ url_for(’login’) }}" method=post>
       <dl>
         <dt>Username:
           <dd><input type=text name=username>
        <dt>Password:
          <dd><input type=password name=password>
        <dd><input type=submit value=Login>
      </dl>
    </form>
  {% endblock %}

 Kaydedip çıkalım. Şimdi görünümü iyileştirmek için css dosyası ekleyeceğiz. 

 $ cd ..
 $ mkdir static
 $ cd static
 $ vim style.css

 Açılan dosya içine şunları ekleyelim: 

 body            { font-family: sans-serif; background: #eee; }
 a, h1, h2       { color: #377ba8; }
 h1, h2          { font-family: ’Georgia’, serif; margin: 0; }
 h1              { border-bottom: 2px solid #eee; }
 h2              { font-size: 1.2em; }

 .page           { margin: 2em auto; width: 35em; border: 5px solid #ccc; padding: 0.8em;  background: white; }
 .entries        { list-style: none; margin: 0; padding: 0; }
 .entries li     { margin: 0.8em 1.2em; }
 .entries li h2  { margin-left: -1em; }
 .add-entry      { font-size: 0.9em; border-bottom: 1px solid #ccc; }
 .add-entry dl   { font-weight: bold; }
 .metanav        { text-align: right; font-size: 0.8em; padding: 0.3em; margin-bottom: 1em;  background: #fafafa; }
 .flash          { background: #cee5F5; padding: 0.5em; border: 1px solid #aacbe2; }
 .error          { background: #f0d6d6; padding: 0.5em; }


  Dosyayı kaydedip çıkabiliriz. 


  Şimdi flaskr.py dosyasının olduğu dizine geçelim ve uygulamayı çalıştıralım

  $ cd ..
  $ python flaskr.py

  Komut satırında karşımıza çıkan url yi tarayıcıya yazarak uygulamanın nasıl çalıştığını görebiliriz.


  

Flask Hello World

  Merhabalar

  Bu yaz stajımda kullanacağım web uygulama çatısı Flask ile basit bir örneğin nasıl yapıldığından bahsedeceğim.

  Flask'ın kurulumuyla başlayalım:
   
  Python ile geliştirme yapacaksak "virtualenv" yani sanal geliştirme ortamını kurmamız kolaylık sağlayacaktır.

  $ sudo pip install virtualenv
  $ mkdir myproject
  $ cd myproject
  $ virtualenv venv
  $ . venv/bin/activate
  $ pip install Flask 

  Şu anda bulunduğumuz dizin içinde "flask" adında bir dizin oluşmuş olmalı. O dizinin içindeki bin dizininin yolunu PATH 'e eklememiz gerekiyor.

  $ vim ~/.profile
 
  Açılan dosyanın sonuna şu satırı ekliyoruz ( bin kendi dosya sisteminizde neredeyse onun yolunu yazmalısınız ) :

  export PATH=~/myproject/flask/bin:$PATH

  Yaptığımız değişikliği aktif etmek için şu komutu veriyoruz:

  $ source ~/.profile

  Flask projelerinin dosya yapısı şu şekildedir :

             /hello_world
                   /static
                   /templates

  static            => css ve javascript dosyaları bu dizinin altında olur.
  templates     => içinde de şablon dosyalarımızı tutarız.

  İlk uygulama için bu dizinlere şimdilik ihtiyacımız yok. Şimdi ilk uygulamamıza geçebiliriz. Bunu yaparken uygulamalarımız için myproject dizininden farklı bir dizin seçersek karışıklığı önleyebiliriz.

  $ mkdir hello_world
  $ cd hello_world
  $ vim hello.py
  
  Açtığımız dosya içine şu satırları ekliyoruz:
  
  from flask import Flask
 app = Flask(__name__)
  
@app.route('/')
@app.route('/index')
def index():
    return "Hello World!"
app.run(debug = True)

  Dosyayı kaydedip çıkıyoruz. 

    $ python hello.py

  Bu komutu çalıştırdığımızda eğer bir sorun yoksa şu çıktıyı verecektir:
    
    * Running on http://127.0.0.1:5000/
 
  Çıktıdaki url yi browser'ın adres çubuğuna yazdığımızda ekranda Hello World! yazdığını görebiliriz.