Hello our valued visitor, We present you the best web solutions and high quality graphic designs with a lot of features. just login to your account and enjoy ...
Hello our valued visitor, We present you the best web solutions and high quality graphic designs with a lot of features. just login to your account and enjoy ...
رقم الخبر | عنوان الخبر | التفاصيل |
---|---|---|
59,820 | مدخل إلى الخوارزميات |
تُحدَّد مشكلةٌ خوارزميةٌ ما من خلال وصف المجموعة الكاملة للمدخلات -الحالات التطبيقية instances- التي يجب أن تعمل عليها المشكلة وكذلك مخرجاتها بعد العمل على إحدى تلك الحالات. واعلم أن التمييز بين المشكلة نفسها والحالة التطبيقية عليها instance مهم جدًا، فمثلًا، تُعرَّف المشكلة الخوارزمية المعروفة بالترتيب sorting على النحو التالي:
قد تكون الحالة التطبيقية لمشكلة الترتيب instance of sorting أيّ تسلسل من العناصر، فقد تكون مصفوفةً من السلاسل النصية، مثل { Haskell, Emacs } أو سلسلة من الأرقام، مثل: {154، 245، 1337}. مثال على خوارزمية Fizz Buzz بسيطة في swiftيمهد هذا الدرس لكيفية كتابة الخورازميات في لغة Swift لمن لا يملك خبرة في هذه اللغة أو من أتى من خلفية برمجية مختلفة مثل بايثون أو جافا. Fizz Buzzانظر سلسلة الأرقام التالية: 1 2 3 4 5 6 7 8 9 10لعلك رأيت Fizz Buzz مكتوبة بهذه الصيغة أو FizzBuzz أو Fizz-Buzz، وجميعها تشير إلى نفس الشيء، وهذا "الشيء" هو محل النقاش هنا، لنبدأ بتعريف هاتين الكلمتين. يشير المصطلحَان Fizz و Buzz إلى أيّ عدد مضاعف للعدد 3 أو 5 على الترتيب، أي إذا كان العدد يقبل القسمة على 3 فيمكن استبداله بـ fizz، وإذا كان قابلاً للقسمة على 5 فيُستبدل ب buzz. أما إذا كان من مضاعفات 3 و 5 فيُستبدَل بـ fizz buzz. أما المعنى الحرفي لهاتين الكلمتين فيشير إلى الصوت التي تحدثه كل كلمة منهما، وأصل استخدامها في هذا المثال يرجع للعبة أطفال شهيرة تُسمّى fizz buzz تقوم على نفس المبدأ. لتنفيذ هذه الخوارزمية، افتح Xcode أو VS code (أو محرِّرك الذي تفضِّله) لإنشاء برنامج جديد وتهيئة مصفوفة من 1 إلى 5، ستكون 3 هي fizz هنا و 5 هي buzz، انظر: let number = [1,2,3,4,5]هنا نمر على جميع عناصر المصفوفة للعثور على جميع قيم fizz و buzz، والتحقق ممّا إذا كانت العناصر من النوع fizz أو buzz، ولذا سننشئ حلقة for كما يلي: for num in number { // الحسابات هنا }بعد هذا، سنستخدم العبارة الشرطية if else، وعامل الباقي module operator في لغة swift أي % لتحديد مواقع fizz و buzz. for num in number { if num % 3 == 0 { print("\(num) fizz") } else { print(num) } }يكون الخرج الناتج: 1 2 3 fizz 4 5سنضيف الآن الجزء المتعلق بالكلمة Buzz مستخدمين نفس التقنية: for num in number { if num % 3 == 0 { print("\(num) fizz") } else if num % 5 == 0 { print("\(num) buzz") } else { print(num) } }سنزيد عناصر المصفوفة إلى 1-15. لاحظ أنّه بما أن 15 مضاعف لكلّ من 3 و 5، فينبغي استبدالها بـ fizz buzz: for num in number { if num % 3 == 0 && num % 5 == 0 { print("\(num) fizz buzz") } else if num % 3 == 0 { print("\(num) fizz") } else if num % 5 == 0 { print("\(num) buzz") } else { print(num) } }ما تزال لدينا مشكلة قائمة، فالغرض الأساسي من الخوارزمية هو ترشيد وقت التنفيذ. تخيّل لو زدنا نطاق المصفوفة من 1-15 إلى 1-100، سيكون على المُصرِّف فحص كل عدد على حدة لتحديد ما إذا كان قابلاً للقسمة على 3 أو 5، ثمّ سيمرّ على الأعداد ثانية للتحقق ممّا إذا كانت قابلة للقسمة على 3 و5 (معًا)، كما سيتعيّن على الشيفرة أن تمرّ على كلّ عدد في المصفوفة مرّتين لأنّها ستتحقق من قابلية قسمة العدد على 3 أولًا، ثمّ على 5. ولتسريع هذه العملية، يمكن أن نأمر المصرّف بقسمة الأعداد على 15 مباشرة. انظر الشيفرة النهائية: for num in number { if num % 15 == 0 { print("\(num) fizz buzz") } else if num % 3 == 0 { print("\(num) fizz") } else if num % 5 == 0 { print("\(num) buzz") } else { print(num) } }هنئيًا لك، بهذا تكون قد كتبت أوّل خوارزمية لك، يمكنك استخدامها في أيّ لغة برمجة، وستعمل كما هو مُتوقّع. ترجمة -بتصرّف- للفصل الأول من كتاب Algorithms Notes for Professionals. اقرأ أيضًا |
59,745 | هل تغيرت الأعراض لدى الملقحين عند الإصابة بـ "دلتا - كورونا"؟ | اللقاحات المعتمدة ضد فيروس كورونا لا توفر مناعة كاملة، لكنها توفر حماية كبيرة في حال الإصابة بفيروس كورونا. مع انتشار متحور "دلتا" بدأت أعراض جديدة تظهر على المصابين بين الملقحين، فما السبب؟ |
59,725 | خطوات تغيير لون واجهة أندرويد 12 |
استخدمت غوغل أسلوب Material بشكل كبير في واجهة أندرويد 12، حيث أصبحت الواجهة الرسمية للنظام مع التطبيقات الجديدة. وتدعى واجهة أندرويد 12 الجديدة Material You، مما يوحي بأن الشركة توفر اختيارات تخصيص جديدة ومتنوعة للنظام. لذلك يمكنك تغيير ألوان واجهة النظام بالكامل داخل التطبيقات عبر إعدادات النظام الخاصة، أو يمكنك ترك النظام يختار اللون المناسب من ألوان الخلفية التي تستخدمها. لكن تختار غوغل مجموعة من الألوان المناسبة للخلفية التي تستخدمها حتى تخرج واجهة أندرويد 12 بأفضل شكل ممكن. خطوات تغيير لون واجهة أندرويد 12يجب أن يستخدم هاتفك نظام أندرويد 12 حتى إن كان في الطور التجريبي، وتتاح هذه الاختيارات لجميع الأجهزة التي تأتي بنظام أندرويد 12. توجه في البداية إلى قائمة الإعدادات ثم قائمة إعدادات الخلفية والأسلوب. وتجد داخل هذه الإعدادات زرًا يدعى الألوان الأساسية، ويمكنك الضغط عليه إن لم تعجبك الألوان التي اختارها النظام. وبعد ذلك تظهر لك قائمة اختيار الألوان المختلفة، وتستطيع تجربة الألوان التي ترغب بها عبر هذه القائمة قبل تطبيقها على كامل النظام. وتستطيع العودة إلى الألوان المتناسبة مع الخلفية عبر الضغط على زر ألوان الخلفية الموجود إلى جانب الألوان الأساسية. مميزات إضافية في النظاميأتي نظام أندرويد 12 بمجموعة جديدة من المميزات التي تقدمها جوجل لأول مرة، وتجعل هذه المميزات تجربة استخدام النظام أفضل. تأتي أحد المميزات الجديدة في أندرويد 12 لتسمح لك بتجربة الألعاب قبل تحميلها وتثبيتها على هاتفك، وذلك عبر خاصية تدعى Play As You Download. حيث تعمل هذه الخاصية بشكل يشبه بلاي ستيشن 4، حيث تستطيع تجربة اللعبة أثناء تحميل الملفات الخاصة بها. كما قررت جوجل التخلي عن تنسيق APK المشهور الذي استخدمته لسنوات طويلة منذ ظهور الأندرويد لصالح تنسيق AAB. ويتيح تنسيق AAB مجموعة من المميزات الجديدة في التعامل مع التطبيقات على الهاتف، ولكن لتتمكن من تشغيل التنسيق الجديد يجب أن تمتلك خدمات جوجل على هاتفك. وقد طورت جوجل هذا التنسيق الجديد بنفسها لتحكم سيطرتها على متاجر الأندرويد، وحتى تجبر المستخدم على تحميل التطبيقات من غوغل بلاي. |
59,670 | مصفوفة المخزن المؤقت ArrayBuffer والمصفوفات الثنائية binary arrays |
نتعامل في تطوير الويب مع البيانات بالصيغة الثنائية لما نتعامل مع الملفات، سواءً عند إنشائها أو رفعها أو تنزيلها، كما يمكن استخدامها في عمليات معالجة الصور، ويمكن إنجاز كل ما سبق في JavaScript التي تتميز العمليات الثنائية فيها بأنها عالية الأداء على الرغم من وجود بعض الالتباسات، نظرًا لوجود العديد من الأصناف، منها ArrayBuffer وUint8Array وDataView وBlob وFile، وغيرها. لا توجد طريقة معيارية للتعامل مع البيانات الثنائية في JavaScript موازنةً بغيرها من اللغات، لكن عندما نصنف الأمور فسيبدو كل شيء بسيطًا نوعًا ما، إذ يمثل الكائن الثنائي الأساسي ArrayBuffer مثلًا مرجعًا إلى مساحة ذاكرة متجاورة وذات حجم محدد، ويمكن إنشاؤه كالتالي: let buffer = new ArrayBuffer(16); // إنشاء مخزن مؤقت حجمه 16 alert(buffer.byteLength); // 16حيث تحجز الشيفرة السابقة حجمًا من الذاكرة مقداره 16 بايت، ويُملأ بالأصفار. اقتباسلايمثل الكائن ArrayBuffer مصفوفةً من الأشياء. لتوضيح الأمور لا بدّ من الإشارة أن ArrayBuffer لا يشترك مع المصفوفات Array بأي شيء:
فالكائن ArrayBuffer هو مساحة من الذاكرة التي لا يمكن معرفة ما يُخزّن فيها، بل هي سلسلة خام من البايتات، وللتعامل مع ArrayBuffer، سنحتاج إلى كائن عرض لا يخزن أي بيانات بمفرده، بل تنحصر مهمته في تفسير البايتات المخزنة في ArrayBuffer، ومن بين هذه الكائنات الآتي:
وبالتالي سيفسَّر الكائن المؤلف من 16 بايت -وفق الكائنات السابقة- إلى 16 عدد صغير، أو 8 أرقام أكبر (بايتان لكل عدد)، أو 4 أعداد أضخم (4 بايتات لكل عدد)، أو عددين بالفاصلة العائمة عاليي الدقة (8 بايتات لكل منهما). فالكائن ArrayBuffer هو الكائن البنيوي وأساس البيانات الخام. ولا بدّ من استخدام كائن عرض عند محاولة الكتابة ضمنه أو المرور على قيمه وكذلك لأي عملية بالأساس، مثلًا: let buffer = new ArrayBuffer(16); // إنشاء مخزن مؤقت من 16 بايت let view = new Uint32Array(buffer); // تعامل مع المخزن كعدد صحيح من 32-بت alert(Uint32Array.BYTES_PER_ELEMENT); // أربعة بايت لكل عدد alert(view.length); // 4 alert(view.byteLength); // 16 // كتابة قيمة view[0] = 123456; // المرور على قيمه for(let num of view) { alert(num); // 123456, then 0, 0, 0 (أربعة قيم ككل) } الكائن TypedArrayإنّ المصطلح الرئيسي لكائنات العرض السابقة هو مصفوفات النوع TypedArray، والتي تشترك جميعها بمجموعة التوابع والخصائص، مع ملاحظة عدم وجود دالة بانية اسمها TypedArray، فهو مجرد مصطلح يمثِّل كائنات العرض السابقة التي تطبق على ArrayBuffer، وهي Int8Array وUint8Array، وغيرها من الكائنات، وسنتابع بقية القائمة لاحقًا. عندما نرى أمرًا وفق الصيغة new TypedArray، فقد يعني ذلك أيًا من new Int8Array أو new Uint8Array وغيرها، إذ تسلك مصفوفات النوع سلوك بقية المصفوفات، فلها فهارس indexes ويمكن المرور على عناصرها، كما يختلف سلوكها باختلاف نوع الوسائط التي تقبلها، وهناك 5 حالات ممكنة للوسائط: new TypedArray(buffer, [byteOffset], [length]); new TypedArray(object); new TypedArray(typedArray); new TypedArray(length); new TypedArray();
يمكن إنشاء مصفوفة نوع مباشرةً دون الإشارة إلى الكائن ArrayBuffer، لكن كائن العرض لا يتشكل دون وجود الكائن الأساسي ArrayBuffer، وبالتالي سيتشكل كائن التخزين المؤقت أوتوماتيكيًا في الحالات السابقة كلها عدا الحالة الأولى (عندما ننشئه نحن). سنستخدم الخصائص التالية للوصول إلى الكائن ArrayBuffer:
وبالتالي يمكننا الانتقال من كائن عرض إلى آخر، مثلًا: let arr8 = new Uint8Array([0, 1, 2, 3]); // كائن عرض آخر للمعطيات نفسها let arr16 = new Uint16Array(arr8.buffer);إليك قائمةً بمصفوفات النوع:
لايوجد النوع int8 أو أي نوع أحادي القيمة single-valued مشابه على الرغم من وجود أسماء مثل Int8Array، فلا يوجد نوع أحادي القيمة مثل int أو int8 في JavaScript، والأمر منطقي هنا، حيث لا يمثل الكائن Int8Array مصفوفةً من هذه القيم المفردة، بل هو عرض وتمثيل للكائن ArrayBuffer. سلوك المصفوفات عند خروج القيم عن حدودهاعندما نحاول كتابة قيمة خارج حدود مصفوفة النوع فلن يظهر لنا خطأ، لكن ستُحذف البتات الزائدة. لنحاول مثلًا وضع القيمة 256 ضمن Uint8Array، فإذا حولنا 256 إلى الصيغة الثنائية، فستكون بالشكل "100000000" (9 بتات)، لكن النوع الذي استخدمناه يحوي 8 بتات فقط، أي قيمًا بين 0 و255، وفي حال أدخلنا رقمًا أكبر من النطاق السابق فستُخزن الخانات اليمينية الثمان (الأقل قيمة) فقط ويُحذف الباقي، وبالتالي سنحصل على القيمة 0 في هذا المثال. لنأخذ العدد 257 مثالًا آخر لذلك، أينما سنحصل ثنائيًا على تسع بتات "100000001"، ستُخزّن منها الخانات اليمينية الثمان الأولى، وسنحصل بالنتيجة على القيمة 1. let uint8array = new Uint8Array(16); let num = 256; alert(num.toString(2)); // 100000000 (التمثيل الثنائي) uint8array[0] = 256; uint8array[1] = 257; alert(uint8array[0]); // 0 alert(uint8array[1]); // 1 للنوع Uint8ClampedArray ميزة خاصة، فهو يعطي القيمة 255 لأي عدد أكبر من 255، والقيمة 0 لأي عدد سالب، وهذا مفيد في معالجة الصور. توابع الصنف TypedArrayلهذا الصنف نفس توابع المصفوفات مع بعض الاستثناءات الواضحة، حيث يمكننا مسح عناصره، وتنفيذ التوابع map وslice وfind وreduce؛ إلا أنه لا يمكن تنفيذ عدة أشياء، منها الآتي:
كما يوجد تابعان إضافيان:
تتيح لنا التوابع السابقة نسخ مصفوفات النوع ودمجها وإنشاء مصفوفات جديدة من مصفوفات موجودة مسبقًا وغيرها. الكائن DataViewيمثل الكائن DataView كائن عرض عالي المرونة بلا نوع untyped للكائن ArrayBuffer، حيث يسمح بالوصول إلى البيانات ابتداءً من أي موضع وبأي تنسيق.
نستخدم DataView كالتالي: new DataView(buffer, [byteOffset], [byteLength])
في المثال التالي نستخرج أعدادًا بتنسيقات مختلفة من المخزن ذاته: // مصفوفة ثنائية مكونة من 4 بايتات، وستكون أكبر قيمة 255 let buffer = new Uint8Array([255, 255, 255, 255]).buffer; let dataView = new DataView(buffer); // الحصول على رقم 8 بت عند الإزاحة 0 alert( dataView.getUint8(0) ); // 255 // الحصول على رقم 16 بت عند الإزاحة 0 alert( dataView.getUint16(0) ); // 65535 (biggest 16-bit unsigned int) // الحصول على رقم 32 بت عند الإزاحة 0 alert( dataView.getUint32(0) ); // 4294967295 (biggest 32-bit unsigned int) dataView.setUint32(0, 0); // إعطاء القيمة 0 لرقم من 4 بايت، وبالتالي تصفير المخزنتَظهر قدرة DataView عند تخزين أرقام ذات تنسيق مختلف في المخزن المؤقت نفسه، فلو خزّنّا مثلًا سلسلةً من البيانات مؤلفةً من الأزواج (عدد صحيح 16 بت، عدد عشري عائم 32 بت)، فسيسمح لنا DataView بالوصول إليها بكل سهولة. الخلاصة
في معظم الأحيان يمكن العمل مباشرةً على مصفوفات النوع محتفظين بالكائن ArrayBuffer خلف الستار، ويمكن الوصول إليه باستخدام الأمر buffer.، كما يمكن إنشاء كائن عرض جديد عند الحاجة. يوجد مصطلحان إضافيان يستخدَمان في وصف التوابع التي تتعامل مع البيانات الثنائية:
مهمات للإنجاز ضم مصفوفات النوع Concatenate typed arrays لنفترض وجود مصفوفة من النوع Uint8Array، يمكن استخدام الدالة (concat(arrays لضمّ عدة مصفوفات في مصفوفة واحدة. الحلإليك الحل المتمثل بالشيفرة التالية: function concat(arrays) { // مجموع أطوال كل مصفوفة let totalLength = arrays.reduce((acc, value) => acc + value.length, 0); if (!arrays.length) return null; let result = new Uint8Array(totalLength); // انسخ محتوى كل مصفوفة إلى الناتج result // يُنسخ محتوى المصفوفة اللاحقة على الجانب الأيمن للمصفوفة السابقة let length = 0; for(let array of arrays) { result.set(array, length); length += array.length; } return result; }افتح الحل في تجربة حية ترجمة -وبتصرف- للفصل Array buffer, Binary data من سلسلة The Modern JavaScript Tutorial. اقرأ أيضًا |
59,669 | التعابير النمطية Regular Expressions في جافاسكريبت |
اقتباس
يبادر البعض إذا قابلَته مشكلة إلى استخدام التعابير النمطية، ولا يدرك المرء أنه بهذا قد جعل المشكلة اثنتين. ـــ جيمي زاوينيسكي Jamie Zawiniski إذا قطعت الخشب في عكس اتجاه أليافه فستحتاج إلى قوة أكبر، كذلك إذا سار البرنامج عكس اتجاه المشكلة، إذ ستحتاج شيفرات أكثر لحلها. ـــ يوان-ما Yuan-Ma، كتاب البرمجة The Book of Programming. إذا نظرنا إلى التقنيات والأدوات البرمجية المنتشرة، فسنرى أنّ التقنية أو الأداة المشهورة هي التي تُثبت كفاءتها العملية في مجالها، أو التي تتكامل تكاملًا ممتازًا مع تقنية أخرى مستخدَمة بكثرة، وليس لأنها الأجمل أو الأذكى.إرشادات للحل سنناقش هنا إحدى تلك الأدوات التي تدعى بالتعابير النمطية Regular Expressions، وهي طريقة لوصف الأنماط patterns في بيانات السلاسل النصية، إذ تُكوِّن هذه التعابير لغةً صغيرةً مستقلةً بذاتها، لكنها رغم ذلك تدخل في لغات برمجية أخرى مثل جافاسكربت، كما تدخل في العديد من الأنظمة. قد تكون صيغة التعابير النمطية غريبةً للناظر إليها، كما أنّ الواجهة التي توفرها جافاسكربت للتعامل معها ليست بالمثلى، لكن رغم هذا، فتلك التعابير تُعَد أداةً قويةً لفحص ومعالجة السلاسل النصية، كما سيعينك فهمها على كتابة حلول أكفأ للمشاكل التي تواجهك. إنشاء تعبير نمطيالتعبير النمطي هو نوع من أنواع الكائنات؛ فإما يُنشأ باستخدام الباني RegExp، أو يُكتب على أساس قيمة مصنَّفة النوع literal value بتغليف النمط بشرطتين مائلتين أماميتين من النوع /. let re1 = new RegExp("abc"); let re2 = /abc/;يُمثِّل كائنا التعبيرات النمطية في المثال السابق النمط نفسه أي محرف a يتبعه b ثم c، ويُكتب النمط على أساس سلسلة نصية عادية عند استخدام الباني RegExp، لذا تطبَّق القواعد المعتادة للشرطات المائلة الخلفية \، على عكس الحالة الثانية التي نرى فيها النمط بين شرطتين مائلتين، إذ تعامَل الشرطات هنا تعاملًا مختلفًا. نحتاج إلى وضع شرطة خلفية قبل أي شرطة أمامية نريدها جزءًا من النمط نفسه، وذلك لأن الشرطة الأمامية تنهي النمط إذا وُجدت. كذلك فإن الشرطات الخلفية التي لا تكون جزءًا من ترميز خاص لمحرف -مثل \n- لن تُتَجاهل كما نفعل في السلاسل النصية، وعليه ستتسبب في تغيير معنى النمط. تملك بعض المحارف مثل علامات الاستفهام وإشارات الجمع مَعاني خاصة في التعابير النمطية، حيث سنحتاج إلى وضع شرطة مائلة خلفية قبلها إذا أردنا لها تمثيل المحرف نفسه وليس معناه في التعابير النمطية. let eighteenPlus = /eighteen\+/; التحقق من المطابقاتتملك كائنات التعابير النمطية توابع عديدة، وأبسط تلك التوابع هو التابع test الذي إن مرَّرنا سلسلةً نصيةً إليه، فسيُعيد قيمةً بوليانيةً تخبرنا هل تحتوي السلسلة على تطابق للنمط الذي في التعبير أم لا. console.log(/abc/.test("abcde")); // → true console.log(/abc/.test("abxde")); // → falseيتكون التعبير النمطي من محارف عادية غير خاصة تمثِّل -ببساطة- ذلك التسلسل من المحارف، فإذا وُجد abc في أيّ مكان في السلسلة النصية التي نختبرها -ولا يُشترط وجودها في بدايتها-، فسيُعيد test القيمة true. مجموعات المحارفيمكن التحقق من وجود abc في سلسلة نصية باستدعاء التابع indexof. تسمح لنا التعابير النمطية بالتعبير عن أنماط أكثر تعقيدًا، فمثلًا كل ما علينا فعله لمطابقة عدد ما هو وضع مجموعة من المحارف بين قوسين مربعين لجعل ذلك الجزء من التعبير يطابق أيًا من المحارف الموجودة بين الأقواس. لننظر المثال التالي حيث يطابق التعبيران جميع السلاسل النصية التي تحتوي على رقم ما: console.log(/[0123456789]/.test("in 1992")); // → true console.log(/[0-9]/.test("in 1992")); // → trueيمكن الإشارة إلى مجال من المحارف داخل القوسين المربعين باستخدام الشرطة - بين أول محرف فيه وآخر محرف، ويُحدَّد الترتيب في تلك المحارف برمز اليونيكود لكل محرف -كما ترى من المثال أعلاه الذي يشير إلى مجال الأرقام من 0 إلى 9-، وهذه الأرقام تحمل رمز 48 حتى 57 بالترتيب في اليونيكود، وعليه فإنّ المجال [0-9] يشملها جميعًا، ويطابق أي رقم. تمتلك مجموعة محارف الأعداد اختصارات خاصة بها كما هو شأن العديد من مجموعات المحارف الشائعة، فإذا أردنا الإشارة إلى المجال من 0 حتى 9، فسنستخدِم الاختصار \d. table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } الاختصار الدلالة \d أيّ محرف رقمي \w محرف أبجدي أو رقمي، أي محرف الكلمة \s أيّ محرف مسافة بيضاء، مثل المسافات الفارغة والجداول والأسطر الجديدة وما شابهها \D محرف غير رقمي \W محرف غير أبجدي وغير رقمي \S محرف مغاير للمسافة البيضاء . أيّ محرف عدا السطر الجديدنستطيع مطابقة تنسيق التاريخ والوقت -كما في 01-30-2003 15:20- باستخدام التعبير التالي: let dateTime = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/; console.log(dateTime.test("01-30-2003 15:20")); // → true console.log(dateTime.test("30-jan-2003 15:20")); // → falseتعيق الشرطات المائلة الموجودة في المثال أعلاه قراءة النمط الذي نعبر عنه، وسنرى لاحقًا نسخةً أفضل في هذا المقال. يمكن استخدام رموز الشرطات المائلة تلك داخل أقواس مربعة، إذ تعني [\d.] مثلًا أيّ رقم أو محرف النقطة .، لكن تفقِد النقطة نفسها معناها المميز لها إذا كانت داخل أقواس مربعة، وبالمثل في حالة إشارة الجمع +؛ أما إذا أردنا عكس مجموعة محارف، أي إذا أردنا التعبير عن رغبتنا في مطابقة أيّ محرف عدا تلك المحارف التي في المجموعة، فنستخدم رمز الإقحام ^ بعد قوس الافتتاح. let notBinary = /[^01]/; console.log(notBinary.test("1100100010100110")); // → false console.log(notBinary.test("1100100010200110")); // → true تكرار أجزاء من النمطلقد بتنا الآن نعلم كيف نطابق رقمًا واحدًا، لكن كيف سنفعل ذلك إذا أردنا مطابقة عدد يحتوي على أكثر من رقم؟ إذا وضعنا إشارة الجمع + بعد شيء ما في تعبير نمطي، فستشير إلى أنّ هذا العنصر قد يكرَّر أكثر من مرة، بالتالي تعني /\d+/ مطابقة محرف رقم أو أكثر. console.log(/'\d+'/.test("'123'")); // → true console.log(/'\d+'/.test("''")); // → false console.log(/'\d*'/.test("'123'")); // → true console.log(/'\d*'/.test("''")); // → trueتحمل إشارة النجمة * معنى قريبًا من ذلك، حيث تسمح للنمط بالمطابقة على أي حال، فإذا لحقت إشارة النجمة بشيء ما، فلن تمنع النمط من مطابقته، إذ ستطابق نُسخًا صفرية zero instances حتى لو لم تجد نصًا مناسبًا لمطابقته؛ أما إذا جاءت علامة الاستفهام بعد محرف في نمط، فستجعل ذلك المحرف اختياريًا optional، أي قد يحدث مرةً واحدةً أو لا يحدث. يُسمح للمحرف u في المثال التالي بالحدوث، ويحقق النمط المطابقة حتى لو لم يكن u موجودًا أيضًا. let neighbor = /neighbou?r/; console.log(neighbor.test("neighbour")); // → true console.log(neighbor.test("neighbor")); // → trueنستخدم الأقواس المعقوصة إذا أردنا حدوث النمط عددًا معينًا من المرات، فإذا وضعنا {4} بعد عنصر ما مثلًا، فسيجبره بالحدوث 4 مرات حصرًا، ومن الممكن تحديد المجال الذي يمكن للعنصر حدوثه فيه بكتابة {2,4} التي تشير إلى وجوب ظهور العنصر مرتين على الأقل، وأربع مرات على الأكثر. لدينا نسخة أخرى من نمط التاريخ والوقت، حيث تسمح بذكر الأيام برقم واحد -أو رقمين-، والأشهر، والساعات، إذ تُعَدّ أسهل قليلًا في قراءتها، وهي المثال الذي قلنا أننا سنعود إليه بنسخة أفضل. let dateTime = /\d{1,2}-\d{1,2}-\d{4} \d{1,2}:\d{2}/; console.log(dateTime.test("1-30-2003 8:45")); // → trueنستطيع تحديد مجالات مفتوحة عند استخدام الأقواس بإهمال الرقم الموجود بعد الفاصلة، وبالتالي، تعني {5,} خمس مرات على الأقل. جمع التعبيرات الفرعيةإذا أردنا استخدام عامل مثل *، أو + على أكثر من عنصر في المرة الواحدة، فيجب استخدام الأقواس، وسترى العوامل الجزء الذي داخل الأقواس من التعبير النمطي عنصرًا واحدًا. let cartoonCrying = /boo+(hoo+)+/i; console.log(cartoonCrying.test("Boohoooohoohooo")); // → trueتطبَّق إشارتا الجمع الأولى والثانية على o الثانية فقط في boo، وhoo على الترتيب؛ أما علامة الجمع الثالثة فتطبَّق على المجموعة كلها (hoo+) مطابِقةً تسلسلًا واحدًا أو أكثر بهذا. يجعل محرف i -الذي في نهاية التعبير- هذا التعبير النمطي غير حساس لحالة المحارف، إذ يسمح بمطابقة المحرف B في سلسلة الدخل النصية رغم تكوّن النمط من محارف صغيرة. التطابقات والمجموعاتيُعَدّ التابع test أبسط طريقة لمطابقة تعبير نمطي، إذ لا يخبرك إلا بمطابقة التعبير النمطي من عدمها وفقط، كذلك تملك التعبيرات النمطية تابعًا اسمه exec، حيث يُعيد القيمة null إذا لم يجد مطابقة، كما يُعيد كائنًا مع معلومات عن المطابقة إذا وجد تطابق. let match = /\d+/.exec("one two 100"); console.log(match); // → ["100"] console.log(match.index); // → 8تكون للكائن المعاد من exec خاصية تدعى index، إذ تخبرنا أين تبدأ المطابقة الناجحة للسلسلة النصية؛ أما خلاف هذا فيبدو الكائن أشبه بمصفوفة من السلاسل النصية -وهو كذلك حقًا-، ويكون أول عنصر في تلك المصفوفة هو السلسلة المطابَقة، كما يكون ذلك هو تسلسل الأرقام الذي كنا نبحث عنه في المثال السابق. تحتوي قيم السلاسل النصية على التابع match الذي له سلوك مشابه: console.log("one two 100".match(/\d+/)); // → ["100"]حين يحتوي التعبير النمطي على تعبيرات فرعية مجمَّعة داخل أقواس، فسيظهر النص الذي يطابق تلك المجموعات في مصفوفة، ويكون العنصر الأول هو التطابق كله دومًا، في حين يكون العنصر التالي هو الجزء المطابَق بواسطة المجموعة الأولى التي يأتي قوس افتتاحها أولًا في التعبير، ثم المجموعة الثانية، وهكذا. let quotedText = /'([^']*)'/; console.log(quotedText.exec("she said 'hello'")); // → ["'hello'", "hello"]إذا لم تطابَق مجموعة ما مطلقًا -كأن تُتبَع بعلامة استفهام-، فسيكون موضعها في مصفوفة الخرج غير معرَّفًا undefined، وبالمثل، فإذا طابقت مجموعةً ما أكثر من مرة، فستكون المطابقة الأخيرة هي التي في المصفوفة فقط. console.log(/bad(ly)?/.exec("bad")); // → ["bad", undefined] console.log(/(\d)+/.exec("123")); // → ["123", "3"]تفيدنا المجموعات في استخراج أجزاء من سلسلة نصية، فإذا أردنا التحقق من احتواء السلسلة النصية على تاريخ، ومن ثم استخراج ذلك التاريخ وبناء كائن يمثله؛ فيمكننا إحاطة الأنماط الرقمية بأقواس، وأخذ التاريخ مباشرةً من نتيجة exec، لكن نحتاج قبل ذلك إلى النظر سريعًا على الطريقة المضمَّنة لتمثيل قيم التاريخ والوقت في جافاسكربت. صنف التاريختحتوي جافاسكربت على صنف قياسي لتمثيل البيانات -أو النقاط- في الزمن، ويسمى ذلك الصنف Date، فإذا أنشأنا كائن تاريخ باستخدام new، فسنحصل على التاريخ والوقت الحاليين. console.log(new Date()); // → Mon Nov 13 2017 16:19:11 GMT+0100 (CET)من الممكن إنشاء كائن لوقت محدد: console.log(new Date(2009, 11, 9)); // → Wed Dec 09 2009 00:00:00 GMT+0100 (CET) console.log(new Date(2009, 11, 9, 12, 59, 59, 999)); // → Wed Dec 09 2009 12:59:59 GMT+0100 (CET)تستخدِم جافاسكربت تقليدًا تبدأ فيه أعداد الشهور بالصفر -وعليه يكون شهر ديسمبر هو عدد 11-، بينما تبدأ أرقام الأيام بالواحد، وذلك أمر محيِّر وسخيف كذلك لكنه واقع، وإنما ذكرناه للتنبيه. تُعَدّ آخر أربعة وسائط arguments -أي الساعات والدقائق والثواني والميلي ثانية- وسائط اختيارية، وإذا لم تحدد قيمة أيّ منهم فتكون صفرًا افتراضيًا. تُخزَّن العلامات الزمنية Timestamps بعدد من الميلي ثانية منذ العام 1970 في منطقة UTC الزمنية -أي التوقيت العالمي-، ويتبع هذا اصطلاحًا ضُبِط بواسطة توقيت يونكس Unix time الذي اختُرع في تلك الفترة أيضًا، كما يمكن استخدام الأرقام السالبة للتعبير عن الأعوام التي سبقت 1970. إذا استُخدم التابع getTime على كائن تاريخ، فسيُعيد ذلك العدد، وهو عدد كبير كما هو متوقع. console.log(new Date(2013, 11, 19).getTime()); // → 1387407600000 console.log(new Date(1387407600000)); // → Thu Dec 19 2013 00:00:00 GMT+0100 (CET)إذا أعطينا الباني Date وسيطًا واحدًا، فسيعامَل الوسيط على أنه تعداد الميلي ثانية، ويمكن الحصول على القيمة الحالية لتعداد المللي ثانية بإنشاء كائن Date جديد، واستدعاء getTime عليه، أو استدعاء الدالة Date.now. توفِّر كائنات التاريخ توابعًا، مثل getFullYear وgetMonth وgetDate وgetHours وgetMinutes وgetSeconds، من أجل استخراج مكوناتها، كما يعطينا التابع getYear السنة بعد طرح 1900 منها -98، أو 119-، لكن لن نستخدِمه كثيرًا لعدم وجود فائدة حقيقية منه. نستطيع الآن إنشاء كائن تاريخ من سلسلة نصية بما أننا وضعنا أقواسًا حول أجزاء التعبير التي تهمنا، أي كما يلي: function getDate(string) { let [_, month, day, year] = /(\d{1,2})-(\d{1,2})-(\d{4})/.exec(string); return new Date(year, month - 1, day); } console.log(getDate("1-30-2003")); // → Thu Jan 30 2003 00:00:00 GMT+0100 (CET)تُهمَل رابطة الشرطة السفلية _، ولا تُستخدَم إلا لتجاوز عنصر المطابَقة التامة في المصفوفة التي يُعيدها التابع exec. حدود الكلمة والسلسلة النصيةيستخرِج التابع getDate التاريخ 00-1-3000 من السلسلة النصية "100-1-30000"، وهو تاريخ غير منطقي لا شك، حيث تحدث المطابقة في أي موقع في السلسلة النصية، لذا تبدأ في حالتنا عند المحرف الثاني، وتنتهي عند المحرف الثاني من النهاية. نضيف العلامتين ^ و$ لإجبار المطابقة على النظر في السلسلة كلها، إذ تطابِق علامة الإقحام بداية سلسلة الدخل، بينما تطابِق علامة الدولار نهايتها، إذ تطابق /^\d+$/ مثلًا سلسلةً مكونةً من رقم واحد أو أكثر، وتطابق /^!/ أي سلسلة تبدأ بعلامة تعجب، بينما لا تطابق /x^/ أي سلسلة نصية، إذ لا يمكن وجود x قبل بداية السلسلة. نستخدم العلامة \b للتأكد من أنّ التاريخ يبدأ وينتهي عند حدود كلمة، وقد يكون حد الكلمة بداية السلسلة، أو نهايتها، أو أي نقطة فيها تملك محرف كلمة -كما في \w على أحد الجانبين، و محرف غير كلمي على الجانب الآخر. console.log(/cat/.test("concatenate")); // → true console.log(/\bcat\b/.test("concatenate")); // → falseلاحظ أنّ علامة الحد لا تطابق محرفًا حقيقيًا، بل تضمن عدم مطابقة التعبير النمطي إلا عند حدوث حالة معينة في الموضع الذي يظهر فيه في النمط. أنماط الاختيارلنقل أننا نريد معرفة هل يحتوي جزء ما من النص على عدد متبوع بإحدى الكلمات التالية: horse، أو cow، أو chicken، أو أي صورة من صور الجمع لها، قد نكتب ثلاثة تعابير نمطية ونختبرها لكن ثَم طريقة أفضل، وذلك بوضع محرف الأنبوب | الذي يشير إلى خيار بين النمط الذي عن يمينه والنمط الذي عن يساره، وعليه نستطيع القول كما يلي: let animalCount = /\b\d+ (horse|cow|chicken)s?\b/; console.log(animalCount.test("15 horses")); // → true console.log(animalCount.test("15 horsechickens")); // → falseيمكن استخدام الأقواس لتقييد جزء النمط الذي يطبَّق عليه عامل الأنبوب، ويمكن وضع عدة عوامل مثل هذا بجانب بعضها البعض للتعبير عن اختيار بين أكثر من بديلين اثنين. آلية المطابقةيبحث محرك التعبير نظريًا عند استخدام exec أو test عن تطابق في سلسلتنا النصية، وذلك بمحاولة مطابقة التعبير من بداية السلسلة أولًا، ثم من المحرف الثاني، وهكذا حتى يجد تطابقًا أو يصل إلى نهاية السلسلة، وعندئذ يُعيد أول تطابق وجده، أو يكون قد فشل في إيجاد تطابق أصلًا؛ أما في عملية المطابقة الفعلية، فيعامِل المحرك التعبير النمطي مثل مخطط تدفق flow diagram، وإذا استخدمنا مثالنا السابق عن الحيوانات، فسيبدو مخطط التعبير الخاص بها كما يلي: يكون تعبيرنا مطابقًا إذا استطعنا إيجاد مسار من جانب المخطط الأيسر إلى جانبه الأيمن، حيث نحفظ الموضع الحالي في السلسلة النصية، ونتأكد في كل حركة نتحركها خلال صندوق من أنّ جزء السلسلة التالي لموضعنا الحالي يطابق ذلك الصندوق. إذا كنا نحاول مطابقة "the 3 horses" من الموضع 4، فسيبدو مسار تقدمنا داخل المخطط كما يلي:
يطابق التعبير النمطي /\b([01]+b|[\da-f]+h|\d+)\b/ عددًا ثنائيًا متبوعًا بـ b، أو عددًا ست عشريًا hexadecimal -وهو نظام رقمي تمثل فيه الأعداد من 10 إلى 15 بالأحرف a حتى f- متبوعًا بـ h، أو عددًا عشريًا عاديًا ليس له محرف لاحق، وفيما يلي المخطط الذي يصف ذلك: سيدخل الفرع العلوي الثنائي عند مطابقة ذلك التعبير حتى لو لم يحوي الدخل على عدد ثنائي، حيث سيصبح من الواضح عند المحرف 3 مثلًا أننا في الفرع الخاطئ عند مطابقة السلسلة "103"، فعلى الرغم تطابق السلسلة للتعبير، إلا أنها لا تطابق الفرع الذي نحن فيه. يبدأ هنا المطابِق matcher بالتعقب الخلفي، فيتذكر موضعه الحالي عند دخول فرع ما -وهو بداية السلسلة في هذه الحالة، بعد صندوق "حد الكلمة" الأول في المخطط-، وذلك ليستطيع العودة والنظر في فرع آخر إذا لم ينجح الفرع الحالي. سيجرب الفرع الخاص بالأرقام الست عشرية في حالة السلسلة النصية "103" إذا وصل إلى المحرف 3، لكنه سيفشل مجددًا لعدم وجود h بعد العدد، وهنا سيحاول في الفرع الخاص بالأعداد العشرية، وتنجح المطابقة، ويُبلَّغ بها. يتوقف المطابِق عندما يجد مطابقةً تامةً، وهذا يعني أنه حتى لو كان لدينا فروع متعددة يمكنها مطابقة سلسلة نصية ما، فهو لن يُستخدَم إلا الفرع الأول الذي ظهر وفقًا لترتيبه في التعبير النمطي. ويحدث التعقب الخلفي أيضًا لعوامل التكرار، مثل + و*، فإذا طابقنا /^.*x/ مع "abcxe"، فسيحاول الجزء .* أخذ السلسلة كلها أولًا، لكن سيدرك المحرك أنه يحتاج إلى x كي يطابق النمط، وبما أنه لا توجد x بعد نهاية السلسلة، فسيحاول عامل النجمة المطابقة من غير المحرف الأخير، لكن لا يعثر المطابِق على x بعد abcx، فيعود أدراجه بالتعقب الخلفي ليطابق عامل النجمة مع abc فقط، وهنا يجد x حيث يحتاجها، ويبلِّغ بمطابقة ناجحة من الموضع 0 حتى 4. قد يحدث ونكتب تعبيرًا نمطيًا ينفذ الكثير من عمليات التعقب الخلفي، وهنا تحدث مشكلة حين يستطيع النمط مطابقة جزء من الدخل بطرق عديدة مختلفة، فإذا لم ننتبه عند كتابة تعبير نمطي لعدد ثنائي، فقد نكتب شيئًا مثل /([01]+)+b/. عندما يحاول التعبير مطابقة سلسلة طويلة من الأصفار والآحاد التي ليس لها لاحقة b، فسيمر المطابِق على الحلقة الداخلية حتى تنتهي الأرقام، ثم يلاحظ عدم وجود المحرف b، فينفِّذ تعقبًا خلفيًا لموضع واحد فقط، ثم يمر على الحلقة الخارجية مرةً واحدةً قبل أن يستسلم ويعود أدراجه ليتعقب الحلقة الداخلية مرةً أخرى، كما سيظل يحاول جميع الطرق الممكنة عبر هاتين الحلقتين، وهذا يعني مضاعفة مقدار العمل مع كل محرف إضافي، فلو أضفنا بعض العشرات من المحارف، لاستغرقت عملية المطابقة إلى ما لا نهاية. التابع replaceتحتوي قيم السلاسل النصية على التابع replace الذي يمكن استخدامه لاستبدال سلسلة نصية بجزء من سلسلة أخرى. console.log("papa".replace("p", "m")); // → mapaيمكن أن يكون الوسيط الأول تعبيرًا نمطيًا، وعندئذ يُستبدل التطابق الأول للتعبير النمطي؛ أما إذا أضيف الخيار g -اختصارًا لـ global- إلى التعبير النمطي، فتُستبدل جميع التطابقات. console.log("Borobudur".replace(/[ou]/, "a")); // → Barobudur console.log("Borobudur".replace(/[ou]/g, "a")); // → Barabadarلو كان لدينا وسيط إضافي للتابع replace بحيث نختار منه استبدال تطابق واحد أو جميع التطابقات، لكان أفضل من الاعتماد على خاصية للتعبير النمطي، بل لو كان من خلال توفير تابع مختلف باسم replaceAll لكان أفضل.
يأتي مكمن القوة في استخدام التعابير النمطية مع التابع replace من حقيقة استطاعتنا الإشارة إلى المجموعات المطابَقة في السلسلة النصية البديلة، فمثلًا، لدينا سلسلة كبيرة تحتوي على أسماء أشخاص، بحيث يحتوي كل سطر على اسم واحد، ويبدأ بالاسم الأخير، ثم الاسم الأول، أي بالصورة: إذا أردنا التبديل بين تلك الأسماء وحذف الفاصلة الأجنبية التي بين كل منها لنحصل على الصورة Firstname Lastname، فنستطيع استخدام الشيفرة التالية: console.log( "Mohsin, Samira\nFady, Eslam\nSahl, Hasan" .replace(/(\w+), (\w+)/g, "$2 $1")); // → Samira Mohsin // Eslam Fady // Hasan Sahlيشير كل من $1، و$2 في السلسلة البديلة إلى المجموعات المحاطة بأقواس في النمط، ويحل النص الذي يطابق المجموعة الأولى محل $1، كما يحل النص الذي يطابق المجموعة الثانية محل $2، وهكذا حتى نصل إلى $9؛ أما التطابق كله فيمكن الإشارة إليه باستخدام $&. من الممكن تمرير دالة بدلًا من سلسلة نصية على أساس وسيط ثاني إلى التابع replace، حيث تُستدعى الدالة لكل استبدال مع المجموعات المطابَقة والتطابق كله على أساس وسائط arguments، وتُدخَل قيمتها المعادة في السلسلة الجديدة، أي كما في المثال التالي: let s = "the cia and fbi"; console.log(s.replace(/\b(fbi|cia)\b/g, str => str.toUpperCase())); // → the CIA and FBIوهذا مثال آخر: let stock = "1 lemon, 2 cabbages, and 101 eggs"; function minusOne(match, amount, unit) { amount = Number(amount) - 1; if (amount == 1) { // only one left, remove the 's' unit = unit.slice(0, unit.length - 1); } else if (amount == 0) { amount = "no"; } return amount + " " + unit; } console.log(stock.replace(/(\d+) (\w+)/g, minusOne)); // → no lemon, 1 cabbage, and 100 eggsيأخذ المثال أعلاه سلسلةً نصيةً، ويبحث عن حالات حدوث عدد متبوع بكلمة أبجدية رقمية، ويُعيد سلسلةً نصيةً، إذ تكون في كل حالة من تلك الحالات أُنقصت بمقدار 1. ستكون المجموعة (\d+) هي الوسيط amount للدالة، وتقيَّد المجموعة (\w+) بالوسيط unit، وتحوِّل الدالة الوسيط amount إلى عدد، وينجح ذلك بما أنه طابَق \d+، كما تُجري بعض التعديلات في حالة إذا كان المتبقي صفر أو واحد فقط. الجشع Greedمن الممكن استخدام replace لكتابة دالة تحذف جميع التعليقات من شيفرة جافاسكربت، لننظر في محاولة أولية لها: function stripComments(code) { return code.replace(/\/\/.*|\/\*[^]*\*\//g, ""); } console.log(stripComments("1 + /* 2 */3")); // → 1 + 3 console.log(stripComments("x = 10;// ten!")); // → x = 10; console.log(stripComments("1 /* a */+/* b */ 1")); // → 1 1يطابق الجزء الذي يسبق العامل or محرفي شرطة مائلة متبوعتين بعدد من محارف لا تكون محارف سطر جديد؛ أما الجزء المتعلِّق بالتعليقات متعددة الأسطر فيملك بعض التفصيل، إذ نستخدم [^] -أيّ محرف ليس ضمن مجموعة المحارف الفارغة- على أساس طريقة لمطابقة أي محرف، غير أننا لا نستطيع استخدام محرف النقطة هنا لاحتواء التعليقات الكتلية على عدة أسطر، ولا يطابق محرف النقطة محارف السطر الجديد. لكن إذا نظرنا إلى خرج السطر الأخير فسنرى أنه خطأ نوعًا ما، وذلك أنّ الجزء [^]* من التعبير سيطابِق كل ما يستطيع مطابقته كما وضحنا في القسم الخاص بالتعقب الخلفي، فإذا تسبب ذلك في فشل الجزء التالي من التعبير، فسيعود المطابِق محرفًا واحدًا إلى الوراء، ثم يحاول مرةً أخرى من هناك، وهو في هذا المثال يحاول مطابقة بقية السلسلة، ثم يعود إلى الوراء من هناك. سيجد الحدث */ بعد العودة أربعة محارف إلى الوراء ويطابقها، وليس هذا ما أردنا، إذ كنا نريد مطابقة تعليق واحد، وليس العودة إلى نهاية الشيفرة لنجد نهاية آخر تعليق كتلي. نقول بسبب هذا السلوك أنّ عوامل التكرار مثل + و* و? و{} هي عوامل جشعة greedy، أي تطابق كل ما تستطيع مطابقته وتتعقب خلفيًا من هناك، لكن إذا وضعنا علامة استفهام بعد تلك العوامل لتصير هكذا ?+ و?* و?? و?{}، فسننفي عنها صفة الجشع لتطابق أقل ما يمكن، ولا تطابِق أكثر إلا كان النمط الباقي لا يناسب تطابقًا أصغر. هذا هو عين ما نريده في هذه الحالة، فبجعل عامل النجمة يطابق أصغر امتداد من المحارف التي تقودنا إلى */، فسنستهلك تعليقًا كتليًا واحدًا فقط. function stripComments(code) { return code.replace(/\/\/.*|\/\*[^]*?\*\//g, ""); } console.log(stripComments("1 /* a */+/* b */ 1")); // → 1 + 1نستطيع على ذلك نسْب الكثير من الزلات البرمجية bugs في برامج التعابير النمطية إلى استخدام عامل جشِع من غير قصد، في حين أنّ استخدام عامل غير جشِع أفضل، لهذا يجب النظر في استخدام النسخة الغير جشعة من العامل أولًا عند استخدام أحد عوامل التكرار. إنشاء كائنات RegExp ديناميكياستكون لدينا حالات لا نعرف فيها النمط الذي يجب مطابقته عند كتابة الشيفرة، فمثلًا، نريد البحث عن اسم المستخدِم في جزء من النص، وإحاطته بمحرفي شرطة سفلية لإبرازه عما حوله، إذ لن نستطيع استخدام الترميز المبني على الشرطة المائلة لأننا لن نعرف الاسم إلا عند تشغيل البرنامج فعليًا، لكن نستطيع رغم ذلك بناء سلسلة نصية، واستخدام باني RegExp عليها، كما في المثال التالي: let name = "Saad"; let text = "Saad is a suspicious character."; let regexp = new RegExp("\\b(" + name + ")\\b", "gi"); console.log(text.replace(regexp, "_$1_")); // → _Saad_ is a suspicious character.يجب استخدام شرطتين خلفيتين مائلتين عند إنشاء علامات الحدود \b، وذلك لعدم كتابتها في تعبير نمطي محاط بشرطات مائلة، وإنما في سلسلة نصية عادية، كذلك يحتوي الوسيط الثاني للباني RegExp على خيارات للتعبير النمطي، وهي "gi" في هذه الحالة لتشير إلى عمومها global وعدم حساسيتها لحالة المحارف case insensitive. إذا احتوى اسم المستخدِم على محارف غريبة مثل "dea+hl[]rd"، فسيتسبب هذا في تعبير نمطي غير منطقي، وسنحصل على اسم مستخدِم لا يطابق اسم المستخدِم الفعلي. سنضيف شرطات مائلة خلفية قبل أي محرف يملك معنىً خاص به لحل هذه المشكلة. let name = "dea+hl[]rd"; let text = "This dea+hl[]rd guy is super annoying."; let escaped = name.replace(/[\\[.+*?(){|^$]/g, "\\$&"); let regexp = new RegExp("\\b" + escaped + "\\b", "gi"); console.log(text.replace(regexp, "_$&_")); // → This _dea+hl[]rd_ guy is super annoying. التابع searchلا يمكن استخدام تعبير نمطي لاستدعاء التابع indexOf على سلسلة نصية، والحل هو استخدام التابع search الذي يتوقع تعبيرًا نمطيًا، حيث يُعيد أول فهرس يجده التعبير كما يفعل indexOf، أو يُعيد -1 إذا لم يجده. console.log(" word".search(/\S/)); // → 2 console.log(" ".search(/\S/)); // → -1لا توجد طريقة في التابع search لاختيار بدء المطابقة عند إزاحة offset بعينها، على عكس indexOf الذي يملكها في الوسيط الثاني، إذ تُعَدّ مفيدةً في بعض الأحيان. خاصية lastIndexلا يوفر التابع exec طريقةً سهلةً لبدء البحث من موضع بعينه في السلسلة النصية، شأنه في ذلك شأن التابع search، والطريقة التي يوفرها لذلك موجودة، لكنها ليست سهلة. تحتوي كائنات التعبير النمطي على خصائص إحداها هي source التي تحتوي على السلسلة التي أُنشئ منها التعبير، وثمة خاصية أخرى هي lastIndex التي تتحكم في موضع بدء التطابق التالي، وإن كان في حالات محدودة، وحتى حينئذ يجب أن يكون كل من الخيار العام g وخيار y اللزج sticky مفعَّلين في التعبير النمطي، كما يجب وقوع التطابق من خلال التابع exec. كان من الممكن هنا السماح بتمرير وسيط إضافي إلى exec. let pattern = /y/g; pattern.lastIndex = 3; let match = pattern.exec("xyzzy"); console.log(match.index); // → 4 console.log(pattern.lastIndex); // → 5إذا نجح التطابق، فسيحدِّث الاستدعاء إلى exec خاصية lastIndex إلى النقطة التي تلي التطابق تلقائيًا؛ أما إذا لم يُعثر على تطابق، فستُضبِط خاصية lastIndex على الصفر، حيث يكون هو القيمة في كائن التعبير النمطي الذي سيُبنى تاليًا. يكون الفرق بين الخيارين العام واللزج هو عدم نجاح التطابق حالة الخيار اللزج إلا عندما يبدأ من lastIndex مباشرةً؛ أما في حالة الخيار العام، فسيبحث عن موضع يمكن بدء التطابق عنده. let global = /abc/g; console.log(global.exec("xyz abc")); // → ["abc"] let sticky = /abc/y; console.log(sticky.exec("xyz abc")); // → nullتتسبب تلك التحديثات التلقائية لخاصية lastIndex في مشاكل عند استخدام قيمة تعبير نمطي مشتركة لاستدعاءات exec متعددة، فقد يبدأ تعبيرنا النمطي عند فهرس من مخلَّفات استدعاء سابق. let digit = /\d/g; console.log(digit.exec("here it is: 1")); // → ["1"] console.log(digit.exec("and now: 1")); // → nullكذلك من الآثار اللافتة للخيار العام أنه يغيِّر الطريقة التي يعمل بها التابع match على السلاسل النصية، إذ يبحث عن جميع تطابقات النمط في السلسلة النصية، ويُعيد مصفوفةً تحتوي على السلاسل المطابَقة عندما يُستدعى مع الخيار العام، بدلًا من إعادة مصفوفة تشبه التي يُعيدها exec. console.log("Banana".match(/an/g)); // → ["an", "an"]لهذا يجب الحذر عند التعامل مع التعابير النمطية العامة، واستخدامها في الحالات الضرورية فقط،، مثل الاستدعاءات إلى replace والأماكن التي تريد استخدام lastIndex فيها صراحةً. التكرار على التطابقاتيُعَدّ البحث في جميع مرات حدوث النمط في سلسلة نصية بطريقة تعطينا وصولًا إلى كائن المطابقة في متن الحلقة loop body أمرًا شائعًا، ويمكن فعل ذلك باستخدام lastIndex، وexec. let input = "A string with 3 numbers in it... 42 and 88."; let number = /\b\d+\b/g; let match; while (match = number.exec(input)) { console.log("Found", match[0], "at", match.index); } // → Found 3 at 14 // Found 42 at 33 // Found 88 at 40يستفيد هذا من كون قيمة تعبير الإسناد = هي القيمة المسندَة، لذا ننفذ التطابق عند بداية كل تكرار باستخدام match = number.exec(input) على أساس شرط في تعليمة while، ثم نحفظ النتيجة في رابطة binding، ونوقف التكرار إذا لم نجد تطابقات أخرى. تحليل ملف INIلنقل أننا نكتب برنامجًا يجمع بيانات عن أعدائنا على الإنترنت، رغم أننا لن نكتبه حقًا وإنما يهمنا الجزء الذي يقرأ ملف التهيئة، على أساس مثال على مشكلة تحتاج إلى التعابير النمطية، إذ سيبدو ملف التهيئة كما يلي: searchengine=https://duckduckgo.com/?q=$1 spitefulness=9.7 ; تُسبق التعليقات بفاصلة منقوطة... ; يختص كل قسم بعدو منفصل [larry] fullname=Larry Doe type=kindergarten bully website=http://www.geocities.com/CapeCanaveral/11451 [davaeorn] fullname=Davaeorn type=evil wizard outputdir=/home/marijn/enemies/davaeornتكون القواعد الحاكمة لهذه الصيغة -وهي صيغة مستخدمة بكثرة، ويطلق عليها اسم INI- كما يلي:
مهمتنا هنا هي تحويل سلسلة نصية مثل هذه إلى كائن تحمل خصائصه سلاسل نصية للإعدادات المكتوبة قبل ترويسة القسم الأول، وكائنات فرعية للأقسام، بحيث يحمل كل كائن فرعي إعدادات القسم الخاص به، وبما أنه يجب معالجة الصيغة سطرًا سطرًا، فمن الجيد تقسيم الملف إلى أسطر منفصلة، مستفيدين من التابع split الذي تعرضنا له في هياكل البيانات: الكائنات والمصفوفات في جافاسكريبت. لا تقتصر بعض أنظمة التشغيل على محرف السطر الجديد لفصل الأسطر، وإنما تستخدِم محرف الإرجاع carriage return متبوعًا بسطر جديد "\r\n"، وبما أنّ التابع split يسمح بالتعبير النمطي على أساس وسيط، فنستطيع استخدام تعبير نمطي مثل /\r?\n/ للتقسيم بطريقة تسمح بوجود كل من "\n" و"\r\n" بين الأسطر. function parseINI(string) { // ابدأ بكائن ليحمل حقول المستوى العلوي let result = {}; let section = result; string.split(/\r?\n/).forEach(line => { let match; if (match = line.match(/^(\w+)=(.*)$/)) { section[match[1]] = match[2]; } else if (match = line.match(/^\[(.*)\]$/)) { section = result[match[1]] = {}; } else if (!/^\s*(;.*)?$/.test(line)) { throw new Error("Line '" + line + "' is not valid."); } }); return result; } console.log(parseINI(` name=Vasilis [address] city=Tessaloniki`)); // → {name: "Vasilis", address: {city: "Tessaloniki"}}تمر الشيفرة على أسطر الملف وتبني الكائن، كما تخزَّن الخصائص التي في القمة داخل الكائن مباشرةً، بينما تخزن الخصائص الموجودة في الأقسام داخل كائن قسم مستقل، كما تشير الرابطة section إلى كائن القسم الحالي. لدينا نوعان من الأسطر المميزة، وهما ترويسة الأقسام، أو أسطر الخصائص، فإذا كان السطر خاصيةً عاديةً، فسيخزَّن في الموضع الحالي؛ أما إذا كان ترويسةً لقسم، فسيُنشأ كائن قسم جديد وتُضبط section لتشير إليه. نضمن بالاستخدام المتكرر لمحرفي ^ و$، مطابقة التعبير للسطر كاملًا وليس جزءًا منه فقط، كما ستعمل الشيفرة عند إهمالهما، لكنها ستتصرف مع بعض المدخلات بغرابة، وهو الأمر الذي سيكون زلةً bug يصعب تعقبها وإصلاحها. يُعَدّ النمط if (match = string.match(...)) شبيهًا بما سبق في شأن استخدام الإسناد على أساس شرط لتعليمة while، فلن نكون على يقين من نجاح استدعاء match، لذا لا نستطيع الوصول إلى الكائن الناتج إلا داخل تعليمة if تختبر ذلك، ولكي لا نقطع سلسلة الصيغ else if، فسنسند نتيجة التطابق إلى رابطة، وسنستخدم هذا التعيين على أساس اختبار لتعليمة if مباشرةً. تتحقق الدالة من السطر باستخدام التعبير /^\s*(;.*)?$/ إذا لم يكن ترويسةً لقسم أو خاصيةً ما، إذ تتحقق من أنه تعليق أو سطر فارغ، حيث يطابق الجزء الذي بين الأقواس التعليقات، ثم تتأكد ? أنه يطابق الأسطر التي تحتوي على مسافة بيضاء فقط، وإذا وُجد سطر لا يطابق أي صيغة من الصيغ المتوقعة، فسترفع الدالة اعتراضًا exception. المحارف الدوليةكان اتجاه تصميم جافاسكربت في البداية نحو سهولة الاستخدام، وقد ترسخ ذلك الاتجاه مع الوقت إلى أن صار هو السمة الأساسية للغة ومعيارًا لتحديثاتها، لكن أتت هذه السهولة بعواقب لم تكن في الحسبان وقتها، إذ تُعَدّ تعابير جافاسكربت النمطية غبيةً لغويًا، فالمحرف الكلمي بالنسبة لها هو واحد من 26 محرفًا فقط، وهي المحارف الموجودة في الأبجدية اللاتينية بحالتيها الصغرى والكبرى، أو أرقامًا عشريةً، أو محرف الشرطة السفلية _؛ أما بالنسبة لأيّ شيء غير ذلك، مثل é أو β، فلن تطابق \w رغم أنها محارف كلمية، لكنها ستطابق الحالة الكبرى منها \W التي تشير إلى التصنيف غير الكلمي nonword category. تجدر الإشارة إلى ملاحظة غريبة في شأن محرف المسافة البيضاء العادية \s، إذ لا تعاني من هذه المشكلة، وتطابق جميع المحارف التي يَعُدّها معيار اليونيكود محارف مسافة بيضاء، بما في ذلك المسافة غير الفاصلة nonbreaking space، والفاصلة المتحركة المنغولية Mongolian vowel separator. أيضًا، من المشاكل التي سنواجهها مع التعابير النمطية في جافاسكربت أنها لا تعمل على المحارف الحقيقية وإنما تعمل على الأعداد البِتّية للمحارف code units كما ذكرنا في الدوال العليا في جافاسكريبت، وبالتالي سيكون سلوك المحارف المكونة من عددين بِتّيين غريبًا، وعلى خلاف ما نريد. console.log(/?{3}/.test("???")); // → false console.log(/<.>/.test("<?>")); // → false console.log(/<.>/u.test("<?>")); // → trueالمشكلة أنّ ? التي في السطر الأول تعامَل على أنها عددين بِتّيين، ولا يطبَّق الجزء {3} إلا على العدد الثاني. وبالمثل، تطابق النقطة عددًا بِتَيًا واحدًا، وليس العددين اللذَين يكونان الرمز التعبيري للوردة، كما يجب إضافة خيار اليونيكود u للتعبير النمطي كي يعامَل مثل تلك المحارف على الوجه الذي ينبغي. سيظل السلوك الخاطئ للتعبير النمطي هو الافتراضي للأسف، لأنّ التغيير قد يتسبب في مشاكل للشيفرة الموجودة والتي تعتمد عليه، ومن الممكن استخدام \p في تعبير نمطي مفعّل فيه خيار اليونيكود لمطابقة جميع المحارف التي يسند اليونيكود إليها خاصية معطاة، رغم أنّ هذه الطريقة معتمدة حديثًا ولم تُستخدم كثيرًا بعد. console.log(/\p{Script=Greek}/u.test("α")); // → true console.log(/\p{Script=Arabic}/u.test("α")); // → false console.log(/\p{Alphabetic}/u.test("α")); // → true console.log(/\p{Alphabetic}/u.test("!")); // → falseيعرِّف اليونيكود عددًا من الخصائص المفيدة رغم أنّ إيجاد الخاصية التي نحتاجها قد لا يكون أمرًا سهلًا في كل مرة، حيث يمكن استخدام الصيغة \p{Property=Value} لمطابقة أيّ محرف له قيمة معطاة لتلك الخاصية، وإذا أُهمل اسم الخاصية كما في \p{Name}، فسيُفترض الاسم إما خاصيةً بِتّيةً مثل Alphabetic، أو فئةً مثل Number. خاتمةالتعبيرات النمطية هي كائنات تمثل أنماطًا في السلاسل النصية، وتستخدم لغتها الخاصة للتعبير عن تلك الأنماط. التعبير النمطي دلالته /abc/ تسلسل من المحارف /[abc]/ أيّ محرف في مجموعة محارف /[^abc]/ أيّ محرف ليس في مجموعة ما من المحارف /[0-9]/ أيّ محرف من مجال ما من المحارف /x+/ مرة حدوث واحدة أو أكثر للنمط x /x+?/ مرة حدوث أو أكثر غير جشعة /x*/ حدوث صفري أو أكثر. /x?/ حدوث صفري أو حدوث لمرة واحدة /x{2,4}/ حدوث لمرتَين إلى أربعة مرات /(abc)/ مجموعة `/a b c/` أيّ نمط من بين أنماط متعددة /\d/ أيّ محرف رقمي /\w/ محرف أبجدي رقمي alphanumeric، أي محرف كلمة /\s/ أيّ محرف مسافة بيضاء /./ أيّ محرف عدا الأسطر الجديدة /\b/ حد كلِمي word boundary /^/ بداية الدخل /$/ نهاية الدخليملك التعبير النمطي التابع test للتحقق هل السلسلة المعطاة مطابقة أم لا، كما يملك التابع exec الذي يُعيد مصفوفةً تحتوي على جميع المجموعات المطابِقة إذا وُجدت مطابقات، ويكون لتلك المصفوفة خاصية index التي توضِّح أين بدأت المطابقة. تملك السلاسل النصية التابع match الذي يطابقها مع تعبير نمطي، وتابع search الذي يبحث عن التعابير النمطية ثم يُعيد موضع بداية التطابق فقط، كما تملك السلاسل النصية تابعًا اسمه replace، حيث يستبدِل سلسلةً نصيةً أو دالةً بتطابقات النمط. يمكن امتلاك التعابير النمطية خيارات تُكتب بعد شرطة الإغلاق المائلة، إذ يجعل الخيار i التطابق حساسًا لحالة الأحرف، كما يجعل الخيار g التعبير عامًا global، ويمكِّن التابع replace من استبدال جميع النسخ بدلًا من النسخة الأولى فقط؛ أما الخيار y فيجعله لزجًا، أي لن يتجاوز جزءًا من السلسلة أثناء البحث عن تطابق، كذلك يفعِّل الخيار u وضع اليونيكود الذي يصلح لنا عددًا من المشاكل المتعلقة بمعالجة المحارف التي تأخذ أكثر من عددين بتيين. وهكذا فإنّ التعابير النمطية أشبه بسكين حاد لها مقبض غريب الشكل، فهي تيسِّر المهام التي ننفذها كثيرًا، لكن قد تصبح صعبة الإدارة حين نستخدمها في مشاكل معقدة، ومن الحكمة تجنب حشر الأشياء التي لا تستطيع التعبيرات النمطية التعبير عنها بسهولة. تدريباتستجد نفسك لا محالةً أثناء العمل على هذه التدريبات أمام سلوكيات محيِّرة للتعابير النمطية، فمن المفيد عندئذ إدخال تعبيراتك النمطية في أداة مثل https://debuggex.com لترى إن كان تصورها المرئي يوافق السلوك الذي أردت أم لا، ولترى كيف تستجيب لسلاسل الدخل المختلفة. Regexp golfCode golf هو مصطلح مستخدم للعبة تحاول التعبير عن برنامج معيَّن بأقل عدد ممكن من المحارف، وبالمثل، يكون regexp golf عملية كتابة تعابير نمطية، بحيث تكون أصغر ما يمكن، وتطابق النمط المعطى فقط. اكتب تعبيرًا نمطيًا لكل عنصر مما يلي، بحيث يتحقق من حدوث أيّ سلسلة نصية فرعية داخل السلسلة النصية الأم، ويجب على التعبير النمطي مطابقة السلاسل المحتوية على إحدى السلاسل الفرعية التي ذكرناها. لا تشغل بالك بحدود الكلمات إلا إذا ذُكر ذلك صراحةً، وإذا نجح تعبيرك النمطي فانظر إن كنت تستطيع جعله أصغر.
استرشد بالجدول الذي في خاتمة المقال أعلاه، واختبر كل حل ببعض السلاسل النصية. تستطيع تعديل شيفرة التدريب لكتابة الحل وتشغيلها في طرفية المتصفح إن كنت تقرأ من متصفح، أو بنسخها إلى codepen. // املأ التعابير النمطية التالية verify(/.../, ["my car", "bad cats"], ["camper", "high art"]); verify(/.../, ["pop culture", "mad props"], ["plop", "prrrop"]); verify(/.../, ["ferret", "ferry", "ferrari"], ["ferrum", "transfer A"]); verify(/.../, ["how delicious", "spacious room"], ["ruinous", "consciousness"]); verify(/.../, ["bad punctuation ."], ["escape the period"]); verify(/.../, ["Siebentausenddreihundertzweiundzwanzig"], ["no", "three small words"]); verify(/.../, ["red platypus", "wobbling nest"], ["earth bed", "learning ape", "BEET"]); function verify(regexp, yes, no) { // تجاهل التدريبات غير المكتملة if (regexp.source == "...") return; for (let str of yes) if (!regexp.test(str)) { console.log(`Failure to match '${str}'`); } for (let str of no) if (regexp.test(str)) { console.log(`Unexpected match for '${str}'`); } } أسلوب الاقتباستخيَّل أنك كتبت قصةً، واستخدمت علامات الاقتباس المفردة فيها لتحديد النصوص التي قالتها الشخصيات فيها، وتريد الآن استبدال علامات الاقتباس المزدوجة بكل تلك العلامات المفردة، لكن مع استثناء الكلمات التي تكون فيها العلامة المفردة لغرض مختلف مثل كلمة aren't. فكر في نمط يميز هذين النوعين من استخدامات الاقتباس، وصمم استدعاءً إلى التابع replace الذي ينفذ عملية الاستبدال المناسبة. تستطيع تعديل شيفرة التدريب لكتابة الحل وتشغيلها في طرفية المتصفح إن كنت تقرأ من متصفح، أو بنسخها إلى codepen. let text = "'أنا الطاهي،' he said, 'إنها وظيفتي.' "; // غيِّر هذا الاستدعاء. console.log(text.replace(/A/g, "B")); // → "أنا الطاهي،" he said, "إنها وظيفتي." إرشادات للحليكون الحل البديهي هنا هو استبدال محرف غير كلمي nonword بعلامات الاقتباس على الأقل من جانب واحد، كما في /\W'|'\W/، لكن سيكون عليك أخذ بداية السطر ونهايته في حسابك. كذلك يجب ضمان أنّ الاستبدال سيشمل المحارف التي طابقها نمط \W كي لا تُنسى، ويمكن فعل ذلك بتغليفها في أقواس، ثم تضمين مجموعاتها في السلسلة النصية البديلة (1$ و2$)، كما لا يُستبدل شيء بالمجموعات التي لم تطابَق. الأعداد مرة أخرىاكتب تعبيرًا لا يطابق إلا الأعداد التي لها نسق جافاسكربت، ويجب عليه دعم علامة + أو - قبل العدد، والعلامة العشرية، والصيغة الأسية -أي 5e-3، أو 1E10-، مع علامتي موجب أو سالب قبل الأس. لاحظ عدم اشتراط وجود أرقام قبل العلامة العشرية أو بعدها، لكن لا يمكن أن يكون العدد مكونًا من العلامة العشرية وحدها، أي يسمح بكل من .5 و5. في جافاسكربت، لكن لا يُسمح بـ .. تستطيع تعديل شيفرة التدريب لكتابة الحل وتشغيلها في طرفية المتصفح إن كنت تقرأ من متصفح، أو بنسخها إلى codepen. // املأ التعبير النمطي التالي. let number = /^...$/; // الاختبارات: for (let str of ["1", "-1", "+15", "1.55", ".5", "5.", "1.3e2", "1E-4", "1e+12"]) { if (!number.test(str)) { console.log(`Failed to match '${str}'`); } } for (let str of ["1a", "+-1", "1.2.3", "1+1", "1e4.5", ".5.", "1f5", "."]) { if (number.test(str)) { console.log(`Incorrectly accepted '${str}'`); } } إرشادات للحل
ترجمة -بتصرف- للفصل التاسع من كتاب Elequent Javascript لصاحبه Marijn Haverbeke. اقرأ أيضًا |
59,668 | كيفية إضافة تسجيل الدخول باستخدام فيسبوك في ووردبريس |
يصعب الحصول على تفاعل من الزوار أو كسب ولائهم من خلال موقع ووردبريس، لذلك يُعَدّ السماح للمستخدمين بالتسجيل ضمن موقعك هو الطريقة الأفضل لتبقى على تواصل معهم، لكن العديد منهم يجد صعوبةً عند استخدام آلية التسجيل التقليدية التي تتطلب منهم حفظ كلمة مرور جديدة قوية وتأكيد بريدهم الإلكتروني، ويُعَد تفعيل تسجيل الدخول باستخدام فيسبوك أحد الحلول للمشاكل السابقة، حيث تُشجِع آلية تسجيل الدخول السهلة ضمن موقعك المستخدمين على التفاعل معك، وهذا ما يهدُف إليه هذا المقال من خلال تعريفك على آلية إضافة تسجيل الدخول باستخدام فيسبوك لموقعك. لماذا تحتاج إضافة تسجيل الدخول باستخدام فيسبوك للموقع في ووردبريسيتضمن ووردبريس آليةً لتسجيل الزوار والسماح لهم بتسجيل الدخول، لذا لماذا تحتاج إضاعة الوقت والجهد لإضافة تسجيل الدخول باستخدام فيسبوك؟ تمتلك منصة فيسبوك شهريًا 2.8 مليار مستخدم نشط وبالتأكيد نسبةً كبيرةً من مُستخدمي موقعك يمتلكون سلفًا حساباتًا ضمن فيسبوك، وبالنظر لعدد أسماء المستخدمين وكلمات المرور التي يحتاج الناس لحفظها هذه الأيام، فمن المنطقي استخدام حساب موجود مُسبقًا للتسجيل ضمن موقعك، ويسمح تسجيل الدخول باستخدام فيسبوك للمستخدمين التسجيل ضمن موقعك باستخدام ضغطة زر واحدة فقط. توجد الكثير من الفوائد لإنشاء المستخدمين حسابات على موقعك حيث يُعَد:
يُمكن لفيسبوك بصفته منصةً واسعة الاستخدام توفير تحليلات دقيقة ومعلومات ديموغرافية لا تستطيع الوصول لها بغير طريقة، وهي معلومات قيّمة تُساعد على تضخيم عملك التجاري. 5 خطوات لكيفية تفعيل تسجيل الدخول باستخدام فيسبوك في ووردبريسأصبحت تعلم الآن لما عليك إضافة هذه الميزة لموقعك، وبالتالي يجب عليك معرفة كيفية إضافة هذه الميزة وحصد منافعها، قد تبدو الخطوات التالية مُعقدةً ولكنها أبسط مما تعتقد. الخطوة الأولى ضبط حساب مطور فيسبوكيجب عليك بالخطوة الأولى التسجيل في حساب مطور فيسبوك، فهذا يسمح لك باستخدام عدة تطوير برمجيات فيسبوك Facebook SDK اختصارً لـ Software Development Kit لإنشاء تطبيقات عديدة، منها زر تسجيل الدخول باستخدام فيسبوك ضمن موقعك. توجه إلى موقع Facebook Developer واضغط على "تسجيل الدخول" في الزاوية العلوية اليُسرى، يجب عليك الإجابة عن مجموعة أسئلة ولن تستغرق هذه العملية وقتًا إذا كنت تمتلك حساب فيسبوك، وبعد الانتهاء سوف تُنقل لصفحة تطبيقات فيسبوك التي تقودك للخطوة الثانية. الخطوة الثانية أنشئ تطبيق فيسبوك جديدعليك الآن إنشاء تطبيق فيسبوك ليكون الوعاء الذي يتضمن الشيفرة التي سوف تربط موقعك مع فيسبوك، لهذا اضغط ضمن الصفحة الرئيسية للتطبيقات على الزر الأخضر "إنشاء تطبيق" للبدء بالعملية. سوف تظهر لك نافذة منبثقة تطلب منك اختيار وظيفة التطبيق الذي تريده. اختر "مستخدم" لضبط تسجيل الدخول باستخدام فيسبوك، ثم أعط اسمًا لتطبيقك وأدخل بريدًا إلكترونيًا للتواصل. اضغط على "إنشاء تطبيق" بعد الانتهاء مما سبق، وسيُطلب منك إثبات أنك إنسان يستخدم هذه الخدمة باستخدام كابتشا CAPTCHA أو من خلال إدخال كلمة مرور حسابك على فيسبوك لتتمكن بعدها من الانتقال للخطوة التالية. الخطوة الثالثة إضافة منتج لتطبيقك الجديديجب عليك الآن اختيار مُنتج لتطبيقك الجديد، وهو عمليًا قسم مُجهز مُسبقًا من الشيفرة البرمجية التي تُساعدك على الانطلاق بالاتجاه الصحيح، وفي حال اخترت "مستخدم" في الخطوة الثانية؛ فيجب ظهور خيار "تسجيل دخول فيسبوك" لك في هذه الصفحة. حرك مؤشر الفأرة فوقه ثم اضغط على "إعداد" ليطلب منك فيسبوك اختيار المنصة التي سوف يعمل ضمنها تطبيقك. اختر "الويب" طالما أنك تريد إضافة هذه الميزة لموقعك الإلكتروني، وستظهر لك في النافذة التالية قائمة تُرشدك بالخطوات التي عليك اتباعها حيث تبدأ بتقديم رابط موقعك الإلكتروني. يُطلب منك في بعض الخطوات نسخ ولصق شيفرة برمجية ضمن مواضع عدة في موقعك الإلكتروني لتفعيل التحليلات وإضافة زر تسجيل الدخول باستخدام فيسبوك، تستطيع عمل ما سبق يدويًا ولكننا سوف نستخدم إضافة ووردبريس في الخطوة الخامسة لتكون العملية أسهل لذلك تستطيع تخطي هذه الخطوات دون أي مشاكل إذا أردت. الخطوة الرابعة ضبط إعدادات زر تسجيل الدخول باستخدام فيسبوكسوف يُقدم لك فيسبوك في هذه المرحلة شيفرةً برمجيةً مرتبطةً بزر تسجيل الدخول، حيث تستطيع ضبط مظهره هنا، وهذا لأن فيسبوك يوفر مولد شيفرة سهل الاستخدام تستطيع الاستعانة به لتغيير مظهر زر تسجيل الدخول بما يُناسبك. تستطيع الآن نسخ الشيفرة ولصقها ضمن الصفحة المناسبة في موقعك الإلكتروني، وللتذكير مرةً أخرى، فنحن سنستخدم إضافةً للاستعاضة عن الطريقة اليدوية لإضافة زر تسجيل الدخول. الخطوة الخامسة عرض زر تسجيل الدخول باستخدام فيسبوك على موقع ووردبريس باستخدام الإضافاتيجب عليك الآن عرض زر تسجيل الدخول باستخدام فيسبوك ضمن موقعك الإلكتروني، وبالرغم من قدرتك على إضافته يدويًا باتباع التعليمات الموجودة في حسابك Facebook Developer، لكن يُنصح باستخدام إضافة لأنها تجعل العملية أبسط، وتُعَدّ إضافة Nextend Social Login خيارًا مثاليًا يسمح لك أيضًا بإضافة تسجيل الدخول باستخدام جيميل وتويتر. توجه إلى لوحة تحكم ووردبريس ثم قسم "إضافات"، واضغط على تبويب "أضف جديدًا"، ثم ابحث عن Nextend وثبّتها وفعلها. توجه بعد ذلك إلى قسم "الإعدادات" ثم تبويب Nextend Social Login. اضغط على Getting Started ضمن إعدادات فيسبوك لضبط الإضافة، حيث سوف تظهر لك نافذة تتضمن قائمة بتعليمات إنشاء تطبيق فيسبوك، وبما أننا انتهينا من هذه الخطوة فتستطيع الانتقال إلى أسفل الصفحة والضغط على زر I am done setting up my Facebook App لتظهر لك بعدها نافذة إعدادات. يتوجب عليك الآن إدخال App ID وApp Secret التي تستطيع إيجادهما ضمن حساب مطور فيسبوك، اضغط على "تطبيقاتي" في أعلى الصفحة ثم اختر التطبيق الذي أنشأته في بداية المقال، واضغط على تبويب "أساسي" ضمن قسم "الإعدادات" في الشريط الجانبي. ستجد App ID وApp Secret في أعلى الصفحة، لهذا أدخل هذه القيم ضمن إعدادات Nextend واحفظ الإعدادات. تستطيع الآن ضبط مظهر زر تسجيل الدخول باستخدام فيسبوك من خلال Buttons في أعلى صفحة إعدادات Nextend، حيث توفر الإضافات بعض التصاميم الجاهزة أو تستطيع استخدام الزر المُخصص الذي أنشأته في الخطوة الرابعة. يجب ظهور زر تسجيل الدخول باستخدام فيسبوك في صفحة تسجيل الدخول حالما تحفظ هذه الإعدادات. الخلاصةتُعَد إضافة تسجيل الدخول باستخدام فيسبوك لموقعك طريقةً مميزةً لاجتذاب المزيد من عمليات التسجيل ضمن الموقع وتشجيع الزوار على التعليق، وحتى الحصول على تحليلات تُساعدك على تحقيق نمو علامتك التجارية، وكما ذكرنا سابقًا، فهذه العملية بسيطة رغم أنها تبدو معقدة، ولذلك لا تتراجع وحاول تطبيقها بنفسك. اتبع الخطوات التالية ببساطة لتفعيل تسجيل الدخول باستخدام فيسبوك في موقع ووردبريس:
ترجمة -وبتصرّف- للمقال How to Integrate Facebook Login with WordPress لصاحبه Will Morris. اقرأ أيضًا |
59,660 | إذا كنت فاقداً للبصر ..هكذا يبدو تصفح إنستغرام! |
تتوفر عدد من التقنيات التي تساعد فاقدي البصر او أصحاب النظر الضعيف لتصفح شبكة الإنترنت، لكن عندما يتعلق الأمر بتطبيق إنستغرام قد يكون ذلك غريباً بعض الشيء. ويقدم التطبيق خاصية "قارئ الشاشة" التي توضح اسم ناشر الصورة ووقت نشرها، بالإضافة إلى عدد الإعجابات. كما تعمل على توضيح محتوى الصورة. خاصية قراءة الشاشةوتعتمد خواص قراءة الشاشة "Screen Reader" على نص يقوم المستخدمين بإدخاله يدوياً. لكن عادةً ما يهمل المستخدمون إضافة هذا النص، وفي هذه الحالة تقوم الخاصية بقراءة نص افتراضي. إلى ذلك، قد يقوم قارئ المحتوى الصوتي بكثير من الأحيان بوصف الصورة بشكل خاطئ، بحسب ما أفاد موقع "البوبة العربية للأخبار التقنية"، نقلاً عن Danielle McCann، منسق شبكات التواصل الاجتماعي في الاتحاد الوطني للمكفوفين. وتعد الأخطاء التي ترتكبها تقنيات وصف محتويات الشاشة كثيرة ومختلفة، إلا أنها قد ساعدت فاقدي البصر على تصفح الشبكات الاجتماعية حتى لو مع تجربة استخدام غير مثالية. ويهتم عدد كبير من المستخدمين بتوضيح النص الوصفي لصورهم، والمعروف باسم Alt Text، وهي خاصية أصبحت شبكات اجتماعية عديدة منها إنستغرام توفرها. وصف الصورة والذكاء الاصطناعيلكن حتى مع اهتمامهم هذا فقد يخطئ الشخص المعافى في تحديد المعلومات التي تهم فاقد البصر لكي يتخيل محتوى الصورة. وقد ذكرت McCann أنها تخبر أصدقائها بأن كتابة النص الوصفي هو أشبه باختبار لجودة الكتابة. وكيف يمكنك وصف المحتوى بدقة في أقل عدد كلمات ممكن. ويجب أن تكون هذه النصوص واصفة ومليئة بالمعروفات، وليست نصوص أدبية صعبة الفهم. من ناحية أخرى، يستطيع الذكاء الاصطناعي الخاص بفيسبوك، والمستخدم أيضاً في إنستاغرام، على تقديم وصف للصورة، لكنه لازال ضعيفاً، ولازال يعاني من أخطاء قد تفسد فهم محتوى الصورة بالكامل بالنسبة لضعيف البصر. وبشكل عام، تصفح إنستاغرام بالنسبة لفاقدي البصر لا يقدم تجربة متكاملة. لكن في حالة أن صاحب الصورة لم يضع وصفاً مناسباً لها، فهذا يظل الحل الوحيد بالنسبة لهذه الفئة من المستخدمين. |
59,659 | 4 أدوات مفتوحة المصدر من أجل مراقبة نظام لينكس |
يُعَد امتلاك المعلومات المناسبة هو الخطوة الأولى لحل أي مشكلة حاسوبية، سواءً كانت هذه المشكلة مرتبطةً بنظام التشغيل لينكس أو بالعتاد الذي يشغّله النظام. توجد العديد من الأدوات المتاحة منها ما يكون مضمّنًا في معظم توزيعات لينكس، ومنها لا يكون مثبّتًا افتراضيًا، ويجب على المستخدم أن يثبتها في حال رغبته باستخدام الأداة. تقدّم هذه الأدوات الكثير من المعلومات المفيدة في تشخيص المشاكل الخاصة بالحاسوب. تناقش هذه المقالة بعض الأدوات التفاعلية التي تعمل بالأوامر CLI، والتي يمكن تثبيتها بسهولة على توزيعات لينكس ريد هات Red Hat وفيدورا Fedora وسينتوس CentOs وكل التوزيعات المشتقّة منها، حيث تتوفر العديد من الأدوات ذات الواجهات الرسومية التي يمكن استخدامها لنفس الغرض إلا أنها لا تكون قابلةً للاستخدام في جميع الأحيان، نظرًا لعدم امتلاك بعض الخوادم القدرة على العرض رسوميًا. تقدّم المقالة أربع أدوات أساسية ضمن بيئة نظام لينكس لمراقبة النظام وتشخيص المشاكل فيه وهي top وatop وhtop وglances، حيث تراقب هذه الأدوات نسبة استخدام الذاكرة ووحدة المعالجة المركزية CPU، كما تتيح معظمها معلومات عن العمليات قيد التشغيل، إضافةً إلى العديد من الجوانب الأخرى، وتظهر هذه المعلومات تقريبًا بالزمن الحقيقي لنشاط النظام. متوسط الحمليمثّل متوسط الحمل Load average متوسط عدد التعليمات التي تنتظر أن ينفذها المعالج، فهو مقياس حقيقي لأداء وحدة المعالجة المركزية خلافًا لنسبة استهلاك وحدة المعالجة المركزية، والتي تُعَد مقياسًا غير دقيق كونها تتضمّن زمن انتظار متعلّق بعملية الإدخال والإخراج حيث يكون عندها المعالج خاملًا. نفترض أنّ النظام يمتلك معالجًا وحيدًا، وبالتالي عندما يكون متوسط الحمل مساويًا للواحد، فهذا يعني أنّ المعالج ينفذ الطلبات الواردة إليه دون تأخير وأن نسبة استخدامه ممتازة؛ أما عندما يصبح متوسط الحمل أقل من واحد، فيعني ذلك أنّ المعالج غير مستخدم حسب المطلوب، وأنّه قادر على تنفيذ المزيد من العمل، وعندما يصبح متوسط الحمل أكبر من واحد، فالمعالج هنا يكون قد أصبح مشغولًا مع وجود بعض التعليمات بحالة انتظار لفترة زمنية قبل أن ينفّذها المعالج. في نظام أحادي المعالج وعندما يكون متوسط الحمل مساويًا 1.5 فإنّ ثلث التعليمات الواردة تنتظر لفترة زمنية قبل أن يبدأ تنفيذها، أما في حال النظم متعددة المعالجات، فلو فرضنا أنه يوجد نظام متعدد المعالجات يمتلك أربع معالجات، فإن متوسط الحمل المثالي يساوي أربعة. فإذا كان هذا المتوسط مساويًا 3.24 فسيعني ذلك أنّ ثلاثة معالجات منها مستخدمة كليًا وقد بلغت نسبة استخدام المعالج الرابع 76%. تكون قيمة متوسط الحمل المثالية مساويةً لعدد المعالجات في النظام، ويعني ذلك أنّ جميع المعالجات مستخدَمة بطاقتها القصوى، ولا تضطر أية تعليمة للانتظار حتى تُنفّّذ. تعطي هذه القيمة على المدى الطويل نظرةً عامّةّ للاستخدام العام للموارد في الحاسوب. الإشاراتتسمح جميع أدوات المراقبة المذكورة سابقًا بإرسال إشارات Signals للعمليات قيد التشغيل، وتكون لكل إشارة وظيفة محددة مرتبطة بها، كما يمكن أن يعرّف البرنامج الذي يستقبل هذه الإشارة، الوظيفة التي تحدث عند استلامه للإشارة. يسمح الأمر Kill بإرسال الإشارات إلى العمليات أيضًا دون الحاجة لاستخدام برامج المراقبة، ويمكن تنفيذ الأمر kill -l لاستعراض جميع الإشارات التي يمكن استخدامها مع العمليات المختلفة، وتُستخدَم ثلاث من هذه الإشارات من أجل إيقاف العمليات والتي تسمى أحيانًا بقتل العملية kill a process.
يمكن تجربة الأوامر السابقة بإنشاء جلسة موجه أوامر جديدة ومن ثم إنشاء ملف ضمن المجلد""/tmp باسم cpuHog، ثم تحويله لبرنامج تنفيذي وإعطائه الأذونات "rwxrxrx" وكتابة المحتوى التالي ضمن الملف: #!/bin/bash # This Little program is a cpu hog X=0; while[1]; do echo $X;X=$(X+1);doneنفتح موجه أوامر في نافذة مختلفة ونضع النافذتين متجاورتين لكي نشاهد النتائج، ومن ثم نشغل الأمر top، وبعدها نشغل برنامج cpuHog الذي كتبناه باستخدام الأمر التالي: /tmp/cpuHogيعمل البرنامج بطريقة عدّاد، مع طباعة القيمة التي وصل إليها إلى المخرج الذي نختاره، وهو افتراضيًا الشاشة. يستهلك هذا البرنامج دورات المعالجة الخاصة بالمعالج، لذا سنشاهد ارتفاعًا ملحوظًا في نسبة استخدام المعالج ضمن نتائج الأمر top. يزداد متوسط الحمل أيضًا مع مرور الزمن، ويمكن فتح نوافذ جديدة وتشغيل البرنامج فيها وملاحظة التغير الذي يحصل على استهلاك المعالج. يمكن عند الحاجة لقتل العملية ضمن الأداة top بالضغط على الحرف K، وستظهر رسالة تطلب رقم التعريف الخاص بالعملية PID التي يريد المستخدم قتلها. وبعد إدخال هذا الرقم نضغط على "Enter"، وعندها ستسأل الأداة المستخدِم عن الإشارة التي يرغب بإرسالها، والتي تكون افتراضيًا "15". يمكن في هذه المرحلة تجربة الإشارات المختلفة وملاحظة الاختلافات فيما بينها. أداة topتُعَد هذه الأداة من أهم الأدوات المستخدمة عند تشخيص المشاكل، وتتميز بأنها متاحة دومًا وموجودة في جميع توزيعات لينكس افتراضيًا دون الحاجة الى تنصيبها. تقدّم هذه الأداة الكثير من المعلومات حول النظام قيد العمل، فنجد فيها معطيات حول استهلاك الذاكرة وأحمال المعالج، وقائمة بالعمليات قيد التشغيل، وإلى جانب كل عملية نجد نسبة استهلاكها لموارد الحاسوب. تُحدّث هذه المعلومات كل ثلاثة ثواني، أي أننا قد نَعُد الأداة وكأنها تعمل في الزمن الحقيقي. تسمح هذه الأداة باستخدام أجزاء الثواني إذا احتاج المستخدِم لاستعمالها، ولكن من النادر أن تؤثر القيم الضئيلة على الأداء الكلي للحاسوب، كما تتميز الأداة بأنها تفاعلية ويمكن للمستخدم أن يرتّب النتائج الظاهرة حسب اهتمامه. يظهر الشكل (1) عينةً من نتائج عمل الأداة top، ويقسم هذا الخرج إلى جزأين أساسيين وهما جزء الملخص "Summary" وجزء العملية "Process" بالترتيب. حيث يمكن الاستفادة من الأوامر التفاعلية الخاصة بالأداة من قِبل المستخدِم لتغيير طريقة العرض الخاصة بالأداة لتناسب المستخدِم، إضافةً إلى التحكم بالعمليات كليًا، إذ تعرض الأداة كل الأوامر المتاحة بالضغط على h لاستعراض المساعدة الخاصة بالأداة والتي تكون موزّعةً على صفحتين، بحيث يحدث الانتقال إلى الصفحة الثانية بالضغط على h مرتين، ويمكن الخروج من الصفحة بالضغط على q. جزء الملخصيقدم هذا الجزء ملخّصًا عامًا عن النظام، حيث يُظهر السطر الأول منه زمن عمل النظام منذ آخر عملية إقلاع له، ومن ثم متوسط الحمل محسوبًا على مدة زمنية تعادل 1، 5، 15 دقيقة على الترتيب، بينما السطر الثاني يظهر عدد العمليات النّشطة في الحاسوب وحالة كل من هذه العمليات. تظهر في السطر الثالث إحصائيات خاصة بالمعالج، بحيث قد تكون هذه الإحصائيات مقتصِرةً على سطر واحد يتضمن الإحصائيات عن جميع المعالجات الموجودة في الحاسوب، ويمكن أن نجد سطرًا لكل معالج على حدة، كما يمكن تبديل طريقة الإظهار بين المعلومات المجمّعة عن المعالج، والمعلومات عن المعالجات إفراديًا بالضغط على الرقم 1، بحيث ستظهر القيم بشكل نسبة مئوية من وقت المعالج المتاح للتنفيذ. نجد في النتائج القيم التالية:
(*) مستوى اللطافة هو تعبير عن الأولوية للعمليات الخاصة بالمستخدِم، والتي تربطها علاقة بأولوية العملية الحقيقية، حيث أن قيمة الأولوية = قيمة اللطافة + 20، وتأخذ قيم اللطافة قيمًا موجبةً وقيمًا أخرى سالبة تتراوح بين المجال -20 (الأعلى) و+19 (الأدنى)، الدليل الموجز إلى القيم الأولوية اللطيفة في النظام البيئي لينكس يعرض السطرين الأخيرين في هذا الجزء استهلاك الذاكرة حيث يظهر كل من استهلاك الذاكرة العشوائية وذاكرة التبادل.
الشكل (1): يُظهر الأمر top المعلومات الكاملة عن معالج رباعي النوى مستخدم كليًا. يمكن الضغط على l لإيقاف عرض متوسط الحمل أو تشغيله، كما يمكن الضغط على t وm من أجل تغيير طرق العرض الخاصة بمعلومات العمليات والذاكرة. جزء العملياتيتضمن هذا الجزء المعلومات عن العمليات قيد التشغيل في النظام، حيث تظهر هذه المعلومات على شكل أعمدة، ويتضمن العرض الافتراضي مجموعةً من الأعمدة، كما يمكن إضافة المزيد منهم من قِبل المستخدِم حسب ما يجده مفيدًا له. فيما يلي المعلومات التي تظهر افتراضيًا:
يمكن الضغط على Page Up وPage Down للتنقل بين قائمة العمليات قيد التنفيذ، ويمكن ضبط المدة الزمنية لأخذ القراءات باستخدام d وs، وتكون هذه المدة افتراضيًا ثلاث ثواني، بحيث يمكن تعديلها لتصبح جزءًا من الثانية، لكن ذلك يزيد من استهلاك الأداة لموارد الحاسوب ومن المفضل ضبط هذه القيمة بحيث تعادل ثانيةً واحدةً كي لا تؤثر سلبًا على أداء الحاسب وتعطي معلومات وافرة عن هذا الأداء. يفيد الضغط على < و > في التنقل بين الأعمدة إلى اليمين أو اليسار، كما يمكن الضغط على k من أجل قتل العملية أو الضغط على r من أجل تعديل مستوى لطافتها، وفي كلتا الحالتين يجب تحديد رقم التعريف الخاص بالعملية، حيث يجب أن نحدد رقم الإشارة عند قتل العملية. عادةً ما تبدأ المحاولات بالإشارة 15 وفي حال عدم نجاحها يمكن استخدام الإشارة 9 لقتل العملية قتلًا مؤكدًا. الضبطيمكن للمستخدِم الذي يعدّل معلومات العرض الخاصة بالأداة، استخدام الأمر W (يجب استخدام الحرف الكبير Uppercase)، وذلك لكتابة التغييرات إلى ملف الضبط، والذي يوجد عادةً في المسار""~/.toprc في المساحة المخصصة للمستخدِم. أداة atopتتيح هذه الأداة معلومات أكثر تفصيلًا موازنةً بالأداة top. ومن أهم المعلومات الإضافية التي يمكن الحصول عليها باستخدام هذه الأداة، هي نشاط الإدخال والإخراج، حيث تتحدث القيم الظاهرة على الشاشة بعد انقضاء عشرة ثواني، ويمكن تغيير هذه المدة بالضغط على i واستخدام قيمة تناسب حاجة المستخدم. لا تستطيع هذه الأداة استخدام أجزاء الثانية مثل سابقتها، لكن يمكن استخدام الأمر h للحصول على المساعدة، وتوجد عدة صفحات ضمن دليل المساعدة يمكن التنقل بينها بالضغط على المسطرة Space. تتميز هذه الأداة بقدرتها على تخزين معلومات الأداء الخام ضمن ملف واستعراض محتوياته لاحقًا من أجل الدراسة المعمقة، مما يفيد في كشف بعض المشاكل الخفية وخصيصًا تلك التي تظهر في الوقت الذي لا يكون فيه النظام خاضعًا للمراقبة. يستخدم البرنامج atopsar لاستعراض محتويات الملفات المخزّنة حسب حاجة المستخدم.
الشكل (2): يقدم نظام المراقبة atop المعلومات حول نشاط الأقراص والشبكة إضافة إلى نشاط المعالج. جزء الملخصتقدّم الأداة atop نفس المعلومات التي تقدّمها الأداة top، إلا أنّها تعرض بعض المعلومات الإضافية مثل المعلومات المتعلقة بنشاط الشبكة والأقراص والحجوم المنطقية ضمن الأقراص. يبين الشكل (2) أعلاه بعضًا من هذه المعلومات، تجدر الإشارة إلى أنّ عدد الأعمدة الذي يظهر هو مرتبط بأبعاد الشاشة، بحيث إذا كانت كافيةً فستعرض الأداة كافة الأعمدة بما تتضمنه من معلومات، وإلا فإنها تهمل بعضًا منها. تتميز هذه الأداة موانةً بجميع أنظمة المراقبة الأخرى بنها تعرض تردد المعالج الحالي، إضافةً إلى تبيان معامل توسيع التردد scaling factor، وتظهر هاتين القيمتين في أقصى اليمين ضمن السطر الثاني. جزء العمليةتعرض الأداة atop بعضًا من الأعمدة التي تعرضها الأداة top، ولكنها تضيف بعض المعلومات مثل معلومات الإدخال والإخراج الخاصة بالقرص وعدد النياسب (الخيوط threads)، إضافةً إلى إحصائيات عن تغير كل من الذاكرتين الافتراضية والحقيقية لكل عملية. كما هو الحال في جزء الملخص، يمكن إظهار كامل الأعمدة إذا سمحت أبعاد الشاشة بذلك، وإلا فلن تظهر بعض الأعمدة مثل العمود المخصص لعرض رقم التعريف الحقيقي للمستخدم RUID الذي يملك العملية، ورقم التعريف الفعلي للمستخدم EUID، وتكون هاتين المعلومتين هامتين عند تشغيل بعض البرامج مع التلاعب بهوية المستخدم الذي ينفذ أمر التشغيل للبرنامج. تقدّم الأداة معلومات تفصيلية عن القرص والذاكرة والشبكة والجدولة الخاصة بكل عملية. يمكن الضغط على d وm وn وs بالترتيب لمشاهدة أي من التفاصيل السابقة، كما يمكن الضغط على g لإعادة الإظهار إلى وضعه الطبيعي. يمكن للمستخدم ترتيب العرض وفقًا لمعيار محدد، حيث يمكن الضغط على C للترتيب اعتمادًا على استهلاك وحدة المعالجة المركزية، أو الضغط على M للترتيب اعتمادًا على استهلاك الذاكرة، أو الضغط على D للترتيب اعتمادًا على استهلاك القرص، أو الضغط على N للترتيب اعتمادًا على استهلاك الشبكة، أو الضغط على A للترتيب التلقائي، ويعني ذلك الترتيب وفقًا للمورد الأكثر إشغالًا من قبل العملية. لن تعمل عمليات الترتيب الخاصة بالشبكة إلا بوجود مكتبة netatop إلى جانب الأداة atop، ويمكن الضغط على k لقتل أي عملية ولا تمتلك هذه الأداة القدرة على تعديل مستوى اللطافة مثل سابقتها. لا تعرِض هذه الأداة أجهزة الشبكة والتخزين التي لا تكون نشطةً ضمن فترة جلب المعلومات، مما قد يعطي انطباعًا خاطئًا عن ضبط الجهاز المستخدَم، فقد يوهم بعض المستخدمين بأن أحد الأجهزة لا يعمل بطريقة صحيحة، ولتجنب ذلك يمكن الضغط على f لعرض جميع الموارد وحتى الخاملة منها. الضبطيشير الدليل الخاص بالأداة atop الموجود ضمن نظام لينكس إلى ملفات الضبط الخاصة بالمستخدم وملفات الضبط العامة، وذلك باستثناء توزيعتي فيدورا وسينتوس. حيث لا توجد أية طريقة لحفظ تعديلات المستخدِم على ملفات الضبط وبالتالي لا تكون هذه التغييرات دائمة. أداة htopتشبه هذه الأداة إلى حد كبير الأداة top، ولكنها تعرض بعض المعلومات الإضافية التي لا تقدمها تلك الأداة، حيث لا تقدم هذه الأداة المعلومات عن القرص والشبكة والإدخال والإخراج كما في atop.
الشكل (3): تمتلك الأداة htop طريقة إظهار جذابة للمستخدمين، كما أنها تعرض شجرة العملية كاملةً. جزء الملخصيتضمن جزء الملخص للأداة htop عمودين أساسيين يتميزان بالمرونة الشديدة وقدرة المستخدم على ضبطهما بالشكل والترتيب الذي يناسبه، حيث يمكن للمستخدم مشاهدة استهلاك المعالج عن طريق الشريط الظاهر أمامه، كما يمكن استخدام شريط واحد لكامل وحدة المعالجة المركزية، إلى جانب إمكانية استعمال شريط لكل معالج موجود، أو تجميع العرض من عدة معالجات معًا ضمن شريط واحد. يُعَد العرض بهذه الطريقة أكثر سهولةً للمستخدم، إلا أنّه يُغفِل العديد من المعلومات الأساسية التي قد تهمّه، ومنها النسبة المستهلكة من المعالج لكل مستخدم، إضافةً إلى وقت الخمول الخاص بالمعالج وغيرها من المعلومات التي تعرضها الأدوات السابقة. يمكن تعديل ضبط هذا الجزء بالضغط على F2 حيث تُعرض الخيارات المتاحة ويضيف المستخدم ما يشاء من هذه الخيارات وترتيبها ضمن العرض كما يشاء. جزء العمليةيشبه جزء العملية الخاص بهذه الأداة إلى حد كبير الأدوات السابقة، حيث يمكن ترتيب العمليات اعتمادًا على نسبة استهلاك المعالج، أو الذاكرة، أو المستخدم، أو رقم تعريف العملية، مع ملاحظة أنه لا يمكن استخدام وظيفة الترتيب عندما يختار المستخدم العرض بالشكل الشجري. يختار المستخدم العمود الذي سيكون الترتيب وفقًا له، وذلك بالضغط على F6 لتُعرض مجموعة الأعمدة التي يمكن الترتيب وفقًا لها، وبعد إقدام المستخدم على الاختيار، فسيضغط على Enter لتنفيذ عملية الترتيب. يمكن التنقّل بين العمليات باستخدام الأسهم وذلك لاختيار عمليةٍ ما، وبعد الاختيار يمكن قتل العملية بالضغط على k، ومن ثم تظهر قائمة بالإشارات ليختار المستخدِم واحدةً منها، بحيث تُرسل إلى العملية. يمكن أيضًا الضغط على المفتاحين F7 وF8 لتغيير مستوى اللطافة للعملية المختارة. يمكن الضغط على F5 لأية عملية لتُعرض شجرة العملية كاملةً، وبالتالي يمكن تحديد العملية الأب الذي ولّد هذه العملية، وتُعَد هذه المسألة هامةً جدًا عند تشخيص مشاكل العمليات، وخصيصًا ظهور عمليات "ميتة-حية" في النظام. الضبطيمتلك كل مستخدم ملف ضبط خاص به مخزنًا في المسار"~/.config/htop/htoprc"، وتُحفَظ التغييرات التي يجريها المستخدم في هذا الملف تلقائيًا. لا تمتلك هذه الأداة ضبطًا عامًا وإنما يوجد الضبط فقط ضمن ملفات المستخدم. أداة glancesتتميز هذه الأداة بقدرتها على عرض الكثير من المعلومات عن الجهاز موازنةً بجميع الأدوات السابقة، كما تعرض الأداة إلى جانب المعلومات التي تعرضها الأدوات السابقة على سبيل المثال: درجات الحرارة الخاصة بمكونات الحاسب، إضافةً إلى سرعة دوران المروحة المستخدمة مع كل مكون، والكثير من المعلومات المفيدة. تُعَد السلبية الوحيدة لهذه الأداة أنها تستهلك نسبةً كبيرةً من الموارد موازنةً بسابقاتها، وتتراوح نسبة استهلاكها للمعالج بين 10% و18% من إجمالي استخدام المعالج، وهذه النسبة كبيرة جدًا خصوصًا في الأنظمة المحدودة بالموارد. جزء الملخصيحتوي جزء الملخص لأداة glances على معظم المعلومات التي تقدّمها أدوات المراقبة الأخرى، حيث تعرض الأداة معلومات استخدام المعالج بشكل شريط و بشكل عددي في حال كانت أبعاد الشاشة تسمح بذلك، وإلا فإنها ستعرض النتائج بالشكل العددي فقط.
الشكل (4): يُظهر الشكل واجهة الأداة glances متضمنةً معلومات الشبكة والقرص ونظام الملفات ومعلومات الحساسات. كما في الأدوات السابقة، يمكن الضغط على 1 لتغيير طريقة عرض معلومات المعالج إما لتعرِض المعلومات عن إجمالي استخدام المعالج أو عرض المعلومات الخاصة بكل معالج على حدى. جزء العمليةيعرض هذا الجزء المعلومات الاعتيادية عن كل من العمليات قيد التشغيل، حيث يمكن أن تُرتَّب العمليات تلقائيًا بالضغط على a، أو بالاعتماد على استهلاك المعالج c، أو بالاعتماد على استهلاك الذاكرة m، أو بالاعتماد على اسم العملية p، أو بالاعتماد على اسم المستخدم u، أو بالاعتماد على معدل الإدخال والإخراج i، أو بالاعتماد على الوقت t. يعني أن الترتيب التلقائي في الأداة هو اختيار عرض العمليات بالاعتماد على المورد الأكثر استخدامًا، فإذا كان استهلاك المعالج أكبر من 70%، فسيعتمد ترتيب العمليات على استهلاك كل عملية من وقت المعالج، وإذا كان استهلاك الذاكرة أكبر من 70%، فيعتمد الترتيب على استهلاك كل عملية من الذاكرة. تُظهر الأداة الإنذارات والتحذيرات في أسفل الشاشة متضمّنةً تاريخ ومدة بقاء الإنذار. حيث يفيد وجود الإنذارات بإخبار المستخدِم عند وقوع المشكلة، وبالتالي لا يكون مضطرًا لمراقبة الشاشة ومتابعة تغير الأرقام بدقة دائمًا. ويمكن تشغيل وإيقاف الإنذارات بالضغط على l، كما يمكن إزالة الإنذارات الحالية بالضغط على w، ويمكن إزالة الإنذارات والتحذيرات معًا بالضغط على x. لا تقتل هذه الأداة العمليات لأنها مجرد أداة للمراقبة، كما أنها لا تغير من مستوى اللطافة للعملية للسبب ذاته، وإذا رغب المستخدم بذلك فيجب عليه استخدام الأوامر kill أو renice خارج هذه الأداة. الشريط الجانبيتمتلك الأداة glances شريطًا جانبيًا جميلًا والذي يعرِض معلومات غير موجودة في كل من top وhtop. يمكن أن تعرِض atop بعضًا من المعلومات التي تعرضها هذه الأداة، ولكن فقط glances هي القادرة على عرض معلومات حساسات الحرارة من الأدوات السابقة، كما يمكن عرض المعلومات عن الأقراص ونظام الملفات والشبكة والحساسات، بالضغط على d أو f أو n أو s بالترتيب، ويمكن اظهار الشريط الجانبي بالضغط على 2، كما يمكن عرض الإحصائيات في أسفل الشاشة بالضغط على D. الضبطلا تتطلب الأداة glances ملفًا للضبط لكي تعمل بصورة صحيحة، ولكن في حال رغبة المستخدم بوجوده، فيوجد ملف الضبط العام ضمن المجلد الحامل لهذه التسمية ""/etc/glances/glances.conf، فعندما ينشئ المستخدم ملف الضبط الخاص به ضمن المسار ""~/.config/glances/glances.conf، فإنه سيصبح ملف الضبط الفعال، ويتجاوز ملف الضبط العام. يمكن ضمن هذه الملفات تحديد عتبات الإنذارات والتحذيرات فقط، في حين فيجب إعادة ضبط أية تعديلات أخرى على الأداة مثل تعديل الشريط الجانبي أو غيره في كل مرة بعد تشغيل الأداة. يتضمن توثيق الأداة معلومات كافية عن استخدام الأداة glances، وتكون موجودةً افتراضيًا ضمن المسار التالي: "/usr/share/doc/glances/glances-doc.html"وعلى الرغم من أنه قد ذُكِر في الوثيقة أنه يمكن ضبط الأداة كاملةً عن طريق الملف، إلا أنّه لم تُذكر أية طريقة لتحقيق ذلك ضمن الملف. الخلاصةيجب على المستخدم قراءة الدليل الخاص بكل أداة من أدوات المراقبة للتعرف على الطريقة التي تناسب المستخدم في ضبطها والتفاعل معها، ويمكن دومًا الاستعانة بالأمر h ضمن الأدوات للاستفادة من المساعدة التفاعلية الموجودة ضمنها، والتي تقدّم الكثير من المعلومات حول تنفيذ عمليات الاختيار والترتيب في الأداة. يمكن أن تقدّم هذه الأدوات الكثير من المعلومات عن سبب المشاكل التي تصادف المستخدم، كما يمكن أن تحدد أيًا من العمليات هو الأكثر استهلاكًا للمعالج، أو تحديد كمية الذاكرة الحرّة المتاحة، إضافةً إلى معرفة أي من العمليات قد أوقفت مؤقتًا لأنها تنتظر عمليات الإدخال والإخراج، أو لأنها تنتظر الشبكة. يمكن بالمراقبة المستمرة لهذه الأدوات أن يستطيع المستخدِم التمييز بين السلوك الطبيعي للنظام عن السلوك غير الطبيعي الذي يظهر بالنهاية على هيئة مشكلة في الأداء، كما يجب الأخذ بالحسبان أنّ هذه الأدوات تستهلك من موارد الحاسوب الذي تراقبه، حيث تستهلك الأداة glances نسبةً تتراوح بين 10% و20% من وقت المعالج، بينما لا تستهلك الأدوات المتبقية أكثر من 3% من نفس المورد، ويجب التفكير بذلك جيدًا عند اختيار الأداة المناسبة بتقدير نوع المعلومات التي يحتاج المستخدم مراقبته إضافةً إلى معرفة مواصفات الجهاز الذي يُراقَب. ترجمة -وبتصرف- للمقال "4 open source tools for Linux system monitoring" لصاحبه David Both. اقرأ أيضًا |
59,623 | ما هي البيانات التي يرسلها تطبيق واتساب إلى فيسبوك |
أدى التغيير الذي أجرته منصة واتساب في بداية العام الحالي بشأن سياسة الخصوصية إلى نزوح جماعي للمستخدمين إلى تطبيقات المراسلة الأخرى مثل تيليغرام وسيغنال. وجاءت الضجة بعد أن أساء ملايين المستخدمين تفسير شروط الخصوصية الجديدة على أنها تعني مشاركة المزيد من البيانات مع الشركة الأم فيسبوك. وشرحت واتساب لاحقًا السياسة الجديدة على أنها تغطي الطريقة التي يتواصل بها الأشخاص مع الشركات، بينما تظل البيانات التي تتم مشاركتها مع فيسبوك كما هي. ومع ذلك فإن تغيير سياسة الخصوصية ورد الفعل العنيف قد سلط الضوء على الكميات الكبيرة من البيانات التي تجمعها المنصة منذ استحواذ فيسبوك عليها في عام 2014. البيانات التي تشاركها واتساب مع فيسبوكأكدت واتساب أنها لا تشارك محتوى محادثاتك مع فيسبوك. ولن يتغير هذا بعد تحديث شروط الخدمة. وذلك لأن هذه المحادثات تظل محمية بتقنية التشفير من طرف إلى طرف. ولا يمكن قراءتها بواسطة أي شخص حتى التطبيق نفسه. ولكن تتضمن البيانات التي يمكن للتطبيق مشاركتها رقم هاتفك واسم حسابك. بالإضافة إلى ذلك يمكن جمع المزيد من المعلومات التفصيلية المعروفة باسم البيانات الوصفية ومشاركتها مع شركات فيسبوك. وتعتبر البيانات الوصفية أداة قيمة لتحليل الاتصالات بين الأشخاص. حيث لا تحتاج الشركة إلى محتوى الرسالة لتتبع الأشخاص. وذلك لأن أنماط النشاط التي تحتويها تخبر الشركة كل شيء عن المستخدم. وتقول واتساب إن البيانات التي تتم مشاركتها مع فيسبوك هي لأغراض محددة مثل منع البريد العشوائي. وليس لاستهداف المستخدمين بالإعلانات. وتوضح أيضًا أنها لا تشارك جهات الاتصال مع فيسبوك. وليس هناك خطط للقيام بذلك. ولكن تظل بعض عمليات مشاركة بيانات تطبيق مبهمة للغاية. على سبيل المثال تصف سياسة الخصوصية كيف أن البيانات الشخصية التي تتم مشاركتها مع فيسبوك قد تتضمن معلومات أخرى محددة في سياسة الخصوصية أو يتم الحصول عليها بناءً على موافقتك. كيف تعمل سياسة خصوصية واتساب الجديدةتعمل سياسة خصوصية واتساب على تغيير طريقة التواصل مع الشركات التي تستخدم واجهة برمجة التطبيقات الخاصة بها. ويتم عادةً تشفير محادثات واتساب بين الأشخاص والشركات أثناء إرسالها. ولكن بعد تحديث الخصوصية الأخير يمكن تخزينها بمجرد استلامها بواسطة شركة في خوادم فيسبوك. وبالرغم من تأكيد فيسبوك أنها لا يمكنها استخدام هذه البيانات المخزنة في خوادمها. ولكن يمكن للشركات استخدامها لاستهدافك بالإعلانات. لدى فيسبوك العديد من التطبيقات والخدمات بما في ذلك التطبيقات الشهيرة مثل فيسبوك وواتساب وإنستاجرام بالإضافة إلى 91 خدمة وتطبيق. ومع ذلك هناك بعض الخطوات التي يمكنك اتخاذها لإيقاف مشاركة بياناتك، مثل عدم التسجيل ضمن مواقع الويب باستخدام فيسبوك. بالإضافة إلى ذلك يمكنك تصفح فيسبوك عبر متصفح الويب وليس التطبيق. واستخدم تطبيق واتساب في هاتف ثانوي وليس هاتفك الرئيسي. |
59,622 | كيفية ضبط إعدادات الخصوصية في ووردبريس |
تُعَد سياسة الخصوصية واحدةً من أكثر أقسام موقع ووردبريس التي لا تحظى بالتقدير، وبالرغم من ذلك يجب أن يضغط كل زائر على خيار الموافقة على سياسة الخصوصية للموقع. من المهم امتلاك سياسة خصوصية مُحكمة في موقعك، فهي توفر حمايةً قانونيةً له (محليًا ودوليًا)، كما تُساهم في رفع ترتيب الموقع وتحسين محركات البحث. يجب أن تكون سياسة الخصوصية واضحةً ومُحّدثةً ومكتوبةً بأفضل صيغة ممكنة، وهناك أدوات ومصادر يُمكن أن تساعدك على كتابتها، وبعض النصائح لما يجب أن تتضمنه سياسة الخصوصية لموقع ووردبريس. ما هي سياسة الخصوصية؟تُخبر سياسة الخصوصية المستخدمين كيف يُعالج موقعك بياناتهم، لذلك عليك التصريح عن المعلومات التي يجمعها موقعك عن الزوار سواءً كانت عنوان بريد إلكتروني أو الاسم أو الكنية أو الموقع الجغرافي أو غيرها، ثم عليك إخبارهم بما تنوي فعله بهذه المعلومات حتى لو كان الأمر بسيطًا وغير مؤذٍ، مثل إرسال تخفيض عبر البريد الإلكتروني بمناسبة ذكرى ولادته. تُعَد اللائحة العامة لحماية البيانات في الاتحاد الأوروبي GDPR تشريعًا من قِبل الاتحاد الأوروبي، يطلب من الزوار الاشتراك قبل أن تُجمع أي بيانات، ويُشترط امتلاك سياسة خصوصية ضمن موقعك في حال استخدمت Google Analytics أو زر الإعجاب الخاص بفيسبوك أو استخدمت إعلانات أو أي أمر مُشابه. ستكون أنت وزوار موقعك مقيدين بسياسة الخصوصية الموجودة على موقعك سواءً قرؤوها أم لا، وعدم وجود سياسة خصوصية ضمن أي موقع تُعرضه للكثير من المشاكل القانونية، وأولها غرامات بآلاف الدولارات، فقد صدر في مطلع عام 2020 تشريع باسم CCPA أكثر صرامةً من GDPR بما يخص المتطلبات والعقوبات، لذلك فلتأمين نفسك قانونيًا؛ فيجب أن يكون أول بند في قائمة أولوياتك. يجب عليك الاستعانة بمحام لمساعدتك على صياغة مسودة سياسة الخصوصية لموقعك، ولكن هذا ليس خيارًا عمليًا لمعظم أصحاب المواقع، ولهذا انتشرت العديد من الخدمات التي يُمكنها مُساعدتك على صياغة سياسة خصوصية، ولكن المشكلة تكمن في أنه لا يُمكنك الوثوق بأي خدمة تجدها ضمن محرك البحث جوجل، وهنا يأتي دور هذا المقال ليُقدّم لك فكرةً عما يجب أن تتضمنه سياسة الخصوصية، حيث ستستطيع بعد قراءة هذا المقال وما يحويه من معلومات؛ استخدام أي خدمة لتوليد سياسة خصوصية لموقعك. كيفية إنشاء سياسة خصوصية باستخدام ووردبريسلحسن الحظ فإن مطوري ووردبريس توقعوا أن عدم امتلاك سياسة خصوصية للموقع سوف يكون له تداعيات سلبية، لذلك فإن الإصدارات الجديدة من ووردبريس تتضمن تبويب "الخصوصية" ضمن قسم "الإعدادات" في لوحة تحكم ووردبريس، وسشرح في ما يلي خطوات إنشاء سياسة خصوصية لموقعك باستخدام لوحة تحكم ووردبريس. سوف تظهر لك رسالة (1) في أعلى الصفحة حال دخول "الخصوصية" في قسم "الإعدادات"، وهذا لأن قسم سياسة الخصوصية (2) فارغ. إنّ ظهور هذه الرسالة لا يعني أنك لا تمتلك سياسة خصوصية، ولكنه يُشير إلى أنك لا تملك سياسة خصوصية مُولدةً باستخدام هذه الخاصية، وسيُساعدك ووردبريس على إنشاء سياسة الخصوصية إن كنت لا تملك واحدة، وكل ما عليك فعله هو الضغط على "إنشاء" (3). يتضمن الشريط الذي في أعلى المنشور (4) مُلخصًا لما يتضمنه المنشور نفسه، حيث تستطيع الضغط عليه لقراءته بالتفصيل، أو تستطيع التنقل باستخدام الشريط المنزلق لمراجعة النص المُوّلد مسبقًا، وكذا التأكد من أنه مناسب لموقعك. تتشابه سياسات الخصوصية في ووردبريس لأن معظم المواقع تستخدم البيانات بنفس الطريقة، فإن كنت تريد سياسة خصوصية سريعةً وسهلة، فعليك مراجعة الفقرات وإزالة عبارة النص المقترح (5)، والضغط على "نشر" (6)، وستحصل على سياسة خصوصية ضمن صفحة جديدة برابط مثل الرابط الدائم المُستخدم عند النشر في الخطوة السابقة، بعد ذلك يجب عليك مراجعة المعلومات مرةً ثانيةً بعد إنشاء ووردبريس لسياسة الخصوصية لموقعك، وذلك لتتأكد أن جميع العبارات ضمنها تُشير لموقعك. ماذا يجب أن تتضمن سياسة الخصوصية؟قد تكون النقاط الذي سوف نذكرها لاحقًا، كافيةً أو غير كافية لموقعك للحصول على سياسة خصوصية مُتقنة ومُحكمة، لذلك عُدَّها نقاطًا أساسيةً يجب أن تتضمنها أي سياسة خصوصية، هذه النقاط هي ما يلي:
هذه هي النقاط الأساسية التي تتضمنها أي سياسة خصوصية، والتي من المُفترض أن يُلقي الزائر عليها نظرةً ليقرر استخدام خدمتك، ولكن هناك عدد قليل فقط من الأشخاص هم من يقرؤون هذه السياسات، لذلك فمهمتها الأساسية هي حمايتك من الناحية القانونية في حال قرر أحدهم مقاضاتك بسبب استخدامك لبياناته، بالرغم من موافقته على ما ذُكر في سياسة خصوصيتك. تتضمن سياسة الخصوصية بقسم كبير منها ذكر ملفات الارتباط التي تُحفظ على حاسوبك، وهي تتضمن إعدادات خاصة لمواقع خاصة، حيث تُستخدم ملفات الارتباط لتتبع المستخدم ضمن الموقع، حيث تسمح لك ملفات الارتباط مثلًا، بالبقاء مُسجلًا ضمن الموقع حتى بعد مغادرته (بالرغم من وجود محدودية لهذه الجزئية)، ويجب أن يُبلغ الموقع زواره عن استخدامه لملفات الارتباط، مع توفير خيار يسمح له بتعطيلها تنفيذًا لما جاء في قانون ملفات الارتباط للاتحاد الأوروبي وتشريعات الخصوصية الإلكترونية. ما تفعله ببيانات المستخدمينمن المهم أن تذكر كيف تستخدم البيانات، إذ لها نفس أهمية ذكر جمعك لها، وذلك لأن للبيانات سوقًا ضخمًا بمليارات الدولارات التي تتدفق سنويًا في هذا السوق، إلى جانب العديد من المواقع التي تبيع بيانات مستخدميها؛ أما البعض الآخر فيستخدم هذه البيانات لتخصيص المحتوى والإعلانات لزواره. كيفية إنشاء سياسة خصوصية مُخصصةإذا كان النشاط التجاري متضمنًا على استخدام بيانات حساسة، فالأفضل هو إنشاء سياسة خصوصية مُفصلة لمتطلبات موقعك، وربما من الأفضل الاستعانة بمحامي، ففي نهاية المطاف سياسة الخصوصية هي عبارة عن وثيقة قانونية مُلزم بها أنت ونشاطك التجاري. وإن كنت لا ماتزال راغبًا في تصميم سياسة خصوصية بدون وجود محامي، فهناك خدمات عدة انتشرت خلال السنوات الماضية، بحيث تُولد لك سياسة خصوصية معيارية قابلةً للتخصيص لموقعك الإلكتروني، وسوف نتحدث عن بعض هذه الخدمات. Termageddonتُعَد Termageddon خدمةً مميزةً تُولّد تلقائيًا سياسات خصوصية مُحدًثة، حيث يُحدث Termageddon سياسة الخصوصية المُضمنة لديك كلما صدر قانون جديد يؤثر على بيانات الخصوصية، فعندما دخلت قرارات CCPA مثلًا حيز التنفيذ؛ فقد حدّث Termageddon سياسات الخصوصية لديه انطلاقًا من تشريعات GDPR. تُعَد عملية ضبط هذه الخدمة سهلة، بحيث تتطلب الإجابة على بعض الأسئلة حول تجارتك أو موقعك الإلكتروني، بعد ذلك عليك لصق شيفرة التضمين ضمن الصفحة التي تريد عرض سياسة الخصوصية فيها، طبعًا ستستطيع تجاوز أي تحديث أو تغيير، كما تستطيع تعديل السياسة يدويًا، وفي حال كنت تتعامل مع كمية كبيرة من البيانات عليك دفع 10$ شهريًا. لا يقتصر استخدام Termageddon على مواقع ووردبريس فقط، بل يمكنك استخدامه لضبط سياسة الخصوصية لمتجر شوبيفاي أو تطبيقات فيسبوك أو غيرها، وبالتالي فإن كنت تستخدم إضافات خارجية لموقعك، فإن Termageddon تُعَد خيارك الأفضل. TermsFeedيسمح لك TermsFeed بتوليد سياسة خصوصية خلال دقائق، بحيث تستطيع بسهولة تخصيصها باستخدام معلومات موقعك، حيث عليك الإجابة على مجموعة من الأسئلة في كل مرة تستخدم فيها هذه الخدمة لإنشاء سياسة خصوصية لموقعك، فهي تُساعدك من خلال هذه الأسئلة على استخدام العبارات القانونية التي تحتاجها، وستستلم سياسة الخصوصية عبر بريدك الإلكتروني عند انتهائك من الإجابة على الأسئلة لتتمكن من استخدامها على الموقع ونشرها ليقرأها الزوار. تُوفر هذه الخدمة خيار تحديث سياسة الخصوصية خاصتك تلقائيًا عند تغيّر القوانين. تستطيع تحميل عدة قوالب جاهزة لشروط الخدمة مع تعديلها حسب حاجتك، إلى جانب كتابة المعلومات التي تريدها ضمنها. إن خدمة TermsFeed ليست مخصصةً فقط لمواقع ووردبريس، بل يُمكن استخدام سياسة الخصوصية التي تُولدها هذه الخدمة على تطبيقات iOS ومنصات SaaS وتطبيقات سطح المكتب التي تحتاج أذون لتعمل محليًا على جهازك. FireBaseلقد صُمِّم FireBase إلى حد كبير لتطبيقات الهاتف، ولكنه يُعد أداةً جيدةً لتوليد سياسة الخصوصية، وخاصةً إن كنت تريد الحصول عليها بسهولة وسرعة، مع تخصيصها لك إلى حد ما. يُعَد من السهل استخدام هذه الخدمة للحصول على سياسة خصوصية بسيطة لكن مفيدة، حيث تُظهر السياسات المُولدة باستخدام هذه الأداة كيف تستخدم ملفات الارتباط والخدمات المتنوعة، وتُعد أفضل سياسة للخصوصية هي تلك الناتجة عن هذه الأداة، لأنها مكتوبة بلغة أبسط يستطيع المستخدم فهمها، إذ لا تغطي سياسة الخصوصية هنا بعض التشريعات المعقدة كما تفعل الخدمات السابقة، ولكن إن أردت مولد سياسة خصوصية سريع وسهل وبلغة واضحة فهي الخيار الأفضل. كيفية إضافة سياسة الخصوصية الجديدة في ووردبريسإذا استخدمت أيًا من الخدمات السابقة وليس الخدمة المقدمة من ووردبريس، فعليك نقل سياسة الخصوصية لموقعك، وإلا فلا فائدة منها. لكن لا داعي للقلق فالعملية بسيطة جدًا، والخطوة الأولى تتطلب منك إضافة صفحة جديدة بالضغط على قسم "صفحات" (1)، ثم خيار "أضف جديد" (2)، بعدها أدخل عنوان صفحة ووردبريس الجديدة وليكن "الخصوصية" أو "سياسة الخصوصية" (3). عليك الآن نقل محتوى سياسة الخصوصية لهذه الصفحة أو لصق شيفرة تضمين السياسة المُقدمة من الخدمة التي استخدمتها. لنفترض أنك قد أنشأت سياسة خصوصية لووردبريس باستخدام أحد المولدات، ثم لصقتها ضمن المحرر التقليدي لووردبريس. اضغط الآن على "نشر" لتبقى خطوة واحدة عليك تنفيذها، وهي جعل هذه السياسة ظاهرةً لجميع المستخدمين، من خلال وضع رابط لها في صفحة "من نحن"، ولكن أفضل مكان لها هو القائمة الرئيسية لووردبريس أو القائمة الموجودة في التذييل. تستطيع إضافة عنصر جديد للقائمة من خلال قسم "مظهر" (1)، ثم تبويب "قوائم" (2)، والآن عليك اختيار القائمة المناسبة لك لتعديلها، اختر صفحة "سياسة الخصوصية" (3) التي أنشأتها وأضفها لتكون عنصرًا رئيسيًا للقائمة، أو ثانويًا لأحد عناصر القائمة (4)، ثم اضغط على "حفظ القائمة" (5). يجب عليك الضغط على "حفظ القائمة"، فهذه من أكثر الخطوات التي يسهو عنها مستخدمو ووردبريس، وللأسف فإن القائمة لا تُحفظ تلقائيًا عند تعديلها. يجب أن تجد الآن صفحة سياسة الخصوصية في القائمة تعمل دون أي مشاكل. الخلاصةلست بحاجة لكتابة وثيقة قانونية جديدة كل مرة تُحدّث فيها سياسة الخصوصية، وبفضل مطوري ووردبريس ومنصات أخرى مثل Termageddon، فستستطيع امتلاك أي عدد من هذه الوثائق القانونية خلال لحظات. يُظهر وجود سياسة خصوصية واضحة للجميع جديّتك بحماية بيانات مستخدميك، بحيث تُوضح ضمنها كيفية استخدامك للبيانات وتحمي نفسك من الناحية القانونية والأخلاقية. ترجمة -وبتصرّف- للمقال How to Configure your WordPress Privacy Settings لصاحبه B.J. Keeton. اقرأ أيضًا |