объект инклудящий файлы #2, MVC и как все сделать

snitko

Новичок
объект инклудящий файлы #2, MVC и как все сделать

Возвращаюсь к поднятой вчера теме. Поразмыслил. Пришел к выводу что таки да, единственный способ - это НЕ определять переменные, которые видны за пределами шаблонов. Но для этого нужно как-то переделать обычную архитектуру MVC. Сейчас покажу пример, иллюстрирующий проблему.

В обычном случае при архитектуре MVC мы имеем модель:

PHP:
class Car {
   private $brand;
   function __construct($brand) {$this->brand=$brand;}
   function getListOfModels() {/*implementation*/};
   function getBrand() {return $this->brand;}
}
Контроллер (я для контроллера тоже использую класс, методы которого вызываются в зависимости от запроса пользователя):
PHP:
class ControllerCar {
   function modelist($brand) {
      $car=new Car('BMW');
      include('template.tpl.php');
   }
и Шаблон:

PHP:
So here's model list for <?=$car->getBrand();?>:
<?php foreach($car->getListOfModels() as $element) print $element;?>
И это все будет работать нормально.
Теперь предположим, что мне требуется добавить в шаблон блок, который будет выводить информацию о том залогинен ли пользователь или нет. Я поступаю следующим образом: добавляю в метод modellist() строку, создающую нужный объект:

PHP:
class ControllerCar {
   function modelist($brand) {
      $car=new Car('BMW');
      $user=new User();
      include('template.tpl.php');
   }
А затем внутри шаблона 'template.tpl.php' наверху дописываю:
PHP:
include('/parts/user.tpl.php');
При этом сам user.tpl.php выглядит примерно так:
PHP:
Your status: <?=$user->getStatus();?>
Описанный подход работает хорошо до тех пор, пока мне не потребуется немного усложнить процедуру инклуда. Предположим (в порядке бреда) я хочу писать 'God Loves you!' каждый раз, как что либо инклудится из папки '/parts/'. То есть, нужно было бы сделать что-то типа этого:
PHP:
include('/parts/user.tpl.php');
print 'God Loves you';
но только так, чтобы вторую строчку не пришлось бы писать каждый раз после инклуда.
Вот именно поэтому я спрашивал в предыдущем посте, а нельзя ли сделать объект, который будет инклудить шаблоны и при этом выполнять еще некоторые действия. Из-за проблем с областью видимости, придется, видимо, как-то переделать архитектуру. Вопрос в том - как?

Надеюсь достаточно подробно и понятно изложил. Буду благодарен за ответы.
 

zerkms

TDD infected
Команда форума
контроллер не должен сам ничего выводить

Вот именно поэтому я спрашивал в предыдущем посте, а нельзя ли сделать объект, который будет инклудить шаблоны и при этом выполнять еще некоторые действия.
вот и реализуй класс, работающий с шаблонами и данными в шаблонах
 

snitko

Новичок
zerkms, чуть более подробно было бы кстати. Как ты себе представляешь работу такого класса?

-~{}~ 13.08.07 02:04:

контроллер не должен сам ничего выводить
Мой подход - калька с Rails. Там по запросу к, например /car/modellist/ как раз вызывается Car::modellist(); Правда инклуд шаблона там происходит как-то иначе - не из контроллера. Ты это имеешь в виду?
 

zerkms

TDD infected
Команда форума
хм....
согласно твоим требованиям:

Предположим (в порядке бреда) я хочу писать 'God Loves you!' каждый раз, как что либо инклудится из папки '/parts/'
PHP:
class view
{
public function display()
{
...
if (strpos($tpl_name, '/parts')) { echo 'god loves you'; }
}
}
м?
 

snitko

Новичок
zerkms, то есть я тогда пишу примерно так:

PHP:
$view->display($template);
ну а где инклудится сам шаблон? Если в методе display() выше, то $user->getStatus() уже будет вне области видимости. опять вернулись к исходной проблеме из топика по ссылке.
 

snitko

Новичок
Ты, извини, если я туплю, но хотелось бы узнать что же будет делать assign() и как? Пока не уловил идею.
 

snitko

Новичок
Я тут глянул в книжку по Рэйлс, там похожая задача решается примерно таким образом: прямо в шаблоне вызывается специальный метод, аргументами которого являются желаемый контроллер, метод и его аргументы (if any). То есть примерно вот так:
PHP:
$this->invoke('User', 'getStatus');
А дальше в getStatus() опять происходит include() нужного шаблона '/parts/user.tpl.php' и так далее.

Вопрос в том, действительно ли это удобно. Пока в сомнении. Может быть оставить include() и забить.
 

HraKK

Мудак
Команда форума
А слабо посмотреть существующий Template Engine? например Смарти ? Я думаю там Вы найдете ответы на все ваши вопросы.
 

snitko

Новичок
В принципе слабо, да. Потому что времени очень мало и решение нужно очень быстро. В принципе, думаю я его нашел в Рэйлс, т.к. знаком с ним лучше чем со Смарти.
 

kostya.sys

Новичок
не путайте рельсы с пхп
рельсы основаны на метапрограммировании, тоесть конечный код преобразуется нечто другое
это позволило скрыть очень многое
в том числе и вызов шаблона из экшена контроллера
если он не указан, то рельсы будут искать шаблон совпадающий по имени.

mvc призвано четко разделить логику на 3 части, а все пытаются эту логику перемешать, в итоге получается полная каша.

в моей системе контроллеры разделены на 2 типа (лоадеры и экшены)

лоадер обробатывает данные запроса, обращается к моделям, определяет какой шаблон вызывать, он и подготавливает данные

при этом в шаблоне есть возможность вызвать экшн.

к примеру у констроллера публикаций есть лоадер view_article
он подготавливает данные, грузит шаблон
а в шаблоне уже вызываются блоки списка последных статей, меню и тд
 
при этом в шаблоне есть возможность вызвать экшн.

тоесть твои шаблоны с другим контроллером использовать нельзя?

-~{}~ 16.08.07 17:43:

в твоей системе бизнес объекты перемешаны с контроллерами и шаблонами?
 

kostya.sys

Новичок
шаблоны тоже бывают разные
есть общая тема
а есть маленький списочек

а вот бизнес объекты это чтото новое
есть бизнес логика, в идеале она в модели, но задачи бывают разные, я не любитель натягивать чтото за уши чтоб засунуть в модель.
MVC это всего лишь один из многих вариантов архитектуры, постоянно идти одниму путем глупо и скучно. У программиста по сути одна задача - уйти от сложности, сделать решение максимально очевидным и простым. И это касается всего как конечного продукта так и исходных кодов конечного продукта.

-~{}~ 16.08.07 18:03:

забыл добавить
результатом работы лоадера или экшена является хтмл
 

kpp

Новичок
PHP:
class tpl{

