06 - Bildirimler ve çeviriler

May 10, 2018 4 minute read

Uptime ekranımızda URL’lerimizi giriyoruz; ama kullanıcı ile bir etkileşim olmuyor. Gerçekten kaydetti mi, bir sorun mu oldu, ne oldu belli değil. Bir de uygulamayı İngilizce geliştiriyoruz; ama Türkçe yerelde Türkçe arayüz görmek istersek ne yapacağız? Birlikte deneyelim, görelim.

Özet

  • Django’da bildirim altyapısını (Messages Framework1) uygulamamızda kullanacağız.
  • Tüm sayfalarda bildirim mesajlarının nasıl çalıştığını inceleyerek Template katmanına sayfa bağımsız içerik nasıl enjekte ediliyor, bu konuya değineceğiz.
  • Bildirim mesajlarını yerelleştireceğiz.
  • Bu yazıyla ilgili kodlara buradan erişebilirsiniz.

Messages Framework

Django admin panelinde dikkatinizi çekti mi, bir Monitor eklemek, düzenlemek veya silmek istediğimizde aşağıdaki gibi bir bildirim alıyoruz:

Notification in admin panel

Aynısını Uptime ekranında kullanmak için, Django ile birlikte gelen Messages Framework’e ihtiyacımız var. İlk kez Django projesi kurduğumuzda bildirimler kullanıma hazır haldedir. Önce basit bir stil düzeltmesi yapalım, bildirim bir hata mesajı mı, yoksa olumlu bir bilgi mi içeriyor, renkle anlaşılsın:

/* static/main.css */
...
ul.messages {
  margin: 0 0 20px 0;
  padding: 0;
  list-style-type: none;
}

ul.messages li {
    margin-bottom: 5px;
    padding: 15px 20px;
    background-color: #eaeaea;
    color: #222;
}

ul.messages li.error { /* Bildirim tag'ı error ise arkaplan kırmızı */
    background-color: #f7e4e1;
}

ul.messages li.success { /* Bildirim tag'ı success ise arkaplan yeşil */
    background-color: #e1faea;
}

Şimdi Template katmanımızı güncelleyelim. Yalnız hangi dosyayı düzenlediğimize dikkat edin, bildirimler tek bir sayfada olmayacak. Yani tüm sayfalarda kullandığımız layout dosyasına bir kod ekleyeceğiz ve hangi sayfa olursa olsun bildirimler tutarlı görünecek:

<!-- templates/base.html -->
...
{% if messages %}
    <ul class="messages">
        {% for message in messages %}
            <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
        {% endfor %}
    </ul>
{% endif %}
...

Şimdi View katmanımızı güncelleyeceğiz. Yalnız bir şeye dikkat etmenizi istiyorum. Form geçerli veya geçersiz olduğunda bir bildirim mesajı ekliyoruz; ama hiç messages diye bir içerik verisi tanımlamadığımız halde bu değişkeni tüm Template dosyalarımızda ortak kullanabiliyoruz. Yani messages değişkenimiz, Template katmanımız yorumlanırken bir şekilde içine enjekte ediliyor:

# hello_uptime/views.py
...
from django.contrib import messages
...

class UptimeDashboardView(ModelFormSetView):
    ...

    def formset_valid(self, formset):
        formset.save()
        # Formlarımızda sorun yoksa bu metod çalışacak.
        # Bildirimimizi messages.success ile ekleyeceğiz.
        messages.success(self.request, _("The monitors have been updated."))
        return super().formset_valid(formset)

    def formset_invalid(self, formset):
        # Formlarımızda sorun varsa bu metod çalışacak.
        # Bir hata mesajı göstermek istediğimiz için messages.error kullanıyoruz.
        messages.error(self.request, _("The monitors could not be updated, please check the form."))
        return super().formset_invalid(formset)

Hiç get_context_data metoduna dokunmadık, hiç messages diye içerik verisi eklemedik; ama çalışıyor, nasıl?

Error message

Sorumuzun cevabı proje ayarlarında gizli:

# settings.py
...
TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'context_processors': [
                ...
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
...

Context Processors konusuna daha sonra bizzat kendimiz bir örnek yazarak tekrar değineceğiz, şimdilik bu kadarıyla yetinebiliriz2.

Çeviriler

Tarayıcımın dili Türkçe olduğunda, bildirimleri de Türkçe görmek için bizim yerelleştirme3 yapmamız gerekiyor. Çeviriler yerelleştirmenin bir konusu; ancak bunun dışında tarih biçimleri, parayı ifade eden sayıların yazılışı, sayı ayraçları da yerelleştirmenin konusudur.

Önce proje ayarlarında çeviri için gerekli birkaç ayar yapmamız gerekiyor:

# settings.py
...
MIDDLEWARE = [
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',  # Sıra önemli.
    'django.middleware.common.CommonMiddleware',
    ...
]
...
LANGUAGE_CODE = 'en'

LANGUAGES = [
    ('en', "English"),
    ('tr', "Türkçe"),
]

LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'locale'),
)
...

Django çeviri için gettext4 kullanıyor. Projemizde locale dizinini oluşturduktan sonra aşağıdaki komutu çalıştırın:

# terminal
$ mkdir locale
$ python manage.py makemessages -l tr
processing locale tr
$ ls locale/tr/LC_MESSAGES/
django.po

Şimdi django.po dosyasını herhangi bir çeviri editörüyle5 açın ve dosya içeriğini inceleyin. Daha önce uygulamanın bir çok yerinde kullandığımız tanıdık kelimeler göreceğiz:

Poedit

Peki, makemessages komutu bizim çevirilebilir mesajlarımızı nasıl bulabildi? View katmanındaki kodumuzda _() kullanımına dikkat edin, projenin başından beri hep çevrilebilir mesajları ugettext metodunu kullanarak yazdık:

# hello_uptime/views.py
...
from django.utils.translation import ugettext as _
...

class UptimeDashboardView(ModelFormSetView):
    ...
    def formset_valid(self, formset):
        ...
        messages.success(self.request, _("The monitors have been updated."))
...

Çevrilebilir mesajlarımızı projede kullanabilmemiz için son bir adım kaldı. Aşağıdaki komutla derleme yapmamız gerekiyor:

# terminal
$ python manage.py compilemessages
processing file django.po in C:\Users...\hello_django\locale\tr\LC_MESSAGES

Geliştirme sunucusunu tekrar çalıştırın, Türkçe yerelini kullanan bir tarayıcıyla uptime uygulamasına gidin ve sadece Kaydet düğmesine basın:

Turkish notification message

Bildirim mesajı artık Türkçe. Böylece nasıl çeviri yapabileceğimizi öğrenmiş olduk. Elbette bu konu bununla sınırlı değil, tekil - çoğul ayrımı, çevirilerin kullanıcı tercihleriyle ilişkilendirilmesi, kodu güncelledikçe değişen cümleler ve daha bir çok detay var. Onun için, her zaman Django’nun kendi belgesine de bir göz atmakta fayda var. İleride biz de gerektikçe örneklendireceğiz.

Bir sonraki konumuz, kullanıcı modelleri oluşturup uptime uygulamasını kullanıcıyla ilişkilendirmek olacak.


  1. Messages Framework ile ilgili detaylı bilgiyi burada bulabilirsiniz. [return]
  2. Örnek bir context processors metodu burada. [return]
  3. Çeviriler ile ilgili detaylı bilgiye buradan erişebilirsiniz. [return]
  4. Gettext’i buradan indirip yükleyin, çeviri dosyası oluşturmamız için gerekiyor. [return]
  5. Ben Poedit kullanıyorum, epey iş görüyor. [return]