HTML এর নতুন টেমপ্লেট ট্যাগ

মানসম্মত ক্লায়েন্ট-সাইড টেমপ্লেটিং

ভূমিকা

টেমপ্লেটিং ধারণাটি ওয়েব ডেভেলপমেন্টে নতুন নয়। আসলে, সার্ভার-সাইড টেমপ্লেটিং ভাষা/ইঞ্জিন যেমন জ্যাঙ্গো (পাইথন), ইআরবি/হামল (রুবি), এবং স্মার্টি (পিএইচপি) দীর্ঘকাল ধরে রয়েছে। যদিও গত কয়েক বছরে, আমরা MVC ফ্রেমওয়ার্কের একটি বিস্ফোরণ দেখেছি। তাদের সবগুলিই কিছুটা আলাদা, তবুও বেশিরভাগই তাদের উপস্থাপনামূলক স্তর (ওরফে দা ভিউ): টেমপ্লেটগুলি রেন্ডার করার জন্য একটি সাধারণ মেকানিক শেয়ার করে৷

চলুন মোকাবেলা করা যাক. টেমপ্লেট চমত্কার হয়. এগিয়ে যান, চারপাশে জিজ্ঞাসা করুন। এমনকি এর সংজ্ঞা আপনাকে উষ্ণ এবং আরামদায়ক বোধ করে:

"...প্রতিবার নতুন করে তৈরি করতে হবে না..." আপনার সম্পর্কে জানি না, তবে আমি অতিরিক্ত কাজ এড়িয়ে যেতে পছন্দ করি। তাহলে কেন ওয়েব প্ল্যাটফর্মে এমন কিছুর জন্য স্থানীয় সমর্থনের অভাব রয়েছে যা বিকাশকারীরা স্পষ্টভাবে যত্নশীল?

WhatWG HTML টেমপ্লেট স্পেসিফিকেশন হল উত্তর। এটি একটি নতুন <template> উপাদান সংজ্ঞায়িত করে যা ক্লায়েন্ট-সাইড টেমপ্লেটিং-এর জন্য একটি আদর্শ DOM-ভিত্তিক পদ্ধতির বর্ণনা করে। টেমপ্লেটগুলি আপনাকে মার্কআপের টুকরোগুলি ঘোষণা করতে দেয় যা HTML হিসাবে পার্স করা হয়, পৃষ্ঠা লোডের সময় অব্যবহৃত হয়, তবে রানটাইমে পরে ইনস্ট্যান্ট করা যেতে পারে। রাফায়েল ওয়েইনস্টাইন উদ্ধৃত করতে:

এগুলি এইচটিএমএল এর একটি বড় ওয়াড রাখার একটি জায়গা যা আপনি চান না যে ব্রাউজারটি কোনও কারণেই এলোমেলো করুক...

রাফায়েল ওয়েইনস্টাইন (স্পেক লেখক)

বৈশিষ্ট্য সনাক্তকরণ

বৈশিষ্ট্য সনাক্ত করতে <template> , DOM উপাদান তৈরি করুন এবং .content সম্পত্তি বিদ্যমান কিনা তা পরীক্ষা করুন:

function supportsTemplate() {
    return 'content' in document.createElement('template');
}

if (supportsTemplate()) {
    // Good to go!
} else {
    // Use old templating techniques or libraries.
}

টেমপ্লেট বিষয়বস্তু ঘোষণা

HTML <template> উপাদানটি আপনার মার্কআপে একটি টেমপ্লেট উপস্থাপন করে। এতে "টেমপ্লেট বিষয়বস্তু" রয়েছে; মূলত ক্লোনযোগ্য DOM এর জড় অংশ । টেমপ্লেটগুলিকে ভারার টুকরো হিসাবে ভাবুন যা আপনি আপনার অ্যাপের সারাজীবন ব্যবহার করতে পারেন (এবং পুনরায় ব্যবহার করতে পারেন)৷

একটি টেমপ্লেট করা বিষয়বস্তু তৈরি করতে, কিছু মার্কআপ ঘোষণা করুন এবং এটি <template> উপাদানে মোড়ানো:

<template id="mytemplate">
    <img src="" alt="great image">
    <div class="comment"></div>
</template>

স্তম্ভ

