Hotwire Nedir?

Hotwire is an alternative approach to building modern web applications without using much JavaScript by sending HTML instead of JSON over the wire.

Hotwire, Basecamp ve Hey tarafından geliştirilen, kendi sitesindeki tanıma göre modern web uygulamaları geliştirmeye alternatif bir yaklaşım. Alıştığımız API isteklerindeki JSON yerine direkt olarak HTML göndererek daha az JavaScript kullanacağımızı vaat ediyor. Bu yaklaşım ile sayfaların ilk yüklenmesi daha hızlı oluyor ve template rendering sunucu tarafında gerçekleşiyor. Zaten isminin açılışı da Html over the wire yani hotwire

Hotwire turbo, stimulus ve strada isminde 3 bileşenden oluşuyor ancak strada henüz yayınlanmadı. Basitçe bildiğimiz iframe ama 2021 versiyonu.

Hotwire bileşenlerine yüzeysel bir giriş yapalım ve Ruby On Rails ile nasıl kullanabileceğimize bakalım.

Turbo

Turbo hotwire’ın ana bileşeni, kalbi. Tek satır JavaScript yazmadan gerçek zamanlı web uygulamarı yapmanıza olanak tanıyor. Turbo Drive, Turbo Streams, Turbo Frames ve Turbo Native olarak kendi içinde dörde ayrılıyor. Kısaca sayfa güncellemelerini WebSocket üzerinden alıp, sadece gerekli kısımların güncellenmesini sağlayarak tam sayfa yenilemesi yapmadan güncelleme yapmamızı sağlıyor. İşin en güzel kısmı eğer ruby on rails kullanıyorsanız controller kısmında hiçbir değişiklik yapmadan sadece modelimize 1-2 satır ekleyerek ve viewlarımızda ufak güncellemeler yaparak kullanabiliyor olmamız. Aynı zamanda turbolinks'in yerini alıyor.

Stimulus

Stimulus arayüz kontrolünü elinizden almadan modern JavaScript yazmanızı sağlayan bir JavaScript framework. İşin %80’lik kısmını turbo halletse de geri kalan kısımlar için stimulus kullanmak gerekebilir demişler kendi sitesinde.

Turbo ve Stimulus'u kendi başlarına kullanabildiğimiz gibi herhangi bir framework ile de kullanabiliyoruz. Ama ben günlük olarak Ruby On Rails kullandığım için yine bu frameworkte nasıl kullanılacağını basitçe göstermek istiyorum.

Kurulum

  • İlk önce hotwire-rails gemini Gemfile dosyamıza ekliyoruz.
bundle add hotwire-rails
bundle install
  • Aşağıdaki komutu çalıştırıyoruz ve kurulum bitiyor.
rails hotwire:install

Bu arada bilgisayarımızda redis kurulu ve çalışıyor olması gerekiyor. Turbo verilerini redis üzerinde tutuyor. Merak etmeyin herhangi bir ayar gerekmiyor ve sizin veri tabanı ayarlarınızı hiçbir şekilde etkilemiyor.

Hepsi bu kadar şimdi örnek bir rails projesi oluşturalım ve nasıl kullanacağımıza bakalım.

Kullanım

Ben hotwire_example isminde bir proje oluşturuyorum.

rails new hotwire_example

Proje oluşturulduktan sonra kurulum aşamasındaki adımları izleyerek kurulumu gerçekleştirdiğinizden emin olun.

Şimdi Blog isminde sadece tek bir alanı olan basit bir scaffold oluşturalım.

rails g scaffold Blog icerik:text

Daha sonra ilgili modelimize güncellemelerin hangi ActionCable kanalı üzerinden yapacağını söylüyoruz. Bunun için Blog modelimiz aşağıdaki hale getiriyoruz. Tırnak içindeki “blogs” kısımları size kalmış ancak bunu başka bir yerde daha kullanacağımız için basit tutun ve model ismini kullanın.

class Blog < ApplicationRecord
    after_create_commit { broadcast_append_to "blog" }
    after_destroy_commit { broadcast_remove_to "blog" }
    after_update_commit { broadcast_replace_to "blog" }
end

Bu eklediğimiz 3 satırla basitçe ve sırayla yeni girdi oluşturduğumuzda, sildiğimizde ve güncellediğimizde hangi kanaldan verileri ileteceğini söylüyoruz.

Şimdi views/blogs/index.html.erb dosyamızı basitleştirim aşağıdaki hale getirelim.

<h1>Blogs</h1>
<%= turbo_stream_from "blog" %>
<%= turbo_frame_tag "blogs" do %>
<%= render @blogs %>
<% end %>

<br>

<%= link_to 'New Blog', new_blog_path %>

Burada güncelleme kanalımızı turbo_stream_from ile belirtiyoruz. Modelde kullandığımızın aynısı olmalı.

Daha sonra bir turbo frame ile sayfamızın güncellenecek kısmını belirliyoruz. Yeni başlayanlara yabancı gelebilir ama burada partials kullanıyoruz. Bunun için views/blogs klasörü içinde _blog.html.erb isminde bir dosya oluşturuyoruz ve aşağıdaki gibi düzenliyoruz.

<%= turbo_frame_tag dom_id(blog) do %>
<%= blog.icerik %><br>
<%= link_to 'Show', blog %>
<%= link_to 'Edit', edit_blog_path(blog) %>
<%= link_to 'Destroy', blog, method: :delete, data: { confirm: 'Are you sure?' } %>
<br><br>
<% end %>

Buradaki turbo_frame_tag için dom_id kullanmamızın sebebi blog girdisinin okunabilir id’sini almak. Sağ tıklayıp incele derseniz blog_1 gibi birşeye karşılık geldiğini görebilirsiniz. Şimdi sırada formumuzu güncellemek var. Bunun için standart _form.html.erb dosyamızın başına turbo_frame_tag ekliyoruz.

<%= turbo_frame_tag dom_id(@blog) do %>
<%= form_with(model: blog) do |form| %>
  <% if blog.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(blog.errors.count, "error") %> prohibited this blog from being saved:</h2>

      <ul>
        <% blog.errors.each do |error| %>
          <li><%= error.full_message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :icerik %>
    <%= form.text_area :icerik %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>
<% end %>

Yapacağımız değişiklikler bitti. Çalışıp çalışmadığını görmek için sunucumuzu başlatalım.

rails s # eğer redis çalışmıyorsa çalıştırmayı unutmayın.

Aşağıya da çalışan halini çektiğim küçük bir gif bırakıyorum.