
আমি জেকিল ব্যবহার করে আমাদের ডকুমেন্টেশন সাইট রিবিল্ড করছি। যেহেতু আমাদের ডকুমেন্টেশন পেজগুলো খুব বড়, আমাদের টপ-লেভেল নেভিগেশনের পাশাপাশি কোনো সাবনেভিগেশন থাকতে হবে।
এই পোস্টে আমরা কভার করব কীভাবে একটি সিম্পল জেকিল প্লাগিন বানানো যায় যা আপনার পোস্ট বা পেজের হেডিং থেকে সাবনেভ লিংক জেনারেট করতে পারে।
ওভারভিউ
আমি এই প্রজেক্টকে নিচের টাস্কগুলোর মধ্যে ভাগ করেছি:
- একটি জেকিল জেনারেটর তৈরি করুন যা সাইটের প্রতিটি পেজে চলে।
- জেনারেটরকে শিখান কীভাবে পেজগুলো প্রি-রেন্ডার করতে হয় যাতে হেডিং ইনফরমেশন বের করা যায়।
- nokogiri ব্যবহার করে পেজের HTML পার্স করুন এবং প্রাসঙ্গিক হেডিং এবং কন্টেন্ট এক্সট্রাক্ট করুন।
- সাবনেভিগেশন রেন্ডার করুন।
নিচের উদাহরণগুলোতে সব সাবনেভ লিংক আ্কর লিংক। এই পদ্ধতির জন্য কাজ করার জন্য, আপনাকে নিশ্চিত করতে হবে আপনার মার্কডাউন প্রসেসর হেডিংয়ের জন্য ID তৈরি করে। RedCarpet with_toc_data অপশন দিয়ে খুব ভালো কাজ করে।
একটি বেসিক জেকিল জেনারেটর
জেকিলের জন্য আপনি কয়েক ধরনের প্লাগিন তৈরি করতে পারেন। আমরা একটি জেনারেটর বানাব।
জেনারেটরগুলো সিম্পলি এমন ক্লাস যেগুলো Jekyll::Generator-এই ইনহেরিট করে এবং যেগুলো একটি generate মেথড প্রদান করে।
জেনারেটরগুলো জেকিল সব মার্কডাউন ফাইল লোড করার পর কিন্তু সেগুলো HTML-এ কনভার্ট করার আগে চলে। generate মেথডে একটি site অবজেক্ট পাস করা হয়। এবং আপনি সাইট অবজেক্ট ব্যবহার করে আপনার সাইটের সব পেজ, পোস্ট এবং অন্যান্য রিসোর্স এক্সেস করতে পারেন।
নিচের উদাহরণে, আমরা একটি জেনারেটর তৈরি করছি যা সব পেজের মাধ্যমে লুপ করে এবং তাদের টাইটেল প্রিন্ট করে।
class MySubnavGenerator < Jekyll::Generator
def generate(site)
site.pages.each do |page|
puts page.data["title"]
end
end
end
আমরা জেনারেটরের ভেতরে পেজ এবং সাইট ডেটা মডিফাই ও করতে পারি—ফ্রন্ট-ম্যাটার এবং সাইট কনফিগারেশন ফাইল থেকে লোড করা ডেটা।
page.data["title"] += " - modified!"
site.data["tagline"]
মার্কডাউন-এইচটিএমএলে প্রি-রেন্ডারিং
আমরা আমাদের মার্কডাউন ডকুমেন্ট থেকে হেডিং এক্সট্রাক্ট করতে চাই। এটি করার সবচেয়ে সহজ উপায় হচ্ছে মার্কডাউনকে HTML-এ কনভার্ট করা এবং তারপর nokogiri-এর মতো একটি টুল দিয়ে HTML পার্স করা।
এটা কি আমাকে একটু গুঁড়ো লাগাচ্ছে? হ্যাঁ। কি এটি কিছুটা স্লো হবে? অবশ্যই। কিন্তু যেহেতু জেকিল একটি স্ট্যাটিক সাইট জেনারেটর, আমাকে রিয়েল-টাইম পারফরম্যান্স নিয়ে চিন্তা করতে হয় না। তাই আমি আমার নাক ধরেই কাজটি করে ফেলব।
এখানে, আমরা জেকিলের বিল্ট-ইন মার্কডাউন র্যাপার ব্যবহার করি প্রতিটি মার্কডাউন পেজ HTML-এ কনভার্ট করার জন্য।
class MySubnavGenerator < Jekyll::Generator
def generate(site)
parser = Jekyll::Converters::Markdown.new(site.config)
site.pages.each do |page|
if page.ext == ".md"
html = parser.convert(page['content'])
# এখানে html-এ কিছু করুন
end
end
end
end
হেডিং এক্সট্রাক্টিং
আমাদের নতুন ডকুমেন্টেশন সাইটের জন্য, আমি সিদ্ধান্ত নিলাম প্রতিটি H2 ট্যাগের একটি সাবনেভিগেশন লিংক থাকবে। তাই আমি nokogiri ব্যবহার করব প্রতিটি পেজের HTML পার্স করতে, তারপর পেজ থেকে প্রতিটি H2 ট্যাগ প্লাক আউট করব।
এখন পর্যন্ত, আমরা শুধু H2-এর কন্টেন্ট এবং ID স্ক্রিনে প্রিন্ট করব:
require "nokogiri"
class MySubnavGenerator < Jekyll::Generator
def generate(site)
parser = Jekyll::Converters::Markdown.new(site.config)
site.pages.each do |page|
if page.ext == ".md"
doc = Nokogiri::HTML(parser.convert(page['content']))
doc.css('h2').each do |heading|
puts "#{ heading.text }: #{ heading['id'] }"
end
end
end
end
end
সাবনেভিগেশন মেনু তৈরি
এখন যেহেতু আমাদের হেডিংর টেক্সট এবং ID আছে, আমরা সাবনেভিগেশন লিংকের একটি লিস্ট তৈরি করতে পারি।
আমরা এই লিংক লিস্টটি পেজের একটি ডেটা অ্যাট্রিবিউট হিসেবে সংরক্ষণ করব। তেমনি, আমরা পেজ টেমপ্লেট থেকে লিংকগুলো এক্সেস করতে পারব।
require "nokogiri"
class MySubnavGenerator < Jekyll::Generator
def generate(site)
parser = Jekyll::Converters::Markdown.new(site.config)
site.pages.each do |page|
if page.ext == ".md"
doc = Nokogiri::HTML(parser.convert(page['content']))
page.data["subnav"] = []
doc.css('h2').each do |heading|
page.data["subnav"] << {
"title" => heading.text,
"url" => [page.url, heading['id']].join("#")
}
end
end
end
end
end
এখন, আপনার টেমপ্লেটে, আপনি সাবনেভ লুপ করে প্রতিটি লিংক ডিসপ্লে করতে পারেন:
{% for item in page.subnav %}
<a href="{{ item.url }}">{{ item.title }}</a>
{% endfor %}
ট্রাবলশুটিং
যেমন আমি আগে বলেছি, এটি সব আপনার মার্কডাউন প্রসেসরের ওপর নির্ভর করে যা প্রতিটি হেডিংয়ের জন্য ইউনিক ID তৈরি করে। এখানে আমার _config.yml- থেকে মার্কডাউন সেটিংস:
# Redcarpet Markdown renderer ব্যবহার করুন
markdown: redcarpet
redcarpet:
extensions:
- 'no_intra_emphasis'
- 'fenced_code_blocks'
- 'autolink'
- 'strikethrough'
- 'superscript'
- 'with_toc_data'
- 'tables'
- 'hardwrap'
পরবর্তী...
উপরের পদ্ধতি খুব ভালো কাজ করে যদি আপনার শুধু একটি লেভেলের সাবনেভিগেশন দরকার হয়। কিন্তু কি হয় যদি আপনার আরও দরকার হয়? অর্থাৎ, আপনি চান H2-এর "ভেতর" থাকা সব H3 ট্যাগ আপনার মেনুতে সাব-সাবনেভিগেশন লিংক তৈরি করে? এটি এবং আরও অনেক কিছু আমরা ভবিষ্যতের একটি ব্লগ পোস্টে কভার করব। তাই টিউন্ড থাকুন!