За последние 24 часа нас посетили 22774 программиста и 1262 робота. Сейчас ищут 732 программиста ...

Шаблоны и подключение неопределенного количества файлов.

Тема в разделе "PHP для новичков", создана пользователем Volt(220), 20 фев 2010.

  1. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Задача:
    Вывести все файлы из дирректории tabs, как вкладки панели вкладок (объект из extJS).

    Решение:
    1)Использовать возможность автоматического создания вкладок
    2)Вывести содержимое файлов в соответствующие <div>:

    main.php
    PHP:
    1. <?php
    2.     function tabsFromFiles($dir){
    3.         tabsFromArrFiles(getPHPFiles($dir));
    4.     }
    5.    
    6.     function tabsFromArrFiles($arr){
    7.         foreach ($arr as $file){
    8.             $name=ucfirst(substr(basename($file),0,-4)); // обрезаем имя папки, расширение и делаем первую букву заглавной
    9.             echo "<div class='x-tab' title='$name'>";
    10.             include($file);
    11.             echo "</div>";
    12.         }
    13.     }
    14.  
    15.     function getPHPFiles($dir){
    16.         return glob($dir."/*.php");
    17.     }
    18.  
    19.     $tpl= new Template("body.tpl");
    20.    
    21.     echo $tpl;
    22. ?>
    body.tpl
    HTML:
    1. <div id="tabDiv">
    2.     <?php tabsFromFiles("tabs");?>
    3. </div>
    4.  
    Вопросы:
    1) Стоит ли заморачиваться на шаблонизацию в функции tabsFromArrFiles? Если да, то как реализовать в шаблоне include($file)?
    2) Стоит ли переделывать вызов tabsFromFiles() в вывод переменной шаблона? Т.е.:
    body.tpl
    HTML:
    1. <div id="tabDiv">
    2.     <?php echo $tabsFromFiles;?>
    3. </div>
    main.php
    PHP:
    1. <?php
    2. ...
    3. $tpl= new Template("body.tpl");
    4. $tpl->tabsFromFiles=tabsFromFiles("tabs");
    5. ...
    6. ?>
    3) Или может стоит вообще решить задачу по другому? Например:
    PHP:
    1. <?php
    2.  
    3. // Создаем массив имен и содержания вкладок
    4. $arrFiles=getPHPFiles("tabs");
    5. foreach($arrfiles as file){
    6.     ob_start();
    7.     include($file);
    8.     $rezArr[]=array(ucfirst(substr(basename($file),0,-4)), ob_get_clean());
    9. }
    10. //Подключаем шаблон и работаем с rezArr
    11. ...
    12. ?>
     
  2. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Volt(220)
    Что будет если файлов в папке пару сотен?
     
  3. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    1) Их будет неудобно просматривать в виде вкладок.
    2) Загрузка страницы будет сильно тормозить. Если вообще сможет загрузиться.
    Только с чего это им там так плодится?
     
  4. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Volt(220)
    Ну тебе виднее :)
    Ты делаешь универсальный компонент? Или конкретное решение?
    Во втором случае почему их(табы-файлы) просто не перечислить где-то в конфиге?
     
  5. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Я решаю конкретную задачу. Однако если я могу сделать универсальное решение малыми силами, то почему нет?

    А что мне это даст? Я опять получу массив с именами файлов, только не через функцию, а вбитый ручками.
     
  6. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Volt(220)
    ? кто-то мешает в конфиг записать яваскрипт?

    Шаблонизацию стоит делать для отдельного файла.
    И затем обрабатывать всех скопом.
    например
    Код (Text):
    1. $arr = array('file1' => 'tpl1', 'file2' => 'tpl2', 'file3' => null);
    можно принять за умолчание что значение пары
    Код (Text):
    1.  '*' => 'defaulttpl'
    применяется ко всем элементам массива, где value = null

    Отдельный общий шаблон (layout) для самой панели с табами тоже можно сделать.

    В общем случае у тебя есть шаблон панели, шаблон(ы) для табов являются подшаблонами.
    Рендер происходит рекурсивно - т.е. ты вызваешь рендер панели, а она в свою очередь вызывает рендер всех элементов внутри себя.
     
  7. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Что-то я не понимаю твою идею...
    У меня есть:
    Шаблоны: Основной шаблон (body.tpl) и шаблоны для каждой вкладки (tpl1, tpl2...)
    Скрипты: Основной скрипт (main.php) и скрипты для вкладок (file1, file2, file3...).
    Ты предлагаешь сопоставить с помощью массива скрипты для вкладок и шаблоны для них?

    И как их обработать скопом? Считать каждый скрипт шаблоном и пропустить через шаблонизатор, тогда это получится нечто вроде варианта кода в вопросе №3.

    UPD:
    Для правильного рендера подшаблонов придется перенести код файлов (тех самых из дирректории tabs) в основной скрипт.
     
  8. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Да. При этом ты можешь просто прописать в значение null и тогда для вкладки будет использоваться дефолтный шаблон.
    Более того в качестве ключей массива, может же быть не только имя файла, а и вообще произвольная строка урл. И тогда у тебя вкладки автоматом можно сделать аяксовыми.

    Ну раз у тебя есть шаблонизатор, то и занимайся реиспользованием кода.

    Тут в другом топике vs приводил свою реализацию шаблонизатора с автоматическим рендеренгом под-шаблонов.
    Как мне кажется - это вполне удобный вариант. При этом мы всегда имеем возможность отренедрить и отдельный подшаблон.
     
  9. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Почему?
     
  10. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Его и использую. =)

    Потому что эти скрипты генерируют нужные переменные для шаблонов.

    Дополним пример выше тремя файлами:
    1) table.tpl - шаблон отрисовки таблицы. Использует ключи и значения массива $tabArr.
    2) auth.php - запрашивает из базы таблицу авторов, формирует массив $tabArr, подключает шаблон table.tpl и выводит его
    PHP:
    1. <?php
    2. $DB=MySQLDB::getDB();
    3. $tabArr=$DB->getTable("select fio, country from authors limit 0,30");
    4. $tpl=new Template("table.tpl");
    5. $tpl->tabArr=$tabArr;
    6. echo $tpl;
    7. ?>
    3) izd.php - аналогичен файлу по авторам, но выполняет запрос к другой таблице.

    соответственно auth.php и izd.php лежат в папке tabs.

    Если не выполнить этих скриптов, то подшаблоны отрендерятся неверно.
    (Кстати, надо еще не забыть проверить что-там с одинаковыми именами переменных будет происходить.)

    Это следующий шаг над которым я буду думать, но сейчас мне хотелось бы довести до конца текущую идею.
     
  11. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Я бы сделал примерно так
    PHP:
    1. <?php
    2. $layout  = new Template('layout.tpl');
    3. $tplAuth = new Template('table.tpl');
    4. $tplIzd  = new Template('table.tpl');
    5. $layout->auth = $tplAuth;
    6. $layout->izd  = $tplIzd;
    7.  
    8. $auth = new Auth();
    9. $izd  = new Izd();
    10. $tplIzd->tabArr  = $izd->getArray();
    11. $tplAuth->tabArr = $auth->getArray();
    12.  
    13. echo $layout;
    Как привинтить тут массив с шаблонами и моделями, и затем подключить все к $layout думаю очевидно.
     
  12. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Можно сделать немного иначе

    PHP:
    1. <?php
    2. $auth = new Auth(new Template('table.tpl'));
    3. $izd  = new Izd(new Template('table.tpl'));
    4.  
    5. $layout->auth = $tplAuth;
    6. $layout->izd  = $tplIzd;
    7.  
    8. echo $layout;
    У моделей Auth, Izd должен быть метод render() и прокси к нему __toString()
    примерно такого содержания
    PHP:
    1. <?php
    2. public function render(Template $tpl = null)
    3. {
    4.     if($tpl) {
    5.         $this->tpl = $tpl;
    6.     }
    7.     $this->tpl->tabArr = $this->getArray();
    8.     return $this->tpl;
    9. }
     
  13. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Т.е главная идея обернуть код в скриптах в классы. Т.е. есть массив, в котором: файл шаблона, имя класса, файл с классом.
    Возможны вариации, типа: вычислять имя класса по имени файла, использовать автозагрузчик, вычислять имя шаблона, и имя класса по имени файла, а массив файлов получать той же самой getPHPFiles.

    Мне приходила в голову идея обернуть код в методы, я не додумал ее до вызова метода по имени в переменной.

    Ну и доводя до конца:
    PHP:
    1. <?php
    2.  $tplAuth = new Template('table.tpl');
    3.  $tplIzd  = new Template('table.tpl');
    4.  
    5.  $auth = new Auth();
    6.  $izd  = new Izd();
    7.  $tplIzd->tabArr  = $izd->getArray();
    8.  $tplAuth->tabArr = $auth->getArray();
    9.  
    10.  // Создаем массив вкладок
    11.  $arrTabs[]=$tplAuth;
    12.  $arrTabs[]=$tplIzd;
    13.  
    14.  $layout  = new Template('layout.tpl');
    15.  $layout->arrTabs= $arrTabs;
    16. ?>
    Иначе придется при добавлении нового файла менять главный шаблон.
     
  14. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    можешь обернуть в функции - не в этом суть :)
    Суть в организации работы так, чтобы все выполнилось тогда, когда это нужно.

    если напишешь автозагрузчик, то файл класса - излишен.

    я просто показал идею, детали реализации - как тебе удобнее
     
  15. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Самое интересное, что конкретных ответов на поставленные вопросы так и не мы так и не написали... =))
     
  16. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Конкретный ответ на поставленный вопрос - это готовое решение :)
    А готовые решения я не люблю бесплатно давать :)

    Но в твоем случае, вполне очевидно, что пошли по 3му варианту