একটি <template> -এ কন্টেন্ট মোড়ানো আমাদের কয়েকটি গুরুত্বপূর্ণ বৈশিষ্ট্য দেয়।

  1. সক্রিয় না হওয়া পর্যন্ত এর বিষয়বস্তু কার্যকরভাবে নিষ্ক্রিয় । মূলত, আপনার মার্কআপ লুকানো DOM এবং রেন্ডার হয় না।

  2. একটি টেমপ্লেটের মধ্যে কোনো বিষয়বস্তুর পার্শ্বপ্রতিক্রিয়া থাকবে না। স্ক্রিপ্ট চালানো হয় না, ছবি লোড হয় না, অডিও প্লে হয় না ,...টেমপ্লেটটি ব্যবহার না করা পর্যন্ত।

  3. বিষয়বস্তু নথিতে নেই বলে মনে করা হয় । মূল পৃষ্ঠায় document.getElementById() বা querySelector() ব্যবহার করলে টেমপ্লেটের চাইল্ড নোড ফিরে আসবে না।

  4. টেমপ্লেটগুলি <head> , <body> , বা <frameset> এর ভিতরে যে কোনও জায়গায় স্থাপন করা যেতে পারে এবং সেই উপাদানগুলিতে অনুমোদিত যে কোনও ধরণের সামগ্রী থাকতে পারে। মনে রাখবেন যে "যেকোনও জায়গায়" মানে হল যে <template> নিরাপদে এমন জায়গায় ব্যবহার করা যেতে পারে যেগুলি HTML পার্সার অনুমোদন করে না... সমস্ত বিষয়বস্তু মডেল শিশুদের ছাড়া। এটিকে <table> বা <select> এর সন্তান হিসাবেও স্থাপন করা যেতে পারে:

<table>
  <tr>
    <template id="cells-to-repeat">
      <td>some content</td>
    </template>
  </tr>
</table>

একটি টেমপ্লেট সক্রিয় করা হচ্ছে

একটি টেমপ্লেট ব্যবহার করতে, আপনাকে এটি সক্রিয় করতে হবে। অন্যথায় এর বিষয়বস্তু কখনই রেন্ডার হবে না। এটি করার সবচেয়ে সহজ উপায় হল document.importNode() ব্যবহার করে এর .content এর একটি গভীর অনুলিপি তৈরি করা। .content প্রপার্টি হল একটি পঠনযোগ্য DocumentFragment যাতে টেমপ্লেটের সাহস থাকে।

var t = document.querySelector('#mytemplate');
// Populate the src at runtime.
t.content.querySelector('img').src = 'logo.png';

var clone = document.importNode(t.content, true);
document.body.appendChild(clone);

একটি টেমপ্লেট স্ট্যাম্প আউট করার পরে, এর বিষয়বস্তু "লাইভ হয়"। এই বিশেষ উদাহরণে, বিষয়বস্তু ক্লোন করা হয়, ছবির অনুরোধ করা হয় এবং চূড়ান্ত মার্কআপ রেন্ডার করা হয়।

ডেমো

উদাহরণ: জড় লিপি

এই উদাহরণটি টেমপ্লেট সামগ্রীর জড়তা প্রদর্শন করে। <script> শুধুমাত্র তখনই চলে যখন বোতাম টিপে, টেমপ্লেটটি স্ট্যাম্পিং করে।

<button onclick="useIt()">Use me</button>
<div id="container"></div>
<script>
  function useIt() {
    var content = document.querySelector('template').content;
    // Update something in the template DOM.
    var span = content.querySelector('span');
    span.textContent = parseInt(span.textContent) + 1;
    document.querySelector('#container').appendChild(
      document.importNode(content, true)
    );
  }
</script>

<template>
  <div>Template used: <span>0</span></div>
  <script>alert('Thanks!')</script>
</template>

উদাহরণ: একটি টেমপ্লেট থেকে ছায়া DOM তৈরি করা

বেশিরভাগ মানুষ .innerHTML এ মার্কআপের একটি স্ট্রিং সেট করে হোস্টের সাথে Shadow DOM সংযুক্ত করে:

<div id="host"></div>
<script>
  var shadow = document.querySelector('#host').createShadowRoot();
  shadow.innerHTML = '<span>Host node</span>';
</script>

এই পদ্ধতির সমস্যা হল যে আপনার শ্যাডো ডম যত জটিল হবে, আপনি তত বেশি স্ট্রিং কনক্যাটেনেশন করছেন। এটি স্কেল করে না, জিনিসগুলি দ্রুত অগোছালো হয়ে যায় এবং শিশুরা কাঁদতে শুরু করে। এই পদ্ধতিতেও XSS এর প্রথম জন্ম হয়েছিল! উদ্ধারের জন্য <template>

