قد يكون HTMLX صفقة كبيرة لـ WordPress

نشرت: 2024-05-10

قد يكون بناء تجربة مستخدم غنية في المتصفح مهمة صعبة، وهي مهمة تتطلب غالبًا قدرًا كبيرًا من تعليمات JavaScript البرمجية. مع نمو احتياجات تطبيقنا وطموحاته، يزداد أيضًا تعقيد كود JavaScript الخاص بنا. لذلك ليس من المفاجئ عدد المرات التي قام فيها المطورون بمراجعة طريقة تفكيرنا في تطبيقات JavaScript وكتابتها.

أيام منذ آخر إطار JS.

مطورو البرنامج المساعد في WordPress لديهم الأمر أسوأ. البيئة التي نستهدفها ليست خادمًا نتحكم فيه، وليست خادمًا يتمتع بالتحكم الكامل في الصفحة بأكملها. في حين أنه من الممكن جدًا استخدام إطار عمل JavaScript بنجاح في مكون WordPress الإضافي، فقد يكون من السهل أيضًا أن ينتهي بك الأمر بمشروع يتجاوز حجمه وتعقيده ما كنت تقصده أو تتوقعه.

ولكن ماذا لو لم يكن من الضروري أن يكون الأمر بهذه الطريقة؟ في هذه المقالة، سنستكشف كيفية إنشاء واجهات مستخدم الويب الحديثة باستخدام JavaScript، والصعوبات التي يواجهها المطورون، والبديل الذي يقدمه HTMLX. على وجه الخصوص، سوف نلقي نظرة على السبب وراء تطابق HTML وWordPress في السماء.

كيف وصلنا إلى هنا

قبل جافا سكريبت، كانت المتصفحات في الأساس مجرد قارئات للمستندات. وعلى هذا النحو، كانت معظم التجارب على الويب عبارة عن "تطبيقات متعددة الصفحات"، أو MPAs للاختصار. MPAs هي تطبيقات ويب تتكون من مستندات HTML متعددة، واحدة لكل صفحة في التطبيق. عندما يستخدم المستخدم التطبيق، تظهر له مستندات مختلفة مع إجراءات مختلفة متاحة.

إن بناء المناطق البحرية المحمية سهل للغاية. يتم التنقل باستخدام علامات <a> للارتباط بمستندات أخرى، ويمكن التقاط مدخلات المستخدم باستخدام عنصر <form> . يستجيب الخادم لطلبات الارتباط والنماذج بمستندات HTML جديدة، ليحل محل الصفحة التي يتم عرضها على الشاشة.

من الأمثلة الجيدة على MPA التي من المحتمل أن تكون على دراية بها هو WP Admin. كل صفحة إدارية عبارة عن مستند يحتوي على HTML يتم إنشاؤه بواسطة كود WordPress PHP الذي يتم تشغيله على الخادم. تميل معظم الصفحات في WP Admin، مثل صفحات إعدادات WordPress، إلى أن تتكون في الغالب من نماذج يمكنك أنت، المستخدم، إرسالها.

وعلى العكس من ذلك، فإن تطبيق الصفحة الواحدة، أو SPA، هو تطبيق يستخدم صفحة HTML واحدة. يتم بعد ذلك التعامل مع التنقل وإدخال المستخدم من خلال كود JavaScript، مما يؤدي إلى تغيير أجزاء الصفحة ديناميكيًا في مكانها دون الحاجة إلى تبديل الصفحة بأكملها أو تحديثها. وينتج عن ذلك تجربة مستخدم أكثر سلاسة واستجابة.

في هذه الأيام، تستخدم العديد من تطبيقات الويب SPA لواجهة الويب الخاصة بها. في RebelCode، قمنا ببناء منتجعات SPA لواجهات الإدارة الخاصة بمكوني WordPress الإضافيين الرئيسيين: Spotlight وAggregator. محرر الموقع الجديد نسبيًا في WordPress هو أيضًا SPA، كما هو الحال مع محرر النشر القائم على الكتلة.

