سلام. یادم میاد چند وقت پیش که با پکیج ماژولار (صفحه گیتهاب ماژول بندی لاراول) لاراول آشنا شدم انگار همه اون چیزی که لاراول کم بود رو یکجا پیدا کرده بودم. خیلی خوب بود که میتونستم برنامم رو کپسوله کنم و هر بخشی رو کامل از بخش دیگه جدا کنم. این روند ادامه داشت تا کمکم کمبود یا نبود قابلیت تم بندی توی برنامم دیگه داشت اذیت میکرد.
شروع کردم به گشتن. یکم گشتم ولی اون چیزی که دوست داشتم پیدا نشد. (https://github.com/FaCuZ/laravel-theme): این بهترین پروژه اوپن سورسی بود که پیدا کردم ولی بازم به دلم نشست چون باید همه کنترلرهامو تغییر میدادم و این خارج از صبر و حوصله من بود.
بلاخره نشستم به خوندن سورس لاراول اون چیزی که میخواستم رو پیدا کردم. توی کلاس Application بود!!!
ولی قبل از این که کلاس Application رو تغییر بدیم نیاز داریم که یک سری پیش نیاز رو درست کنیم که اول به اونا میپردازیم و بعدش میریم سراغ Application.
یک فایل به نام themes.json درون پوشه resources درست میکنیم. دلیل این که این فایل رو با پسوند json درست کردیم اینه که بعدا هم توی php ازش استفاده میکنیم هم توی webpack!
فایل themes.json دارای دو متغیر اصلیه، یکی active که اسم تم فعال برنامه رو درون خودش نگهداری میکنه، یکی دیگه هم list که برامون لیستی از تمهای موجود توی برنامه رو نگهداری میکنه که بعدا اگر خواستم بتونیم به لیست تمهای موجود دسترسی پیداکنیم. (لیست برای من بیشتر یک جنبه تکمیلی داره و شما میتونین حذفش کنین!)
خب از اونجایی که میخوایم برنامه رو تم بندی کنیم، بهتره همه فایل هایی که تم ها استفاده میکنن رو از هم جدا کنیم که این فایل شامل هر فایلی که داخل پوشه resource هست میشه. خب از اونجایی که تمام فایلهای درون پوشه resource در حال حاضر مربوط به یک تم میشه رو به داخل اسم همون تم درون پوشه تم انتقال میدیم. (اینجا تمی که من استفاده میکنم اسمش metronicه و واسه همین از این به بعد از این اسم واسه پوشه تمم استفاده میکنم.)
خب پس اگر تا اینجای کار درست پیش رفته باشیم درون پوشه resource ما یک فایل themes.json وجود داره و چند تا پوشه به نام تمهای برنامه.
خب ما میدونیم که هر تمی یک سری فایل js و css مربوط به خودش رو داره و ما برای این که بتونیم تا حد امکان برنامه رو منعطف نگه داریم و برای تغییر تم به کمترین تغییرات توی برنامه نیاز داشته باشیم فایل های webpack.mix.js و package.json رو درون پوشه هر تم درست میکنیم.
درون فایل webpack.mix.js تمام محتوای webpack قدیمی که درون پوشه اصلی برنامه قرار داشت رو قرار میدیم و به شکل زیر تغییر میدیمش.
که برای من به صورت زیر شد.
و برای فایل package.json همه پیش نیاز های برنامه رو قرار میدیم.(چون ما قبلا کلا یک تم داشتیم میتونیم فایل رو به صورت مستقیم از پوشه اصلی برنامه درون پوشه تم مورد نظرمون کپی میکنیم.)
نیاز به بهبود: از اونجایی که من تجربه زیادی توی nodjs و webpack ندارم ممکنه برای تغییراتم راه بهتری هم باشه و برای package.json راهی پیدا نکردم که npm نیازمندیهای پروژه رو به صورت خودکار از داخل package.json خود تم بخونه و نصب کنه و وقتی میخوایم تم رو عوض کنیم باید package.json رو از داخل پوشه تم به پوشه اصلی کپی کنیم که بتونیم نیازمندیهاشو نصب کنیم! ( از دوستان کسی اگر تجربه ای توی این زمینه داره ممنون میشم راهنمایی کنه تا این مطلب تکمیل تر بشه.)
از اونجایی که فایل webpack نیاز داره از درون پوشه خود تم اجرا بشه ما یک فایل webpack.mix.js درون پوشه اصلی پروژه درست میکنیم (همون فایل اصلی که موقع نصب لاراول بین فایل ها وجود داره) و به صورت زیر تغییرش میدیم.
از الان به بعد هر موقع دستورهای npm run ... رو اجرا کنیم فایل webpack مخصوص به تم اجرا میشه و ما نیازی به تغییر webpack نداریم.
خب تقریبا تمام کارهایی که پیش نیاز بود رو انجام دادیم.
تا الان ما فایل های css و js برنامه جدا شدن و به صورت خودکار از داخل پوشه تم خونده و اجرا میشن، فقط میمونه فراخوانی view ها که زمانی که ما یک view رو فراخوانی میکنیم، برنامه به صورت خودکار از تم مورد نظر بخونه و اجرا کنه!
خوب از اونجایی که برنامه ما همیشه از داخل پوشه public و فایل index.php اجرا میشه، در اولین مرحله فایل autoload کومپوزر بارگذاری میشه که وظیفه لود کردن کلاس ها و فایل ها رو به عهده میگیره! بعد از اون میاد فایل app.php از داخل پوشه bootstrap رو بارگذاری میکنه که از این فایل به ما یک شی از کلاس Illuminate\Foundation\Application برگشت داده میشه. بعدش ما یک شی از درخواست کاربر تحت کلاس Illuminate\Http\Request درست میکنیم و به کرنل ارسال میکنیم که برامون پردازشش کنه و جواب متناسب رو برگرودنه. بعدش درخواست رو به کاربر بر میگردونیم و تموم، کاربرمون جوابشو گرفته.
خوب از اونجایی که کلاس Illuminate\Foundation\Application داخل فایل bootstrap/app.php ساخته میشه، میریم یک سری به اونجا میزنیم و یک سری تغییراتی که میخوایم بدیم رو اونجا اعمال میکنیم!
خب همینطور که میبینیم توی این فایل یک شی از کلاس Application میسازه ادرس پوشه جاری رو به عنوان آدرس اصلی اجرایی برنامه ارسال میکنه (البته اگر داخل $_ENV متغیر APP_BASE_PATH تنظیم نشده باشه!).
ما نیاز داریم که این که کلاس رو مطابق نیازمون یکسری تغییرات ریز بدیم که در ادامه با هم اون تغییرات رو اعمال میکنیم تا برنامه به صورت پویا تم رو فراخونی کنه.
خب از اونجایی که ما نمیتونیم داخل پوشه vendor تغییرات ایجاد کنیم و اگر تغییری ایجاد کنیم با هر بار نصب یا اپیدت composer همه تغییرات به فنا میره، یک کلاس به اسم Application داخل پوشه app درست میکنیم و اونو از کلاس Illuminate\Foundation\Application ، Extend میکنیم و تغییرات زیر رو درونش میدیم.
اگر یک زمانی به فایل نیاز داشتین میتونین اینجا به این فایل دسترسی داشته باشین.
خب دیگه تقریبا تغییرات تمومه و فقط میمونه فایل bootstrap/app.php که به صورت زیر تغییرش میدیم.
خب دیگه تغییراتمون تموم شد و از الان به بعد به راحتی میتونیم از تم بندی سایتمون لذت ببریم.
راستی شما داخل کنترلرهاتون هیچ تغییری نیاز ندارین بدین چون داخل هسته لاراول پوشه تم مورد نظرتون رو به عنوان پوشه resource معرفی کردین و فقط کافیه مثل قدیم از تابع view() استفاده کنین تا فایل های viewتون رو فراخونی کنین.
از الان به بعد موقع تعویض تم شما فقط نیاز دارین که