joomla 5

فصل هفتم: توسعه یک ماژول

(زمان تقریبی مطالعه: 15 - 30 دقیقه)

بیان خلاصه ای از بحث توسط هوش مصنوعی:

در فصل های قبلی، ما یک کامپوننت کاملاً برجسته ایجاد کردیم که به ما امکان می دهد اطلاعات را به راحتی از پایگاه داده خود اضافه و بازیابی کنیم.

با کامپوننت خود، می توانیم اطلاعات را در نمای صفحه نمایش دهیم، و حتی می توانیم این داده ها را با استفاده از وب سرویس مصرف کنیم. اما، اگر لازم باشد داده های انتخابی را به همراه سایر نماهای کامپوننت در سایت خود نشان دهیم، چه؟ برای این کار، باید یک ماژول همراه برای کامپوننت خود ایجاد کنیم.

ماژول های جوملا یک راه ساده برای نمایش داده ها در هر موقعیتی در سایت شما هستند. از آنجایی که می توان آنها را به هر موقعیت موجود در قالب اضافه کرد و همچنین می تواند با استفاده از کدهای کوتاه در محتوای شما بارگذاری شود، آنها متنوع ترین گزینه برای نمایش اطلاعات هستند.

در این فصل، ما یاد می گیریم که چگونه یک ماژول همراه برای کامپوننت خود ایجاد کنیم که لیست پروژه هایی را که روی آن کار می کنیم نشان می دهد و شما درک بهتری از الگوی تزریق وابستگی جوملا (Joomla Dependency Injection) خواهید داشت که در فصل 2 شروع به یادگیری آن کردیم. وقتی به ساختار فایل ماژول می پردازیم، خواهید دید که توسعه ماژول جوملا کاملاً شبیه به توسعه کامپوننت است و اینکه چگونه الگوی MVC اکنون به طور کامل در ماژول ها ادغام شده است.

پس از اتمام این فصل، شما قادر خواهید بود هر نوع ماژولی را که برای نمایش هر نوع اطلاعاتی (مربوط به کامپوننت شما یا غیر) در وب سایت خود نیاز دارید، توسعه دهید.

ما برای تحقق آن این مسیر را دنبال خواهیم کرد :

  • درک ساختار فایل ماژول
  • استفاده از پارامترهای پیکربندی ماژول
  • استفاده از ماژول های کمکی

الزامات فنی

در این فصل، ما به بهبود افزونه Simple Project Manager خود ادامه خواهیم داد، بنابراین شما به موارد زیر نیاز دارید :

  • Visual Studio Code (یا ویرایشگر کد دلخواه شما)
  • سایت جوملا که در فصل های قبل نصب کردیم

همه کدهای استفاده شده در این فصل را در GitHub پیدا خواهید کرد:

 https://github.com/PacktPublishing/Developing-Extensions-for-Joomla-5/tree/chapter07

درک ساختار فایل ماژول

ماژول ها در جوملا داخل پوشه modules  سایت ما هستند. در هر نصب معمولی جوملا، این پوشه پر از پوشه هایی است که متعلق به ماژول ها هستند. نام این پوشه ها با پیشوند mod_  شروع می شود تا تاکید شود که یک ماژول هستند. این یک قانون در هنگام نامگذاری ماژول های ما نیست، اما جوملا در صورت عدم وجود، پیشوند را به نام پوشه اضافه می کند.

از زمان جوملا4، معماری ماژول همان معماری کامپوننت بوده است.

بنابراین، هنگام فراخوانی یک ماژول، جوملا به دنبال فایل provider.php  در داخل ماژول های سرویس میگردد. در فایل provider.php ، سرویس مورد نیاز خود را در ماژول خود ثبت می کنیم.

پس از ثبت سرویس ما، جوملا به دنبال فایل Dispatcher.php  ماژول ما می گردد که داخل پوشه src/Dispatcher/ ماژول ما قرار دارد . ما به یک ساختار پوشه به شکل زیر نیاز داریم :

  • services :  این پوشه حاوی فایل provider.php  است. این فایل مانند src/component/admin/services/provider.php  است و برای ثبت ماژول ما در جوملا استفاده می شود. این در واقع اولین فایلی است که جوملا در هنگام اجرای ماژول ما به دنبال آن خواهد بود.
  • src :  این شامل کد ماژول ما است که به درستی در پوشه های مختلف سازماندهی شده است. ممکن است در اینجا پوشه Dispatcher  یا پوشه Helper  را پیدا کنیم.
  • tmpl :  این شامل فایل های چیدمان مختلف برای ماژول ما است. معمول است که حداقل یک فایل default.php با چیدمان خود داشته باشیم.

این پوشه ها حاوی معماری جدید ماژول ها در جوملا هستند. بیایید هر یک از آنها را مرور کنیم تا ببینیم ماژول ها در جوملا چگونه کار می کنند.