একটি ছায়া রুটে টেমপ্লেট সামগ্রী যুক্ত করে সরাসরি DOM-এর সাথে কাজ করা আরও বুদ্ধিমানের কাজ হবে:

<template>
<style>
  :host {
    background: #f8f8f8;
    padding: 10px;
    transition: all 400ms ease-in-out;
    box-sizing: border-box;
    border-radius: 5px;
    width: 450px;
    max-width: 100%;
  }
  :host(:hover) {
    background: #ccc;
  }
  div {
    position: relative;
  }
  header {
    padding: 5px;
    border-bottom: 1px solid #aaa;
  }
  h3 {
    margin: 0 !important;
  }
  textarea {
    font-family: inherit;
    width: 100%;
    height: 100px;
    box-sizing: border-box;
    border: 1px solid #aaa;
  }
  footer {
    position: absolute;
    bottom: 10px;
    right: 5px;
  }
</style>
<div>
  <header>
    <h3>Add a Comment
  </header>
  <content select="p"></content>
  <textarea></textarea>
  <footer>
    <button>Post</button>
  </footer>
</div>
</template>

<div id="host">
  <p>Instructions go here</p>
</div>

<script>
  var shadow = document.querySelector('#host').createShadowRoot();
  shadow.appendChild(document.querySelector('template').content);
</script>

গোটচাস

বন্য অঞ্চলে <template> ব্যবহার করার সময় আমি এখানে কয়েকটি গোটচা পেয়েছি:

  • আপনি যদি modpagespeed ব্যবহার করেন, তাহলে এই বাগ থেকে সতর্ক থাকুন। যে টেমপ্লেটগুলি ইনলাইন <style scoped> সংজ্ঞায়িত করে, অনেকগুলিকে পেজস্পিড-এর সিএসএস পুনর্লিখনের নিয়মগুলির সাথে মাথায় নিয়ে যাওয়া হয়।
  • একটি টেমপ্লেট "প্রি-রেন্ডার" করার কোন উপায় নেই, যার অর্থ আপনি সম্পদ প্রিলোড করতে পারবেন না, JS প্রক্রিয়া করতে পারবেন, প্রাথমিক CSS ডাউনলোড করতে পারবেন না। এটি সার্ভার এবং ক্লায়েন্ট উভয়ের জন্যই যায়। একটি টেমপ্লেট রেন্ডার করার একমাত্র সময় যখন এটি লাইভ হয়।
  • নেস্টেড টেমপ্লেটগুলির সাথে সতর্ক থাকুন৷ তারা আপনার প্রত্যাশা অনুযায়ী আচরণ করে না। উদাহরণ স্বরূপ:

    <template>
      <ul>
        <template>
          <li>Stuff</li>
        </template>
      </ul>
    </template>
    

    বাইরের টেমপ্লেট সক্রিয় করা ভিতরের টেমপ্লেট সক্রিয় হবে না. অর্থাৎ, নেস্টেড টেমপ্লেটগুলির প্রয়োজন হয় যে তাদের সন্তানদেরও ম্যানুয়ালি সক্রিয় করা হবে।

একটি মান রাস্তা

আমরা কোথা থেকে এসেছি তা ভুলে গেলে চলবে না। মান-ভিত্তিক এইচটিএমএল টেমপ্লেটের রাস্তাটি দীর্ঘ হয়েছে। বছরের পর বছর ধরে, আমরা পুনঃব্যবহারযোগ্য টেমপ্লেট তৈরি করার জন্য কিছু চতুর কৌশল নিয়ে এসেছি। নীচে আমি জুড়ে আসা দুটি সাধারণ বেশী. আমি তুলনা করার জন্য এই নিবন্ধে তাদের অন্তর্ভুক্ত করছি.

পদ্ধতি 1: অফস্ক্রিন DOM

একটি পদ্ধতি যা লোকেরা দীর্ঘদিন ধরে ব্যবহার করে আসছে তা হল "অফস্ক্রিন" DOM ​​তৈরি করা এবং hidden বৈশিষ্ট্য বা display:none ব্যবহার করে এটিকে দৃশ্য থেকে আড়াল করা।

<div id="mytemplate" hidden>
  <img src="logo.png">
  <div class="comment"></div>