الثمن الذي ندفعه

SPA هي تطبيقات خاصة بها، مكتوبة بلغة JavaScript وتعمل في المتصفح. تعريفهم الخاص هو أيضًا أكبر تحذير لهم: ليس لديهم إمكانية الوصول الفوري إلى موارد الخادم. وهذا يعني أننا بحاجة إلى إنشاء قناة اتصال بين SPA والخادم.

لنقم بإنشاء مكون إضافي بسيط لـ WordPress لاستخدام مثال. يوفر هذا البرنامج المساعد
واجهة مستخدم CRUD بسيطة لإدارة الكتب. قد تبدو واجهة برمجة التطبيقات الداخلية للمكون الإضافي على الخادم كما يلي:

 <?php function get_books(?int $count = null, int $page = 1): Book[]; function get_book(int $id): Book; function insert_book(Book $book): Book; function update_book(Book $book): Book; function delete_book(int $id): void;

لإنشاء واجهة SPA الحديثة، سنستخدم إطار عمل JavaScript مثل React؛ إطار عمل JavaScript الأكثر شيوعًا والذي يستخدمه WordPress أيضًا. لنبدأ بإضافة صفحة إدارية:

 <?php add_action('admin_menu', function () { add_menu_page('Books', 'Books', 'manage_options', 'books', 'books_page'); }); function books_page() { echo '<div></div>'; }

ستعرض صفحتنا عنصر <div> فارغًا واحدًا والذي سيكون بمثابة جذر تطبيق React الخاص بنا حيث سيتم عرض بقية واجهة المستخدم.

 const rootEl = document.getElementById("books-app"); const root = ReactDOM.createRoot(rootEl); root.render(<BooksApp />); function BooksApp() { return ( <div> <h1>My Books</h1> ... </div> ); }

فكيف نقوم بإدراج الكتب المخزنة في قاعدة البيانات؟ الكود الخاص بذلك موجود على الخادم، لذا نحتاج إلى طريقة للاتصال به والحصول على نتيجته.

للقيام بذلك، يمكننا كشف JSON API من الخادم. يمكن لتطبيق React بعد ذلك تقديم طلب على عنوان URL الخاص بواجهة برمجة التطبيقات (API)، واستلام الكتب بتنسيق JSON، ثم عرض القائمة. في هذا المثال، لنفترض أننا أضفنا نقطة نهاية إلى WordPress REST API:

 GET https://my-wp-site.com/wp-json/books { "books": [ { "id": 15, "title": "Mistborn", "author": "Brandon Sanderson", }, { "id": 44, "title": "The Hobbit", "author": "JRR Tolkien", }, ] }

يمكننا بعد ذلك كتابة مكون React الذي يجلب الكتب ويعرضها كقائمة:

 function BookList() { const [books, setBooks] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); useEffect( function () { setIsLoading(true); fetch("https://my-wp-site.com/wp-json/books") .then((res) => res.json()) .then((data) => setBooks(data.books)) .else((error) => setError(error)) .finally(() => setIsLoading(false)); }, [setBooks, setIsLoading], ); if (isLoading) { return <div>Loading...</div>; } if (error) { return <div>Error: {error}</div>; } return ( <ul> <li> {books.map((book) => ( <a key={book.id} href={book.url}> {book.title} </a> ))} </li> </ul> ); }

لكن هذا الحل ساذج جدًا وينتج عنه تجربة مستخدم صعبة. ولا يلبي تغييرات الحالة بعد إلغاء تحميل المكون، أو تخزين الاستجابة مؤقتًا، أو إعادة محاولة الاستعلامات الفاشلة، أو منع الحالة القديمة من الكتابة فوق الحالة الأحدث. في الواقع، الطريقة التي نستخدم بها fetch() في تأثير React غير محبذة عمومًا.

