Program akışını sağlayan koşullu ifadeleri ve tekrarlı görevleri kolayca yerine getirmeyi sağlayan döngüleri HTML şablonları içinde de kullanabiliriz.
HTML Şablonlarında Koşullu İfadeler Kullanmak
if koşullu ifadesinin HTML şablonu içindeki kullanımı şu şekildedir;
{% if ilk_koşul %} Eğer koşul doğruysa gösterilecek olan içerik {% elif diğer_koşul %} Eğer diğer koşul doğruysa gösterilecek olan içerik {% else %} Koşulların hiçbiri sağlanmadığında gösterilecek içerik {% endif %}
<iframe src="//www.hava.one/widget/widget_frame?id=745044&days=5&w=250" scrolling="no" frameborder="0" style="border:none;overflow:hidden;height:243px;width:250px;" allowTransparency="true"></iframe>
Hangi şehre ait hava durumu verisinin gösterildiğini id değeri belirlemektedir. Öyleyse kullanıcının bulunduğu şehre göre id verisini değiştirerek yaşadığı şehrin hava durumunu gösterebiliriz. Yan sütun HTML şablonunu açıp iframe kodunu yerleştiriyoruz ve Python kodumuzdan gelen şehir verisine göre if koşullu ifadesini kullanarak id değerini değiştiriyoruz;
<aside> {% block yan %} <iframe src="//www.hava.one/widget2/widget_frame?id= {% if sehir == 'istanbul' %} 745044 {% elif sehir == 'ankara' %} 323786 {% else %} 740264 {% endif %} &days=3&color=68a7d4&pos=v&w=250&header=true" scrolling="no" frameborder="0" style="border:none;overflow:hidden;height:232px;width:250px;" allowTransparency="true"></iframe> {% endblock %} </aside>
Kullanıcının yaşadığı şehir verisi de bize Python dosyamızdan geliyor;
from flask import Flask, render_template ilkproje = Flask(__name__) konum = "ankara" @ilkproje.route("/") def anasayfa(): return render_template("index.html", sehir = konum) @ilkproje.route("/hakkimizda") def hakkimizda(): return render_template("hakkimizda.html", sehir = konum) if __name__ == '__main__': ilkproje.run(debug=True)
Gördüğünüz gibi biz değişkeni yansutun.html şablonuna değil index.html şablonuna gönderdik ama index.html dosyası temel.html şablonunda miras alan bir alt sınıf olduğu ve temel.html şablonu içine yansutun.html şablonu dahil(include) edilmiş olduğu için sorunsuz çalışıyor;
Bir sonraki konuya geçmeden önce, örneğimiz de yer alan Başlık Alanı, Alt Alan gibi ifadeleri kaldırarak, ana sayfamıza biraz içerik ekleyip, alt alan da yer alan standart bilgileri düzenledim. Header alanına da logo ve sosyal medya ikonları yerleştirdim. Amacımız sunucu tarafı yazılım özelliklerini öğrenmek olduğu için, tasarım açısından çok görselliğin üzerine düşmesek de, biraz daha gerçeğe yakın bir görüntü elde ettik. Yapılan değişiklikleri buraya da ekleyeyim ki bire bir kendisi uygulayarak dersleri takip eden arkadaşlarımız var ise farklılık olmasın;
baslik.html dosyası;
<!DOCTYPE html> <html lang="tr"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Flask ile Web Geliştirme</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body> <div id="container"> <header> <div class="row baslik"> <div class="col"> <a href="/" class="footer-logo"> <img src="{{ url_for('static',filename='resimler/fwg-h75px.png') }}" alt="footer_logo" class="img-fluid"> </a> </div> <div class="col d-flex justify-content-end align-items-center"> <a href="#" class="fa fa-facebook"></a> <a href="#" class="fa fa-twitter"></a> <a href="#" class="fa fa-linkedin"></a> <a href="#" class="fa fa-instagram"></a> <a href="#" class="fa fa-pinterest"></a> </div> </div> </header> <nav> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <div class="container-fluid"> <a class="navbar-brand" href="/">Flask ile Web Geliştirme</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav me-auto mb-2 mb-lg-0"> <li class="nav-item"> <a class="nav-link active" aria-current="page" href="/">Ana Sayfa</a> </li> <li class="nav-item"> <a class="nav-link" href="/hakkimizda">Hakkımızda</a> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"> Portföy </a> <ul class="dropdown-menu" aria-labelledby="navbarDropdown"> <li><a class="dropdown-item" href="#">Web Geliştirme</a></li> <li><a class="dropdown-item" href="#">Web Tasarım</a></li> </ul> </li> <li class="nav-item"> <a class="nav-link" href="#">İletişim</a> </li> </ul> <form class="d-flex"> <input class="form-control me-2" type="search" placeholder="Arama terimini giriniz..." aria-label="Search"> <button class="btn btn-outline-success" type="submit">BUL</button> </form> </div> </div> </nav> </nav>
Burada dikkatinizi asıl çekmek istediğim nokta; logoyu yerleştirirken kullandığımız
img src=”{{ url_for(‘static’,filename=’resimler/fwg-h75px.png’) }}”
ifadesidir. Flask projelerinde yazdığınız CSS ve Javascript dosyalarınız, tasarıma ilişkin resimler gibi statik içerikler standart olarak static klasörü altında oluşturacağınız klasörler içinde yer alırlar. Bu dosyaların konumlarını belirtmek için de; url_for() fonksiyonundan yararlanırız. Bu fonksiyon ilk parametre olarak static klasör adını, ikinci parametre olarak da klasöradı/dosyaadı parametresini kullanır.
Not: url_for() fonksiyonunun bir başka kullanım amacı da, yazdığınız bir fonksiyonun web adresini(URL) belirlemektir. Bu fonksiyona ilk parametre olarak fonksiyonun adını veririz. Sonra da istediğiniz sayıda değişkeni parametre olarak ekleyebilirsiniz. Bilinmeyen değişken adları web adresine(URL) sorgu parametresi olarak eklenir.
Bunun dışında bir de redirect() fonksiyonuna parametre olarak verilen url_for() fonksiyonu vardır. Bu da bir web adresi yönlendirme işlemi yapar. redirect(url_for()) şeklinde kullanılır ve örneğin bir web adresi tanımlama fonksiyonunun içinde döndürülüyorsa adresi url_for() ile verilen fonksiyonun adresine yönlendirir. Örneğin, index() fonksiyonu içinde döndürülen return redirect(url_for(hakkimizda)) ifadesi anasayfayı hakkımızda sayfasına yönlendirir.
temel.html dosyası;
{% include "baslik.html" %} {% include "icerik.html" %} <div class="row"> <div class="col-sm-8 govde"> {% block icerik %} {% endblock %} </div> <div class="col-sm-4"> {% include "yansutun.html" %} </div> </div> {% include "altalan.html" %}
altalan.html dosyası;
<footer id="dk-footer" class="dk-footer"> <div class="container"> <div class="row"> <div class="col-md-12 col-lg-4"> <div class="dk-footer-box-info"> <a href="/" class="footer-logo"> <img src="{{ url_for('static',filename='resimler/fwg.png') }}" alt="footer_logo" class="img-fluid"> </a> <p class="footer-info-text"> Reference site about Lorem Ipsum, giving information on its origins, as well as a random Lipsum generator. </p> </div> </div> <!-- End Col --> <div class="col-md-12 col-lg-8"> <div class="row"> <div class="col-md-6"> <div class="contact-us"> <div class="contact-icon"> <i class="fa fa-map-o" aria-hidden="true"></i> </div> <!-- End contact Icon --> <div class="contact-info"> <h3>Dünya Ticaret Merkezi</h3> <p>Çankaya/Ankara</p> </div> <!-- End Contact Info --> </div> <!-- End Contact Us --> </div> <!-- End Col --> <div class="col-md-6"> <div class="contact-us contact-us-last"> <div class="contact-icon"> <i class="fa fa-volume-control-phone" aria-hidden="true"></i> </div> <!-- End contact Icon --> <div class="contact-info"> <h3>+90 555 555 55 55</h3> <p>Bizi arayın</p> </div> <!-- End Contact Info --> </div> <!-- End Contact Us --> </div> <!-- End Col --> </div> <!-- End Contact Row --> <div class="row"> <div class="col-md-12 col-lg-6"> <div class="footer-widget footer-left-widget"> <div class="section-heading"> <h3>Hızlı Erişim</h3> <span class="animate-border border-black"></span> </div> <ul> <li> <a href="/">Ana Sayfa</a> </li> <li> <a href="/hakkimizda">Hakkımızda</a> </li> <li> <a href="#">İletişim</a> </li> </ul> <ul> <li> <a href="#">Web Geliştirme</a> </li> <li> <a href="#">Web Tasarım</a> </li> <li> <a href="#">Blog</a> </li> </ul> </div> <!-- End Footer Widget --> </div> <!-- End col --> <div class="col-md-12 col-lg-6"> <div class="footer-widget"> <div class="section-heading"> <h3>Haberdar Olun</h3> <span class="animate-border border-black"></span> </div> <p><!-- Don’t miss to subscribe to our new feeds, kindly fill the form below. --> Email adresiniz ile listemize dahil olun, yeniliklerden ilk siz haberdar olun.</p> <form action="#"> <div class="form-row"> <div class="col dk-footer-form"> <input type="email" class="form-control" placeholder="Email Adresiniz"> <button type="submit"> <i class="fa fa-send"></i> </button> </div> </div> </form> <!-- End form --> </div> <!-- End footer widget --> </div> <!-- End Col --> </div> <!-- End Row --> </div> <!-- End Col --> </div> <!-- End Widget Row --> </div> <!-- End Contact Container --> <div class="copyright"> <div class="container"> <div class="row"> <div class="col-md-4 col-sm-6 col-xs-12 text-center"> <span>Copyright © 2020, Tüm hakları saklıdır</span> </div> <!-- End Col --> <div class="col-md-8 col-sm-6 col-xs-12 text-center"> <div class="copyright-menu"> <ul> <li> <a href="/">Ana Sayfa</a> </li> <li> <a href="#">Kullanım Koşulları</a> </li> <li> <a href="#">Gizlilik Politikası</a> </li> <li> <a href="/iletisim">İletişim</a> </li> </ul> </div> </div> <!-- End col --> </div> <!-- End Row --> </div> <!-- End Copyright Container --> </div> <!-- End Copyright --> <!-- Back to top --> <div id="back-to-top" class="back-to-top"> <button class="btn btn-dark" title="Back to Top" style="display: block;"> <i class="fa fa-angle-up"></i> </button> </div> <!-- End Back to top --> </footer> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" /> <link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='css/stildosyam.css') }}"> </body> </html>
Burada da, biraz önce bahsettiğimiz şekilde kendi yazdığımız CSS kodlarını içeren dosyayı nasıl eklediğimize dikkat ediniz;
<link rel= “stylesheet” type= “text/css” href= “{{ url_for(‘static’,filename=’css/stildosyam.css’) }}”>
stildosyam.css dosyası;
/* Genel biçimlendirme ayarları */ a { text-decoration: none; } .baslik { padding: 10px 40px } .yansutun { padding: 20px } .govde { padding: 20px 20px 20px 40px } /* Sosyal medya ikonlarının biçimlendirilmesi */ .fa { text-align: center; text-decoration: none; margin: 5px 2px; border-radius: 50%; } .fa:hover { opacity: 0.7; } .fa-facebook { background: #3B5998; color: white; padding: 10px; font-size: 15px; width: 35px; } .fa-twitter { background: #55ACEE; color: white; padding: 10px; font-size: 15px; width: 35px; } .fa-linkedin { background: #007bb5; color: white; padding: 10px; font-size: 15px; width: 35px; } .fa-instagram { background: #125688; color: white; padding: 10px; font-size: 15px; width: 35px; } .fa-pinterest { background: #cb2027; color: white; padding: 10px; font-size: 15px; width: 35px; } /* Alt alan(Footer) biçimlendirme ayarları */ .footer-widget p { margin-bottom: 27px; color: #ccc; } #footer p { font-family: 'Nunito', sans-serif; font-size: 14px; color:white; line-height: 28px; } .animate-border { position: relative; display: block; width: 100%; height: 1px; background: #007bff; } .animate-border:after { position: absolute; content: ""; width: 35px; height: 1px; left: 0; bottom: 0; border-left: 10px solid #fff; border-right: 10px solid #fff; -webkit-animation: animborder 2s linear infinite; animation: animborder 2s linear infinite; } @-webkit-keyframes animborder { 0% { -webkit-transform: translateX(0px); transform: translateX(0px); } 100% { -webkit-transform: translateX(200px); transform: translateX(200px); } } @keyframes animborder { 0% { -webkit-transform: translateX(0px); transform: translateX(0px); } 100% { -webkit-transform: translateX(200px); transform: translateX(200px); } } .animate-border.border-white:after { border-color: #fff; } .animate-border.border-yellow:after { border-color: #F5B02E; } .animate-border.border-orange:after { border-right-color: #007bff; border-left-color: #007bff; } .animate-border.border-ash:after { border-right-color: #EEF0EF; border-left-color: #EEF0EF; } .animate-border.border-offwhite:after { border-right-color: #F7F9F8; border-left-color: #F7F9F8; } /* Animated heading border */ @keyframes primary-short { 0% { width: 15%; } 50% { width: 90%; } 100% { width: 10%; } } @keyframes primary-long { 0% { width: 80%; } 50% { width: 0%; } 100% { width: 80%; } } .dk-footer { padding: 35px 0 0; background-color: #151414; z-index: 2; position: fixed; left: 0; bottom: 0; width:100% } .dk-footer .contact-us { margin-top: 0; margin-bottom: 30px; padding-left: 40px; } .dk-footer .contact-us .contact-info { margin-left: 50px; } .dk-footer .contact-us.contact-us-last { margin-left: -40px; } .dk-footer .contact-icon i { font-size: 24px; top: -15px; position: relative; color:#007bff; } .dk-footer-box-info { background: #202020; padding: 20px 20px 10px 20px; text-align: center; z-index: 2; } .dk-footer-box-info .footer-social-link h3 { color: #fff; font-size: 24px; margin-bottom: 25px; } .dk-footer-box-info .footer-social-link ul { list-style-type: none; padding: 0; margin: 0; } .dk-footer-box-info .footer-social-link li { display: inline-block; } .dk-footer-box-info .footer-social-link a i { display: block; width: 40px; height: 40px; border-radius: 50%; text-align: center; line-height: 40px; background: #000; margin-right: 5px; color: #fff; } .dk-footer-box-info .footer-social-link a i.fa-facebook { background-color: #3B5998; } .dk-footer-box-info .footer-social-link a i.fa-twitter { background-color: #55ACEE; } .dk-footer-box-info .footer-social-link a i.fa-google-plus { background-color: #DD4B39; } .dk-footer-box-info .footer-social-link a i.fa-linkedin { background-color: #0976B4; } .dk-footer-box-info .footer-social-link a i.fa-instagram { background-color: #B7242A; } .footer-awarad { margin-top: 285px; display: -webkit-box; display: -webkit-flex; display: -moz-box; display: -ms-flexbox; display: flex; -webkit-box-flex: 0; -webkit-flex: 0 0 100%; -moz-box-flex: 0; -ms-flex: 0 0 100%; flex: 0 0 100%; -webkit-box-align: center; -webkit-align-items: center; -moz-box-align: center; -ms-flex-align: center; align-items: center; } .footer-awarad p { color: #fff; font-size: 24px; font-weight: 700; margin-left: 20px; padding-top: 15px; } .footer-info-text { margin: 26px 0 26px; color: #ccc; } .footer-left-widget { padding-left: 40px; } .footer-widget .section-heading { margin-bottom: 35px; } .footer-widget h3 { font-size: 20px; color: #fff; position: relative; margin-bottom: 15px; max-width: -webkit-fit-content; max-width: -moz-fit-content; max-width: fit-content; } .footer-widget ul { width: 50%; float: left; list-style: none; margin: 0; padding: 0; } .footer-widget li { margin-bottom: 18px; } .footer-widget p { margin-bottom: 27px; } .footer-widget a { color: #878787; -webkit-transition: all 0.3s; -o-transition: all 0.3s; transition: all 0.3s; } .footer-widget a:hover { color: #007bff; } .footer-widget:after { content: ""; display: block; clear: both; } .dk-footer-form { position: relative; } .dk-footer-form input[type=email] { padding: 10px 20px; border-radius: 10px; background: #2E2E2E; border: 1px solid #2E2E2E; } .dk-footer-form input::-webkit-input-placeholder, .dk-footer-form input::-moz-placeholder, .dk-footer-form input:-ms-input-placeholder, .dk-footer-form input::-ms-input-placeholder, .dk-footer-form input::-webkit-input-placeholder { color: #878787; font-size: 14px; } .dk-footer-form input::-webkit-input-placeholder, .dk-footer-form input::-moz-placeholder, .dk-footer-form input:-ms-input-placeholder, .dk-footer-form input::-ms-input-placeholder, .dk-footer-form input::placeholder { color: #878787; font-size: 14px; } .dk-footer-form button[type=submit] { position: absolute; top: 0; right: 0; padding: 10px 16px 10px 17px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border: 1px solid #007bff; background: #007bff; color: #fff; } .dk-footer-form button:hover { cursor: pointer; } /* ========================== Contact =============================*/ .contact-us { position: relative; z-index: 2; margin-top: 65px; display: -webkit-box; display: -webkit-flex; display: -moz-box; display: -ms-flexbox; display: flex; -webkit-box-align: center; -webkit-align-items: center; -moz-box-align: center; -ms-flex-align: center; align-items: center; } .contact-icon { position: absolute; } .contact-icon i { font-size: 36px; top: -5px; position: relative; color: #007bff; } .contact-info { margin-left: 75px; color: #fff; } .contact-info h3 { font-size: 18px; color: #fff; margin-bottom: 0; } .copyright { padding: 28px 0; margin-top: 35px; background-color: #202020; } .copyright span, .copyright a { color: #878787; -webkit-transition: all 0.3s linear; -o-transition: all 0.3s linear; transition: all 0.3s linear; } .copyright a:hover { color:#007bff; } .copyright-menu ul { text-align: right; margin: 0; } .copyright-menu li { display: inline-block; padding-left: 20px; } .back-to-top { position: relative; z-index: 2; } .back-to-top .btn-dark { width: 35px; height: 35px; border-radius: 50%; padding: 0; position: fixed; bottom: 20px; right: 20px; background: #2e2e2e; border-color: #2e2e2e; display: none; z-index: 999; -webkit-transition: all 0.3s linear; -o-transition: all 0.3s linear; transition: all 0.3s linear; } .back-to-top .btn-dark:hover { cursor: pointer; background: #FA6742; border-color: #FA6742; } /* Mobil Biçimlendirme Ayarları */ @media only screen and (max-width: 600px) { .dk-footer{ position: relative; } .contact-us{ margin: auto !important; padding: 20px; } .footer-left-widget{ padding-left: 0; } .dk-footer-form button[type=submit]{ padding: 5px 16px 5px 17px; } .copyright-menu ul{ text-align: center; padding-left: 0; } .copyright-menu li{ padding-left: 0; } .fa { padding: 5px; font-size: 14px; width: 25px; } }
Bu değişikliklerin nasıl göründüğünü de bu konunun sonunda göreceğiz.
HTML Şablonlarında Döngü Kullanımı
Flask kodlarımızı yazdığımız Python dosyamız içinde oluşturduğumuz fonksiyonlar ile gerçekleştirdiğimiz işlemler sonucunda HTML şablonlarında görüntülemek üzere her zaman tek bir değişken değeri göndermeyiz. Hatta çoğu zaman Python’ın Liste, Demet, Küme, Sözlük gibi içinde bir çok veri barındıran veri yapıları kullanılır.
Bildiğiniz gibi Python’da bu veri türleri ile çalışırken standart çıktıda görüntülemek için her bir veriyi tek tek yazmıyor, döngü kullanıyorduk. Flask ile web sayfaları oluştururken de aynı şekilde ziyaretçilerimize göstermek için web sayfasına çıktıları yazdırmak amacıyla döngülerden faydalanacağız.
Örneğin ana sayfamızı oluşturan içeriğin tarafımızdan direkt statik olarak eklenmediğini, bir yönetim panelinden yapılan girdiler ile oluşturulmuş bir listeden çekildiğini düşünelim;
from flask import Flask, render_template ilkproje = Flask(__name__) konum = "ankara" @ilkproje.route("/") def anasayfa(): verilistesi=["Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."] return render_template("index.html", sehir = konum, veriler = verilistesi) @ilkproje.route("/hakkimizda") def hakkimizda(): return render_template("hakkimizda.html", sehir = konum) if __name__ == '__main__': ilkproje.run(debug=True)
Liste içindeki verileri görüntülemek için web sayfamızda for..in döngüsünü kullanacağız;
index.html dosyası;
{% extends "temel.html" %} {% block icerik %} {% for veri in veriler %} <p>{{ veri }}</p> {% endfor %} {% endblock %}
Sonuç olarak her bir liste verisi eklediğimiz <p> HTML etiketinin de etkisiyle bir paragraf olarak ekranda görüntüleniyor;
Bağlantıda Kalalım