Turbolinks, আপনার ওয়েব অ্যাপ্লিকেশনের নেভিগেশন দ্রুত করার একটি চমৎকার টুল, আর সক্রিয়ভাবে ডেভেলপ করা হচ্ছে না। এটি Hotwire 엄্ব্রেলার অংশ olan একটি নতুন ফ্রেমওয়ার্ক Turbo দ্বারা প্রতিস্থাপিত হয়েছে।
تیমটি বুঝতে পেরেছিল যে Turbolinks থেকে এক্সট্র্যাক্ট করা অনুরূপ কনসেপ্টগুলো ফ্রেম, ফর্ম সাবমিশন এবং নেটিভ অ্যাপসের মতো অন্যান্য বিষয়গুলোর সाएতেও দ্রুত ওয়েবের জন্য গ্রহণ করা যেতে পারে।
এই আর্টিকেলটি Turbo ফ্রেমওয়ার্কের জন্য একটি গাইড প্রদান করতে লক্ষ্য করে, যা Turbolinks-এর নতুন প্রতিস্থাপক, এবং একটি প্র্যাকটিক্যাল মাইগ্রেশন গাইড অন্তর্ভুক্ত করে যা ব্যাখ্যা করবে কীভাবে Turbolinks-এর সবচেয়ে গুরুত্বপূর্ণ এবং সাধারণত ব্যবহৃত অংশগুলো Turbo-এ ব্যবহার করতে হয়।
আমরা কী নিয়ে আলোচনা করব সেটি ভালোভাবে বুঝতে, Turbolinks সম্পর্কে কিছু জ্ঞান থাকা অপরিহার্য। আপনি এর সম্পর্কে আরও জানতে পারেন এখানে এবং এখানে।
Turbo পরিচিতি
Turbo হলো মডার্ন এবং দ্রুত ওয়েব অ্যাপ তৈরি করার জন্য বেশ কিছু টেকনিকের সমষ্টি, যা কম JavaScript দিয়ে সম্ভব। এটি সার্ভারকে সমস্ত লজিক হ্যান্ডল করার অনুমতি দেয় যা সরাসরি HTML আকারে ব্রাউজারে ডেলিভার করা হয়। ফলে ব্রাউজারের একমাত্র দায়িত্ব হলো সাদা HTML প্রসেস করা।
এটি করার জন্য Turbo নিজকে চারটি প্রধান অংশে ভাগ করে:
- Turbo Drive, Turbo-এর হৃদয়, আপনার লিংক এবং ফর্মের সব ক্লিককে অটোমেটিকভাবে ইন্টারসেপ্ট করে, ব্রাউজারকে তা কল করতে বাধা দেয়, History API-এর মাধ্যমে URL পরিবর্তন করে, AJAX-এর মাধ্যমে পৃষ্ঠাটি পেছনের দরজায় রিকোয়েস্ট করে, এবং রেসপন্সটি যথাযথভাবে রেন্ডার করে।
- Turbo Frames পেজ সাবসেট/ফ্রেম নিয়ে কাজ করে ফ্রন্ট-এন্ড ডেভেলপাররা ফ্রেমসকে কীভাবে স্বতন্ত্রভাবে পেজের সাবসেট হ্যান্ডল করত তা পুনরাবিষ্কার করে। এটি পৃষ্ঠাগুলোকে আলাদা স্কোপ এবং লেজি লোড ক্ষমতা সহ স্বতন্ত্র কনটেক্সট সেটে ডিকম্পোজ করে।
- Turbo Streams সাধারণ পারশিয়াল পেজ আপডেটকে ওয়েব সকেটের মাধ্যমে অ্যাসিনক্রোনাস ডেলিভারির সাথে একটি সিম্পল CRUD কন্টেইনার ট্যাগ সেট দ্বারা প্রতিস্থাপন করে। এদের মাধ্যমে আপনি HTML ফ্র্যাগমেন্ট একই ওয়েব সকেটের মাধ্যমে পাঠাতে পারেন এবং পেজটি UI রি-প্রসেস করতে বুঝতে পারে।
- Turbo Native আপনি যদি iOS/Android-এ নেটিভ হওয়ার পথ বেছে নেন, তবে এমবেডেড ওয়েব অ্যাপের জন্য নেটিভ শেলে Turbo ব্যবহার করার সমস্ত প্রয়োজনীয় টুলিং সরবরাহ করে।
প্রজেক্ট সেটআপ
দ্রুত শুরু করার জন্য, আমি একটি রেডি-টু-ইউজ Rails অ্যাপ প্রজেক্ট প্রদান করলাম যার মধ্যে স্ক্যাফোল্ডেড পোস্ট ফর্ম-ফ্লো এমবেড করা আছে, এবং স্টাইলিং-এর জন্য Bootstrap আছে।
এটি আপনাকে সেটআপে সময় না হারাতে সাহায্য করবে, 그와 더불어 Turbolinks অটোমেটিক্যালি অ্যাড করা একটি ওয়ার্কিং প্রজেক্ট দেবে। যদি আপনার নিজস্ব প্রজেক্ট থাকে, তবে সেটিও ঠিক আছে; আপনি এখনও আর্টিকেলটি ফলো করতে পারবেন।
আপনি rails কমান্ড দিয়ে একটি নতুন স্ক্যাফোল্ডেড Rails অ্যাপও জেনারেট করতে পারেন।
GitHub রিপোজিটরির লিংকটি এখানে পাবেন। সেটি লোকালি ক্লোন করুন এবং bundle install কমান্ড রান করে সব Rails ডিপেন্ডেন্সি ইনস্টল করুন।
সব কিছু সেট হলে rails s কমান্ড দিয়ে Rails সার্ভার শুরু করুন এবং নিচে দেখানো /posts URI চেক আউট করুন:
Rails-এ Posts CRUD
Turbolinks-এর ফিচারস একশনে দেখতে, শুধু নতুন পোস্ট তৈরি বা আইটেম ডিসপ্লে করার লিংকগুলোর মাধ্যমে নেভিগেট করুন। আপনি দেখবেন পৃষ্ঠা রিলোড ছাড়া URL পরিবর্তন হচ্ছে।
মাইগ্রেশন স্টেপস
প্রপার Node প্যাকেজ ইনস্টলেশন দিয়ে শুরু করা যাক। আপনার আর turbolinks দরকার নেই, তাই আমরা সেটি আমাদের Node লিস্ট থেকে সরিয়ে turbo-rails ডিপেন্ডেন্সি যোগ করতে পারি, নিচের দুটি কমান্ডে দেখানো হয়েছে:
yarn remove turbolinks
yarn add @hotwired/turbo-rails
Rails-এর সাথে কাজ করলে সব কিছু প্রপারলি ইনস্টল হয়েছে কিনা নিশ্চিত করার আরেকটি চমৎকার উপায় হলো নিচের কমান্ড রান করা:
rails turbo:install
যদি অ্যাপ্লিকেশনে Webpacker ইনস্টল থাকে, তবে এটি npm-এর মাধ্যমে Turbo ইনস্টল করবে। এই কমান্ডটি আপনার প্রজেক্ট থেকে Turbolinks-এর পুরনো সব ডিপেন্ডেন্সি রিমুভ করার চেষ্টা করবে যদি আপনি কিছু মিস করে থাকেন।
তারপর app/javascript/packs/application.js ফাইলটি খুলুন এবং নিচের কোড লাইনগুলো লোকেট করুন:
import Turbolinks from "turbolinks";
Turbolinks.start();
নোট করুন, আপনার Rails অ্যাপের ভার্সনের উপর ভিত্তি করে ইম্পোর্টগুলো কিছুটা ভিন্ন হতে পারে (পুরনো ভার্সনগুলো import এর বদলে require ব্যবহার করত)।尽管如此, প্রসেসটি দুটি কেসেই একই।
তারপর সেগুলোকে নিচের কোডদিয়ে প্রতিস্থাপন করুন:
import "@hotwired/turbo-rails";
হ্যাঁ, শুধু একটি ইম্পোর্ট; কোনো কিছু ম্যানুয়ালি স্টার্ট করার দরকার নেই। Turbo ইন্সট্যান্সটি ইম্পোর্ট করার সাথে সাথে window.Turbo অবজেক্টে অটোমেটিক্যালি অ্যাসাইন হয়ে যায়, যা ম্যানেজ করা সহজ।
টেস্ট করতে এবং দেখতে যে আমরা শুধু Turbo খুঁজছি Turbolinks আর নয়, ফাইলের শেষে নিচের কোড স্নিপেটটি যোগ করুন:
$(document).on("turbolinks:load", () => { console.log("turbolinks!"); });
$(document).on("turbo:load", () => { console.log("turbo!"); });
ব্রাউজারে পেজ রিলোড হলে, কনসোল লগ চেক করুন কী প্রিন্ট হয়েছে:
Turbo লোড ইভেন্ট লগ চেক করা
app/views/layouts/application.html.erb ফাইলে আরেকটি পরিবর্তন করতে হবে, যা মূলত পুরনো Turbolinks ডেটা অ্যট্রিবিউটগুলো Turbo-এর সমতুল্যে পরিবর্তন করা। data-turbolinks-* অ্যট্রিবিউট ব্যবহার করা দুটি ট্যাগ লোকেট করুন এবং সেগুলোকে নিচের কোডদিয়ে প্রতিস্থাপন করুন:
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbo-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbo-track': 'reload' %>
এটি গুরুত্বপূর্ণ যাতে Turbo head ট্যাগে ইম্পোর্ট করা সব অ্যাসেট অটোমেটিক্যালি ট্র্যাক করতে পারে এবং পরিবর্তন হলে সেগুলো রিলোড করতে পারে। এটি সব ফাইলে প্রযোজ্য, আপনি সেখানে যোগ করা সব স্ক্রিপ্ট এবং স্টাইলসহ।
Turbo ফিচারস এক্সপ্লোর করা
যেহেতু Turbo আপনার অ্যাপ্লিকেশনের সব লিংককে অটোমেটিক্যালি ইন্টারসেপ্ট করে রিলোড ছাড়া কল করে, তাই যদি আপনি কোনো নির্দিষ্ট লিংকের জন্য সেই ফাংশনালিটি ডিজেবল করতে চান, তবে আপনাকে সেটি এক্সপ্লিসিটলি কোড করতে হবে।
app/views/posts/index.html.erb ফাইলে "New Post" বাটনটি নিচের মত আপডেট করে টেস্ট করুন:
<%= link_to 'New Post', new_post_path, :class => "btn btn-primary btn-sm", "data-turbo" => "false" %>
নোট করুন, আমরা এক্সপ্লিসিটলি নতুন ডেটা অ্যট্রিবিউট data-turbo যোগ করছি, যাতে Turbo স്പেসিফিক এই লিংকে ক্লিক হলে সেটি খুঁজে না পায়।
অ্যাপ্লিকেশন রিলোড করুন এবং "New Post" বাটনে ক্লিক করুন। আপনি দেখবেন পেজটি এখন সাধারণ অ্যাপের মত ফুল রিলোড হচ্ছে।
এটি Turbo আপনার অ্যাপ্লিকেশনে সেট ও ওয়ার্কিং আছে কিনা টেস্ট করার চমৎকার একটি উপায়।
ফর্মসের জন্যও একই কথা। Turbo সব ফর্ম সাবমিশন অটোমেটিক্যালি হ্যান্ডেল করে, তাই সেগুলো অ্যাসিনক্রোনাসলি হয়। যদি app/views/posts/_form.html.erb ফাইলের ফর্মের জন্য ডিজেবল করতে চান, তবে সাবমিট বাটনটি নিচের মত পরিবর্তন করুন:
<div class="actions">
<%= form.submit class: "btn btn-primary btn-sm", "data-turbo" => false %>
</div>
অ্যাপ রিলোড করুন এবং টেস্ট করুন! নতুন পোস্ট তৈরি করার সময় একই আচরণ দেখবেন।
ফর্ম সাবমিশন
ফর্মের কথা বললে, Turbo ফর্মগুলোকে লিংকের মতোই হ্যান্ডেল করে। কিন্তু ফর্ম রিকোয়েস্টগুলো সবসময় সফলভাবে শেষ হয় না।
এটি প্র্যাকটিসে দেখি! প্রথমে পোস্টের name এবং title প্রপার্টিগুলো রিকোয়ার্ড করার জন্য কয়েকটি ভ্যালিডেশন যোগ করুন। এর জন্য app/models/post.rb ফাইলটি খুলুন এবং নিচের মত পরিবর্তন করুন:
class Post < ApplicationRecord
validates :name, presence: true
validates :title, presence: true
end
অ্যাপ রিলোড করুন এবং এখন নতুন পোস্ট যোগ করার চেষ্টা করুন, সব ফিল্ড খালি রেখে। আপনি লক্ষ্য করবেন কিছুই হচ্ছে না। যদি ব্রাউজার কনসোল ইন্সপেক্ট করেন, তবে নিচের এরর দেখতে পাবেন:
ফর্ম রেসপন্স অবশ্যই অন্য লোকেশনে রিডাইরেক্ট হতে হবে
এটি ফিক্স করার দুটি উপায় আছে। প্রথম উপায় হলো পোস্ট কন্ট্রোলারের আপডেটেবল অ্যাকশনগুলোতে (POST, PUT, ইত্যাদি) status যোগ করা এবং সেটিকে unprocessable entity অবজেক্ট হিসেবে মান দেওয়া।
নিচে create এবং update (post_controller.rb) মেথডগুলোর কোড পরিবর্তনগুলো দেওয়া হলো:
# def create
format.html { render :new, status: :unprocessable_entity }
# def update
format.html { render :edit, status: :unprocessable_entity }
এডিটস সেভ করুন এবং ফর্মটি আবার টেস্ট করুন। এই বার ভ্যালিডেশন এররগুলো সঠিকভাবে ডিসপ্লে হচ্ছে:
UI-তে ভ্যালিডেশন এরর ডিসপ্লে করা
দूसরা উপায় হলো turbo_frame_tag ব্যবহার করা। Turbo ব্যবহার করে একটি Rails অ্যাপে, আমরা যে Turbo Frames নিয়ে কথা বলেছি সেগুলো এই ট্যাগ দিয়ে রেন্ডার হয়।
যখন আপনি আপনার পেজের এক টুকরো আইসোলেট করতে চান এবং ব্যাকএন্ড অ্যাপের সাথে একটি ডাইরেক্ট টানেল খুলতে চান যাতে Turbo রিকোয়েস্ট এবং রেসপন্স স্পেসিফিক এই ফ্রেমে আট্যাচ করতে পারে, তখন এটি একটি চমৎকার রিসোর্স।
টেস্ট করতে, প্রথমে আপনার _form.html.erb ফাইলের পুরো কন্টেন্টকে এই ট্যাগের মধ্যে র্যাপ করুন:
<%= turbo_frame_tag post do %>
...
<% end %>
ফর্মের কেসে post থাকার očвид কারণ আছে। ব্রাউজারে ফেরত যান এবং আবার টেস্ট করুন, একই ভ্যালিডেশন এররها আশা অনুযায়ী শো হবে।
এখানে আরেকটি আকর্ষণীয় বিষয় হলো সেই ফর্মের জন্য জেনারেটেড HTML। এক নজর দিন:
<turbo-frame id="new_post">
<form action="/posts" accept-charset="UTF-8" method="post">
...
</form>
</turbo-frame>
এই কাস্টম HTML এলিমেন্টটি হলো Turbo ফ্রেমসকে হোল-পেজ-বেজড অ্যাকশন থেকে আলাদা করার পদ্ধতি।
প্রগ্রেস বার
সাধারণ বোধ হলো, যখন আপনি ব্রাউজারের ডিফল্ট লোডিং মেকানিজম সরিয়ে দেন, তবে স্লো লোড হয় এমন কেসের জন্য আরেকটি প্রদান করেন।
Turbo ইতিমধ্যে পেজের টপে একটি বিল্ট-ইন CSS-বেসড প্রগ্রেস বার দিয়ে থাকে, যা Bootstrap এবং Material Design-এর মত বড় লাইব্রেরিগুলো দিয়ে থাকে।
এটি শুধু তখন ডিসপ্লে হয় যখন রিকোয়েস্টগুলো ৫০০ ms-র বেশি টাইম নেয় প্রসেস করতে, যা আমাদের টেস্ট প্রজেক্টের জন্য যথেষ্ট দীর্ঘ নয়।
আপনি যদি এর স্টাইল পরিবর্তন করতে চান বা পুরোপুরি রিমুভ করতে চান, তবে .turbo-progress-bar CSS ক্লাসের সাথে এক্সপেরিমেন্ট করতে পারেন, নিচে দেখানো মতে:
.turbo-progress-bar {
height: 15px;
background-color: gold;
}
টেস্ট করতে, application.js ফাইলে প্রগ্রেস বার ডিলে কমাতে হবে নিচের কোডদিয়ে:
window.Turbo.setProgressBarDelay(1);
প্রদত্ত টাইম মিলিসেকেন্ডে। নিচে আপডেট করা প্রগ্রেস বার রিপ্রেজেন্টেশন দেওয়া হলো।
আপডেট করা প্রগ্রেস বার ডিসপ্লে
শেষ করুন
Turbo এবং এর চমৎকার ফিচারস, যেমন Streams এবং Native মডিউলস নিয়ে আরও অনেক কিছু আলোচনা করা যেতে পারে। কিন্তু আর্টিকেলটি ফোকাসড রাখতে আমরা এই প্রাথমিক স্টেপগুলোতে সীমাবদ্ধ থাকব।
সর্বদার মত, অফিশিয়াল Turbo Handbook রিকমেন্ড করা এড়াতে পারিনি, যা এই পুরো মাইগ্রেশন প্রসেসে শুরুতে আমার খুব কাজে লাগেছিল। সেখানে আপনার প্রজেক্টের স্পেশাল কন্ডিশনগুলো হ্যান্ডল করার সব মাটেরিয়াল পাবেন।
যদি আপনার অ্যাপ Devise ব্যবহার করে, তবে সম্ভবত কিছু অ্যাডাপটেশন লাগবে। خوشবশলত Turbo টিম Devise-র সাথে Turbo নিয়ে একটি চমৎকার টিউটোরিয়াল দিয়েছে যা মিনুটিয়া হ্যান্ডেল করতে সাহায্য করে।