ومن نواحٍ عديدة، يمكن أن يكون هذا أسوأ من MPA التقليدية. لذا، للقيام بذلك بشكل صحيح، سنحتاج إلى تنفيذ بعض الأشياء الإضافية في عميلنا. أو، بشكل أكثر واقعية، استخدم حزم الطرف الثالث.

لكن كل هذا بدأ يبدو وكأنه قدر غير متناسب من الجهد لمجرد تقديم قائمة من الكتب. هل نحتاج حقًا إلى إنشاء تطبيق JavaScript وواجهة برمجة تطبيقات JSON لإنشاء تجربة مستخدم سلسة؟

دعونا نقارن هذا مع MPA، حيث يمكن تقديم قائمة الكتب في بضعة أسطر فقط من كود PHP، دون أي تبعيات:

 <?php function render_books() { ?> <ul> <?php foreach (get_books() as $book): ?> <li> <a href="<?= $book->url ?>"> <?= $book->title ?> </a> </li> <?php endforeach; ?> </ul> <?php }

لكن بالطبع هذه ليست مقارنة عادلة. قائمة الكتب هذه هي مجرد HTML ثابت؛ فهو لا يتفاعل مع تغييرات الحالة أو إدخال المستخدم.

إذا أردنا الحصول على تجربة تشبه تجربة SPA أثناء عرض HTML على الخادم، حيث يكون للكود الخاص بنا إمكانية الوصول الفوري إلى قاعدة البيانات، فسنحتاج إلى إيجاد طريقة لجعل HTML المقدم من الخادم يجد طريقه إلى المتصفح واستبدال قائمة الكتب السابقة. لكن تحقيق ذلك بدون أي كود جافا سكريبت أمر مستحيل حاليًا، لذلك يتعين علينا أن نتعامل مع الأمر ونستخدم جافا سكريبت على أي حال.

لكننا لسنا بحاجة إلى كتابتها بأنفسنا.

إدخال HTML

HTMX هي مكتبة جافا سكريبت صغيرة تقوم في المقام الأول بشيء واحد: السماح لـ HTML بطلب HTML جديد من الخادم. وهو يفعل ذلك باستخدام سمات جديدة، والتي تسمح لنا بإخبار HTMX من أين يمكن الحصول على HTML الجديد، وما الذي يجب استبداله به، وما الذي يؤدي إلى التبديل. إنه بمثابة جسر بين خادم HTML الخاص بنا والصفحة في المتصفح.

هذه طريقة مختلفة تمامًا للتفكير في SPA، نظرًا لأننا لا نبني تطبيق JavaScript للعميل لتحديث الصفحة الحالية. وبدلاً من ذلك، نقوم ببساطة بإضافة بعض سمات HTML لنخبر HTML كيف نريد أن تتغير الصفحة عند حدوث أحداث معينة.

حتى بدون استخدام HTMLX، يمكنك بالفعل تغيير ما يظهر على الشاشة باستخدام HTML فقط، وإن كان ذلك بطريقة محدودة جدًا. أنت على دراية بميزة HTML هذه: عنصر الارتباط المتواضع <a> .

 <a href="https://my-wp-site.com/books">View books</a>

يوفر عنصر الارتباط للمتصفح جميع المعلومات الضرورية لإجراء التنقل. عند النقر عليه، يأخذ المتصفح href من العنصر، ويقدم طلبًا على عنوان URL هذا، وينزل الاستجابة، وعلى افتراض أنه يحتوي على HTML، يستبدل محتويات الصفحة بـ HTML الجديد.

يعد عنصر <form> مثالًا آخر لكيفية قيام HTML بطلب HTML جديد.

 <form action="/contact.php"> <label> Your message: <input type="text" name="message" /> </label> <button type="submit">Send message</button> </form>

هذه المرة، يقوم المتصفح بجمع القيم من كافة المدخلات في النموذج، وإرسالها إلى الخادم، وتنزيل الاستجابة، وعرضها على الشاشة.

