Smarty – не просто шаблоныВступлениеСкажем сразу, этот материал не будет вас учить пользоваться базовыми возможностями данной библиотеки. Напротив, я капну гораздо глубже. Цель этого материала взглянуть на шаблонизатор Smarty с другой стороны, и увидеть в нем не просто очень удобный и мощный шаблонный движек, а некий фреймворк для разработки ваших приложений. Часто, говоря о Smarty, незаслуженно обвиняют его в низкой производительности и «тормознутости», что ж – автор данного материала с указанными товарищами не согласен. Напротив, раз уж мы приняли решение использовать в своем приложении эту библиотеку, я предлагаю вам на полную катушку задействовать ее возможности, отдав на откуп шаблонизатору как вывод информации пользователю, так и управление этой информацией. Компонентная модель Одна из сильных сторон Smarty – это возможность создавать свои плагины и расширения. Воспользуемся этой его возможностью в полной мере и попробуем реализовать на ее основе компонентную модель сайта. Что такое в нашем понимании компонент? Под компонентом я буду подразумевать обособленный блок сайта, который умеет выполнять строго определенный набор действий и, в результате своей работы, либо выводить что-либо на экран, либо готовить какие-то данные для других компонентов. Компонент – это элемент сайта, который, во-первых, точно знает какие действия он может совершать, во-вторых, какие библиотеки для совершения этих действий ему нужны. В результате сайт будет состоять из ядра - набора библиотек (классов), которые содержат в себе какие-то низкоуровневые действия, например работают с базой, – и компоненты, которые подключают эти библиотеки и, в нужном порядке, вызывают те или иные их методы. В чем положительная сторона такого подхода? вы пишите специальные классы (объекты) ядра своего сайта, они никак не зависят от вывода на экран, а просто подготавливают и обрабатывают данные, тем самым обеспечивается высокая переносимость кода и возможность его повторного использования; в случае командной работы, вам не надо заботиться о том, что делает соседний программист, который пишет свой компонент; стандартизация кода – вы можете создать интерфейс компонента и строго следовать его требованиям, что позволит одному программисту легко разобраться в компоненте другого программиста. Это основные преимущества данного подхода. Общие классы Безусловно, в каждом приложении есть набор классов, которые нужны всем, или большинству компонентов, например, класс для работы с базой. Как поступить в таком случае? И для этой проблемы в Smarty есть удачное решение. Впрочем, давайте по порядку. Сначала инициализируем класс Smarty:<?php /** Путь до Smarty */ define ( 'SMARTY_DIR' , '/smarty/' ); /** Путь до Smarty шаблонов */ define ( 'TEMPLATES' , '/templates/' ); /** Путь до Smarty компилированных шаблонов */ define ( 'TEMPLATES_C' , '/templates_c/' ); require_once( SMARTY_DIR . 'Smarty.class.php' ); $smarty = new Smarty; $smarty -> compile_check = TRUE; $smarty -> force_compile = TRUE; $smarty -> template_dir = TEMPLATES; $smarty -> compile_dir = TEMPLATES_C; $smarty -> plugins_dir [] = LIBS_PATH; $smarty -> caching = FALSE; ?> Итак, Smarty готов к работе. Что необходимо сделать с общими классами, чтобы обеспечить доступ к ним внутри любого компонента? Скажем, у нас есть несколько общих компонентов: adodb – класс для работы с базой; session – класс для работы с сессиями; errors – класс для обработки ошибок; variables – класс для хранения и обработки состояния массивов $_GET и $_POST. Первым делом, нам необходимо создать объекты данных классов (параметры конструкторов зависят от вашей конкретной реализации). В целом, это делается стандартным образом:<?php require_once( CLASSES_DIR . '/variables.class.php' ); $vars = new Variables (); require_once( CLASSES_DIR . '/errors.class.php' ); $errors = new Errors ( $smarty ); require_once( CLASSES_DIR . '/security.class.php' ); $security = new Security ( $adodb ); // и так далее... ?> Объекты созданы и теперь необходимо обеспечить доступ к ним в любом компоненте нашего приложения. Для этого необходимо зарегистрировать данные объекты в Smarty:<?php $smarty -> register_object ( 'adodb' , $adodb ); $smarty -> register_object ( 'vars' , $vars ); $smarty -> register_object ( 'errors' , $errors ); $smarty -> register_object ( 'security' , $security ); ?> Для регистрации объектов мы используем метод Smartyregister_object(). После чего ваш объект станет доступным везде, где он может понадобиться. Как «достать» нужный вам зарегистрированный объект мы рассмотрим в следующей части. Функция «Компонент» К текущему моменту Smarty ничего не знает о каких-либо компонентах, и нам нам надо научить его работать с ними. Для этого мы добавляем к синтаксису шаблонов новый тег – {component}. Чтобы Smarty научился обрабатывать этот тег – пишем простую функцию:<?php // Smarty function Component // // @author Feskov Kuzma function smarty_function_component ( $params , & $smarty ) { $adodb = & $smarty -> get_registered_object ( 'adodb' ); $vars = & $smarty -> get_registered_object ( 'vars' ); $errors = & $smarty -> get_registered_object ( 'errors' ); $security = & $smarty -> get_registered_object ( 'security' ); if (empty( $params [ 'name' ])) { $params [ 'name' ] = 'site_view'; } if ( is_file ( ADMIN_LIBS_PATH . '/' . $params [ 'name' ] . '.component.php' )) { require( ADMIN_LIBS_PATH . '/' . $params [ 'name' ] . '.component.php' ); } else { echo 'Component ' . $params [ 'name' ] . ' not found'; } unset( $adodb , $errors , $security , $vars ); } ?> Давайте разберемся, что делает данная функция. Во-первых, она создает обработчик для нового тега – {component}, во-вторых, достает (get_registered_object()) и делает доступными вызванному компоненту зарегистрированные ранее общие объекты. Немножко теории. Чтобы вызвать данную функцию к жизни, необходимо в любом шаблоне написать тэг {component}. Поскольку функция не выполняет никаких продуктивных действий, и служит исключительно диспетчером компонентов, просто написать {component} недостаточно, поскольку эта команда неинформативна. Конечно, функция не даст сбоя, и запустит принятый по умолчанию компонент 'site_view'. Каким образом уточнить, какой именно компонент вам требуется и как передать ему дополнительные параметры? Все очень просто, мы несколько измени вызов компонента в шаблоне:{component name='имя требуемого компонента' var1='значение параметра' var2='значение другого параметра'} И так далее, как вы понимаете, name, var1, var2 – это дополнительные параметры для нашего компонента. Name, например, указывает имя компонента, который мы хотим вызвать, а остальные параметры – это дополнительные данные для вызываемого компонента, их количество может быть любым, ровно как и их имена. После того, как в шаблоне встретится указанный выше тег, произойдет вызов нашей функции, которая, в свою очередь, вызовет нужный вам компонент. Все дополнительные параметры будут доступны как в нашей функции так и в вызываемом компоненте, они будут содержаться в массиве $params, где ключ – это название параметра, а значение – соответственно – его значение. Вступление Скажем сразу, этот материал не будет вас учить пользоваться базовыми возможностями данной библиотеки. Напротив, я капну гораздо глубже. Цель этого материала взглянуть на шаблонизатор Smarty с другой стороны, и увидеть в нем не просто очень удобный и мощный шаблонный движек, а некий фреймворк для разработки ваших приложений. Часто, говоря о Smarty, незаслуженно обвиняют его в низкой производительности и «тормознутости», что ж – автор данного материала с указанными товарищами не согласен. Напротив, раз уж мы приняли решение использовать в своем приложении эту библиотеку, я предлагаю вам на полную катушку задействовать ее возможности, отдав на откуп шаблонизатору как вывод информации пользователю, так и управление этой информацией. Компонентная модель Одна из сильных сторон Smarty – это возможность создавать свои плагины и расширения. Воспользуемся этой его возможностью в полной мере и попробуем реализовать на ее основе компонентную модель сайта. Что такое в нашем понимании компонент? Под компонентом я буду подразумевать обособленный блок сайта, который умеет выполнять строго определенный набор действий и, в результате своей работы, либо выводить что-либо на экран, либо готовить какие-то данные для других компонентов. Компонент – это элемент сайта, который, во-первых, точно знает какие действия он может совершать, во-вторых, какие библиотеки для совершения этих действий ему нужны. В результате сайт будет состоять из ядра - набора библиотек (классов), которые содержат в себе какие-то низкоуровневые действия, например работают с базой, – и компоненты, которые подключают эти библиотеки и, в нужном порядке, вызывают те или иные их методы. В чем положительная сторона такого подхода? вы пишите специальные классы (объекты) ядра своего сайта, они никак не зависят от вывода на экран, а просто подготавливают и обрабатывают данные, тем самым обеспечивается высокая переносимость кода и возможность его повторного использования; в случае командной работы, вам не надо заботиться о том, что делает соседний программист, который пишет свой компонент; стандартизация кода – вы можете создать интерфейс компонента и строго следовать его требованиям, что позволит одному программисту легко разобраться в компоненте другого программиста. Это основные преимущества данного подхода. Общие классы Безусловно, в каждом приложении есть набор классов, которые нужны всем, или большинству компонентов, например, класс для работы с базой. Как поступить в таком случае? И для этой проблемы в Smarty есть удачное решение. Впрочем, давайте по порядку. Сначала инициализируем класс Smarty:<?php /** Путь до Smarty */ define ( 'SMARTY_DIR' , '/smarty/' ); /** Путь до Smarty шаблонов */ define ( 'TEMPLATES' , '/templates/' ); /** Путь до Smarty компилированных шаблонов */ define ( 'TEMPLATES_C' , '/templates_c/' ); require_once( SMARTY_DIR . 'Smarty.class.php' ); $smarty = new Smarty; $smarty -> compile_check = TRUE; $smarty -> force_compile = TRUE; $smarty -> template_dir = TEMPLATES; $smarty -> compile_dir = TEMPLATES_C; $smarty -> plugins_dir [] = LIBS_PATH; $smarty -> caching = FALSE; ?> Итак, Smarty готов к работе. Что необходимо сделать с общими классами, чтобы обеспечить доступ к ним внутри любого компонента? Скажем, у нас есть несколько общих компонентов: adodb – класс для работы с базой; session – класс для работы с сессиями; errors – класс для обработки ошибок; variables – класс для хранения и обработки состояния массивов $_GET и $_POST. Первым делом, нам необходимо создать объекты данных классов (параметры конструкторов зависят от вашей конкретной реализации). В целом, это делается стандартным образом:<?php require_once( CLASSES_DIR . '/variables.class.php' ); $vars = new Variables (); require_once( CLASSES_DIR . '/errors.class.php' ); $errors = new Errors ( $smarty ); require_once( CLASSES_DIR . '/security.class.php' ); $security = new Security ( $adodb ); // и так далее... ?> Объекты созданы и теперь необходимо обеспечить доступ к ним в любом компоненте нашего приложения. Для этого необходимо зарегистрировать данные объекты в Smarty:<?php $smarty -> register_object ( 'adodb' , $adodb ); $smarty -> register_object ( 'vars' , $vars ); $smarty -> register_object ( 'errors' , $errors ); $smarty -> register_object ( 'security' , $security ); ?> Для регистрации объектов мы используем метод Smartyregister_object(). После чего ваш объект станет доступным везде, где он может понадобиться. Как «достать» нужный вам зарегистрированный объект мы рассмотрим в следующей части. Функция «Компонент» К текущему моменту Smarty ничего не знает о каких-либо компонентах, и нам нам надо научить его работать с ними. Для этого мы добавляем к синтаксису шаблонов новый тег – {component}. Чтобы Smarty научился обрабатывать этот тег – пишем простую функцию:<?php // Smarty function Component // // @author Feskov Kuzma function smarty_function_component ( $params , & $smarty ) { $adodb = & $smarty -> get_registered_object ( 'adodb' ); $vars = & $smarty -> get_registered_object ( 'vars' ); $errors = & $smarty -> get_registered_object ( 'errors' ); $security = & $smarty -> get_registered_object ( 'security' ); if (empty( $params [ 'name' ])) { $params [ 'name' ] = 'site_view'; } if ( is_file ( ADMIN_LIBS_PATH . '/' . $params [ 'name' ] . '.component.php' )) { require( ADMIN_LIBS_PATH . '/' . $params [ 'name' ] . '.component.php' ); } else { echo 'Component ' . $params [ 'name' ] . ' not found'; } unset( $adodb , $errors , $security , $vars ); } ?> Давайте разберемся, что делает данная функция. Во-первых, она создает обработчик для нового тега – {component}, во-вторых, достает (get_registered_object()) и делает доступными вызванному компоненту зарегистрированные ранее общие объекты. Немножко теории. Чтобы вызвать данную функцию к жизни, необходимо в любом шаблоне написать тэг {component}. Поскольку функция не выполняет никаких продуктивных действий, и служит исключительно диспетчером компонентов, просто написать {component} недостаточно, поскольку эта команда неинформативна. Конечно, функция не даст сбоя, и запустит принятый по умолчанию компонент 'site_view'. Каким образом уточнить, какой именно компонент вам требуется и как передать ему дополнительные параметры? Все очень просто, мы несколько измени вызов компонента в шаблоне:{component name='имя требуемого компонента' var1='значение параметра' var2='значение другого параметра'} И так далее, как вы понимаете, name, var1, var2 – это дополнительные параметры для нашего компонента. Name, например, указывает имя компонента, который мы хотим вызвать, а остальные параметры – это дополнительные данные для вызываемого компонента, их количество может быть любым, ровно как и их имена. После того, как в шаблоне встретится указанный выше тег, произойдет вызов нашей функции, которая, в свою очередь, вызовет нужный вам компонент. Все дополнительные параметры будут доступны как в нашей функции так и в вызываемом компоненте, они будут содержаться в массиве $params, где ключ – это название параметра, а значение – соответственно – его значение. Источник: i-faq.ru |
КОНТАКТЫ
г. Екатеринбург info@vismech.ru |
текущее: НОВОСТИ 05.12.2013 - Уход за флэш-накопителем 05.12.2013 - Компьютер самопроизвольно выключается 05.12.2013 - Почему не запускается компьютер? 27.11.2013 - Canon Legria HF R406 - Описание видеокамеры 27.11.2013 - TravelMate P645 новый лэптоп бизнес-класса от Acer |