ایجاد کد ارائه دهنده (provider)

در معماری جوملا، اهمیت ارائه دهنده بسیار مهم است. همانطور که در مورد کامپوننت ها اتفاق افتاد، فایل ارائه دهنده ظرف تزریق وابستگی ( DIC )( Dependency Injection Container)  را دریافت می کند و سرویس مختلف را برای استفاده در ماژول ما ثبت می کند.

کد زیر را به فایلsrc/module/mod_projectslist/services/provider.php  اضافه کنید:

 
<?php 
use Joomla\CMS\Extension\Service\Provider\HelperFactory; 
use Joomla\CMS\Extension\Service\Provider\Module; 
use Joomla\CMS\Extension\Service\Provider\ 
ModuleDispatcherFactory; 
use Joomla\DI\Container; 
use Joomla\DI\ServiceProviderInterface; 
return new class () implements ServiceProviderInterface { 
public function register(Container $container) 
{ 
$container->registerServiceProvider(new 
ModuleDispatcherFactory('\\Piedpiper\\Module 
\\ProjectsList')); 
$container->registerServiceProvider(new 
HelperFactory('\\Piedpiper\\Module\\ProjectsList 
\\Site\\Helper')); 
$container->registerServiceProvider(new Module()); 
} 
}; 

در این کد، ارائه دهنده یک کلاس PHP ناشناس را بر می گرداند (دقیقاً همانطور که در مورد کامپوننت ها اتفاق می افتد) که در آن سرویس های زیر را ثبت می کنیم:

  • ModuleDispatcherFactory: این فضای نام توزیع کننده (dispatcher) ما را در ظرف ثبت می کند
  • HelperFactory: این فضای نامی را که کلاس های کمکی شما در آن آمده است را ثبت می کند (اگر از کلاس های کمکی استفاده نمی کنیم می توانیم آن را حذف کنیم)
  • Module: این ارائه دهنده، ماژول را در ظرف مقداردهی اولیه می کند

اینها مراحل اولیه جوملا برای شروع کار با ماژول خود هستند، اما هنوز باید کد ماژول را بنویسیم. ما این کار را در dispatcher انجام خواهیم داد، بنابراین بیایید فایل src/module/mod_projectslist/src/Dispatcher/Dispatcher.php  را با کد زیر ایجاد کنیم.

 
<?php 
namespace Piedpiper\Module\ProjectsList\Site\Dispatcher; 
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher; 
use Joomla\CMS\Helper\HelperFactoryAwareInterface; 
use Joomla\CMS\Helper\HelperFactoryAwareTrait; 
class Dispatcher extends AbstractModuleDispatcher 
implements HelperFactoryAwareInterface 
{ 
use HelperFactoryAwareTrait; 
protected function getLayoutData() 
{ 
$data = parent::getLayoutData(); 
$data['projects'] = $this->getHelperFactory()-> 
getHelper('ProjectsListHelper')-> 
getProjects($data['params'], $this-> 
getApplication()); 
return $data; 
} 
} 

ابتدا، ما فضای نامی را برای dispatcher ماژول خود تعریف کنید. این به جوملا کمک می کند تا توزیع کننده ماژول ما را پیدا کند. سپس، فضای نامی را که در کد خود استفاده می کنیم، اعلام می کنیم.

در ماژول خود از کلاس های کمکی برای انجام برخی عملیات و داشتن کد ماژولار (modular) استفاده می کنیم، بنابراین باید فضاهای نام HelperFactoryAware  را اعلام کنیم.

تنها متدی که در کلاس خود نیاز داریم متد getLayoutData  است که لیست پروژه ما را بازیابی کرده و آن را بر می گرداند.

این روش جایی است که می توانیم مزایای استفاده از کلاس های CMS TM  جوملا و کلاس های HelperFactoryAware  را ببینیم، زیرا به ما امکان می دهد لیست پروژه ها را با یک خط کد دریافت کنیم.

در آن خط، کلاس helper را برای ماژول خود بازیابی می کنیم و از متدgetProjects   برای دریافت داده ها استفاده می کنیم.

از زمان جوملا 4، استفاده از helpers در پیشرفت  های ما و مخصوصاً در ماژول ها برای داشتن کدهای تمیز و خوانا اهمیت زیادی داشته است. بیایید ببینیم که چگونه با helpers در ماژول های خود را در بخش بعدی ببینیم.

استفاده از ماژول های کمکی

معماری ماژول جوملا برای پردازش اطلاعاتی که در ماژول نمایش خواهیم داد به متد getLayoutData    از dispatcher متکی است.

ما می توانیم تمام منطق خود را در این متد قرار دهیم و اجازه دهیم به هر اندازه  ای که نیاز داریم رشد کند، اما این باعث می شود کد ما تعداد زیادی از اصول کدنویسی، مانند DRY   (مخفف عبارت Don't Repeat Yourself )، مسئولیت تکی و غیره را زیر پا بگذارد.

از آنجایی که ماژول های helper بخش اصلی کلاس های ماژول جوملا هستند، ما باید از آنها استفاده کنیم و با کلاس های helper که منجر به کد تمیز تر می شوند، کار کنیم.

به دنبال کد Dispatcher.php  از بخش قبلی، تماسی با ماژول helper وجود داشت. اکنون باید کدی را برای Helper خود ایجاد کنیم، بنابراین فایل  src/module/mod_projectslist/src/Helper/ProjectsListHelper.php را با محتوای زیر ایجاد می کنیم:

 
<?php 
namespace Piedpiper\Module\ProjectsList\Site\Helper; 
use Piedpiper\Component\Spm\Site\Model\ProjectsModel; 
use Joomla\CMS\Application\SiteApplication; 
use Joomla\CMS\Component\ComponentHelper; 
use Joomla\CMS\Factory; 
use Joomla\Registry\Registry; 
class ProjectsListHelper 
{ 
public function getProjects(Registry $params, 
SiteApplication $app) 
{ 
$model = $app->bootComponent('com_spm')-> 
getMVCFactory()->createModel('Projects', 'Site', 
['ignore_request' => true]); 
$model->setState('params', $app->getParams()); 
$items = $model->getItems(); 
return $items; 
} 
} 

در این کد، فضای نام را برای کمک کننده خود تعریف می کنیم. سپس، بقیه فضاهای نامی را که قرار است استفاده کنیم ثبت می کنیم.

اولین فضای نامی که ثبت می کنیم، فضای نام ProjectsModel  است. این به این دلیل است که ما از مدل واقعی کامپوننت سایت خود برای دریافت لیست پروژه ها استفاده می کنیم. به این ترتیب، برای بازیابی پروژه ها نیازی به بازنویسی کوئری نداریم و می توانیم از تمام فیلترهای تعریف شده در مدل خود استفاده کنیم.

در واقع ما متدgetProjects   را با نمونه سازی کلاس ProjectsModel  شروع می کنیم. در جوملا، ما از متد  bootComponent  از کلاس Application  برای مقداردهی اولیه کامپوننت خود استفاده می کنیم. این به ما امکان می دهد مدل مورد نیاز خود را از کامپوننت دریافت کنیم.

هنگامی که کامپوننت را داریم، با استفاده از متد setState مقداری کد به آن اضافه می کنیم و در نهایت متدgetItems  را برای دریافت لیست پروژه ها فراخوانی می کنیم.

با این helper، لیست پروژه ها را به  dispatcherبر می گردانیم و در قسمت بعدی نحوه قالب بندی داده های خود را با استفاده از سیستم چیدمان جوملا (Joomla layouts system) خواهیم دید.

اضافه کردن چیدمان برای ماژول

هنگامی که داده هایی را می خواهیم نمایش دهیم، می توانیم آن را با این ابزار نمایش دهیم. همانطور که ما در حال گسترشAbstractModuleDispatcher  برای ایجاد dispatcher برای ماژول خود گسترش می دهیم، فقط باید پیش فرض چیدمان را در داخل پوشه tmpl  ایجاد کنیم. بنابراین ما فایل  src/module/mod_projectslist/tmpl/default.php را ایجاد می کنیم و آن را با این کد ساده مقداردهی اولیه می کنیم:

 
<ul class="mod-projects-list"> 
<?php foreach ($projects as $item) : ?> 
<li> 
<?php echo $item->name; ?> 
</li> 
<?php endforeach; ?> 
</ul> 

این کد یک لیست HTML نامرتب را نشان می دهد که در آن هر مورد از لیست، نام یکی از پروژه های ما خواهد بود.

جالب است بدانید که ما پروژه های خود را از متغیر  $projects فراخوانی می کنیم. این نام کلیدی است که برای ذخیره لیست پروژه های خود در ارسال قبلی استفاده کردیم:

 ($data['projects']).

 

نوشتن مانیفست برای ماژول ما

برای نصب ماژول و استفاده از آن در جوملا، باید یک فایل مانیفست ایجاد کنیم. این فایل مانند فایلی است که قبلاً برای کامپوننت خود در فصل 2 نوشتیم ، با تفاوت هایی که در این بخش به آنها می پردازیم.

فایل مانیفست ماژول ما یک فایل XML است و شامل تمام داده هایی است که جوملا برای نصب و پیکربندی ماژول نیاز دارد.

بیایید فایل src/module/mod_projectslist/mod_projectslist.xml  را با محتوای زیر ایجاد کنیم:

 
<?xml version="1.0" encoding="UTF-8"?> 
<extension type="module" client="site" method="upgrade"> 
<name>MOD_SPM_PROJECTSLIST</name> 
<author><![CDATA[Carlos Cámara]]></author> 
<authorEmail>این آدرس ایمیل توسط spambots حفاظت می شود. برای دیدن شما نیاز به جاوا اسکریپت دارید</authorEmail> 
<authorUrl>extensions.hepta.es</authorUrl> 
<creationDate>2022-07-21</creationDate> 
<copyright>(C) 2022 Piedpiper Inc.</copyright> 
<license>GNU General Public License version 2 or later; 
see LICENSE.txt</license> 
<version>0.1.0</version> 
<description><![CDATA[MOD_SPM_PROJECTSLIST 
_DESCRIPTION]]></description> 
<namespace path="src">Piedpiper\Module\ProjectsList 
</namespace> 
<files> 
<folder module="mod_projectslist">services</folder> 
<folder>src</folder> 
<folder>tmpl</folder> 
</files> 
<languages> 
<language tag="en-GB">language/en-GB/ 
mod_projectslist.ini</language> 
<language tag="en-GB">language/en-GB/ 
mod_projectslist.sys.ini</language> 
</languages> 
</extension> 

در این کد XML، ما تمام ابرداده  های مربوط به ماژول خود را با استفاده از تگ  های XML ، مانند name ، author  یا license  پوشش می دهیم.

ما از حروف بزرگ برای برچسب های زبان استفاده می کنیم تا نشان دهیم که قابل ترجمه هستند. ما از آنها به عنوان کلید برای نام ماژول و توضیحات در ترجمه خود استفاده خواهیم کرد.

با تگ، فضای نام ماژول خود را به جوملا می گوییم و جوملا اکنون می  داند که کجا کلاس  های ماژول خود را پیدا کند.

در این قسمت پوشه های ماژول خود را تعریف می کنیم و صریحاً به جوملا می گوییم که پوشه services ما را با ماژول مرتبط کند و ویژگی ماژول را به تگ آن اضافه کنیم.

در نهایت، فایل های زبان خود را به مانیفست اضافه کنید. در این مورد، ما ترجمه انگلیسی را اضافه می کنیم، بنابراین ما نیز باید این فایل ها را ایجاد کنیم.

بنابراین، پوشه src/module/mod_projectslist/language/en-GB/  را ایجاد کنید و فایل های زبان mod_projectslist.ini  و mod_projectslist.sys.ini  را اضافه کنید و سپس ترجمه رشته های زبانی را که قبلا در ماژول وارد کرده اید را اضافه کنید:

 
MOD_SPM_PROJECTSLIST="Projects List" 
MOD_SPM_PROJECTSLIST_DESCRIPTION="A simple projects list module to show projects of the Simple Project List component" 

سیستم ترجمه زبان همان است که در فصل 5 مشاهده می شود.

هنگامی که فایل مانیفست را ایجاد کردیم، می توانیم کد خود را در یک فایل ZIP بسته بندی کنیم و آن را در جوملا نصب کنیم. همانطور که مشاهده میکنید، ماژول ما فقط یک هدف را دنبال می کند - نشان دادن لیست پروژه ها با یک ترتیب خاص - بنابراین اجازه دهید در بخش بعدی برخی از پارامترهای پیکربندی را اضافه کنیم تا آن را انعطاف پذیر تر کنیم.

استفاده از پارامترهای پیکربندی ماژول

هنگامی که شروع به استفاده از ماژول می کنید، ممکن است متوجه شوید که می تواند چندین هدف را انجام دهد. به عنوان مثال، می توانید از ماژول برای نمایش تمام پروژه هایی که روی آنها کار می کنید، در صفحه اصلی استفاده کنید. یا می توانید از آن برای نشان دادن پروژه های مربوط به یک مشتری خاص استفاده کنید.

گاهی اوقات شما می خواهید فقط سه پروژه را نشان دهید، و گاهی اوقات ممکن است بخواهید ترتیب لیست را تغییر دهید. توسعه ماژول و تغییر کوئری پایگاه داده عملی نیست و ما به اصل DRY احترام نمی گذاریم، زیرا همان کد را با محدودیت متفاوتی برای جستجوی لیست خواهیم داشت.

بنابراین، اجازه دهید به ماژول خود برخی از پارامترها را بدهیم که کاربران ما می توانند آنها را تغییر دهند تا ماژول متناسب با نیازهای خود داشته باشد. برای افزودن پارامترها به پیکربندی ماژول خود، باید یک بخش جدید در فایل مانیفست XML مطابق با تعریف فرمی که در فصل 4 دیدیم، ایجاد کنیم.

به دنبال پاراگراف اول این بخش، بیایید پارامترهای زیر را ایجاد کنیم:

  • مشتریان  Customers: این یک کشویی چند انتخابی خواهد بود که می توانیم مشتریان را از داخل لیستی انتخاب کنیم
  • حداکثر پروژه برای نمایش Maximum projects to show : این یک جعبه متن برای وارد کردن یک عدد صحیح خواهد بود
  • سفارش Ordering : این یک انتخاب کشویی خواهد بود که در آن ما سه گزینه خواهیم داشت:

 جدیدترین newest ، قدیمی ترین oldest و تصادفی random

می توانیم بخش&lt;config&gt;  زیر را به فایل مانیفست واقع در src/module/mod_projectslist/mod_projectslist.xml ، اضافه کنیم، درست قبل از بستن تگ:

 
<config> 
<fields name="params"> 
<fieldset name="basic"> 
<field name="customer" 
type="sql" 
label="MOD_SPM_PROJECTSLIST_CONFIG_CUSTOMER_LABEL" 
description="MOD_SPM_PROJECTSLIST_CONFIG 
_CUSTOMER_DESCRIPTION" 
header="MOD_SPM_PROJECTSLIST_CONFIG_CUSTOMER_ALL" 
multiple="multiple" 
sql_select="id, CONCAT(firstname, ' ', 
lastname) AS name" 
sql_from="#__spm_customers" 
key_field="id" 
value_field="name" 
sql_order="lastname ASC" 
/> 
 </fieldset> 
</fields> 
</config> 

در این کد، بخشconfig  فایل مانیفست را تعریف کرده ایم. در داخل این بخش، بخش fields  را می بینیم که در آن زبانه های ناحیه Configuration  را تعریف می کنیم. اولین برگه یک زیر بخشfieldset  از این خواهد بود که basic نامیده می شود. در نهایت اولین فیلد خود را تعریف می کنیم. این یک فیلد SQL برای دریافت اطلاعات مشتریان و نمایش آن در select است. ما این فیلد را multiple تعریف کرده ایم تا بتوانیم پروژه های مشتریان مختلف را نشان دهیم. همچنین برای سهولت کار کاربران ماژول، مشتریانی سفارش داده شده را با نام خانوادگی نشان می دهیم.

برای فیلد total ، کد زیر را در زیر بخش مجموعه فیلدها خود قرار می دهیم:

 
<field name="total" 
type="number" 
label="MOD_SPM_PROJECTSLIST_CONFIG 
_TOTAL_LABEL" 
 description="MOD_SPM_PROJECTSLIST_CONFIG_ 
TOTAL_DESCRIPTION" 
default="5" 
filter="integer" 
min="1" max="5" 
validate="number" 
/> 

ما فقط به پنج پروژه در هر فهرست اجازه می دهیم و این نیز پیش فرض خواهد بود، بنابراین فیلد حداکثر (max) را تنظیم می کنیم تا مطمئن شویم کاربران ما این محدودیت را رعایت می کنند.

در نهایت، فیلد سفارش (ordering) یک فیلد لیست ساده با جدیدترین (newest) به عنوان مقدار پیش  فرض برای نمایش آخرین پروژه ها است. بنابراین، ما آن را به مجموعه فیلدها اضافه می کنیم:

 
<field name="ordering" type="list" 
label="MOD_SPM_PROJECTSLIST_CONFIG_ORDERING_LABEL" 
description="MOD_SPM_PROJECTSLIST_CONFIG_ORDERING_DESC" 
default="newest" 
> 
<option value="newest"> 
MOD_SPM_PROJECTSLIST_CONFIG_ORDERING_OPTION_NEWEST 
</option> 
<option value="oldest"> 
MOD_SPM_PROJECTSLIST_CONFIG_ORDERING_OPTION_OLDEST 
</option> 
<option value="random"> 
MOD_SPM_PROJECTSLIST_CONFIG_ORDERING_OPTION_RANDOM 
</option> 
</field> 

سه گزینه برای لیست را ایجاد میکنیم و گزینه جدیدترین (newest) به طور پیش فرض خواهد بود.

رشته های زیادی در این بخش پیکربندی  (Configuration) وجود دارد ، بنابراین بیایید ترجمه ها را به فایلsrc/module/language/en-GB/mod_projectslist.ini  اضافه کنیم:

 
; Configuration 
MOD_SPM_PROJECTSLIST_CONFIG_CUSTOMER_LABEL="Customer's 
Project" 
MOD_SPM_PROJECTSLIST_CONFIG_CUSTOMER_DESCRIPTION="Show 
projects of the selected customers" 
MOD_SPM_PROJECTSLIST_CONFIG_CUSTOMER_ALL="All" 
MOD_SPM_PROJECTSLIST_CONFIG_TOTAL_LABEL="Max projects" 
MOD_SPM_PROJECTSLIST_CONFIG_TOTAL_DESCRIPTION="This will 
limit the maximum number of projects to show. A maximum 
of 5 projects is allowed." 
MOD_SPM_PROJECTSLIST_CONFIG_ORDERING_LABEL="List ordering" 
MOD_SPM_PROJECTSLIST_CONFIG_ORDERING_DESC="Choose how do 
you want to order the projects on the list" 
MOD_SPM_PROJECTSLIST_CONFIG_ORDERING_OPTION_NEWEST="Newest 
projects first" 
MOD_SPM_PROJECTSLIST_CONFIG_ORDERING_OPTION_OLDEST="Oldest 
projects first" 
MOD_SPM_PROJECTSLIST_CONFIG_ORDERING_OPTION_RANDOM="Show 
projects in random order" 

پس از افزودن ترجمه ها به فایل زبان، می توانیم به پیکربندی ماژول دسترسی پیدا کنیم و پارامترهای خود را برای پیکربندی ماژول خواهیم دید. ممکن است متوجه شوید که قسمت Configuration  با پارامترهای ما در تب اول ماژول ما قرار دارد و مانند بقیه ماژول های هسته جوملا تب Advanced  وجود ندارد.

تب Advanced  هنگام توسعه ماژول جوملا مورد نیازی نیست، اما در تمام ماژول  های جوملا وجود دارد و اکثر توسعه  دهندگان از آن در ماژول  های خود استفاده می کنند، بنابراین یک ویژگی خوب برای کاربران ما است. بیایید ببینیم چگونه می توانیم آن را در بخش بعدی اضافه کنیم.

افزودن تب Advanced به پیکربندی ماژول ما

همانطور که هدف اصلی یک ماژول نمایش محتوا است، می توان انتظار داشت که ارتباط مستقیمی با قالب سایت جوملا داشته باشد. در پایان، جوملا تمام محتوای چیدمان ماژول را دریافت می کند و آن را به موقعیت ویژه ی قالب، متصل می کند.

برای ارائه انعطاف بیشتر، تمام ماژول  های هسته ی جوملا یک تب Advanced  را در پیکربندی ماژول ارائه می کنند که در آن می توانید برخی از مشخصات را در مورد نحوه نمایش ماژول خود پیکربندی کنید.

این تنظیمات معمولاً مربوط به نحوه نمایش اطلاعات در قالب هستند، بنابراین ممکن است انتظار داشته باشید که در همه سناریوها وجود نداشته باشد. اما در واقع، اکثر توسعه دهندگان جوملا این تنظیمات را به عنوان یک استاندارد واقعی تطبیق داده اند و ایده خوبی است که آنها را در پیکربندی ماژول خود ارائه دهیم.

برای افزودن این پارامترها به پیکربندی فعلی خود، باید یک زیر بخش جدید در بخش خود وارد کنیم، بنابراین بیایید این کد قبل از بسته شدن تگ را به فایلsrc/module/mod_projectslist/mod_projectslist.xml   اضافه کنیم:

 
<fieldset name="advanced"> 
<field 
name="layout" 
type="modulelayout" 
label="JFIELD_ALT_LAYOUT_LABEL" 
class="form-select" 
validate="moduleLayout" 
/> 
<field 
name="moduleclass_sfx" 
type="textarea" 
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL" 
rows="3" 
validate="CssIdentifier" 
/> 
<field 
name="cache" 
type="list" 
label="COM_MODULES_FIELD_CACHING_LABEL" 
default="1" 
filter="integer" 
validate="options" 
> 
<option value="1">JGLOBAL_USE_GLOBAL</option> 
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING 
</option> 
</field> 
<field 
name="cache_time" 
type="number" 
label="COM_MODULES_FIELD_CACHE_TIME_LABEL" 
default="900" 
filter="integer" 
/> 
</fieldset> 

این پارامترهای زیر در تب Advanced  پیکربندی ماژول اضافه شده اند :

  • Layout  : کاربران ممکن است در اینجا یک فایل چیدمان متفاوت را برای ماژول ما مشخص کنند، در صورتی که ما چیزی بیش از چیدمان پیش فرض ارائه دهیم یا یک لغو ایجاد کنند.
  • Module class suffix : هنگامی که ماژول ها در قالب نمایش داده می شوند، در داخل یک عنصر HTML با یک کلاس خاص که توسط الگو تعیین می شود، ادغام می شوند. این پارامتر همچنین ممکن است شامل یک کلاس CSS باشد تا امکان استایل بهتر ماژول را فراهم کند. این پارامتر به ما اجازه می دهد تا یک پسوند به کلاس پیش فرض اضافه کنیم.
  • Cache : این پارامتر تعیین می کند که آیا جوملا هنگام نمایش این ماژول از سیستم کش پیکربندی شده استفاده کند یا خیر. این قطعا گزینه خوبی برای ارائه به کاربران ما است.
  • Cache time : این پارامتر تعیین می کند که هر چند وقت یک  بار ماژول باید حافظه پنهان خود را تازه  سازی کند.
  • Cache mode : این آخرین پارامتر در واقع برای کاربر پنهان است، اما باید آن را مشخص کنیم تا نوع ذخیره سازی ماژول را تعیین کنیم. در بخش بعدی کمی بیشتر در مورد حافظه پنهان خواهیم دید.

برای این پارامترها، نیازی به افزودن هیچ ترجمه ای به فایل های زبان خود ندارید، زیرا از رشته های کلید عمومی که قبلاً در جوملا وجود دارد استفاده می کنیم.

ذخیره ماژول ها در جوملا

سه پارامتر آخری که به پیکربندی پیشرفته خود اضافه کرده ایم مربوط به حافظه پنهان جوملا است. برای ماژول ها، هنگام استفاده از این معماری ماژول جوملا، لازم نیست نگران فراخوانی روش های ذخیره سازی از کلاس های جوملا  CMS باشید.

فقط با اضافه کردن این پارامترها، جوملا تمام مراحل لازم برای ارائه محتوای کش برای ماژول ها را انجام خواهد داد.

برای ماژول ها، ما چهار حالت کش داریم که می توانیم در جوملا از آنها استفاده کنیم:

  •  static : این حالت، تمام ماژول های یک نوع را با پارامترهایشان در کش می کند، بنابراین نمونه های مختلف ماژول از یک ماژول با پارامترهای یکسان، حافظه پنهان خود را به اشتراک خواهند گذاشت. همچنین به شما این امکان را می دهد که چندین بار یک نوع ماژول را در یک URL بدون اشتراک گذاری اطلاعات حافظه پنهان آنها داشته باشید، بنابراین در صورت شک، یک حالت پیش فرض امن برای استفاده برای ماژول ها است.
  • id  : این حالت ماژول ها را با شناسه داخلی منحصربفردشان کش می کند. این بدان معناست که دو نمونه مختلف از یک ماژول یک کش را به اشتراک نمی گذارند.
  • itemid  : این حالت کش به ازای هر آیتم منو ( itemid ) امکان ذخیره کش های مختلف را می دهد. این بدان معناست که همان نمونه ماژول در صفحات مختلف فایل کش خود را ایجاد می کند.
  • safeuri  : این حالت به ازای ترکیبی از پارامترهای URL، یک فایل کش متفاوت ایجاد می کند و معمولاً برای نشان دادن ماژول هایی استفاده می شود که محتوای آنها با توجه به موردی که در حال مرور آن هستیم تغییر می کند.

ما یک ماژول بسیار انعطاف پذیر با توجه به پیکربندی، ایجاد کردیم، اما تا کنون، این پارامترها رفتار ماژول ما را به خودی خود تغییر نمی دهند. اکنون باید به ماژول دستور دهیم تا آنها را در کد بازیابی و تحلیل کند.

استفاده از پارامترهای ذخیره شده در کد شما

افزودن ناحیه ی  پیکربندی Configuration  ماژول ما با استفاده از قابلیت های  CMS جوملا آسان بوده است. اکنون، باید پیکربندی ماژول را در کد خود بخوانیم تا تغییرات در لیست پروژه های حاصل را منعکس کند.

تنظیمات پیکربندی ماژول در ماژولDispatcher.php  به عنوان ویژگیparams $this-&gt;module  موجود است. این ویژگی تنظیمات ماژول را به عنوان یک آبجکت Registry که به عنوان رشته JSON کد گذاری شده است، بر می گرداند. از آنجایی که ما از کلاس Registry  استفاده می کنیم، باید فضای نام مناسب را به dispatcher اضافه کنیم، بنابراین لطفاً این خط را به اعلان فضاهای نام خود در فایل src/modules/mod_projectslist/src/Dispatcher/Dispatcher.php  اضافه کنید:

 
Use Joomla\Registry\Registry; 

سپس، می توانید این کد را در متد  getLayoutData فایل dispatcher وصل کنید:

 
$settings = new Registry($this->module->params); 
dump($settings); 

این کد پیکربندی ماژول را بازیابی می کند، یک آبجکت  Registry ایجاد می کند و آن را در یک پیام  dump با فرمت زیبا نشان می دهد.

اما در واقع، ما نیازی به انجام این کار نداریم، زیرا در داخلgetLayoutData  کلاس والد را با$data =parent::getLayoutData    در ابتدا فراخوانی می کنیم و این فراخوانی آرایه$data  را با پارامترهای زیر مقداردهی می کند:

 
[ 
'module' => $this->module, 
'app' => $this->app, 
'input' => $this->input, 
'params' => new Registry($this->module->params), 
'template' => $this->app->getTemplate(), 
]; 

اینها همه پارامترهایی هستند که به ماژول ما مرتبط هستند، بنابراین از این پس می توانیم فقط از آرایه $data  استفاده کنیم.

اگر به دقت تماس با Helper خود را در getLayoutData بررسی کنیم، متوجه می  شویم که $data['params']  را به ماژول Helper  خود ارسال میکنیم تا لیست پروژه ها را دریافت کنیم:

 
$data['projects'] = $this->getHelperFactory()-> 
getHelper('ProjectsListHelper')-> 
getProjects($data['params'], $this->getApplication()); 

بیشتر تنظیمات ما فقط بر نحوه دریافت لیست پروژه ها تأثیر می گذارد، بنابراین بیایید به جایی برویم که لیست پروژه ها را دریافت می کنیم و از پارامترها در آنجا استفاده می کنیم. بیایید شروع به تنظیم تعداد کل پروژه ها برای نمایش کنیم. برای این، ما فایل src/module/src/Helper/Helper.php  را ویرایش می کنیم و قبل از دریافت آیتم ها، خط زیر را اضافه می کنیم:

 
$model->setState('list.limit', (int) $params->get('total',5)); 

این خط تعداد آیتم ها را در حالت در حال اجرا ذخیره می کند و همانطور که ما از Site Projects Model خود استفاده می کنیم، در کوئری پایگاه داده در متد  getListQueryاز src/component/site/src/Model/ProjectsModel.php  تنظیم می شود.

برای اضافه کردن تنظیمات سفارش (ordering) ، باید کد بیشتری اضافه کنیم. اول از همه، ما از کلاس های پایگاه داده برای به دست آوردن تنظیمات تصادفی پایگاه داده استفاده می کنیم. در جوملا، ما می توانیم با پیاده سازی DatabaseAwareInterface ، آبجکت پایگاه داده را در کلاس های خود دریافت کنیم، بنابراین باید کمی تعریف کلاس خود را تغییر دهیم و همچنین باید از چند فضای نام اضافی استفاده کنید. پس، اجازه دهید تعریف کلاس خود را با این کد جایگزین کنیم:

 
use Joomla\Database\DatabaseAwareInterface; 
use Joomla\Database\DatabaseAwareTrait; 
class ProjectsListHelper implements DatabaseAwareInterface 

اکنون در متد getProjects ما می توانیم کد زیر را درست پس از تنظیم وضعیتlist.limit  از پاراگراف قبلی اضافه کنیم:

 
switch ($params->get('ordering', '')) { 
case 'random': 
$db = $this->getDatabase(); 
$ordering = $db->getQuery(true)->rand(); 
break; 
case 'oldest': 
$ordering = 'a.created ASC'; 
break; 
case 'newest': 
default: 
$ordering = 'a.created DESC'; 
} 
$model->setState('list.ordering', $ordering); 
$model->setState('list.direction', ''); 

ما نمی  توانیم مقادیر پارامترهای ordering را مستقیماً در پایگاه داده خود استفاده کنیم، زیرا معنی ندارند، (به یاد داشته باشید، آنها newest, oldest, random بودند). بنابراین در این کد، متغیر $ordering را با کد پایگاه داده مناسب پر می کنیم تا پروژه ها به ترتیب درست قرار بگیرند. برای حالت random ، ما از متد getDatabase برای بدست آوردن آبجکت پایگاه داده استفاده می کنیم که وسیله ای برای بدست آوردن متد rand برای ایجاد ترتیب تصادفی ما فراهم می کند.

ما از newest  به  عنوان حالت پیش  فرض استفاده کنید، و ما آن را برای شفافیت به کد اضافه کرده ایم، اما میتوانیم این خط را حذف کنید.

هنگامی که متغیر $ordering را به درستی تنظیم کردیم ، فقط مقدار آن را به حالت مدل تزریق می کنیم.

ممکن است تعجب کنید که چرا باید پارامتر "list.direction" را تنظیم کنیم. خوب، همانطور که ما از مدل سایت کامپوننت خود استفاده می کنیم، آن پارامتر با "ASC" پر می شود ، بنابراین باید آن را پاک کنیم زیرا از قبل جهت را در  پارامتر  "list.ordering" اضافه کرده ایم.

در نهایت، لیست پروژه ها را بر اساس مشتری محدود می کنیم. بنابراین باید کد زیر را بعد از کد قبلی اضافه کنیم:

 
$model->setState('filter.customer', (int) $params-> get('customers', 0)); 

در این مرحله، ارزش بررسی این را دارد که متدgetListQuery  ، همه ی این متغیرهای حالت را بررسی کند. برای این کار می توانیم به فایل src/component/site/src/Model/ProjectsModel.php  برویم و بررسی کنیم که کد زیر وجود دارد:

 
$orderCol = $this->state->get('list.ordering', 'a.nameASC'); 

این کد حالت ordering را از مدل دریافت می کند و آن را در کوئری قرار می دهد، بنابراین اگر موجود نباشد، وضعیت هیچی (nothing) است.

ما همچنین به این کد نیاز داریم:

 
$id_customer = $this->state->get('filter.customer', 0); 
if ($id_customer) { 
$query->where( 
$db->quoteName('a.id_customer') 
. ' = ' . (int) $id_customer 
); 
} 

این کد مقدار متغیر حالت customer  را دریافت می کند و اگر عدد مثبت باشد، کوئری را به این مشتریان محدود می کند.

 

منابع فصل

فصل های دیگر کتاب

نوشتن دیدگاه

ارسال