	var $template;

	function tpl($template){
		$this->template=$template;
						}

	function replace($tdf){
		$result = $this->template ;

				foreach($tdf as $var=>$value)
				{
						$pat = '{{' .$var. '}}' ;
						   if (is_array ($value))
						     $repl = join ("\n", $value) ;
						   else
						     $repl = strval ($value) ;
						   $result = str_replace ($pat, $repl, $result) ;
				}
		$result=eval("?>$result");		
		
		return $result;
		}



}






$tpl=new tpl($tpl_text);

$tdf=array();
$tdf['title'] = $title;
$tdf['content'] = $content;

echo $tpl->replace($tdf);

Вот то, что тебе нужно.
 
kostya.sys
ну так вот, у тебя есть бизнес объект НОВАСТИ, и есть бизнес объект НЕНОВАСТИ, и они посути практически одинаковые, и чтобы вывести "маленький списочек" из title/contents можно воспользоваться одним и тем же шаблоном. В твоем случае это копипаст?

-~{}~ 16.08.07 19:28:

kpp
<?php echo $tdf['title']; ?> вот все что тебе нужно ;)
 

kpp

Новичок
<?php echo $tdf['title']; ?> вот все что тебе нужно
Это типа я лол такой? А если серьёзно, у меня в админке только "тайтл" вставляется и "контент". Этого мало? Админкой пользоваться должны любые незнающие РНР люди. Человек ставит {{title}}
и {{content}} в шаблон и всё. А портом уже в админке может на эти места вписывать что угодно и называть новым именем страницу. В принципе это не смертельно, если только тайтл и контент? Можно ещё дискрипшн вставить, конечно, для поисковиков.
 
kpp
ацкая админка. а если сделать str_replace(array('{{', '}}'), array('<?php echo $tp["', '"];?>'), $blah); ?
 

kpp

Новичок
В принципе не сомневался, что скажут "Ацкая", "Х***я" и т.п.
Да всё работает. То, что я написал выше сейчас работает на 5-7 сайтах (1 сайт и несколько поддоменных...3 уровня)
Всё работает отлично, только там всё без админки, руками ставятся параметры замены, то есть хэш, там в несколько мест идёт замена, а не в 2 как у меня.

Есть что сказать в адрес этог7о способа? По мне это единственный нормальный способ.. им на мой взгляд все и пользуются ))))
 
Сверху