- Modules 101
- File Structure
- Creating a new module
- Module Front-End
- Module Back-End
- Using Assets
- Loading modules
- Module parameters
- Module functions
- Checking if the module is in Live edit mode
- Things to know
- Модульное программирование на PHP или как написать маленький портал
- MVC PHP разбор полётов, всё ли верно я сделал?
Modules 101
Microweber modules are PHP scripts that can be placed on the website. They are executed in a sandboxed environment, but can access Microweber, Laravel and any custom dependency’s functionality. Modules help developers make easy modifications and add functionality to user pages.
Microweber comes bundled with a handful of preinstalled modules that you can examine and extend. We encourage learning and the principles of creating modules by looking at the existing code.
In most cases, modules are «blocks» that users drag and drop wherever they need them on their website. Galleries, menus, displaying a post, listing posts in given category, contact forms, etc. are examples of such modules.
Modules don’t have to depend on the website’s content or design and can have their own presentation layer.
File Structure
Each module is contained within its own folder in userfiles/modules . In order for new modules to be available, you have to open the modules administration page in the back-end and click Reload Modules .
Every module needs the following files to work
Filename | Description |
---|---|
config.php | this file contains the info for your module |
index.php | this file loads the module after it is dropped or opened from the frontend |
admin.php | when you open the module settings from the admin or from the live edit, this file is loaded |
functions.php | optional file, it is loaded on system start with the website |
icon.png | icon for your module (size 32×32) |
Creating a new module
There are just few steps you need to make in order to create new module
- Make new folder for your module for example userfiles/modules/example_module/
- Make index.php and admin.php files, so your module can be displayed
- Create a config.php file with the information for your module
Module Front-End
The index.php file in the module’s folder is being rendered anywhere on the site the user has placed the module.
If you drop the module on a page you will be able to see your text.
Module Back-End
Users can access administration pages for their installed modules from both the front-end (in a modal) or from the back-end. Creating an administration page for your module has many advantages. It’s handy for a number of cases, such as allowing users to edit global or instance-specific module settings.
The admin.php file in your module’s root directory is executed and rendered when the user accesses the administration of your module.
Using Assets
Upon execution modules are injected with a $config array inside their scope. It contains the module path, name and other module info.
The module’s filesystem location and URL can be found in the $config array. You can use it to load assets or other scripts from the module folder.
The $config[‘url_to_module’] key contains the full url to the module folder (ex. http://.com/userfiles/modules/example_module/ )
The $config[‘path’] key contains the full path to the module folder (ex. /var/www/userfiles/modules/example_module/ )
Provided there is a file named logo.png in your module folder you can easily display it with code like this:
Loading modules
In Microweber the modules are loaded via the tag inside your template, where the «type» parameter is the path to your module. Additionally they can be dragged and dropped by the user in the editable regions of your site.
This code will load the file userfiles/modules/example_module/index.php
If you wish to load a file other than index.php you can do it by
This code will load the file userfiles/modules/example_module/something.php
Module parameters
The modules can accept parameters, which are passed as html attributes.
You can access the parameters inside the module from the $params array. Open index.php in your module folder and add this code
Each module have an «id» which is accessible with $params[‘id’] and its unique for every module, unless you set it as html attribute. If you do not put an «id» attribute on your module, Microwber will generate one.
Module functions
If you create a file named functions.php in the module folder, this file will be loaded automatically on every request. You can use it to make your custom functions, autoload classes and do whatever you like.
Checking if the module is in Live edit mode
Things to know
- You can load other modules in your modules
- You can have editable regions in your modules
- Important: in order you module to show, you need to click realod modules button in admin panel
Модульное программирование на PHP или как написать маленький портал
Я попытаюсь тут разъяснить то, как я подхожу к написанию сайтов, где могут применять подключаемые модули. Пример тому известный скрипт PHPNuke. Как бы не ругали его, подход, примененный в нем, к модульному программированию очень удобен. Но из-за корявости общего кода применять такой скрипт на серьезных сайтах, точнее скажем порталах, с большим количеством посетителей, не рекомендуется. Почему? Скрипт работает медленно, очень большая нагрузка на базу данных. Можно еще очень много чего описать, но это уже материал для другой статьи. Если кому интересно , то в интернете полно описаний этого движка. В PHPNuke я убедился сам. Мой основной проект NVIDIA BIOS Collection в начала базировался на PHPNuke, но постоянные проблемы с хостингом заставили меня начать разработку своей система портала с нуля. Из PHPNuke я взять только суть модулей, все остальное же делал сам. И так для начала. Прежде всего, надо продумать систему каталогов, что и где будет лежать. Вот примерный вариант.
* /mods/ — каталог для хранения модулей
* /img/ — картинки
* /include/ — каталог вспомогательных файлов
Это что нам сейчас пока надо. Применять блоки и скины мы пока не будем. В моем портале также были другие каталоги
* /blocks/ — Тоже своего рода модули, но не выводящие сами информацию, а возвращающие заполненную переменную.
* /js/ — каталог для Java скриптов
* /theme/ — каталог выбора тем или, грубо говоря, набор скинов для сайта.
* /files/ — файлы для скачивания
В корневом каталоге храниться всего один файл index.php и вся работа идет через него. Теперь надо решить как будет выглядеть сам сайт. Для нашего примера подойдет наипростейший вариант дизайна , верх сайта , низ сайта, а в середине наша информация из модулей. Для этого в каталоге include создадим два файла top.php и bottom.php, что соответственно будет верхней частью дизайна и нижней частью дизайна.
здесь выводится шапка
Меню сайта - Модуль1
- Модуль2"; ?> Предвижу комментарии, где скажут, почему я не вывожу HTML код отдельно, а php отдельно. Я приучил себя к написанию 100% PHP кода, с одной стороны не очень и красиво может выглядеть, но мне так удобнее. Если кто-то хочет писать по-другому, то тут я не советчик. Заметьте переменную $PAGE_TITLE в top.php. В моей реализации вся информация о модулях храниться в базе данных, где помимо имени файла модуля храниться также и его название, которое потом и кладется в $PAGE_TITLE, для вывода его в головок браузера.
Также создадим файл конфигурации config.php и положим его в каталог include.
Вот примерная схема работы index.php
$PAGE_TITLE="Модуль $mod"; include("inc/top.php"); include("inc/$mod.php"); include("inc/bottom.php"); ?>Теперь создадим два файла mod1.php и mod2.php и положим их в каталог mods.
echo "Это модуль номер 1!
"; echo "А здесь можно посмотреть на модуль номер 2"; ?> mod2.php echo "Это модуль номер 2!
"; echo "А здесь можно посмотреть на модуль номер 1"; ?>Поясню немного вот эту строку
if (!eregi(«index.php», $PHP_SELF))
В каждый модуль желательно включать такую проверку во избежании вызова файла модуля вне самого index.php. На примере моего портала до вызова модуля у меня идет подключение в базе данных, считывание некоторых глобальных переменных и без них, ни один модуль сам по себе работать не сможет. Так что лучше всего просто запретить вызов модуля напрямую. Вызов модулей в данном случае производится через строку в виде index.php?mod=имя модуля, но тут можно применить и систему ЧПУ. Тогда URL примет вид index.php/имя модуля/
Вот в принципе очень грубая схема реализации модулей. Можно добавить любой модуль, просто положив его в каталог mods/ и придерживаясь общей концепции работы, построить очень сложный сайт. В чем удобства работы? По сути вы отодвигаете от себя основную заботу по натягиванию кода на дизайн. Это делает один раз в index.php. Сам же модуль должен только работать и приносить пользу. Централизация сбора основной информации из базы или конфигурационного файла, глобальные переменные сайта, информация о пользователе и т.д. С другой стороны есть недостатки (хотя при определенном взгляде они не кажутся недостатками), скажем надо четко следить за тем какие имена переменных используются до модуля, чтобы не перезаписать, случайно, их внутри модуля. Один раз у меня такое случилось. После такого случая, я взял для себя за правило называть системные переменные в таком виде $sys_имя переменной. Другой очевидный недостаток это трудность реализации разных вариантов дизайна для разных модулей. Но! Тут есть выход тоже.
Если взять за правило, что каждый модуль обязан сам вывести шапку и низ сайта, то вам уже предоставляется свобода по выбору что и как выводить.
К примеру, наши простые модули можно модифицировать в таком варианте.
$PAGE_TITLE="Это Я, модуль номер 1. "; include("inc/top.php"); echo "Это модуль номер 1!
"; echo "А здесь можно посмотреть на модуль номер 2"; include("inc/bottom.php"); ?>Как делать в данном и конкретном случае решать Вам. Я же просто попытался направить тех, кто начинает писать на php, а может и тех, кто уже пишет, на определенный вариант или стиль программирования.
MVC PHP разбор полётов, всё ли верно я сделал?
Сразу скажу, что я не претендую на премию Дарвина.
И так, задался вопросом написания простой MVC.1. Единая точка входа
2. Разделение логики -> model, view, controller
3. В теории всё просто — приступаюAddDefaultCharset UTF-8 #ErrorDocument 404 /404 Options +FollowSymlinks RewriteEngine on RewriteBase / RewriteCond % !-d RewriteCond % !-f RewriteCond % !-l RewriteRule ^([^/]*)$ index.php?module=pages&url=$1 [QSA,L] RewriteRule ^main/?$ index.php?module=main [L,QSA] RewriteRule ^/?$ index.php?module=main [L,QSA]
session_start(); error_reporting(E_ALL); ini_set('display_errors', 1); define('ROOT', dirname(__FILE__)); require_once(ROOT . '/classes/Loader.php'); $router = new Router(); if(($content = $router->start()) !== false) < print $content; >else < header("HTTP/1.0 404 Not Found"); header("Status: 404 Not Found"); $_GET['module'] = 'pages'; $_GET['url'] = '404'; print $router->start(); > if(1) < $time_end = microtime(true); $exec_time = $time_end-$time_start; echo "errors() AS $errors) < echo $errors . "\r\n"; >echo "Автозагрузка: \r\n"; var_dump(spl_autoload_functions()); echo "-->"; >
3. Загрузчик классов Loader.php
spl_autoload_register('Autoload'); spl_autoload_extensions('.php'); function Autoload($class_name) < if(stristr($class_name, '_') === FALSE)< $class_file = ROOT . '/classes/' . $class_name . '.php'; >else < $file_type = explode('_', $class_name); $module = $file_type[0]; $file_type = $file_type[1]; $class_file = ROOT . '/modules/' . $module . '/' . $file_type. '.php'; >if (is_readable($class_file)) < require $class_file; >else < return false; >>
class Router < public $request; public $config; public $errors; public function __construct()< $this->request = new Request(); $this->config = new Config(); $this->errors = new Errors(); > public function start()< $module = $this->request->get('module'); $module = preg_replace('/[^A-Za-z0-9]+/', '', $module); $module = strtolower($module); $action = $this->request->get('action'); $action = preg_replace('/[^A-Za-z]+/', '', $action); if(empty($module)) < $module = 'main'; >if(empty($action)) < $action = 'Index'; >$controller_class = ucfirst($module) . '_Controller'; $controller_path = ROOT . '/modules/'. $module .'/Controller.php'; $model_path = ROOT . '/modules/'. $module .'/Model.php'; if(!file_exists($controller_path))< $this->errors->set('Контроллер модуля ' . $module . ' не найден'); return false; > if(!file_exists($model_path))< $this->errors->set('Модель модуля ' . $module . ' не найдена'); > $controller = new $controller_class; if(method_exists($controller, $action)) < print $controller->$action(); > else < $this->errors->set('Метод ' . $action . ' модуля ' . $module . ' не найден'); return false; > > public function errors()< return $this->errors->get(); > >
5. Класс для вывода ошибок Errors.php
class Errors < public $data = array(); public function set($error) < return $this->data[] = $error; > public function get() < return $this->data; >
class Controller < public $template; public $request; public function __construct()< $this->template = new Template(); $this->request = new Request(); > >
class Model < public $db; public function __construct()< $this->db = new Database(); > >
Все модули (ROOT . ‘/modules/папка_с_модулем’) наследуют главную модель и контроллер.. В главном контролле вызываем шаблонизатор. В главной моделе вызываем подключение к бд собсно.
На примере, папка: modules/test
1. Контроллер: modules/test/Controller.php
2. Модель: modules/test/Model.php
3. Шаблоны модулей (.tpl) хранятся в основной папке шаблона default.class Test_Controller extends Controller < public $test; public function __construct()< parent::__construct(); $this->test= new Test_Model(); > public function index()< $this->template->set('colors', $this->test->get_colors()); return $this->template->display('test.tpl'); > >
class Test_Model extends Model < public function __construct()< parent::__construct(); >public function get_colors() < return array(1 =>'green', 2 => 'red'); > >
Классы Request, Database, Config и прочее описывать не буду, они просты и суть их ясна.
Больше интересует вопрос про саму реализацию!
Все ли я правильно сделал? Ничего ли не забыл? Какие могут быть подводные камни.
Для себя хотелось простого и понятного mvc.
На практике — работает, но хотелось бы услышать комментарии по этому поводу.
И в конце, не посылайте меня к гигантом и прочим yii, symphony, codeigniter .. etcОценить 2 комментария