ماژول نویسی دروپال بخش دو
ماژول نویسی دروپال بخش سه
ماژول نویسی دروپال بخش چهار
ماژول نویسی دروپال بخش پنج
ماژول نویسی دروپال بخش شش
ماژول نویسی دروپال بخش هفت
ماژول نویسی دروپال بخش هشت
یکی از جذابترین کارهایی که میشه انجام داد، نوشتن یک ماژول هست. دروپال پیش از آن که یک سیستم مدیریت محتوا باشد، یک فریمورک PHP است، برای انجام بعضی کارها نیاز به نوشتن کدهای PHP پیدا میکنیم و باید با این فریمورک آشنایی کافی داشته باشیم.
برای مثال ممکن است نیاز پیدا کنید در هنگام ایجاد شدن یک محتوا از نوع صفحه پایه (Basic Page) یک محتوا از نوع مقاله (Article) به صورت خودکار ایجاد شود و توسط ماژول Relation یک ارتباط بین آنها ایجاد شود. یک راه برای انجام این کار استفاده از قابلیتهای ماژول Rules است. اما اگر یک مرحله جلوتر بریم و بخواهیم هنگام ساختهشدن یک relation، رکوردی در یک دیتابیس دیگر نیز نوشته شود، نیاز به کد نویسی داریم.
در این مقاله قصد ایجاد چنین ماژول نسبتا پیچیدهای رو ندارم و نحوه کار ماژولها رو توضیح میدم.
نحوه کار سیستم ماژول ها
دروپال از سیستم قلاب (Hook) استفاده میکند. هنگامی که درخواستی به دروپال توسط کاربر فرستاده میشود (مثل مشاهده یک محتوا)، سیستم پس از Boostrap شدن که شامل مراحلی مثل بارگذاری تنظیمات، اتصال به پایگاه داده و ... میشود، در فرایند آمادهسازی درخواست کاربر، دادههای خود رو در اختیار هوکهای ماژولها میگذارد. مثلا پس از خواندن فیلدهای یک مقاله از پایگاه داده؛ آنها رو در یک آرایه قرار میدهد و هر ماژولی که هوک مربوط به نمایش محتوا رو تعریف کرده باشد، با آرایه تولید شده صدا میزند. ماژولی که با هوک (قلاب) نمایش محتوا، خود رو به فرایند نمایش محتوا متصل کرده، این اطلاعات رو دریافت میکند و میتواند فرایندهای خود رو از قبیل «اضافه کردن یک کلمهی خاص به متن عنوان محتوا» رو اجرا کند. هر ماژول میتواند در فرایندهای خود باز هوکهایی رو تعریف کند که دیگر ماژولها فرایند پیشفرض ماژول رو تغییر دهند. مثلا میتواند هوکی تعریف کند که بتوان کلمهی اضافه شده رو تغییر داد.
ایجاد ماژول
ابتدا لازم است وجود ماژول و برخی ویژگیها و تنظیمات اون رو به دروپال اعلام کنیم. فرض کنیم نام ماژول مورد نظر drupalion است. این کار با ساخت یک فایل با پسوند .info صورت میگیرد:
drupalion.info
محتویات این فایل به این شکل است:
name = drupalion description = this is a test module and does nothing core = 7.x package = other php = 5.2 version = 7.x-1.x dependencies[] = views files[] = drupalion.class.inc ;configure = admin/drupalion
name مشخص کنندهی نام ماژول، description توضیحات آن و core تعیینکننده ورژن دروپالی که ماژول برای آن نوشته شده است این سه مورد برای تعریف یک ماژول الزامیست. با package میتوان مشخص کرد در صفحهی admin/modules ماژول نوشته شده در کدام بخش قرار گیرد که در صورت ذکر نشدن آن، به صورت پیشفرض Other خواهد بود. php تعیین کنندهی حداقل ورژن قابل قبول PHP برای اجرای ماژول است و version، ورژن ماژول رو تعیین میکند. البته توجه کنید که تعیین ورژن توسط سیستم packaging در drupal.org صورت میگیرد و به هنگام ارسال ماژول به drupal.org، باید آن را حذف کنید.
dependencies که به فرم یک آرایه نوشته میشود تعیین کنندهی ماژولهایست که برای فعال شدن ماژول نوشته شده باید موجود و قابل فعال شدن باشند. درصورتی که از Drush برای فعالسازی استفاده شود، همهی dependency ها به صورت خودکار دانلود و فعال خواهند شد. برای نام بردن هر ماژول dependency نام اون رو در یک خط جداگانه قرار میدهیم به این صورت:
dependencies[] = views dependencie[] = date
بخش files که اعلان آن مشابه dependencies است برای تعیین فایلهای مربوط به ماژول است. برای مثال فایلهای CSS، جاوااسکریپت، پلاگینهای ماژول views و ...
قرار دادن کدها:
پس از ایجاد فایل .info ، فایلی با پسوند .module به نام ماژولی که مینویسیم ایجاد میکنیم. برای مثال drupalion.module. این فایل محتوی کدهای PHP ما خواهد بود. البته فایلهای خاص دیگری مثل MODULE.views.inc یا MODULE.rules.inc هم وجود دارند که توسط دیگر ماژولها صدا زده میشوند. باید توجه کنیم که فایل .module همیشه با تگ PHP به صورت کامل شروع میشود اما به علت وجود باگی در PHP، هیچگاه با تگ پایانی تمام نمیشود، یعنی:
<?php // Starting tag. function drupaion_menu() { // Do something here. } // NO ending tag.
در این فایل برای افزودن قابلیت خاصی به دروپال، از سیستم هوکها استفاده میکنیم. برای مثال اگر بخواهیم یک لینک به منوی تنظیمات دروپال استفاده کنیم، ابتدا هوکی را که این کار را انجام میدهد رو پیدا میکنیم و آن رو متناسب با ماژول خود پیادهسازی میکنیم. برای ایجاد منو؛ به HOOK_menu() نیاز داریم. کلمهی HOOK باید با اسم ماژولی که در فایل .info انتخاب کردیم یکسان باشد در غیر این صورت توسط دروپال شناسایی نخواهد شد. اگر به راهنمای مربوطه در سایت api.drupal.org که لیست تمامی هوکها رو دارد مراجعه کنیم، پیادهسازی صحیح این تابع (هوک) رو پیدا میکنیم:
/** * Implements hook_menu() */ function drupalion_menu() { // Administration page. $items['admin/drupalion'] = array( 'title' => 'Drupalion module', 'page callback' => 'drupal_get_form', 'page arguments' => '_drupaion_get_form', 'access argument' => array('access administrative pages'), 'type' => MENU_LOCAL_TASK, ); return $items; }
با برسی قطعه کد بالا متوجه چند نکته میشیم:
یخش کامنت: دروپال برای کامنتگذاری از سیستم doxygen استفاده میکند. حجم کدهای هسته دروپال به سیصدهزار خط میرسد و نزدیک به بیستهزار ماژول در drupal.org موجود است بنابراین استفاده از یک سیستم کامنتگذاری یکسان بین تمامی پروژهها که بتوان به سادگی از آن documentation هر بخش کد رو هم استخراج کرد بسیار مهم و ضروریست. کامنتهای مربوط به توضیحات یک بخش از کد همیشه با // شروع میشود و از # نباید استفاده کرد. اولین حرف کامنت به صورت Capital است و به کل عبارت به نقطه ختم میشود.
علاوه بر سیستم کامنت، دروپال در نوشتن خود کدها هم سختگیریهای خاصی دارد و یک ماژول قبل از راهیابی به سایت دروپال باید از این استاندارهای کدنویسی دروپالی تبعیت کند در غیر این صورت مدیریت این حجم کد برای خطایابی، تصحیح و نوشتن کد جدید بر مبنای کدهای قبلی و همچنین آموزش کدنویسان جدید تقریبا غیر ممکن میشد. برای مثال طول هرخط از کد نباید بیش از ۸۰ حرف باشد (تا حد امکان) و یا آیتمهای آرایههایی که در چند خط تعریف میشوند، همیشه با علامت , پایان میابند. اگر از محیطهای توسعه مثل Eclipse یا NetBeans استفاده میکنید راهنمای تنظیم اونها بر اساس این استانداردها در دروپال موجود است. (اگر مثل من از vim استفاده میکنید بدونید تنها نیستید و برای vim هم تنظیمات مربوطه موجود است!).
نکتهی قابل توجه دیگر، استفاده از آرایه برای تعریف آیتم منوست. با بررسی کد دروپال ۷ یا ۶، با تعداد بیشماری استفاده از آرایه مواجه خواهید شد که دلیل اون سرعت بالای تولید و پردازش اونها در PHP است. دروپال برای خیلی چیزها مثل تعریف منوها، کاربر، Node، Entity، فرمها و .... قبل از پردازش ساختار مربوطه رو در آرایه تعریف میکند. شاید بتوان گفت استفاده از آرایه در دروپال مثل وجود استفاده از اشیا (Objects and Classes) در دیگر فریمورکهاست. البته دروپال ۸ قول استفاده خیلی بیشتری از قابلیتهای Objective زبان PHP رو داده است!
ارتباط منو با ایجاد صفحههات و مسیرها چیست؟ یک استاندارد معمول در خیلی از فریمورکها، استفاده از یک سیستم Router است که مسیرهای خاصی رو به توابع یا اشیا مورد نظر متصل میکنند. این سیستم در دروپال سیستم منو نام دارد. در قطعه کد بالا ما مسیر admin/drupalion رو به تابع drupal_get_form متصل کردیم. آرگومانی که هنگام دسترسی این مسیر باید به این تابع فرستاده شود را نیز مشخص کردیم: _drupalion_get_form که خود نام تابع دیگریست. سیستم منو فقط با رشتهها (string) سروکار دارد، و اهمیتی به تابع بودن یا نبودن _drupalion_get_form نمیدهد بلکه فقط این نام را به drupal_get_form میفرستد. تابع drupal_get_form، انتظار دارد آرگومانی که هنگام فراخوانی دریافت میکند، نام تابعی باشد که یک «فرم» بر میگرداند. یک وظیفه بسیار مهم دیگر سیستم منو، تعیین مجوز دسترسی به مسیرها توسط کاربران است، در اینجا با ذکر نام مجوز access administrative pages، به کاربرانی که دارای نقشی با این مجوز هستند، اجازهی دسترسی به این مسیر را دادیم. توجه کنید که حتما نام مجوزهای لازم باید در آرایه ذکر شود حتی اگر یک مورد باشد. متدها و روشهای دیگر تعیین دسترسی را در صفحات راهنمای hook_menu در druapl.org میتوانید بررسی کنید.
تا این مرحله ما با پیادهسازی هوک منو، مسیرهای مربوط به ماژول رو به سیستم منوی دروپال معرفی کردیم. با پاک کردن حافظهی موقت منو (Menu cache) سیستم منو دوباره به جمعآوری اطلاعات مسیرها از ماژولها میپردازد (پس اگه ماژول رو فعال کردید و مسیر شما قبل از پاک کردن Cache پیدا نشد، دنبال باگ توی کد خودتون نباشید!).
در مقالهی بعدی، نحوهی ساخت صفحهی مورد نظر رو آموزش خواهم داد
شاد و موفق باشید.