لماذا يجب أن يتمكن <a> و <form> فقط من تقديم طلبات HTTP؟ لماذا يجب أن تكون قادرًا فقط على استبدال الشاشة بأكملها ؟

من التمهيدي GitHub الخاص بـ HTMX

حسنا، HTML يغير ذلك.

 <a href="https://my-wp-site.com/books" hx-target="#books"> View books </a> <div></div>

باستخدام سمة HTMX hx-target ، سيؤدي النقر فوق الارتباط الآن إلى وضع الاستجابة من https://my-wp-site.com/books داخل العنصر بمعرف "books" . بالطبع، تضمين صفحة داخل صفحة أخرى ليس هو الهدف هنا. لا يحتاج خادمنا إلى الرد بالصفحة الكاملة، ويمكنه بدلاً من ذلك الرد بجزء HTML فقط.

من خلال الكشف عن أجزاء HTML من خادمنا وإخبار HTML كيف وأين ومتى يتم الحصول على هذه الأجزاء، يمكننا إنشاء تطبيق ويب يشبه SPA بدون أي JavaScript، حيث يكون الخادم في السيطرة الكاملة. بمعنى ما، أصبح HTML JSON الجديد الخاص بنا.

وكل ما يتعين علينا فعله هو تحميل نص HTMLX في صفحتنا:

 <script src="https://unpkg.com/[email protected]"></script>

(تأكد من مراجعة وثائق HTML للحصول على الإرشادات، حيث قد يكون الكود أعلاه قديمًا).

دعونا ننظر إلى مثال آخر:

 <button hx-get="/button/off" hx-target="this" hx-swap="outerHTML"> Turn off </button>

هناك الكثير مما يحدث هنا، لذلك دعونا نحللها:

  • يحدد hx-get عنوان URL لإرسال طلب GET إليه عند النقر فوق الزر.
  • hx-target="this" يطلب من HTMX تبديل الزر الذي تم النقر عليه مع الاستجابة.
  • يطلب hx-swap="outerHTML" من HTML تبديل الزر بالكامل، وليس فقط ما بداخله.

كل هذا معًا يخبر HTMX:

عند النقر على الزر، أرسل طلب GET إلى /button/off واستبدل هذا الزر بالاستجابة.

لنفترض أن الخادم يستجيب لـ /button/off باستخدام HTML أدناه:

 <button hx-get="/button/on" hx-target="this" hx-swap="outerHTML"> Turn on </button>

هل يمكنك ان ترى الاختلاف؟ تشير السمة hx-get الآن إلى /button/on والنص الموجود داخل الزر أصبح الآن "Turn on". عند النقر على هذا الزر، سيتم أيضًا استبداله بالاستجابة من /button/on . كما يمكنك أن تتخيل، يمكننا أن نجعل الخادم يستجيب بالزر الأصلي لإكمال التبديل!

هذه الفكرة البسيطة المتمثلة في السماح لأي عنصر بطلب HTML جديد من الخادم وتحديد المكان الذي سينتقل إليه HTML تبين أنها فكرة قوية جدًا. يمكننا إنشاء علامات تبويب والبحث باستخدام النتائج المباشرة وأشرطة التقدم والمزيد.

إيجابيات وسلبيات

على عكس معظم أطر عمل JavaScript، لا يتطلب HTMLX تجميع كود تطبيق العميل الخاص بنا وتجميعه. وهذا وحده فائدة عظيمة؛ قد يكون من الصعب جدًا إعداد أنظمة بناء JavaScript وصيانتها، خاصة عندما تبدأ في تقديم المزيد من الميزات والمكتبات الغريبة، مثل معالجات TypeScript وJSX وCSS المسبقة وما إلى ذلك. ليس من غير المألوف أن تمتلك الفرق المتوسطة والكبيرة عضو أو أكثر مخصص لهذه المهمة.

