שלום אורח התחבר

3 רעיונות מדליקים לשימוש ב Tagged Template Literals

הבלוג מתעדכן בכל שבוע ביום ראשון. הזינו כתובת מייל וקבלו את הפוסטים החדשים לתיבה.

מתכנתי JavaScript כבר אמורים להכיר את אופרטור ה Template Literal, הוא סימן ` המאפשר פענוח משתנים בתוך מחרוזת. מעטים יודעים שאפשר לבנות שפה שלמה על אופרטור זה באמצעות פיצ'ר שנקרא Tagged Template Literals.

1איך זה עובד

באופן רגיל שתילת משתנים בתוך מחרוזת ב JavaScript נראית כך:

const user = 'Jones';
const text = 'hello world';
const greeting = `1. ${user} said: "${text}"`
console.log(greeting); // prints: 1. Jones said: "hello world"

עד כאן אין הפתעות, אבל מסתבר שאפשר להוסיף פונקציה משלנו לטיפול בפענוח המחרוזת, ולכתוב למשל קוד שנראה כך:

const user = 'Jones';
const text = 'hello world';
const greeting = b`1. ${user} said: "${text}"`

console.log(greeting); 
// prints: 1. <b>Jones</b> said: "<b>hello world</b>"
// (assuming we defined function b as a tag)

כל פונקציה יכולה לשמש בתור תגית. בשימוש כזה הדפדפן באופן אוטומטי מפצל את המחרוזת שבתוך ה ` לחלקים ומפעיל את הפונקציה עם רשימת החלקים ורשימת המשתנים שצריך לשתול פנימה. הקוד שרשמתי מעלה שקול לקוד הבא שמשתמש בפונקציה b באופן ישיר (וזכרו עדיין לא הגדרתי את קוד הפונקציה כך שבינתיים אף אחת מהגרסאות לא תעבוד):

const user = 'Jones';
const text = 'hello world';
const greeting = b(['1. ', ' said: "', '"'], 'Jones', 'hello world')
console.log(greeting);

הפרמטר הראשון לפונקצית תג הוא רשימת המחרוזות הקבועות, ולאחר מכן לפי סדר המשתנים שנשתלו בתוך המחרוזת. בשביל שהקוד יעבוד יש להגדיר פונקציה בשם b שיודעת להתמודד עם הפעלה מסוג זה. המימוש הבא יעטוף כל אחד מהמשתנים השתולים בתגית b:

function b(strings, ...values) {
  const result = [];
  strings.forEach(s => {
    result.push(s);
    result.push('<b>' + (values.shift() || '') + '</b>');
  });
  return result.join('');
}

ואפשר לראות איך הכל מתחבר כאן:

אז מה אפשר לעשות עם זה? קבלו שלושה רעיונות מדליקים.

2שמירה על תווים רגישים ב HTML

הקוד הבא עלול להוביל לבעיית אבטחה אם אין סינון על הקלט שמועבר אליו:

const p = document.querySelector('#content');
p.innerHTML = `${user} said: <b>We</b> must go to ${thePlace}`;

הבעיה שאם המשתנים user או thePlace כוללים תגיות HTML, תגיות אלו ייכתבו לעמוד ועלולים להוביל להרצת קוד JavaScript שלא התכוונו להריץ. הפתרון: להחליף את התווים המיוחדים בגירסא הרגילה שלהם. כך זה נראה עם הספריה lodash.

const p = document.querySelector('#content');
const safeUser = _.escape(user);
const safePlace = _.escape(thePlace);

p.innerHTML = `${safeUser} said: <b>We</b> must go to ${safePlace}`;

אבל הרבה יותר קל להשתמש ב tag:

function safe(strings, ...values) {
  const result = [];
  strings.forEach(s => {
    result.push(s);
    result.push(_.escape(values.shift() || ''));
  });
  return result.join('');
}

p.innerHTML = safe`${user} said: <b>We</b> must go to ${thePlace}`;

כי את התג צריך להגדיר רק פעם אחת במקום בכל שימוש. הקוד המלא עם התוצאה נראה כך:

3תרגום

הספריה es2015-i18n-tag מציגה תחביר לתרגום המבוסס על Template String Tags, כך שלאחר התקנתה אפשר לכתוב קוד כזה:

console.log(i18n`Hello ${ name }, you have ${ amount }:c in your bank account.`)
// Hallo Steffen, Sie haben US$ 1,250.33 auf Ihrem Bankkonto.

מה שיפה כאן שבניגוד להפעלת פונקציה, ספריה זו מתרגמת גם סימני מיקום. שימו לב לנקודותיים ואז c אחרי הסכום, שמציין שזהו מחיר ולכן מופיע סימן הדולר. דוגמא נוספת הפעם עם תאריך:

const date = new Date(2012, 11, 20, 19, 0, 0);
i18n`The date is ${date}:t(D).`

// The date is Thursday, December 20, 2012.

סימני המיקום נכתבים כחלק מהמחרוזת בצמוד למשתנים, ומנגנון ה Template Tags מעביר אותם אוטומטית לפונקציה בצורה שיהיה קל לתרגם גם אותם.

למידע נוסף בקרו באתר הספריה בגיטהאב: https://github.com/skolmer/es2015-i18n-tag

4כתיבת CSS ב JavaScript (עבור ריאקט)

מתכנתי React מכירים את הצורך לכתוב CSS בתור אוביקט JavaScript. הקוד הבא למשל מייצג בריאקט פיסקה בצבע טקסט אדום וגבול כתום:

<p style={{ color: 'red', border: '1px solid orange' }}>Hello World</p>

זה לא הכי נוח בעולם, כי כלי הפיתוח שלנו לא יודעים שאנחנו כותבים CSS ולכן אנו מפסידים השלמות ובדיקות תקינות אוטומטיות. ספריה בשם styled-components נעזרת ב Tagged Template Literals כדי לשפר את הכתיב (ועושה עוד מיליון דברים שקשורים לעיצוב על הדרך). באמצעותה אפשר יהיה לכתוב קוד שנראה כך:

const Content = styled.p`
    color: red;
    border: 1px solid orange
`;

למידע נוסף בקרו בעמוד הספריה בגיטהאב או בדף התיעוד שם תוכלו גם לנסות לכתוב פקדים מעוצבים בעצמכם באמצעות כתיב שנראה כמו CSS רגיל.

5ועכשיו תורכם

נתקלתם בשימוש מעניין ל Tagged Template Literals? אולי לא ידעתם שככה קוראים לזה וחשבתם שמישהו שינה לכם את השפה? ספרו לי על זה בתגובות.


נהניתם מהפוסט? מוזמנים לשתף ולהגיב