</div>

যদিও এই কৌশলটি কাজ করে, সেখানে অনেকগুলি খারাপ দিক রয়েছে। এই টেকনিকের রানডাউন:

  • DOM ব্যবহার করা - ব্রাউজার DOM জানে। এটা এটা ভাল. আমরা সহজেই এটি ক্লোন করতে পারি।
  • কিছুই রেন্ডার করা হয় না - hidden যোগ করা ব্লকটিকে দেখানো থেকে বাধা দেয়।
  • জড় নয় - যদিও আমাদের বিষয়বস্তু লুকানো থাকে, তবুও ছবির জন্য একটি নেটওয়ার্ক অনুরোধ করা হয়৷
  • বেদনাদায়ক স্টাইলিং এবং থিমিং - একটি এমবেডিং পৃষ্ঠায় টেমপ্লেটে শৈলীগুলিকে স্কোপ করার জন্য #mytemplate এর সাথে তার সমস্ত CSS নিয়ম উপসর্গ করা আবশ্যক। এটি ভঙ্গুর এবং এর কোনো নিশ্চয়তা নেই যে আমরা ভবিষ্যতে নামকরণের সংঘর্ষের সম্মুখীন হব না। উদাহরণস্বরূপ, যদি এমবেডিং পৃষ্ঠায় ইতিমধ্যেই সেই আইডি সহ একটি উপাদান থাকে তাহলে আমরা হোজড থাকি৷

পদ্ধতি 2: ওভারলোডিং স্ক্রিপ্ট

আরেকটি কৌশল হল <script> ওভারলোড করা এবং একটি স্ট্রিং হিসাবে এর বিষয়বস্তু ম্যানিপুলেট করা। জন রেসিগ সম্ভবত প্রথম যিনি 2008 সালে তার মাইক্রো টেমপ্লেটিং ইউটিলিটি দিয়ে এটি দেখান। এখন handlebars.js এর মতো ব্লকে কিছু নতুন বাচ্চা সহ আরও অনেকে রয়েছে।

উদাহরণ স্বরূপ:

<script id="mytemplate" type="text/x-handlebars-template">
  <img src="logo.png">
  <div class="comment"></div>
</script>

এই টেকনিকের রানডাউন:

  • কিছুই রেন্ডার করা হয় না - ব্রাউজার এই ব্লকটি রেন্ডার করে না কারণ <script> display:none
  • নিষ্ক্রিয় - ব্রাউজার স্ক্রিপ্টের বিষয়বস্তুকে JS হিসাবে পার্স করে না কারণ এর ধরন "টেক্সট/জাভাস্ক্রিপ্ট" ছাড়া অন্য কিছুতে সেট করা আছে।
  • নিরাপত্তা সমস্যা - .innerHTML ব্যবহারকে উৎসাহিত করে। ব্যবহারকারীর সরবরাহকৃত ডেটার রান-টাইম স্ট্রিং পার্সিং সহজেই XSS দুর্বলতার দিকে নিয়ে যেতে পারে।

উপসংহার

মনে আছে যখন jQuery DOM এর সাথে কাজ করা সহজ করে দিয়েছে? ফলাফল হল querySelector() / querySelectorAll() প্লাটফর্মে যোগ করা হচ্ছে। স্পষ্ট জয়, তাই না? একটি লাইব্রেরি সিএসএস নির্বাচকদের সাথে DOM নিয়ে আসা জনপ্রিয় করে তোলে এবং স্ট্যান্ডার্ড পরে এটি গ্রহণ করে। এটা সবসময় যে ভাবে কাজ করে না, কিন্তু আমি ভালোবাসি যখন এটা করে.

আমি মনে করি <template> একটি অনুরূপ কেস। এটি আমরা যেভাবে ক্লায়েন্ট-সাইড টেমপ্লেটিং করি তা মানসম্মত করে, কিন্তু আরও গুরুত্বপূর্ণভাবে, এটি আমাদের 2008 হ্যাকের প্রয়োজনীয়তা দূর করে। সম্পূর্ণ ওয়েব অথরিং প্রক্রিয়াটিকে আরও বুদ্ধিমান, আরও রক্ষণাবেক্ষণযোগ্য এবং আরও সম্পূর্ণ বৈশিষ্ট্যযুক্ত করা আমার বইতে সর্বদা একটি ভাল জিনিস।

অতিরিক্ত সম্পদ