فائدة أخرى واضحة هي عدم وجود تطبيق عميل منفصل. وبما أن كل ما نحتاجه هو خادم HTTP يستجيب باستخدام HTML، فيمكننا استخدام أي لغة برمجة نحبها. قد تكون هذه نقطة بيع كبيرة بالنسبة لك إذا كان فريقك يفتقر إلى الإلمام بجافا سكريبت الحديثة، أو ليس كبيرًا بما يكفي لتبرير إنشاء تطبيقين. قد يكون الأمر مغريًا بشكل خاص إذا كنت مطورًا لمكونات WordPress الإضافية، حيث يمكنك استخدام PHP لجميع جوانب مكونك الإضافي.

ولكن ربما تكون الفائدة الأكثر أهمية هي أنك لم تعد بحاجة إلى واجهة برمجة التطبيقات (API) بين الواجهة الخلفية والواجهة الأمامية لتطبيقك. يمكن أن يوفر هذا قدرًا هائلاً من وقت التطوير، بالإضافة إلى تقليل كمية التعليمات البرمجية التي يمكن أن تنتج أخطاء، مما يوفر أيضًا الوقت على المدى الطويل.

ومع ذلك، لا ينبغي لنا أن نكون ساذجين لدرجة أننا نفترض أن استخدام HTML يعني عدم الحاجة إلى كتابة أي JavaScript. قد تظل هناك حاجة إلى قدر معين من JavaScript لأشياء مثل السحب والإفلات، والمخططات، ومنتقيات الألوان والتاريخ، وما إلى ذلك. على الرغم من أنه يمكننا دائمًا استخدام الحلول المحايدة لإطار العمل، مثل SortableJS وFloating UI. بالإضافة إلى ذلك، قد نجد أيضًا حاجة أقل لجافا سكريبت في المستقبل مع استمرار معايير الويب في التطور مع عناصر HTML الجديدة، مثل عنصر <dialog> الحديث.

ثانيًا، من المفارقات أن PHP ليست جيدة جدًا في قوالب HTML، على الرغم من أنها مصممة للقيام بذلك. بناء جملة العلامة الخاصة به مطول بشكل مفرط، كما أن بناء جملة سلسلة HEREDOC الخاص به له دعم محدود لاستكمال السلسلة.

وأخيرًا، إنشاء نقطة نهاية في WordPress ليس بالأمر السهل جدًا. النظر في البرنامج المساعد للكتب من الأمثلة السابقة. نحن بحاجة إلى مسار على الخادم يستجيب بقائمة الكتب في شكل HTML. كيف نسجل نقطة النهاية هذه؟

  • اكتشاف معلمة GET أثناء إجراء init أو admin_init ؟
  • هل تستخدم Admin Ajax API؟
  • تسجيل نقطة نهاية REST API؟
  • إضافة قاعدة إعادة كتابة مخصصة؟

هناك العديد من الخيارات، ولكن لا شيء يجعل الأمر بهذه البساطة كما ينبغي.

هاتيواس

هناك تفاصيل دقيقة في مثالنا السابق يسهل جدًا تفويتها، ومن المرجح أن تبدو واضحة بمجرد الإشارة إليها.

عندما نحصل على HTML من الخادم، يكون الزر الموجود على الصفحة إما متغير ON أو متغير OFF. اعتمادًا على الخيار الذي يظهر على الشاشة، سيكون إجراء النقر مختلفًا.

ولهذا السبب، لا يحتاج المتصفح إلى فهم تطبيقنا. عادةً ما نجعل المتصفح يفهم من خلال إعطاء كود JavaScript للبرمجة بشكل صريح في جميع السلوكيات. الآن، لدينا HTML فقط، ولا يحتاج المتصفح إلى معرفة مسبقة بكيفية تصرف تطبيقنا أو حالته. كل ما يحتاجه هو عرض HTML على الشاشة، والذي يقوم في حد ذاته بتشفير حالة تطبيقنا.

