مولّد slug للروابط
يحوّل العنوان إلى slug للرابط مع نقل حرفي من العبرية والعربية والسيريلية واليونانية، وصيغة مسار بيونيكود وكشف التعارضات.
creme-brulee-grusse-aus-munchencrème-brûlée-grüße-aus-münchencr%C3%A8me-br%C3%BBl%C3%A9e-gr%C3%BC%C3%9Fe-aus-m%C3%BCnchenيعرض المتصفح الصيغة المقروءة أعلاه ويرسل هذه. وكلتاهما المسار نفسه.
ما الذي يفعله هذا الأداة
ألصق عنوانًا بأي خط فيعود إليك على هيئة الـ slug الذي يستطيع الرابط حمله: حروف صغيرة، بلا علامات ترقيم، وكلمات يصل بينها فاصل من اختيارك. تُزال العلامات اللاتينية، وتُنقل العبرية والعربية والسيريلية واليونانية حرفيًّا إلى حروف لاتينية.
وإلى جانب الـ slug يقف العنوان نفسه محفوظًا بخطه الأصلي. وتلك الصيغة مسار مشروع هي الأخرى، وهي في الخطوط التي تفقد أكثر ما تفقد في النقل الحرفي غالبًا الجواب الأفضل — ولذلك تُنتَج الصيغتان من عنوان واحد بدل أن تختار الأداة عنك.
لماذا يوجد الـ slug
الـ slug هو الجزء الذي يقرأه الإنسان من الرابط: القطعة التي تلي آخر شرطة مائلة فتسمّي الصفحة بدل أن ترقّمها. وهو موجود لأن مسارًا يُقرأ كالكلمات يصمد أمام اللصق في رسالة، والطبع على شريحة عرض، والقراءة بصوت عالٍ عبر الهاتف، والمعرّف الرقمي لا يصمد أمام شيء من ذلك.
ولهذا أيضًا جاءت صيغته بهذا الضيق. ينبغي للـ slug أن يكون ثابتًا — فتغييره يكسر كل رابط يشير إلى الصفحة بالفعل — وأن يكون قاطع الدلالة حين يُكتب باليد، وهو ما يستبعد المسافات، والحروف الكبيرة التي قد يستنسخها القارئ وقد لا يفعل، وعلامات الترقيم التي تعني شيئًا لصدفة الأوامر أو لمحلّل Markdown.
كيف تسقط العلامات
معظم العلامات اللاتينية تزيلها المنصّة لا جدول. فيونيكود يعرّف é على أنها قابلة للتفكيك إلى e مجردة يتبعها علامة حِدّة مركِّبة، ولذلك فإن التطبيع إلى تلك الصيغة المفكَّكة ثم إسقاط كل علامة مركِّبة يُبقي الحرف المجرد. والعملية نفسها تكفي لـ ñ و‑ç و‑ő ومئات غيرها، ولا يمكن أن تتقادم، لأنها تستعمل بيانات يونيكود التي يحملها المتصفح أصلًا.
وهي لا تكفي لكل شيء، والثغرة جديرة بأن تُعرف. فالحرف الذي علامته خط يشقّ الرسم لا علامة فوقه — ø و‑ł و‑đ و‑ħ و‑ŧ — محرف واحد لا يتجزأ وبلا تفكيك البتة، فإزالة العلامات تتركه كما كان تمامًا. وكذلك الحال في الحرف المزدوج: ß و‑æ و‑œ يمثّل كل منها تتابع أصوات، لا حرفًا وزينة فوقه. وكلها تحتاج إلى كتابة صريحة، ولولاها لاختفت من الـ slug ببساطة.
لماذا يغيّر إعداد اللغة الجواب
ليس لـ ü نقل لاتيني واحد صحيح. فالألمانية تكتبها ue منذ ما قبل وجود علامة الترقيق — إذ بدأت النقطتان e صغيرة مرفوعة — ولذلك فإن Müller هو mueller على وجهه، ويجد القارئ الألماني muller خطأً. أما الفرنسية والإسبانية والبرتغالية فتعامل علاماتها بوصفها زينة على حرف هو نفسه في الأصل، ولذلك فإن crème brûlée هو creme-brulee على وجهه، وكتابته cruemme لا معنى لها.
واللغات الإسكندنافية يخالف بعضها بعضًا على النحو ذاته. فالدنماركية والنرويجية تضاعفان حرف العلة اتّباعًا للكتابة الأقدم التي حلّ الحرف محلها؛ والسويدية لا تفعل:
- الألمانية — تصير ä إلى ae، و‑ö إلى oe، و‑ü إلى ue، و‑ß إلى ss. فيصير München إلى muenchen.
- الدنماركية والنرويجية — تصير æ إلى ae، و‑ø إلى oe، و‑å إلى aa. فيصير Ålborg إلى aalborg.
- السويدية — تصير ä إلى a، و‑ö إلى o، و‑å إلى a. فيصير Ålborg إلى alborg.
- العام — تُسقَط كل علامة ويبقى الحرف الأساس. فيصير Ålborg إلى alborg و‑München إلى munchen.
وليست هذه تقريبات متنافسة لجواب واحد؛ بل أربعة أجوبة صحيحة مختلفة لأربعة أسئلة مختلفة. ولا يمكن أن يكون الافتراضي إلا واحدًا، ولذلك جُعل الإعداد ظاهرًا وتقول الأداة أي عرف أنتج ما تراه. وحرف واحد لا يختلف في أي مكان: ß حرف مزدوج لا علامة، فإسقاطه يمحو صوتًا، وهو ss في كل الإعدادات هنا.
الخطوط التي تحتاج إلى جدول
ليس في المتصفح ما ينقل السيريلية أو اليونانية أو العبرية أو العربية إلى اللاتينية، فكل منها جدول كُتب باليد في مقابل معيار منشور. واثنان منها يخرجان خروجًا حسنًا، لأنهما يكتبان حركاتهما:
- السيريلية تتبع BGN/PCGN، وهو النقل المعتمد في الخرائط وجوازات السفر الإنجليزية: ж هي zh، و‑ч هي ch، و‑щ هي shch، و‑х هي kh. فتصير Москва إلى moskva و‑Чехов إلى chekhov.
- واليونانية تتبع ELOT 743 بما فيه من ثنائيات يعرّفها: ου هي ou لا oy، و‑ευ هي ev. فتصير Αθήνα إلى athina و‑Ευρώπη إلى evropi.
و‑ISO 9 هو المعيار السيريلي المعروف الآخر، وهو متروك هنا عن قصد. فهو قابل للعكس، وتلك غايته، لكنه يبلغ ذلك بالعلامات: ж فيه ž. ولا متّسع في الـ slug لعلامة الهاء المقلوبة، فينبسط الحرف من فوره إلى z — فيصير Жуков و‑Зуков slug واحدًا. أما ثنائي BGN فيصمد أمام هذا الانبساط.
وفي الجدول السيريلي تفصيل يسهل الخطأ فيه ويستحق أن يُقال. فـ ё و‑й تبدوان حرفين بعلامة، ويونيكود يفكّكهما على هذا النحو فعلًا، غير أن العلامة هنا هي ما يجعلهما حرفين مختلفين لا زينة على الحرف نفسه. وإزالة العلامات قبل الرجوع إلى الجدول — وهو الترتيب الصحيح لكل خط آخر هنا — تحوّل Ёлка بهدوء إلى elka و‑Андрей إلى andrei.
العبرية والعربية، وما تفقدانه
يكتب الخطّان الصوامت ويتركان معظم الحركات لعلامات لا يحملها النص العادي. وليست هذه مشكلة ترميز كان يمكن لهذه الأداة أن تحلّها بجدول أفضل: فالمعلومة ليست في النص أصلًا. «مقال» أربعة حروف، ميم-قاف-ألف-لام، والقراءة maqal تأتي من قارئ يعرف الكلمة سلفًا. أما حرفًا حرفًا فلا يمكن أن تخرج إلا mqal.
وما يمكن عمله معمول. فحيث يقوم الحرف مقام علامة الحركة يُستفاد من الموضع، لأنه الدليل الوحيد الذي يتركه نص غير مشكول:
- ו و‑י صامتان في أول الكلمة وحرفا علة في وسطها، وهذا ما يجعل שלום تخرج shlom لا shlvm.
- و‑וו أو יי المضاعفة هي الصامت في الموضعين — وهذا التضعيف هو بعينه طريقة العبرية في الفصل بين القراءتين.
- و‑ב و‑כ و‑פ شديدة في أول الكلمة ورخوة في وسطها. والدَّغَش الذي يميّز بينهما علامة حركة، فلم يبقَ إلا الموضع.
- والحرف الذي يتبعه غِرِش هو الصوت الذي لا حرف له في الأبجدية: ג׳ هي j، و‑צ׳ هي ch، و‑ז׳ هي zh. وإهماله يجعل ג׳אז كلمة أخرى.
- والصوامت المفخَّمة في العربية تنطبق على نظائرها المرقَّقة، لأن ASCII لا موضع فيه للنقطة السفلى التي تميّزها. فتُنتج «صابر» و«سابر» الـ slug نفسه.
والحاصل مقروء يمكن التعرّف عليه، وليس كتابة يسمّيها أحد صحيحة. وتقول الأداة ذلك عند كل نتيجة عبرية أو عربية بدل أن تقدّم جوابًا ناقصًا على أنه تام — وتشير إلى الصيغة أدناه، التي لا تفقد شيئًا البتة.
مسار يونيكود الذي لا يحتاج إلى نقل حرفي
مسار الرابط غير محصور في ASCII. فالمعيار RFC 3987 يعرّف الـ IRI — وهو معرّف يجوز أن يحمل أي محرف يونيكود — وقاعدة إرساله على الشبكة أن تُرمَّز بايتات UTF-8 بصيغة النسبة المئوية. وكل متصفح يفعل ذلك منذ عقدين، ولهذا تقدّم ويكيبيديا عناوين مقالاتها العربية والروسية بأسمائها نفسها، ويعرضها شريط العنوان مقروءة.
ومن ثمّ فالمخرج الثاني هنا هو العنوان وقد نُظّفت علاماته ومسافاته ولم يُمسّ فيه غير ذلك، والثالث هو صورته الحقيقية على الشبكة. وهما المسار نفسه: المقروء ما يعرضه المتصفح وما ينسخه الإنسان، والمرمَّز ما يسجّله الخادم.
وأيّهما تستعمل قرار حقيقي لا إجراء شكلي. فصيغة يونيكود لا تفقد شيئًا، وتُقرأ قراءة صحيحة لكل من يعرف اللغة، وهي ما سيعرضه محرك البحث. أما الصيغة المنقولة فتصمد أمام اللصق في مواضع تفسد الترميز، وتدخل في أنظمة تفترض مسارات ASCII، ويمكن قراءتها عبر الهاتف. وفي العربية والعبرية على وجه الخصوص تكون صيغة يونيكود عادةً الجواب الأفضل، وذلك بالضبط لأن النقل الحرفي عاجز عن ردّ الحركات.
التعارضات، ولماذا لا تُحلّ عنك
صوغ الـ slug يزيل الترقيم، فالعناوين التي لا تختلف إلا فيه تكفّ عن الاختلاف رأسًا. فـ«دليلنا إلى CSS» و«دليلنا إلى CSS!» مقالتان و‑slug واحد. وفي وضع القائمة يُعلَّم كل اصطدام كهذا بالسطر الذي تعارض معه، لأن هذا هو العطب الذي يخفيه نظام إدارة المحتوى: يضيف لاحقة في صمت، وينشر، فإذا الرابط الذي توقعته للمقالة الأخرى.
واللاحقة متاحة مفتاحًا يُنتج أسلوب WordPress و‑Django — dlylna-ila-css و‑dlylna-ila-css-2 — لحالة القائمة التي يُراد لصقها في مكان ما كما هي. وهو مطفأ افتراضيًّا لأن التعارض في الغالب مشكلة محتوى لا مشكلة تسمية، ويبقى التعارض معلَّمًا حتى مع تشغيل المفتاح، فتشغيله إذن لا يخفي شيئًا.
الطول، والقطع في الموضع الصحيح
حدّ الطول يقطع عند حدّ فاصل، ولا يقطع داخل كلمة أبدًا. فالبتر في وسط الكلمة لا يعطي slug أقصر بقدر ما يعطي slug آخر — و‑introduction-to-crypt ليس introduction-to-cryptography أكثر ترتيبًا — ونصف الكلمة كلمة تعني شيئًا آخر. وإذا كانت كلمة واحدة أطول من الحدّ فلا حدّ يُقطع عنده، فتُعاد كاملة بدل أن تُشرَّح.
وليس ثمّة حدّ صحيح على الإطلاق. فمحركات البحث تعرض نحو الستين إلى السبعين محرفًا الأولى من الرابط، والأنظمة القديمة تحدّ أحيانًا مقطع المسار، لكن لا شيء ينكسر عند رقم بعينه. وترك الحقل فارغًا يترك الـ slug بالطول الذي يقتضيه العنوان.
الأسئلة الشائعة
- ما المحارف الآمنة في slug الرابط؟
- حروف ASCII الصغيرة والأرقام وفاصل واحد ستعمل في كل مكان بلا استثناء. والشرطة هي الفاصل المتعارف عليه؛ والشرطة السفلية تعمل مثلها تمامًا لكن رؤيتها أعسر تحت رابط مسطَّر. أما المسافات والحروف الكبيرة وعلامات الترقيم فكلها قابلة للترميز نظريًّا وكلها تجرّ المتاعب عمليًّا، ولذلك يزيلها الـ slug.
- شرطة أم شرطة سفلية؟
- شرطة، لسببين يعمّران أطول من الموضة. فهي ما تستعمله كل منصّة كبيرة، فهي إذن ما يتوقعه القرّاء وسائر الأدوات، وهي تختفي تحت التسطير الذي تحمله أكثر الروابط، بخلاف الشرطة السفلية. والخيار معروض هنا لأن للأنظمة القائمة أعرافًا قائمة، ولأن الاتساق داخل الموقع الواحد أهم من أيّ من الجوابين.
- لماذا يفقد عنواني العربي أو العبري حركاته؟
- لأنها لم تُكتب قط. فالخطّان يعلّمان معظم الحركات بنقاط يُسقطها النص العادي، فالقراءة حرفًا حرفًا هي كل ما تستطيع أي أداة إنتاجه دون محرّك تشكيل يخمّن الكلمة المقصودة. وهذه الأداة تنقل ما هو مكتوب فعلًا، وتصرّح بذلك على النتيجة، وتعرض صيغة المسار بيونيكود التي تبقي العنوان كما كُتب تمامًا.
- هل يمكن أن يحتوي الرابط على عربية أو عبرية أو صينية مباشرة؟
- نعم. يستطيع المسار حمل أي محرف يونيكود؛ ويُرمَّز بالنسبة المئوية بصيغة UTF-8 على الشبكة، ويعرضه المتصفح مقروءًا. وهكذا تقدّم ويكيبيديا عناوين مقالاتها بكل لغة تغطيها. وتعرض هذه الأداة الصيغتين، المقروءة والمرمَّزة، لأن الثانية هي التي تظهر في سجلات الخادم وفي التحليلات.
- لماذا يكون Müller أحيانًا mueller وأحيانًا muller؟
- لأن كليهما صحيح، في لغتين مختلفتين. فالألمانية تكتب علامة الترقيق بحروفها كاملة — إذ بدأت النقطتان e صغيرة مرفوعة — بينما تعامل الفرنسية والإسبانية علاماتهما بوصفها زينة على حرف هو نفسه في الأصل. وإعداد اللغة يختار عرفًا، والأداة تخبرك بأيّها طبّقت.
- لماذا يُنتج عنوانان من عناويني الـ slug نفسه؟
- لأن صوغ الـ slug يزيل الترقيم وحالة الأحرف، وهما في الغالب كل ما يفرّق بين عنوانين. ووضع القائمة يعلّم كل تعارض بالسطر الذي اصطدم به. ويمكنك تشغيل لاحقة -2 على طريقة WordPress، غير أن السؤال الأعمق — أينبغي حقًّا أن تحمل مقالتان اسمًا واحدًا تقريبًا — جدير بأن يُجاب أولًا.
- هل يُرسَل شيء مما أكتبه إلى خادم؟
- لا. كل تحويل يجري داخل متصفحك؛ ولا شيء يُرفَع أو يُسجَّل، وهو يعمل بلا اتصال بالشبكة.