يُعرف هذا النوع من الهندسة باسم HATEOAS، والذي يرمز إلى "الوسائط التشعبية باعتبارها محرك حالة التطبيق". إنه نوع متخصص من بنية REST يستخدم الوسائط التشعبية كوسيلة لنقل الحالة، وتصبح نفس الوسائط التشعبية هي الواجهة التي من خلالها يقوم المستخدم بقيادة التطبيق إلى حالات جديدة.

يحتوي موقع HTMLX على مجموعة رائعة من المقالات والمقالات والمحادثات حول هذا الموضوع، إذا كنت مهتمًا بمعرفة المزيد. ولأغراض هذه المقالة، دعنا ننتقل إلى السبب الذي يجعل HTMLX أمرًا مهمًا لمطوري WordPress.

HTML <3 ووردبريس

WordPress هو خادم PHP عملاق ومتجانس. تتم أيضًا كتابة مكونات WordPress الإضافية بشكل أساسي بلغة PHP. يمكنهم إضافة وظائف جديدة إلى الموقع باستخدام PHP APIs التي يوفرها WordPress، مثل Hooks API وDatabase API. لا تتوفر واجهات برمجة التطبيقات هذه من JavaScript، لذا يجب على مطوري المكونات الإضافية الاحتفاظ بأكبر قدر ممكن من رموز المكونات الإضافية الخاصة بهم على الخادم قدر الإمكان. إذا كان هناك أي دافع لاستخدام لغة HTML، فهذا هو الدافع!

في العديد من النواحي، تم إنشاء HTMLX لـ WordPress. أو بالأحرى لتطبيقات مثل WordPress؛ التطبيقات التي لا تفضل أن تكون مثقلة بلغة أجنبية تجبرها على ترك مجموعاتها من واجهات برمجة تطبيقات الخادم. لا سيما عندما يكون مجرد نقل الحالة باستخدام الوسائط التشعبية كافيًا.

إن تسهيل إنشاء واجهات مستخدم جيدة لمكونات WordPress الإضافية يمكن أن يكون له تأثير كبير على النظام البيئي للمكونات الإضافية. قد يجد المطورون الذين يحتفظون بمكونات إضافية مجانية أنه من المجدي بناء تجارب مستخدم أفضل لمستخدميهم، وقد تتمكن الفرق الأصغر من تكرار الميزات بشكل أسرع مع توفير الوقت. يمكن أن يساعد هذا في جعل المكونات الإضافية الأصغر حجمًا أكثر قدرة على المنافسة في السوق الذي تهيمن عليه بشكل كبير فرق كبيرة ذات ميزانيات أكبر.

قد تكون المكونات الإضافية الأكبر حجمًا أيضًا مهتمة بشكل خاص. يمكن أن تنمو تطبيقات JavaScript بسرعة هائلة. يمكن أن يسمح HTML لهذه المكونات الإضافية بإزالة واجهات برمجة تطبيقات JSON وتطبيقات JavaScript الضخمة، وترك خادم HTML بسيط في مكانه يتمتع بإمكانية الوصول الكامل إلى واجهات برمجة تطبيقات WordPress.

افكار اخيرة

لقد كنت أتعامل مع HTML لفترة من الوقت، واستخدمه مع PHP وGo. فهو يوفر بديلاً مقنعًا لبناء واجهات المستخدم على الويب، وحجة مقنعة لاستخدام الوسائط التشعبية لتوجيه حالة التطبيق.

إذا كنت أحد مطوري المكونات الإضافية، فتأكد من مراجعة HTMLX. بالكاد قمنا بخدش السطح في هذه المقالة، والوثائق مكتوبة بشكل جيد للغاية مع الكثير من الأمثلة. كما أنها قصيرة بشكل مدهش، نظرًا لمقدار HTML الذي يأتي مزودًا خارج الصندوق. من المفترض أن تكون قادرًا على البدء باستخدام HTML وPHP في بضع دقائق.