[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Курсы PHP. Урок №5 от IRBIS-team
twin
Если ты тут впервые, прочитай это!!!

Урок здесь



Спустя 1 день, 5 часов, 19 секунд (27.11.2009 - 19:56) levitaly написал(а):
Скажите мы используем в SQL обратные кавычки `, это для чего-то обязательно или просто стиль?

Спустя 2 часа, 46 минут, 24 секунды (27.11.2009 - 22:43) VolCh написал(а):
levitaly Хорошая привычка ставить такие кавычки везде, чем каждый раз думать обязательны они тут или нет (а главное, в конце-концов где-нибудь да забудешь поставить rolleyes.gif и потом полдня дебажить wacko.gif )

Хозяин Огня Даже с именами таблиц/полей из русских букв , разделенных пробелами? Или даже просто, например, в таблицу into вставь данные wink.gif

Спустя 10 дней, 14 часов, 9 минут, 54 секунды (8.12.2009 - 12:53) Хозяин Огня написал(а):
Домашка:
Ссылка на галерею:
<a href="<?php echo href('mod=gallery','rem=show'); ?>"><?php echo $language['gallery']; ?></a>


modules\gallery\index.php:
/**
* The switch of modules
* Переключатель модулей
*/


$rem = preg_replace('#[^a-z0-9_]+#i', '', $GET['rem']);
$path = ROOT .'/modules/gallery/'. $rem .'_controller.php';

if (file_exists($path))
{
include ($path);
}
else
{
header("HTTP/1.1 404 Not Found");
exit(file_get_contents(ROOT .'/404.html'));

}

/**
* The switch of templates
* Переключатель шаблонов
*/

$tpl = ROOT .'/skins/tpl/gallery/'. $rem .'.tpl';
if (file_exists($tpl))
include ($tpl);
else
exit('The template <b>'. $tpl .'</b> is absent in the specification');


modules\gallery\show_controller.php:
$tpl = getTpl('gallery/fotoes');
$data['hello'] = 'Hello world';
$fotoes = parseTpl($tpl,$data);

\skins\tpl\gallery\fotoes.tpl

<!-- ./skins/news/read.tpl begin -->
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<?php
echo $hello; ?>
</table>

<!-- ./skins/news/read.tpl end -->


\skins\tpl\gallery\show.tpl
<!-- ./skins/news/read.tpl begin -->
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<?php
echo $fotoes; ?>
</table>

<!-- ./skins/news/read.tpl end -->


Выводит "Привет мир".
Вопрос - функции для работы с файлами и каталогами будем выносить в отдельный файл, подобно mysql.php?

Спустя 17 минут, 45 секунд (8.12.2009 - 13:11) twin написал(а):
Так. Немного невнимательно прочитал это место:
Цитата
Запомните три правила.
1. Не используйте этот шаблонизатор, если требуется всего одно включение шаблона. Инклюд будет быстрее.
...
...

Что бы посмотреть как работает, конечно пойдет. Но лучше тогда было циклик организовать для наглядности. А статику инклюдом вывести.
А вообще норм. Красиво. smile.gif

Спустя 3 дня, 10 часов, 10 минут, 29 секунд (11.12.2009 - 23:21) VolCh написал(а):
twin, по-моему, исходя как раз из этих соображений и надо делать как-то более обще что-ли. Одному дал задание написать контролер, который даёт в итоге, например, массив $data, другому дал задание сверстать из графического дизайна (.psd например) html файл (если он ничего больше не умеет и в нашей системе не шарит), ну а третьему поручил в шаблоне (или еще где, но не в контроллере, которым занимается первый) сделать из html полноценный шаблон, который с нуля принимает $data (в нашем случае со всеми новостями) и выдает полный html. Чтобы не пересекались области ответственности, чтобы не редактировали один и тот же файл несколько человек.
Цитата
В принципе нам осталось два момента (два урока) - работа с внешними данными и библиотека общих полезных функций.

Цитата
Просто тут пока элементарные примеры, чтоб сильно не грузить. А вообще view.php как раз для этого и нужен.

По-моему, третий урок с полным отделением бизнес-логики от логики отображения нужен обязательно. Тема, по-моему, достаточно обширная, чтобы посвятить ей отдельный урок

Спустя 18 минут, 48 секунд (11.12.2009 - 23:40) twin написал(а):
На самом деле это голая теория. Никогда никто не делит на 100% бизнесс-логику и отображение. Это идея фикс, просто модное течение. Не сможет ни один человек написать полноценный контроллер, не проверив его в боевых условиях. А по сему, хочет он или нет, ему придется делать вывод. И шаблон естественно.
Вот тут и точка соприкосновения. Я вот лично не вижу особого смысла вытаскивать формирование массива данных для шаблонизатора в отдельную структуру (view тот же самый). В файле, отвечаюшим за вывод на мой взгляд должно быть распределение шаблонов и предварительная подготовка переменных вывода, коли они в ней нуждаются. А само формирование спокойно( и проще) можно делать и в контроллере. Что собственно и сделано в примере. Иначе прдется формировать лишний массив, непонятно ради чего... Ради моды и доктрины тут не катит, тут все опирается на здравый смысл, а не штампы.
По этому и не стал сильно акцентироваться. Программист по долгу службы обязан уметь сделать вывод в шаблон. А как бантики ему навешать - задача верстальщика. И нет меж ними прокладки.
Есть голый вывод рабочего модуля и есть верстка страницы. Осталось их собрать в кучу.

Спустя 21 час, 22 минуты, 50 секунд (12.12.2009 - 21:03) aparion написал(а):
Вот попробовал написать что-то похожее на галерею.

Спустя 15 минут, 51 секунда (12.12.2009 - 21:19) Хозяин Огня написал(а):
Цитата
Переменные не могут называться цифрами и начинаться с цифры.


Вот вот.)

twin, попытался сделать галерею (пока только вывод) посмотри плиз, в чём ошибка:

/**
* News line generation
* Генерация cтраницы галереи
*/

$tpl = getTpl('gallery/fotoes');
var_dump($tpl);

if (is_dir(GALLERY))
{
if ($dir = opendir(GALLERY))
{
while ($file = readdir($dir))
{
if ($file !="." && $file !="..")
{
$images[] = $file;
}
}

closedir($dir);
}
else echo 'Cant open directory';
}
else echo 'This is not directory';

#var_dump($images);
$amount = count($images);
$pages = ceil($amount/MAX_FOTOES);

$p = $_GET['page'];

if (!$p OR $p=='')
{
$nmin = 0;
$nmax = MAX_FOTOES - 1;
}
else
{
$nmin = ($p * MAX_FOTOES) - MAX_FOTOES;
$nmax = (MAX_FOTOES * $p) - 1;
}
# Вывод фотографий
for ($i = $nmin; $i <= $nmax; $i++)
{
if ($images[$i])
{
$foto = GALLERY.'/'.$images[$i];
#print_r($foto);
echo '<br>';
$fotoes .= GparseTpl($tpl, $foto);
print_r($fotoes);
}
}


GparseTpl:
    function GparseTpl($cont, $foto)
{
print_r($cont);
preg_match_all("#<\?php(.*?)\?>#uis", $cont, $code);
$count = count($code[0]);
if($count)
for($i = 0; $i < $count; ++$i)
{
ob_start();
eval($code[1][$i]);
$echo = ob_get_contents();
ob_end_clean();
$cont = str_replace($code[0][$i], $echo, $cont);
print_r($cont);
}

return $cont;
}


fotoes.tpl
<!-- ./skins/gallery/fotoes.tpl begin -->
<hr>
<a
href="<?php echo $foto; ?>">
<img
style="border:0px blue dashed; width:160px; height:120px;" src="<?php echo $foto; ?>"/>
</a>
  
<!-- ./skins/gallery/fotoes.tpl end -->


show.tpl
<!-- ./skins/gallery/show.tpl begin -->
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<?php
echo $fotoes; ?>
</table>

<!-- ./skins/gallery/show.tpl end -->


Cейчас выводит только string(239) " " ($tpl)
и кучу линий (<hr>, см. fotoes.tpl)

Спустя 1 час, 12 минут, 37 секунд (12.12.2009 - 22:31) twin написал(а):
aparion
Незачет.
<?php ##Показ первой картинки в каталоге и ссылки на остальные

/**
* Generation of page of an error at access out of system
* Генерация страницы ошибки при доступе вне системы
*/

if(!defined('KEY'))
{
header("HTTP/1.1 404 Not Found");
exit(file_get_contents('../../404.html'));
}

echo 'Для просмотра изображения в полную величину щелкните по нему .<br>';

$tpl=getTpl('gallery/allread');

foreach($images as $key=>$im)
{
$key++;
$data['img_adr'].='<a href='.href("mod=gallery","rem=read","id=$key").'>['.($key).']</a> ';
}

$data['gead_img']=$images[$id-1];

$data['full_image']=href('mod=gallery','rem=full','id='.($id));
$img=parseTpl($tpl,$data);

?>


1. Стиль. Отступа нет, операторы не отделяются пробелом, закрывающий дескриптор не нужен. Комментарий не по стандарту.
Посмотри, как это должно было быть:
Свернутый текст
<?php

/**
* The controller of a conclusion of photos
* Контроллер вывода фотографий
*
@author IT studio IRBIS-team
*
@copyright © 2009 IRBIS-team
*/
/////////////////////////////////////////////////////////

/**
* Generation of page of an error at access out of system
* Генерация страницы ошибки при доступе вне системы
*/

if(!defined('KEY'))
{
header("HTTP/1.1 404 Not Found");
exit(file_get_contents('../../404.html'));
}

/**
* Generation of page with small photo
* Генерация страницы с превью
*/

echo 'Для просмотра изображения в полную величину щелкните по нему .<br>';

$tpl = getTpl('gallery/allread');

foreach($images as $key => $im)
{
$key++;
$data['img_adr'] .= '<a href='. href("mod=gallery", "rem=read", "id=$key") .'>['. $key .']</a> ';
}

$data['gead_img'] = $images[$id - 1];

$data['full_image'] = href('mod=gallery','rem=full','id='. $id );
$img = parseTpl($tpl, $data);


2. Никакой вывод не допустим в скриптах. echo допускается только в шаблонах. В скриптах только для отладки.

3. Функция getImages() используется только в галерее и причем только в одном контроллере. Вот там ей и место, не нужно помещать её в дефолтные. В дефолтных только те функции, которые используются на многих страницах.

4. Сообщения дебаггинга
exit ('В директории '.$path.' не найдено изображений.');

только на английском нужно писать. Это норма.



А вообще прицип усек, молодец. smile.gif

Спустя 2 часа, 11 минут, 24 секунды (13.12.2009 - 00:43) twin написал(а):
Хозяин Огня
Так а ты зачем то убрал разбор массива...
Вот так надо ведь (в свете последних поправок):
/**
* Function of analysis of a template
* Функция разбора шаблона
*/

function parseTpl($cont, $data)
{
extract($data);

preg_match_all("#<\?php(.*?)\?>#uis", $cont, $code);

$count = count($code[0]);

if($count)
for($i = 0; $i < $count; ++$i)
{
ob_start();
eval($code[1][$i]);
$echo = ob_get_contents();
ob_end_clean();
$cont = str_replace($code[0][$i], $echo, $cont);
}

return $cont;
}

Спустя 10 часов, 6 минут, 12 секунд (13.12.2009 - 10:49) aparion написал(а):
Немного исправил согласно замечаниям. А getImages располагал в дефолтных потому что хотел использовать в нескольких контроллерах, а потом забыл переместить. Сейчас исправил.

Спустя 1 день, 3 часа, 15 минут, 42 секунды (14.12.2009 - 14:04) twin написал(а):
aparion
Цитата
Немного исправил согласно замечаниям.

Зря немного. Надо было все исправить. smile.gif
По стилю - это важно. Мы будем писать разные модули одного сайта и по этому стиль должен быть один. Вот я переписал функцию, найди отличия.
/**
* Reads images from a special folder
* Считаывание изображений из специальной директории
*/

function getImages($path)
{
if(($dir = opendir($path)) === false)
exit ('Path not found');

while(($file = readdir($dir))!== false)
{
if($file !== '.' && $file !== '..' && is_file(ROOT.'/files/images/'. $file) && preg_match('/\.(jpe?g|png|gif)$/i', $file))
$data[] = HOST.'files/images/'. $file;
}

if(count($data))
return $data;
else
{
exit ('In a directory <b>'. $path .'</b> is not found of the images.');
return false;
}
}

Обрати внимание на пробелы у операторов (=, < и т.д.), на названия переменных (не пиши $d или $e), английский комментарий (мы русские потом убирать будем), на расположение фигурных скобок.
Вообще по стилю почитай здесь.

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

Спустя 4 часа, 22 минуты, 20 секунд (14.12.2009 - 18:27) Хозяин Огня написал(а):
twin
Сорри, надо было сразу rolleyes.gif

Спустя 22 часа, 2 минуты, 56 секунд (15.12.2009 - 16:30) A.V. написал(а):
twin,

в libs\mysql.php по-моему было исправлено название функции mysqlQuery. Или нет? В аттаче к 6-му уроку таки есть.

И ещё. Таблица (irbis_gallery по аналогии с irbis_news?) какую структуру должна иметь?
Я пробую сделать галерею, используя такую:
CREATE TABLE `irbis_gallery` (
`id` int(11) NOT NULL auto_increment,
`file` tinytext NOT NULL,
`date` timestamp NOT NULL,
`text` text,
PRIMARY KEY (`id`)
)
ENGINE=MyISAM DEFAULT CHARSET=utf8;


Поле file - для хранения пути к файлу на сервере. Кстати, в каком месте изображения должны храниться? Насколько я понимаю, skins\images - для "рабочих" файлов, так?

Спустя 9 часов, 48 минут, 22 секунды (16.12.2009 - 02:18) AmberLEX написал(а):
Не знаю даже, вникал-вникал, попробую выразить мысль на счет шаблонов, только сильно не ругайте)
Вы предлагаете в принципе вариант нативного пассивного шаблона (лишенный логической составляющей)

Верстальщик делает весь статичный сайт в html виде с подключенными css и js (и 3 файла)
Например запустив index.html - я вижу как будет выглядеть главная страница.
Запустив news_all.html - я вижу как будет выглядеть страница с новостями и постраничка.
Запустив news_one.html - как выглядит страница с новостью и комментариями.

Т.е. я режу и получаю, грубо говоря: header, footer, menu и content.
Динамичны здесь, допустим, только:
1. список новостей и постраничка в news_all.html;
2. новость и комменты в news_one.html

Что делается в контроллере для модуля новостей:
- передаю $title, $keywords, $description, ($url, $link ?);
- текущую страницу $page и количество страниц $pages;
- массив новостей $news

В шаблоне примерно так (ну header, footer, menu и постраничку я отбросил):
<?php if (is_array($news)): ?>

<table>

<?php
foreach ($news as $key => $val): ?>
<tr>
<td><?php
echo $val['date']; ?></td>
<td><?php
echo $val['subtitle']; ?></td>
<td><?php
echo $val['text']; ?></td>
<a
href="<?php echo $url; ?>"><?php echo $link; ?></a>
</tr>
<?php
endforeach; ?>

</table>

<?php
include "файл шаблона постранички в этом же роде" ?>

<?php
else: ?>

<p>
Новостей нет</p>

<?php
endif; ?>

(Если подсветку кода в редакторе нормальная, то очень даже читабельно выходит, смесь htlm и php все равно в шаблонах будет)
Шаблон для news_one.html - примерно тоже. Сама новость и инклюдится шаблон комментов.

Что мы имеем:
- Верстальщик сделал все в html и забыл;
- ему не нужно париться как и че резать и какие данные входные и какая там логика;
- Для меня не составит труда разделить на части этот html, зачем это объяснять верстальщику;
- получился синтаксис - нативней и быстрее некуда (кажись), чего и добивались;
- шаблон самой новости в одном файле и не нужно размельчать на части и логика не так уж все усложнила, а ее все равно придется где-то делать;
- отпадает потребность в функции parseTpl которая вызывается в цикле while в которой есть preg_match_all, цикл for и str_replace;
- отпадает потребность во view.php, я еще не знаю че там будет даже smile.gif
- В принципе вся логика в шаблоне это if и циклы foreach.

Для среднего сайта мне кажется, этого вполне достаточно. Ну т.к. Вы еще не закончили с уроками, то как будет удобнее верстальщику и сколько человек будет работать над проектом, и как это будет все распределено, то рано, наверное, об этом говорить. Или примерно за ранее определиться, что бы потом путаницы меньше было (просто я не очень вижу целостную картину как это на практике будет sad.gif ).

Если работать верстальщику и программисту, то на своем примере могу сказать, что сайт с галлереей, фотокункурсом(типа можно фотки оценивать), гостевой и 8 страниц текста + админка на данном мне верстальщиком шаблоне html (три страницы) я делал за два дня (могу ссылку дать, если интересно). В качестве шаблонизатора я правда СМАРТИ использовал, но можно было и например Savant3 - там логики нет, все на нативе и код бы вышел типа как я выше написал (только переменные выглядели бы так <?php if (is_array($this->news)): ?>).

Хотя Вы, в принципе, все равно определились как делать будете, но вдруг кого-то натолкнет на мысль какую-то. Может я сделаю альтернативный вариант Вашей CMS (правда тоже времени мало) и можно будет сравнить по простоте и производительности?
P.S. Если этот пост не в тему можете стереть я не обижусь smile.gif

Спустя 25 минут, 10 секунд (16.12.2009 - 02:43) twin написал(а):
Ну вообщето я ничего против нативных шаблонов никогда не имел. На мой взгляд это самое эффективное решение с точки зрения оптимальности и производительности.
Впринципе я даже согласен с тем, что не так уж и сложна разработка проекта с нативными шаблонами.
Но. Есть одно но, которое и перечеркивает все прелести классического натива.
Дело в том, что очень часто приходится работать с шаблонами после натяжки. И работать приходится верстальщику. И вот тут ступор. По крайней мере я очень часто с этим сталкивался. В результате времени на согласование уходит гораздо больше, чем на разработку. Либо проггер перематерившись и проклиная весь род "бестолковых верстальщиков", сам лезет в css, шаблоны и прочая.
Особенно это здорово заметно на удаленке.

Кроме того, хорошо отлаженный движок не требует особого вмешательства во время эксплуатации. Чего ни как нельзя сказать о дизайне. То там подправить, то тут добавить... С моим движком справляются даже далеко не профессилнальные люди. Обычные хозяева сайтов, прочитавшие самоучитель по HTML.
А вот натив их тут же повергает в непробудную депрессию. Это нужно искать программиста, а то не дай Бог что то не так пойдет или сломается. А тот говорит - дай денек. И вот "благодарный" заказчик втыкает заговоренную иглу в соломенную куклу. А мы потом удивляемся - почему дела не прут. smile.gif

Я это решение выстрадал smile.gif , не просто так пришел к этому.
Хотя оно из натива и вытекло, потому что смарти, - еще хуже в этом плане.

А хочется собрать ну ооочень простой в эксплуатации движок. Как для разработки, так и для дальнейшего обслуживания.

Спустя 27 минут, 5 секунд (16.12.2009 - 03:10) AmberLEX написал(а):
Да я тоже за натив как бы smile.gif
Но у меня как раз наоборот было. Программисту дают ТЗ, он примерно прикидывает как и че делать, какая БД и может начать делать ту часть, которая от дизайна не зависит (типа админки, связи таблиц в БД, обычные страницы типа контакта, обратной связи). И то, пока окончательного дизайна нет, особо много и не сделаешь.
Верстальщик делает сайт с более-менее всеми деталями. Показывает заказчику, если че ему не нравится - доделывает или переделывает. Потом заказчик когда со всем согласен, утверждают дизайн, что б если чего, претензий особых не было. Дизайн вообще потом сложно переделывать.
Потом программист видит, то что конкретно будет на сайте и делает свою работу. Может просто верстальщик шарящий был wink.gif
Я вообще не очень представляю, как верстальщику потом объяснить какие там страницы и что у него на входе после того как я напрограммировал и как это ему отобразить в шаблоне smile.gif Н-н-да... smile.gif Мне куда проще порезать его шаблон и выставить всю логику)))

Спустя 30 минут, 4 секунды (16.12.2009 - 03:40) twin написал(а):
Вообще нормальная работа проходит не так обычно. Сначала разрабатывается и утверждается TЗ. Там весь функционал. Что, как и где, сколько каких страниц и что именно на них. Следом, по тз, разрабатывается дизайн. То есть картинки. PSD. Утверждается. И вот потом по этим двум утвержденным документам начинается разработка. Она может спокойно вестись параллельно, потому что все исходные данные есть. Ппрогер по тз видит, что именно надо вывести, а по картинке примерно куда. А верстальщик режет PSD и верстает цельные страницы. Потом это все собирается в кучу.

А вот потоооом, когда заказ готов почти, идет доводка и подточка. Потому что где то что то недоглядели, где то недопоняли, где то пошли на уступки.
И это обычно занимает бОльшую часть времени.

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

Вот с моими шаблонами верстальщики работают на раз, даже и не спрашивают ничего. А с нативом далеко не всегда. И далеко не все.

Спустя 17 часов, 20 минут, 5 секунд (16.12.2009 - 21:00) Хозяин Огня написал(а):
twin, исправил.
Вроде всё на месте.

Спустя 3 часа, 35 минут, 30 секунд (17.12.2009 - 00:36) twin написал(а):
Вобщем по стилю уже совсем гут. smile.gif
Я поставил на новую версию, запускай как есть. Замечания в комментах. Обрати внимание на переменные в шаблоне и на сам шаблонизатор.

Спустя 14 часов, 14 минут, 15 секунд (17.12.2009 - 14:50) A.V. написал(а):
Ещё я не сдулся ))
Интересно. И хочется научится многому. По мере сил стараюсь во всём разбираться.

Изначально начинал делать модуль по аналогии с новостной лентой, храня пути к файлам в БД, но потом посмотрел как сделал Хозяин огня, и решил, что правильно - лучше без БД обойтись.

В общем виде у меня вот так выходит:

Функция для чтения директории:

/**
* Function for reading files from directory and recording in array.
* Функция: считываем файлы в заданной директории и записываем их в массив.
*/


function readDirect($direct)
{
$rd = opendir($direct);
while(($dir=readdir($rd)) !== false)
{
if($dir!=='.' && $dir!=='..')
{
$pics[] = $dir;
}
}

// closedir($direct);

print_r($pics);

return $pics;
}

/**
/* Вызов функции вида:
/* readDirect(HOST."gallery/")
*/


$img = readDirect(HOST."gallery/");



Кстати. Вопрос: почему при использовании функции closedir() выводится ошибка
Warning: closedir(): supplied argument is not a valid Directory resource in...?


Примерно такого вида выходит read_controller.php

/**
/* Full gallery.
/* Вывод всех фотографий в галерее.
*/


$tpl = getTpl('gallery/row_gallery');

/**
/* Подсчитываем кол-во изображений в папке и перебираем имена в массиве.
/* С ссылками пока не разобрался. Пользовательская функция href?
*/


$num = count($img);

foreach ($img as $key=>$val)
{
$image = $val;
}

$image=parseTpl($tpl,$img);



И шаблоны:
row_gallery.tpl

<!-- ./skins/gallery/row_gallery.tpl begin -->
<
table width="100%" border="0">
<?php echo $image; ?>
</table>
<!-- ./
skins/gallery/row_gallery.tpl end -->



...и gallery.tpl

 <!-- ./skins/gallery/gallery.tpl begin -->
<
tr>
<
td>
<
a href="<?php echo href('id='. $id); ?>" ><img src="<?php echo $image; ?>"/></a>
</
td>
</
tr>
<!-- ./
skins/gallery/gallery.tpl end -->


А full_gallery для вывода полного изображения ещё в разработке.


В самом общем виде получается такое. Как задать ID для каждого изображения ещё не разобрался.
Ссылка при переборе массива с изображениями, видимо, выходит такого вида:
$imgHref = "<a href=".href('mod=gallery','rem=???','id=$key').">[".($val)."]</a>";

Спустя 24 минуты, 37 секунд (17.12.2009 - 15:15) Хозяин Огня написал(а):
twin, спасибо за разбор. Всё понятно.
Но вот что-то картинки никак не хотят выводится - опять кусочки рамок(в твоём аттаче всё нормально).

Вот скажи, почему у тебя в $GET['page'] хранится строка 'index.php', а у меня единица?
При нажатии на рамку в новом окне выходит 404 и
Цитата
Notice: Undefined index: photo in X:\home\kurs.ru\www\libs\default.php on line 37

37 - это
return $meta[$GET['mod']][$tag];



Может я какое-то обновление пропустил?
На всякий случай прикрепляю мой текущий вариант

Спустя 31 минута, 6 секунд (17.12.2009 - 15:46) twin написал(а):
Хозяин Огня
Цитата
Может я какое-то обновление пропустил?


Там много обновлений. Я весь курс перетряхнул и даже написал об этом тут. Ты попробуй с самого начала пробежаться.

A.V.
Цитата
Ещё я не сдулся ))
Это радует))). Еще немного терпения и начнут раздаваться сладости. Заказов полно, деньги так и просятся. Я один никак не справляюсь.
Цитата
почему при использовании функции closedir() выводится ошибка

Потому что нужно закрывать директорию по ресурсу, а не по названию. Вот так:
closedir($rd);

И тоже пробегись еще раз. Там довольно глобальные изменения в плане шаблонизатора.



Спустя 5 часов, 2 минуты, 42 секунды (17.12.2009 - 20:49) Shturman написал(а):
Цитата (A.V. @ 17.12.2009 - 11:50)
Ещё я не сдулся ))

Я тоже тут. Просто дел под Новый Год навалилось - УЖАС!
Но я все отслеживаю! После праздников освобожусь, плотнее смогу заниматься.

twin, сладенького оставишь? biggrin.gif

Спустя 23 минуты, 27 секунд (17.12.2009 - 21:12) twin написал(а):
У всех завал. Я и не тороплю события. После каникул плотно займемся. До нового года еще один урок напишу, чтоб было чем заняться. А вот со следующего бум капусту резать))) Кто выживет.

Спустя 2 дня, 36 минут, 42 секунды (19.12.2009 - 21:49) Хозяин Огня написал(а):
Оказывается не работало из-за строчек в .htaccess:

#RewriteRule ^admin/(.*)$ admin/index.php?route=$1 [L,QSA]
#RewriteCond %{REQUEST_URI} !^/admin</span>


Они, кстати, пропали из всех аттачев.

twin, прикрепляю файлик с ответами на твои комменты)

Теперь займусь постраничкой.

Спустя 14 минут, 39 секунд (19.12.2009 - 22:03) twin написал(а):
Хозяин Огня
Цитата
Они, кстати, пропали из всех аттачев.

Правильно сделали. )))
Я же не догматик.
Чем больше такого плана комментариев, тем лучше будет в итоге всем.)))
Давайте как можно тщательнее это всё переработаем и сделаем действительно оптимальный и крайне прозрачный двиг.
А научиться более серьёзным вещам - нам не застрянет))
Есть у нас более продвинутые курсы.

Спустя 14 часов, 23 минуты, 1 секунда (20.12.2009 - 12:26) Evilsoul написал(а):
Хотел еще спросить, что это за паблик? `public` varchar(1) default NULL, - какая его функция?

Спустя 40 минут, 16 секунд (20.12.2009 - 13:07) twin написал(а):
Ну это нужно для предпросмотра новости. Чтоб сначала подготовить. подправить, посмотреть, а потом сразу опубликовать. Когда сделаем админку, станет понятно.

Спустя 2 часа, 36 минут, 26 секунд (20.12.2009 - 15:43) Хозяин Огня написал(а):
Постраничку сделал:

В show_controller добавил

/**
* Navigation bloc
* Блок навигации
*/


for ($n=1; $n<=$pages; $n++)
{
if($n != $GET['page'])
$data['n'] = $n;
elseif($n = $GET['page'])
$data['this'] = $n;
$navigation .= parseTpl($nav_tpl, $data);
unset($data['this']);
}


navigation.tpl
<!-- ./skins/gallery/navigation.tpl begin -->
<a href="<?php echo href('mod=gallery', "page=$tpl_n"); ?>"><?php echo $tpl_n; ?></a>
<b><?php
echo $tpl_this; ?></b>
<!-- ./skins/gallery/navigation.tpl end -->


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

Спустя 4 часа, 7 минут, 16 секунд (20.12.2009 - 19:50) twin написал(а):
А вообще по хорошему шаблон тут даже и не нужен, просто можно вывести так:
/**
* Navigation bloc
* Блок навигации
*/


$page = $GET['page'];

for ($n = 1; $n <= $pages; $n++)
if($n != $page)
$navigation .= '<a href="'. href("mod=gallery", "page=$n") .'">'. $n .'</a>';
else
$navigation .= $n;

Спустя 7 часов, 35 минут, 16 секунд (21.12.2009 - 03:26) AmberLEX написал(а):
Вот, сделал постраничку для новостей, посмотрите.
Добавил:
1. В ru.php строку
define('NO_NEWS',  'Новостей нет');

2. Добавил шаблон no_news.tpl на случай если нет новостей
<tr>
<td
style="width:200px;padding-left:10px;background-color:#f9f9f9">
<?php
echo $tpl_no_news; ?>
</td>
</tr>


Сам read_controller.php
<?php

/**
* Generation of page of an error at access out of system
* Генерация страницы ошибки при доступе вне системы
*/

if(!defined('KEY'))
{
header("HTTP/1.1 404 Not Found");
exit(file_get_contents('../../404.html'));
}


/**
* News line generation
* Генерация ленты новостей
*/

// $count - количество видимых новостей в базе (используется для постранички)
$res = mysqlQuery("SELECT COUNT(*) FROM `". DB_PREFIX ."news` WHERE `public` = '1'");
list($count) = mysql_fetch_row($res);

// Строка с номерами страниц
$navigation = '';

// Для тестирования убрать перед $count //
// $count = 0;

// Если есть новости

if ($count)
{
$tpl = getTpl('news/row_news');

// Постраничка
$pages = ceil($count/NUM_NEWS); // Количество страниц
$page = (int)$GET['page']; // Текущая страница
if (($page<1) || ($page>$pages)) // Сброс на первую страницу если вне диапазона
$page = 1;

$start = abs(($page - 1) * NUM_NEWS); // Номер новости в базе с которой начинается вывод на страницу

// Если страниц больше одной

if ($pages > 1)
{
// Формируем строку с номерами страниц
for($n = 1; $n <= $pages; $n++) {
if ($n != $page)
$navigation .= '<a href="'. href("mod=news", "rem=read", "page=$n") .'">'. $n .'</a> | ';
else
$navigation .= $n. ' | ';
}
}


$res = mysqlQuery("SELECT `id`, `date`,`subtitle`,`public`,
DATE_FORMAT(`date`,'%d') AS `day`,
DATE_FORMAT(`date`,'%m') AS `month`,
DATE_FORMAT(`date`,'%Y') AS `year`,
SUBSTRING_INDEX(`text`,' ',"
.NUM_WORD_NEWS.") AS `text`
FROM `"
. DB_PREFIX ."news`
WHERE `public` = '1'
ORDER BY `id` DESC
LIMIT "
. $start .", ". NUM_NEWS
);


$news = '';

while($row = mysql_fetch_assoc($res))
{
$data['date'] = $row['day'] .' '. $month_string[$row['month']] .' '. $row['year'];
$data['subtitle'] = htmlspecialchars($row['subtitle']);
$data['text'] = clearTags($row['text'])."...";
$data['url'] = href('rem=full', 'id='. $row['id'], 'page='. $page);
$data['link'] = FULL_NEWS;

$news .= parseTpl($tpl,$data);
}
}


// Если новостей нет
else
{
$tpl_no_news = NO_NEWS;
$rem = 'no_news';
}

При чтении новости "Полностью" и возврате на "Все новости" остаемся на той же странице.
1. Я так думаю, постраничку нужно вынести в отдельную функцию.
2. Как будет организована логика для шаблонов я не знаю, поэтому сделал пока так.

Спустя 15 минут, 58 секунд (21.12.2009 - 03:42) twin написал(а):
Постраничка - это хорошо. Вот тут я пытался сделать, еще не добил до конца.

А вот что касается "нет новостей", новерно это излишняя процедура. Она нужна только единожды - при первом запуске сайта. Так проще сунуть такую запись в базу данных при инсталляции... Причем можно даже туда поместить анотацию какую нибудь или что то плана "спасибо, что выбрали наш двиг" и прочий диферамб. Но за наводку спасибо, хорошая идея. smile.gif

Спустя 9 минут, 42 секунды (21.12.2009 - 03:51) AmberLEX написал(а):
Да, на счет "Нет новостей" - тоже думаю, что лишнее, просто хотел немного усложнить и попробовал как будет) Хотя, у меня уже есть пара сайтов (еще и на 3-х языках каждый), так 3 месяца прошло, а заказчики еще не все страницы заполнили и сейчас они пустые (про заполнении на украинском и английском я вообще молчу biggrin.gif ) В общем выглядят они какими-то недоделанными, т.к. пустые страницы - пустые (без "Нет статей..." или "Страница на стадии заполнения...")
И еще:
1. Чем сейчас занимаются-то по заданиям? (если галереей, то какая структура БД, если простая, то это почти тоже самое, что и новости, только картинки выводить вместо текста, может задачу конкретнее как-то поставить)
2. Меня мучает вопрос))) Если будут категории, например статей (а они будут я так думаю), то нужна еще переменная в GET. Это может сразу нужно предусмотреть было или рассмотреть как будет.

Спустя 1 час, 56 минут, 55 секунд (21.12.2009 - 05:48) twin написал(а):
Переменные можно добавлять по ходу движения, но в обычной практике хватает 4-5. Я еще использую язык, что бы не зависеть ни от кук ни от сессий. Ну и все остальное тоже можно добавить. Главное не менять порядок.

Спустя 14 часов, 35 минут, 19 секунд (21.12.2009 - 20:24) Хозяин Огня написал(а):
От собачки избавиться было проще, чем казалось на первый взгляд:

if (isset($images[$i])) 

Спустя 2 часа, 31 минута, 11 секунд (21.12.2009 - 22:55) AmberLEX написал(а):
Я вот хотел уже типа небольшого сайтика сделать и появились еще вопрсы:
1. На сайте будут одностраничные документы (типа О нас, Контакты), которые есть в меню сайта. Не модуль же делать на каждую страницу. Я делал в БД таблицу в которой хранились эти страницы, выходил как бы один модуль pages и по id выводил страницу. Но тут для модуля читаются title, keywords и description. Так не совсем подходит. Тут самому выкручиваться или есть уже направление как реализовать?
2. Хотелось бы логику для шаблонов. Она появится? А то постраничка, если ее нет, то хотелось бы не пустую строку выводить, а не выводить этот блок вообще (а то выходит что table или div в котором находятся страницы все-таки остается и влияет на оформление)
3. Пробовал я ввести еще параметр для категории, например статей. Выходит, что он всегда тогда присутствует и в новостях, хотя он там не нужен. Получается типа http://irbis/news/read/0/12/2, где 12 - id новости, 2 - страница. Это как то решается? Мне кажется это чуть ли не в первую очередь нужно. Почти везде есть категории.

Спустя 1 час, 47 минут, 51 секунда (22.12.2009 - 00:43) twin написал(а):
Снизу вверх.

Нет, не решается. Вернее это можно решить, но оно того не стоит. В обычном ЧПУ в таких случаях применяют идентификатор переменной. То есть если их много, то пишут так:

http://irbis/mod/news/rem/read/page/1

и тогда можно использовать только нужные. Но это сильно усложняет правила реврайта и всю работу в целом. По этому у нас важен порядок переменных, а значит придется писать их все.
Другой вопрос, что их много не нужно. Обычно хватает 4-5. Потому что тот же id совсем не обязательно оставлять пустым и делать id_categories, если первая не нужна. Собственно можно даже назвать иначе, чтоб не путаться. Главное соблюдать порядок следования.

Дальше. Логика шаблонов определяется в структуре view. В отдельном файле или в контроллере - не важно. Главное правильно шаблоны сгруппировать и выдать.

И третий. Для статичных страниц обычно пишется один модуль. Он их и выбирает. Ключами в массиве с тайтлами можно задать название разделов и передать их в функцию.



Спустя 2 дня, 12 часов, 42 минуты, 36 секунд (24.12.2009 - 13:25) Хозяин Огня написал(а):
twin, а как быть с $_POST' ом? Начал делать дипломный проект на твоём движке - сайт универа, начал с гостевухи.
Форма передаёт данные обработчику, но пост-данные не проходят тот же путь, что и гет- , так что обработчик не знает ни о функциях, ни о константах, объявленных нами в других файлах.

Спустя 34 минуты, 28 секунд (24.12.2009 - 14:00) twin написал(а):
Это будет в следующем уроке. К сожалению боюсь не успею до нового года написать следующий, но постараюсь хотя бы основу.

Спустя 26 минут, 44 секунды (24.12.2009 - 14:26) Хозяин Огня написал(а):
twin, подскажи принцип, я сам постараюсь сделать, а потом (если получится) сравним biggrin.gif ?




Спустя 29 минут, 58 секунд (24.12.2009 - 14:56) twin написал(а):
Ну вот, разбирайся:


/**
* Buttons
* Кнопки
*/

$exit = !empty($_POST['exit'])?true:false;
$add = !empty($_POST['add'])?true:false;
$edit = !empty($_POST['edit'])?true:false;
$ok = !empty($_POST['ok'])?true:false;

/**
* Initialization of variables POST
* Инициализация переменных POST
*/


$POST = array(

'value1' => NULL,
'value2' => NULL,
'value3' => NULL,
'value4' => NULL,
'value5' => NULL,
'value6' => NULL,
'value7' => NULL,
'value8' => NULL,
'value9' => NULL,
'value10' => NULL,


);


if(!empty($_POST['form']))
$POST = array_merge($_POST['form'], array_diff_key($POST, $_POST['form']));


<form action="" method="post" >
<input
name="form[value1]" type="text" />
<input
name="ok" type="submit" />
</form>

Спустя 1 день, 10 минут, 46 секунд (25.12.2009 - 15:07) A.V. написал(а):
Решил вчера вернуться к модулю галереи.
Принцип прост и понятен. Попытку сделать вывод всех изображений прикрепляю...
Однако выскакивает Notice: Undefined offset: 8 in C:\httpserver.ru\www\modules\gallery\read_controller.php on line 39.
Не могу пока понять, почему там что-то не определено.


Да, twin, то, что во многих файлах пропущен закрывающий дескриптор ?> не особо критично? Или будет исправлено потом?

Спустя 19 часов, 30 минут, 37 секунд (26.12.2009 - 10:38) twin написал(а):
Нет, он не пропущен. Больше скажу - там где он есть ( а это вряд ли) толучше его убрать. Закрывающий дескриптор в конце файла не требуется синтаксисом и обычно даже вредит. Правда по моей схеме на это плевать, можно ставить, можно нет. Лучше не ставить.

Спустя 3 дня, 15 часов, 32 минуты, 10 секунд (30.12.2009 - 02:10) AmberLEX написал(а):
Вот, наконец-то добрался и сделал новости и галерею. Получился сайтик smile.gif
Добавил:
1. Если читаешь полную новость, то в строке заголовка окна "Название новости | Название модуля | Название сайта" (аналогично и в галереи)
2. Если новостей нет, выводит, что "Новостей нет" (аналогично и в галереи)
3. Разбивка на страницы (аналогично и в галереи)
4. В галереи изображения на странице располагаются автоматически в зависимости от количества
5. Изменил дизайн

В full_controller.php галереи сделал так
    if (mysql_num_rows($res) > 0)
{

$tpl = getTpl('gallery/full');

$row = mysql_fetch_assoc($res);

$tpl_date = $row['day'] . ' ' . $month_string[$row['month']] . ' ' . $row['year'];
$tpl_title = $row['title'];
$tpl_url_full = IRB_HOST . 'uploads/gallery/' . $row['fname']; // Путь к полному изображению
$tpl_url = href('mod=gallery', 'rem=read'); // Ссылка на страницу галереи
}
т.е. не использовал как в новостях $news = parseTpl($tpl, $data); Вы вроде говорили, то если цикла нет, то можно просто include сделать.
Может и в новостях так сделать чтобы не парсить (смысла то нет особого)?
В общем, я архив и БД прилагаю.
P.S. В архиве вместо полноразмерных картинок - такие же как и в превью, т.к. иначе файл выходит > 100 Кб и я его не прикреплю)

Спустя 5 дней, 3 часа, 59 минут, 9 секунд (5.01.2010 - 06:09) twin написал(а):
Ну вот и у меня руки добрались после праздников. smile.gif

Очень симпотично получилось. Как в плане внешнего оформления, стиля кода, так и в плане отдельных мелочей. Возьму за основу, когда буду в следующий раз рихтовать курс. smile.gif

Кому интересно, посмотреть можно здесь

Спустя 4 часа, 18 минут, 26 секунд (5.01.2010 - 10:28) AmberLEX написал(а):
Спасибо. А то думал никому и не надо и не пишут ничего. Склонился к тому, что празднуют все еще smile.gif

Спустя 16 часов, 28 минут, 7 секунд (6.01.2010 - 02:56) AmberLEX написал(а):
На счет кавычек. Числа нужно в кавычки ставить или нет? Строковые константы в SQL заключаются в кавычки, числовые нет. Т.е.

$res = mysqlQuery("SELECT `id`, `date`, `subtitle`,
DATE_FORMAT(`date`,'%d') AS `day`,
DATE_FORMAT(`date`,'%m') AS `month`,
DATE_FORMAT(`date`,'%Y') AS `year`,
`text`
FROM `"
. IRB_DBPREFIX ."news`
WHERE `public` = 1
AND `id` = "
. (int)$GET['id']);
выходит правильно (просто в разных файлах по-разному)
А если все в кавывчках писать, тогда нужно так написать:

$res = mysqlQuery("SELECT `id`, `date`, `subtitle`,
DATE_FORMAT(`date`,'%d') AS `day`,
DATE_FORMAT(`date`,'%m') AS `month`,
DATE_FORMAT(`date`,'%Y') AS `year`,
`text`
FROM `"
. IRB_DBPREFIX ."news`
WHERE `public` = '1'
AND `id` = '"
. (int)$GET['id'] . "'");
И тип данных для public может char или enum поставить, они наверное быстрее сравниваться будут? А то я так тип boolean и не нашел. Тип char вроде сколько укажешь столько и занимает в памяти.

Спустя 8 часов, 47 минут, 35 секунд (6.01.2010 - 11:43) AmberLEX написал(а):
И все равно, не нашел я где сказано, что обратные кавычки ставить нужно.
Если запрос с алиасами, то одни кавычки получаются)
$res = mysqlQuery("SELECT `cat`.`cid`, `cat`.`cover`, `cat`.`title`, `cat`.`description`,
COUNT(`art`.`cid`) AS `count_art`
FROM `"
. IRB_DBPREFIX . "categories` AS `cat`
Left Join `"
. IRB_DBPREFIX . "articles` AS `art` ON `cat`.`cid` = `art`.`cid`
GROUP BY `cat`.`cid`
ORDER BY `cat`.`weight`"
);

Спустя 13 минут, 20 секунд (6.01.2010 - 11:57) twin написал(а):
В этих запросах нет внешних данных и обробатывать пока нечего. По этому и говорю - торопишься. smile.gif

Спустя 4 часа, 7 минут, 15 секунд (6.01.2010 - 16:04) A.V. написал(а):
twin,

Цитата
Кому интересно, посмотреть можно здесь


а полный код модуля галереи только в новом уроке будет выложен?
Или после праздников можно будет ещё самому пробовать?

Спустя 2 часа, 11 минут, 45 секунд (6.01.2010 - 18:16) Lenarfate написал(а):
почему закрывающий дескриптор не нужен? huh.gif

Спустя 13 минут, 41 секунда (6.01.2010 - 18:29) glock18 написал(а):
Lenarfate
почему то мне кажется, что там, где ты это прочитал, есть объяснение.

Спустя 3 часа, 5 минут, 14 секунд (6.01.2010 - 21:34) Хозяин Огня написал(а):
AmberLEX, классно получилось!

Спустя 1 час, 16 минут, 7 секунд (6.01.2010 - 22:51) Lenarfate написал(а):
почему то у меня месяц не выводится biggrin.gif

исправил)

Спустя 7 дней, 16 часов, 59 минут, 42 секунды (14.01.2010 - 15:50) A.V. написал(а):
Мой вариант модуля галереи.

Работает, вроде бы, как положено, но надо ещё доводить до ума.

Спустя 4 минуты, 59 секунд (14.01.2010 - 15:55) A.V. написал(а):
В аттаче к теме в папке skins/tpl все tpl-файлы в кодировке ANSI.

Когда пробую считывать с сервера имена папок с русскоязычными названиями, вылезают крокозябры. Перекодировал в UTF-8, всё равно та же ерунда.

Спустя 29 дней, 1 час, 40 минут, 56 секунд (13.02.2010 - 17:36) AmberLEX написал(а):
В общем вернулся я к логике в шаблонах. Она будет или нет?
Хотел привести проект в порядок, но там немеренно недоделок, в общем запарился я и остановился. А то сделаешь, а twin скажет не годится и все не так smile.gif Вопросов то хватает.
Вот основные, например:
1. У нас в шаблоне index.tpl там <?php echo IRB_LANG_SITE_SLOGAN; ?> Если мы в админке, то можно условием выбирать: или слоган выводить или надпись"Админ панель". Если перенести index.tpl в папку админ, то это решается без логики. (как я уже говорил, может быть и дизайн отличный от сайта и подключаемые js и css, которые в админке нужны, а на сайте нет) Твин эту идею отбросил.
2. Вывод постранички. Его или доделать нужно или тоже нужна логика в шаблоне. Т.е. если страниц нет, то чтобы не выводился блок, в котором находятся номера страниц. Сейчас он невидимый и если страниц нет то блок есть, но его не видно. Это тоже как-то криво. Если номера страниц будут находится на каком-то фоне, то он останется.
Плюс к этому, если новостей нет в БД, то эта конструкция if (mysql_num_rows($res) > 0) выдает предупреждение на запрос $res = $paginator -> countQuery
3. В шаблоне (я уже говорил) для вывода галереи используется html код, теперь появился вызов функции getPages('setup');
Это я к чему? Может тогда уже сделать логику в шаблонах используя альтернативный синтаксис
<?php if ($a == 5): ?>
A is equal to 5
<?php endif; ?>
По-моему это никак не уменьшит удобство верстки и не нужно ничего програмно изобретать и запутывать. (А то что в циклах, то у нас формируется в контроллерах, так что в шаблонах выходит будут только условия и то редко)
4.Как-то проект еще не разросся, а уже довольно запутано.
- В шаблонах выходит, что доступ есть к любым переменным (массиву $language, $navigation, $title),
- переменным типа $news, $gallery (они почти в каждом файле шаблона, контроллере, переключателе контроллера, все инклудится др. в др.) - путано довольно,
- к переменным, что парсятся parseTpl (с приставкой $tpl_),
- к константам,
- в контроллере html код, в шаблоне вызов функции (ну это ладно...)
5.Уже весь код написан с любым количеством пробелов, табов, после строк куча мусора (невидимых символов), но это не проблема. NetBeans убирает это все почти автоматом.
6.Ну и ошибки при таких путях: http://site/0/news/read или в sequrity.php строки типа exit(file_get_contents('../../404.html'));

Мне одному кажется, что сложность возрастает, а структура все запутаней и сложно уследить где и что находится? Так это почти голый проект, пустой. А дальше? Че-то тут не додумано кажется smile.gif Кто-то вообще пробовал взять уже готовый шаблон (какой-то из бесплатных скачать) и сделать все сначала, чтобы ровненько работало, без накладок?

До админки я еще почти не добрался, но по-моему здесь еще работать и исправлять много.

Спустя 21 минута, 39 секунд (13.02.2010 - 17:58) twin написал(а):
Знач так, не трогай ничего, я перепишу полностью курс. Рановато мы взялись с галереями мудрить и новостями. Я их делал, что бы легче и нагляднее было понять саму структуру, а получилось что все внимание прилипло к ним. А суть ускользает.

Сегодня же перепишу.

Спустя 19 минут, 26 секунд (13.02.2010 - 18:17) AmberLEX написал(а):
Ок. А то я бы уже сам давно сайт придумал и написал с новостями, галареей, гостевой, статикой, админкой на этом каркасе. А так выходит куча вопросов, только на месте стою. То я еще не все спросил. biggrin.gif В общем сейчас, чтобы написать простенький сайт на этой раме, то ничего как бы и не определено и ничего нет. На своем двиге я бы за день все написал, но хочется же на этом более-менее сайтик наваять с учетом требований smile.gif .

Спустя 3 дня, 13 часов, 58 минут, 28 секунд (17.02.2010 - 08:16) Литрофак написал(а):
В блоке генерации новости по id:
link вроде сюда: IRB_LANG_ALL_NEWS должен быть

Спустя 13 дней, 13 часов, 57 минут, 56 секунд (2.03.2010 - 22:14) KonstantinK написал(а):
Я видимо сильно опаздываю, но осмелюсь спросить вот тут в курсе когда показан первоначальный контроллер

if(mysql_num_rows($res) > 0) 
while($row = htmlChars(mysql_fetch_assoc($res)))
{
++$i;
$rows .= "<tr>\n\t<td>". $i ."</td>\n\t<td>". $row['text'] .
"</td>\n\t<td>". $row['price'] ." руб</td>\n</tr>";
}


видимо не хватает фигурной скобки после If , ну и соответственно закрывающей тоже, или я не понял чего-то , но и сам вопрос - собственно я не понял а как работает такой цикл. В переменную $row попадает многомерный массив и получается что while проходит построчно его так что ли?

Спустя 9 минут, 19 секунд (2.03.2010 - 22:23) twin написал(а):
Цитата
видимо не хватает фигурной скобки после If ,

Нет, все там в порядке. Фигурная скобка не обязательна, если выполняемое выражение одно. У нас только цикл. Вот в цикле выражений уже два - блок. Тогда и нужны скобки.

Остальные рассуждения верны. Так оно и есть.

Спустя 46 минут, 55 секунд (2.03.2010 - 23:10) noo написал(а):
Только начал изучать курс. Появился такой вопрос - а как работать с шаблонизатором, если мне нужно вытаскивать данные из разных таблиц. Сейчас объясню. Вот ваш пример контроллера:
   $res = mysqlQuery("SELECT *  
FROM `"
. IRB_DBPREFIX ."test`"
);

$rows = '';
$i = 0;

if(mysql_num_rows($res) > 0)
{
$tpl = getTpl('second/price_rows');

while($row = htmlChars(mysql_fetch_assoc($res)))
{
++$i;
$row['num'] = $i;
$rows .= parseTpl($tpl, $row);
}
}

у меня есть таблица с записями и таблица с тегами (к каждой записи). В итоге контроллер вышел таким:
   $res = mysqlQuery("SELECT *  
FROM data"

);
$rows = '';


if(mysql_num_rows($res) > 0)
{
$tpl = getTpl('second/price_rows');

while($row = htmlChars(mysql_fetch_assoc($res)))
{
$post_id = $row['id'];
$r2 = mysqlQuery ("
SELECT `tag` FROM (`tags`)
JOIN `tags_data` ON `tags_data`.`tag_id`=`tags`.`id`
JOIN `data` ON `data`.`id`=`tags_data`.`post_id` WHERE `data`.`id` = '"
.$post_id."'
"
);

$rows1 = '';

if(mysql_num_rows($r2) > 0) {
$tpl = getTpl('second/tags');

while ($rm=mysql_fetch_assoc($r2))
{
$rows1 .= parseTpl($tpl, $rm);

}
}

$rows .= parseTpl($tpl, $row);
}
}

теперь у меня:
<!-- ./skins/tpl/second/price_rows.tpl begin -->
<
tr>
<
td><?php echo $tpl_name; ?> </td>
<
td><?php echo $tpl_text; ?></td>
<
td><?php echo $tpl_dop; ?></td>
<
td><?php echo $rows1; ?></td>


</
tr>
<!-- ./
skins/tpl/second/price_rows.tpl end -->

и
<!-- ./skins/tpl/second/tags.tpl  -->
<?php echo $tpl_tag; ?>,
<!-- ./
skins/tpl/second/tags.tpl end -->


Но почему-то не работает, подскажите, что не так?

Спустя 10 минут, 32 секунды (2.03.2010 - 23:20) twin написал(а):
Не так - запрос в цикле. Зто можно нужно решить одним запросом. Тогда и шаблонизатор нужно использовать один раз.

Я с просонок немогу понять, ведь нижний запрос уже идет из двух таблиц, зачем сверху то его?

Спустя 56 минут, 27 секунд (3.03.2010 - 00:17) noo написал(а):
в один запрос не получится, потому что из одной таблицы мы получаем саму запись, а из другой теги к ней. теги же хранятся по-одному с привязкой в ид_записи. Что посоветуете?

Спустя 5 часов, 54 минуты, 9 секунд (3.03.2010 - 06:11) twin написал(а):
Структуру таблиц покажи

Спустя 6 часов, 37 минут, 8 секунд (3.03.2010 - 12:48) noo написал(а):
data: id|text
tags: id|tag
tags_data: tag_id|post_id

Спустя 1 день, 2 часа, 45 минут, 43 секунды (4.03.2010 - 15:34) twin написал(а):
Ниего я не понял. Структуру, это я дамп имел ввиду. И по подробнее, что где хранится и когда нужно что достать.

Спустя 5 часов, 3 минуты, 26 секунд (4.03.2010 - 20:37) noo написал(а):
ну вы в вордпрессе знаете как устроена система тегов?
вот подобное пытаюсь вписать в наш шаблонизатор.
Нужно:
1) к конкретной записи выводить теги по ней
2) выводить список записей (из data), под каждой записью выводить теги (tags) к ней . Таблица-связка записей и тегов tags_data
Упрощенный дамп ниже:
-- Структура таблицы `data`

CREATE TABLE `data` (
`id` int(5) NOT NULL auto_increment,
`text` text NOT NULL,

PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=43 DEFAULT CHARSET=utf8 AUTO_INCREMENT=43 ;

-- Дамп данных таблицы `data`

INSERT INTO `data` VALUES (2,'Любой текст тут');
INSERT INTO `data` VALUES (1,'Любой текст тут2');


CREATE TABLE `tags` (
`id` int(9) NOT NULL auto_increment,
`tag` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 AUTO_INCREMENT=28 ;

-- Дамп данных таблицы `tags`

INSERT INTO `tags` VALUES (1, 'тег1');
INSERT INTO `tags` VALUES (2, 'тег2');
INSERT INTO `tags` VALUES (3, 'тег3');

-- Структура таблицы `tags_data`

CREATE TABLE `tags_data` (
`tag_id` int(11) NOT NULL default '0',
`post_id` int(8) NOT NULL default '0',
PRIMARY KEY (`tag_id`,`post_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- Дамп данных таблицы `tags_data`

INSERT INTO `tags_data` VALUES (1, 1);
INSERT INTO `tags_data` VALUES (2, 1);
INSERT INTO `tags_data` VALUES (3, 1);
INSERT INTO `tags_data` VALUES (1, 2);
INSERT INTO `tags_data` VALUES (3, 2);

Спустя 1 день, 38 минут, 28 секунд (5.03.2010 - 21:16) noo написал(а):
Перепробовал уже все возможные варианты.
twin, объясните, почему наша функция parseTpl не может работать сразу с данными из двух таблиц?

Спустя 15 минут, 59 секунд (5.03.2010 - 21:32) twin написал(а):
Может. Только у тебя вообще все не верно как то построено. Сейчас сдам срочный заказ и гляну внимательно.

Спустя 4 минуты, 34 секунды (5.03.2010 - 21:36) noo написал(а):
хокей, жду smile.gif структура бд как раз правильная, а вот контроллера код получился не ура.

Спустя 15 часов, 41 минута, 46 секунд (6.03.2010 - 13:18) twin написал(а):
Пытался воспроизвести, не смог. Лень обуревает...
Плиз мне в личку или аську с полной выкладкой, попробуем решить.
Если напиться по поводу праздника не успею)))

Спустя 29 дней, 3 часа, 26 минут, 50 секунд (5.04.2010 - 15:45) ohxxx написал(а):
Добрый день в пятом уроке есть такой код

/**
* Function of processing of variables for a conclusion in a stream
* Функция обработки переменных для вывода в поток
*/

function htmlChars($data)
{
if(is_array($data))
$data = array_map("htmlChars", $data);
else
$data = htmlspecialchars($data);

return $data;
}

Собственно я чего то понять не могу если $data будет массив то получается вызов функции htmlChars произойдет внутри самой функции htmlChars ?


еще вопросик почему когда писали ф-ю
function parseTpl($cont, $data = '')  
а не просто
 function parseTpl($cont, $data)  
что это дает вообще ?

Спустя 30 минут, 36 секунд (5.04.2010 - 16:16) twin написал(а):
Цитата
Собственно я чего то понять не могу если $data будет массив то получается вызов функции htmlChars произойдет внутри самой функции htmlChars ?

Да. Это называется "рекурсия" То есть она будет вызываться до тех пор, пока аргументом будет массив. То есть может обработать вложенные массивы.
function parseTpl($cont, $data = '')  

Это дает возможность необязательного аргумента. Тоесть можно вызвать так:
$rows .= parseTpl($cont, $data);

или так
$rows .= parseTpl($cont);
а иначе будет варнинг.

Спустя 12 дней, 5 часов, 32 минуты, 29 секунд (17.04.2010 - 21:48) ohxxx написал(а):
Добрый день или ночь wink.gif
Irbis-Team и г-н Twin

По пятому уроку ядра
1.
текст :
Не появился? Правильно. А кто будет кривой запрос с прошлого урока из контроллера главной страницы убирать? Пушкин?
Написано же русским языком -
//* @TODO To clean in release

Тут должно быть потому что то что выше явно неправильно даже если за комментировать не заработает huh.gif . Собственно что должно быть ниже.
Исправляем запрос из прошлого урока
$res = mysqlQuery("SELECT count 
FROM `"
. IRB_DBPREFIX ."test`");

Делаем его правильным
$res = mysqlQuery("SELECT * 
FROM `"
. IRB_DBPREFIX ."test`");

Между прочим значек * обозначает что вытаскиваем все данные из таблицы

2.
текст урока
/**
* Function of reading of templates
* Функция чтения шаблонов
*/

function getTpl($tpl)
{
if(file_exists(IRB_ROOT .'/skins/tpl/'. $tpl .'.tpl'))
return file_get_contents(IRB_ROOT .'/skins/tpl/'. $tpl .'.tpl');
else
die('The template <b>'. $tpl .'.tpl</b> is absent in the specification')....
;
Думаю надо дописать что этот код надо занести в libs/view.php а то там непонятно куда его писать . Например мне пришлос скачать архив и вычислять куда этот код засовывать.

3.
текст :
Что нам даст эта функция. А то, что мы считаем шаблон в переменную, как и при обычной шаблонизации, так же разберем его, но вместо псевдотегов у нас будут обычные php вставки. И код, который находится между мы исполним с помощью функции eval(). Данные, поступающие в аргумент функции мы будем брать из шаблона, а это внутренние данные.

_Cтоит пояснить как отличить внутренние данные от не внутренних (я наприменр только смутно представляю) Ато народ наколбасит с этой eval()

4. Я не нашол нормального описания eval() в нете поэтому только попрошу чтобы вы сделали её описание

5.
Да кстати
$rows .= parseTpl($tpl, $row); 

надобы пояснить что значит .= (точка и знак равно) ну правда не в этом уроке а раньше. (хотя я может что то упустил и это пояснено )

Ну вот так например:

Если после переменной стоит .= то это значит что к данным переменной будут добавлены данные после знака равно.
Пример:
$a = 'Дом номер ';
$b = '35';
$a .=$b ;

echo $a;

Впринцепе сами посмотрите что будет wink.gif


Вроде всё .
С уважением Ohxxx

Спустя 1 час, 31 секунда (17.04.2010 - 22:49) twin написал(а):
Очень тревожит то, что нет разноса по 4-му уроку... Должен быть хоть один варнинг или нотайс хотя бы biggrin.gif

Принял к сведению, поправлю. Спасибо. smile.gif

Спустя 25 минут, 47 секунд (17.04.2010 - 23:14) ohxxx написал(а):
Цитата (twin @ 17.04.2010 - 19:49)
Очень тревожит  то, что нет разноса по 4-му уроку... Должен быть хоть один варнинг или  нотайс хотя бы  biggrin.gif

Принял к сведению, поправлю. Спасибо.  smile.gif

Четвертый я потом сделаю скорее всего.. после восьмого
Там в прицепе всё понятно и так конечно есть что добавить и поправить

Хотя ... можно написать кое чего .... просто я ещё раз тогда должен курсы просмотреть чтобы проверить не надумал я чего лишнего ....

А сейчас я не могу этим заняться по причинам 1.Времени мало (работы много) 2.Когда оно появляется лень (в смысле ничего не хочется).
3.Я сейчас буду 6-ой изучать не хочу сейчас назад откатываться
4.ы-й для меня легче всего прошол я его проскочил smile.gif

Я думаю пока и так нормально поэтому я его на самый конец отложил . А там я уж найду время и напишу wink.gif .

Спустя 9 часов, 15 минут, 35 секунд (18.04.2010 - 08:30) freed-master написал(а):
Про htmlspecialchars() шла речь:
Цитата
Это вопросы безопасности и корректного отображения данных. Позже к ним мы вернемся более подробно, а пока запомните - никогда не отправляйте в поток необработанные данные из базы. Это чревато последствиями.
А как на счет оформления текста, например элементарное разбиение на абзацы и перенос строки?

Спустя 53 минуты, 13 секунд (18.04.2010 - 09:23) ohxxx написал(а):
Цитата (freed-master @ 18.04.2010 - 05:30)

А как на счет оформления текста, например элементарное разбиение на абзацы и перенос строки?


Обычно текст разбивается не при выводе из БД ,а при вводе в БД. Тесть при выводе он уже должен быть готов со всеми тегами отступами и тд.

Эм по поводу разбиения ... если ты специально хочешь разбить после определённого кол-ва символов перенос то тогда это при том же вводе делается.
Я например переснос строки не делал ни разу текст сам разбивается на строки.

Спустя 28 минут, 10 секунд (18.04.2010 - 09:51) freed-master написал(а):
Цитата
Обычно текст разбивается не при выводе из БД ,а при вводе в БД.
вот именно, если текст записан в бд с тегами, то htmlspecialchars() так теги и выдаст...
значит
Цитата
никогда не отправляйте в поток необработанные данные из базы
не совсем верно...

Спустя 59 минут, 18 секунд (18.04.2010 - 10:51) twin написал(а):
freed-master

Да, сформулировано неверно. Исправил. Сеньк. smile.gif

Спустя 10 часов, 46 минут, 12 секунд (18.04.2010 - 21:37) twin написал(а):
Поправил пятый урок в свете замечаний. eval() тут. smile.gif

Спустя 9 дней, 17 часов, 24 минуты, 56 секунд (28.04.2010 - 15:02) ohxxx написал(а):
Привет г-н Twin

Я подумал хоршобы в конце урока добавить заметку ,чтобы людям легче было разбираться

Обработка данных получаемых из бд происходит следующим образом. Или как работает наш трёхколёсный велосипед.

a. Запрос в БД через mysqlQuery
b. Проверка есть ли шаблон через getTpl
c. Переменной $row присваиваем значения $res обработанные функцией mysql_fetch_assoc и добавляем к полученному массиву номер строчки $row['num']
d. Далее ф-я parseTpl разбивает массив через extract и добавляет всем префикс tpl_
e. Стартует буферизация и фя eval вызывает шаблон обработки price_rows.tpl
f. Буферизацция закрывается и все данные переедаются в переменную $cont.
g. И последнее из переменной $cont добавляются в переменную $rows.

Лично я для себя сделал такую заметку сразу стало легче. wink.gif

З.Ы. суперское описание функции eval() мне понравилось.

С уважением Ohxxx

Спустя 1 час, 25 минут, 39 секунд (28.04.2010 - 16:27) twin написал(а):
гут, так и сделаем. smile.gif

Спустя 13 дней, 4 часа, 12 минут, 43 секунды (11.05.2010 - 20:40) ogogo написал(а):
Выполняю уроки, читаю значиться форум - а тут все про какие-то "галереи" и "новости" говорят, все что-то шлют. вот у меня и возникает вопрос, где это я что пропустил? в смысле чувствую что домашку где-то задавали, а хде собсно)?

Спустя 2 часа, 18 минут, 39 секунд (11.05.2010 - 22:59) twin написал(а):
Это было давно, в самом начале. Теперь все упростили донельзя. Но и этого оказалось мало)))
Праздники внесли коррективу опять. Работа копится, делать некогда. Сейчас все утрясем и пойдем дальше. И галерея там будет, и новости, и вообще куча всего.

Спустя 8 дней, 23 часа, 23 минуты, 34 секунды (20.05.2010 - 22:22) gomer505 написал(а):
Fatal error: Call to undefined function getinfo() in U:\home\my-site.ru\www\skins\tpl\second\show.tpl on line 5

Не работает. Правда когда убрал из этого файла 5 линию
<strong style="color:#FF0000"><?php echo getInfo($info); ?></strong> 

то заработало...Не пойму где я упустил эту функцию?

И, похоже, в файле modules/second/read_controller.php в следующем коде
  
if(!$POST['value1'])
$info[] = IRB_NO_NAME;

if(!$POST['value2'])
$info[] = IRB_NO_TEXT;


IRB_NO_NAME и IRB_NO_TEXT должны быть в одинарных кавычках? Или нет?


Спустя 4 часа, 58 минут, 6 секунд (21.05.2010 - 03:20) twin написал(а):
Где то я упустил функцию...
Цитата
IRB_NO_NAME и IRB_NO_TEXT должны быть в одинарных кавычках? Или нет?

Нет.

Спустя 17 часов, 25 минут, 20 секунд (21.05.2010 - 20:46) gomer505 написал(а):
Цитата (twin @ 21.05.2010 - 00:20)
Где то я упустил функцию...
Цитата
IRB_NO_NAME и IRB_NO_TEXT должны быть в одинарных кавычках? Или нет?

Нет.

Но без кавычек выдает ошибку...?Почему-то.

Спустя 8 минут, 8 секунд (21.05.2010 - 20:54) twin написал(а):
Ну да, тоже мой косяк. Эти константы должны быть определены в языковом файле. В примере есть, в описании забыл указать

Спустя 7 дней, 23 часа, 18 минут, 26 секунд (29.05.2010 - 20:12) igor717 написал(а):
Еще раз здравствуйте, появился такой вопрос:

Вы говорили "Так как подключений к базе может быть не одно, а много, то вместо include, лучше использовать include_once..." Но если весь контент сайта впринцепе находится в базе, то не проще ли include-ом этот файл подключить в самом начале?

Спустя 3 дня, 33 минуты, 41 секунда (2.06.2010 - 20:46) gomer505 написал(а):
А тут пока без изменений???

"Fatal error: Call to undefined function getinfo() in U:\home\my-site.ru\www\skins\tpl\second\show.tpl on line 5"

Спустя 18 минут, 59 секунд (2.06.2010 - 21:05) twin написал(а):
Исправил. smile.gif
Как то упустил, не успеваю сразу реагировать.

Спустя 15 минут, 56 секунд (2.06.2010 - 21:21) gomer505 написал(а):
Цитата (twin @ 2.06.2010 - 18:05)
Исправил.  smile.gif
Как то упустил, не успеваю сразу реагировать.

Теперь порядок! Спасибо.


Спустя 21 минута, 25 секунд (2.06.2010 - 21:42) gomer505 написал(а):
И еще
/**   
* The block of reading of the information
* Блок чтения информации
*/
$posts = getData('./data/'. $GET['num']);
include './libs/bb_tags.php';


Это из Вашего листинга. Обратите внимание на bb_tags.php !!! Это не моя ошибка.

Спустя 14 минут, 27 секунд (2.06.2010 - 21:57) twin написал(а):
А как должно быть? У меня нет по другому нигде... И это правильное написание вообще то...

Спустя 17 минут, 5 секунд (2.06.2010 - 22:14) gomer505 написал(а):
Цитата (twin @ 2.06.2010 - 18:57)
А как должно быть? У меня нет по другому нигде... И это правильное написание вообще то...

Простите. Значит это все же моя нелепая ошибка.

Спустя 1 месяц, 27 дней, 11 часов, 2 минуты, 33 секунды (30.07.2010 - 09:16) uhans написал(а):
В этом уроке, в файле modules/second/read_controller.php вводится сравнение с константой NUM_POSTS

if($num >= NUM_POSTS)
{
++$file;
unset($posts);
}

а в конфиурационном прописывается

define('IRB_NUM_POSTS', 5);

Это вызывает ошибку о том что константа не определена.

И еще строка
header('location: '. IRB_HOST .'?page=second&num='. $file);
почему то вызывает ошибку:
Warning: Cannot modify header information - headers already sent by (output started at Z:\home\localhost\www\script\config.php:1) in Z:\home\localhost\www\script\modules\second\read_controller.php on line 57
Зарание спасибо.

Спустя 1 час, 7 минут, 2 секунды (30.07.2010 - 10:23) twin написал(а):
Это в листинге или образце?

Спустя 10 часов, 6 минут, 39 секунд (30.07.2010 - 20:30) uhans написал(а):
В тексте урока http://irbis-team.com/15/16/5. Просто мне кажется, что нужно исправить NUM_POSTS либо в config.php либо modules/second/read_controller.php.

Спустя 15 минут, 41 секунда (30.07.2010 - 20:46) twin написал(а):
Угу, действительно ляп. Исправил, спасибо. smile.gif

Спустя 1 минута, 39 секунд (30.07.2010 - 20:47) twin написал(а):
Цитата
Warning: Cannot modify header information - headers already sent by (output started at Z:\home\localhost\www\script\config.php:1) in Z:\home\localhost\www\script\modules\second\read_controller.php on line 57

Это нужно почитать про BOM. Вот тут есть.

Спустя 9 минут, 42 секунды (30.07.2010 - 20:57) uhans написал(а):
Так не за что, мы должны друг другу помогать.

Спустя 8 минут, 5 секунд (30.07.2010 - 21:05) uhans написал(а):
Сейчас попробую тряхнуть Adobe Dreamweaver CS4 на предмет ВОМ. Но почему тогда во всех предыдущих уроках при надписи
header("Content-Type: text/html; charset=utf-8");
error_reporting(E_ALL);
никаких проблем не было? Ни крякозяблов ни ругани!

Спустя 20 минут, 8 секунд (30.07.2010 - 21:25) twin написал(а):
Не могу сказать. Но адрес "помехи" указан явно: config.php:1

Спустя 16 минут, 56 секунд (30.07.2010 - 21:42) uhans написал(а):
Извиняюсь за назойливость - в этом месте правильные настройки?

Спустя 17 минут, 30 секунд (30.07.2010 - 22:00) uhans написал(а):
Ошибку нашел - прописал по запарке комментарий перед <?php спасибо за помощь. smile.gif

Спустя 22 дня, 13 часов, 25 минут, 53 секунды (23.08.2010 - 11:26) Rasty написал(а):
Здравствуйте twin и форумчане. Изучаю уроки, может снова где-то не дочитал или недопонял - несерчайте.

Хочу прояснить для себя ситуацию по логике структуры - контроллёр - вид - шаблон.
Рассмотрю на примере простого сайта. Структура такова : есть хедер с главным меню сайта, есть контент, есть блок вертикального дополнительного меню, есть футер. Неизменяемые блоки на сайте - хедер, правый блок вертменю, футер. Есть главный шаблон индекса (в корне tpl), подключенный в главный индекс.php. Я правильно понимаю, что именно в этот главный шаблон выводится то, что является неизменным на всех страницах сайта? То есть не изменяемые блоки, а именно хедер, правый блок вертменю и футер? Эти блоки имеют свою логику и верстку. Их (эти неизменяемые блоки-модули) нужно делать модулями, то есть в папке модули для каждого свой каталог, с контроллером вьюшой и роутером, или же ложить эти файлы в корень например как вы ложили шаблон меню, в корень рядом с главным шаблоном индекса? Где реализовать логику например вертикального меню (в нем есть логика с БД, в цикле выводится список категорий), неизменяемых модулей страниц? Отдельными модулями с шаблонами? Как правильно разделить неизменяемые модули сайта и модули изменяемого контента сайта?

И второй вопрос по файлам вью. Не совсем понятна логика этого файла в каждом модуле. В большинстве случаев он используется только для подключения шаблона данного модуля. Что реализовывать в файле вью в модуле? Логика реализуется в файле контроллёр, в нём же присваиваются значения переменным, которые выводятся напрямую в шаблон. Что если подключить шаблон непосредственно в роутер, напрямую без вьшки? Не улавливаю именно тут логику.
В уроке Вы используете главный файл вью с папки libs для написания в нём функций, касающиеся отображения, функция проверки потока, чтения шаблона, разбор шаблона. Тоесть вьюшки - файлы для написания таких функций? Для чего ещё можно использовать этот файл в модулях? Тут непонятно. Вы в основном используете главную вьюшку, в папке libs, в ней пишете основные функции для вывода, они общие для всего сайта, а для чего использовать файл вью именно в модулях, проясните ещё раз логику.

Ну и последний вопрос по шаблонам. Я так понимаю, что шаблон должен выглядеть так: дивы или таблицы, с выводом в них переменных с данными через echo. Минимум текста, нет вообще логики, максимум html, для быстрой и удобной вёрстки. Как быть с текстами на страницах, например какими то пояснениями ремарками, ссылками, то есть рабочий, текст-суппорт страниц,
который имеет отношение к данной странице, но не является её главным контентом? Все реализовывать в шаблоне? И как быть с формами, их тоже реализовывать в шаблоне, или делать дополнительные шаблоны для форм или ещё подобных конструкций страницы, и подключать потом в через вью как и главный chow.tpl страницы?
Спасибо. smile.gif

Спустя 36 минут, 27 секунд (23.08.2010 - 12:02) twin написал(а):
Вопросов много. Но ответов однозначных на них нет. Каждый это все определяет для себя сам. На курсах просто показаны возможные пути решения.

Где и как реализовать тот или иной функционал - зависит от конкретных требований к сайту.

Допустим меню можно сделать отдельным модулем и подключать в case нужных страниц. А можно для каждой страницы своё меню. И свой контроллер.

Это уже дело разработчика - придумать архитектуру.

То же самое касается и вьюшек. Можно не делать эти файлы вовсе. если в них только переключение шаблонов. Можно этот функционал поместить в роутер. А если контроллер один к примеру, то и роутер не нужен - все в контроллер запихать.

Тут нет никаких рамок, это же не фреймворк. Это просто основа для построения.

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

Этот курс не для того, чтобы "собрать профессиональный сайт за 22 часа". Там просто показаны возможные направления, а как делать конкретно - зависит от фантазии разработчика.

Спустя 1 час, 3 минуты, 53 секунды (23.08.2010 - 13:06) Rasty написал(а):
twin спасибо. Скажите, будет ли логичным и правильным например такой поворот. Скажем есть второстепенная страница, содержащая в себе:

вывод некого текста из бд
html форму
текст-суппорт.

логика построения страницы такова:

-запрос реализуется в контролёре
-результат запроса присваивается переменной $text во вьюшке
-html форма присваивается переменной $form во вьюшке
-текст-суппорт присваивается константе в языковом файле
-в шаблон выводится переменная $text , $form и на место текста-суппорта -константа.

верна ли логика построения страницы?

unsure.gif

Спустя 39 минут, 45 секунд (23.08.2010 - 13:46) twin написал(а):
Цитата
-html форма присваивается переменной $form во вьюшке

Это зачем? А форму почему просто в шаблоне не сделать?

Спустя 17 минут, 6 секунд (23.08.2010 - 14:03) Rasty написал(а):
вот) а переменные $text присвоить в контролёре, и делов то. А во вьюшку просто нечего писать)

Цитата
Представление — это PHP-скрипт, состоящий преимущественно из элементов пользовательского интерфейса. Он может включать выражения PHP, однако рекомендуется, чтобы эти выражения не изменяли данные и оставались относительно простыми. Следуя концепции разделения логики и представления, большая часть кода логики должна быть помещена в контроллер или модель, а не в скрипт представления.


элементов пользовательского интерфейса - что вот это такое, если это не html,
наведите пожалуйста пример как использовать вьюшку в модуле, просто словами без кодов, так сказать суть логики этого файла.

ps извините за настырность

Спустя 30 минут, 47 секунд (23.08.2010 - 14:34) twin написал(а):
Это не я писал. smile.gif И комментировать чужие умозаключения не могу.

По мне так эти все догмы и рекомендации - только костыли, мешающие нормальной работе скрипта.

По сути верно, но делать нужно так, как удобно в данный момент.
Вьюшка для того и нужна, чтобы вытащить в неё максимум логики представления, оставив в шаблонах простой вывод. Вот например возврат данных в форму. Перед выводом данные нужно обязательно обработать функцией htmlspecialchars(). И делать это нужно именно в части "ВИД", не раньше. Ибо для того и функция.

Можно пойти таким путем:
<input type="text" value="<?php echo htmlspecialchars($POST['value1']) ?>" />
<input
type="text" value="<?php echo htmlspecialchars($POST['value2']) ?>" />
но это вызов функции в шаблоне.

А можно обработать весь массив в файле view.php
$POST = htmlChars($POST);

и вывести в шаблон просто переменные
<input type="text" value="<?php echo $POST['value1'] ?>" />
<input
type="text" value="<?php echo $POST['value2'] ?>" />


Принцип не меняется - обработка данных для вывода происходит в части "ВИД", но при том в самих шаблонах полное отсутствие логики.

Но это не обязательно так. Если кроме этой функции ничего больше не нужно, не стоит из-за неё создавать отдельный файл. Сунуть в контроллер и вся недолга.

Нет универсальных рецептов. Если бы они были, я бы ни за что не стал программистом. Ибо это было бы смертельно скучно.

Спустя 12 минут, 10 секунд (23.08.2010 - 14:46) Rasty написал(а):
twin, спасибо за терпение и ответы. smile.gif
добью 10 постов, скажу спасибо в репку)

Спустя 8 дней, 22 часа, 50 минут, 39 секунд (2.09.2010 - 13:36) Tokugava написал(а):
Слишком все сложно, а в итоге всеравно <?php echo ...> так и вылазит, в html... зачем делать целых 3 файла для одного простейшего модуля?
Почему не сделать проще, файл модуля php и файл шаблона tpl...?

От простого к сложному всетаки учить пхп проще, много лишней (на мой взгляд) информации...

Вобщем уроки осилил... но вот сайт как то иначе не напишу точно, то есть изучал не пхп а как писать именно такой сайт. sad.gif

З.Ы. Еще окончательно запутался с гет параметрами... распутать так и не смог. Пойду в тысячный раз перечитывать. ph34r.gif

Спустя 42 минуты, 44 секунды (2.09.2010 - 14:19) twin написал(а):
А не надо. Зачем? Осилил = значит можешь и сам. Думай и делй. Там же не руководство к действию, а один из способов.
Если придумаешь как круче - покажи. Я там опубликую, мож кому то тоже на пользу пойдет. smile.gif

Спустя 1 день, 21 час, 37 минут, 49 секунд (4.09.2010 - 11:57) Rasty написал(а):
добрый день, утро, вечер?

Понравились решение с циклами - элегантно получилось.

делаю решение для своего проекта, использую Ваш принцип, но с циклом foreach, так как данные ужо в сессионном массиве:

 $rows = '';
$tpl = getTpl('vented/show_2');
foreach ($_SESSION['vented'] as $ind => $dir)
{
$row = array();
$row['id'] = $dir;
$rows .= parseTpl($tpl, $row);

}

Смысл таков: в сессионном массиве лежат id необходимых полей таблицы БД.
Нужно в массив $row [], добавить так сказать остальную инфу из БД.
я думаю реализовать это вот так:


$rows = '';
$tpl = getTpl('vented/show_2');
foreach ($_SESSION['vented'] as $id => $dir)
{
$row = array();
$row['id'] = $dir;

// запрос к бд по id
$result = mysqlQuery ("SELECT *
FROM tabl
WHERE id='
$dir'");
$mdt = htmlChars(mysql_fetch_assoc($result));
// присваивание массиву $row[] значений из бд

$row['val1'] = $mdt['text']
$row['val2'] = $mdt['telefon']
// и так далее

$rows .= parseTpl($tpl, $row);

}

Мучает такой вопрос: Будет Ли Верным такое решение вопроса?

зы чувствую, что обращение к бд в цикле не есть хорошо.. а что делать?)

ph34r.gif

пасиб

Спустя 10 минут, 44 секунды (4.09.2010 - 12:08) twin написал(а):
Есть такой оператор в SQL - IN()
Вот он и функция implode тут будут уместнее. Запрос будет один всего.

Спустя 39 минут, 23 секунды (4.09.2010 - 12:47) Rasty написал(а):
Вы не представляете моё счастье )

Спустя 2 дня, 9 часов, 14 минут, 33 секунды (6.09.2010 - 22:02) Слава написал(а):
if(mysql_num_rows($res) > 0) 
{
$tpl = getTpl('second/price_rows');

while($row = htmlChars(mysql_fetch_assoc($res)))
{
++$i;
$row['num'] = $i;
$rows .= parseTpl($tpl, $row);
}
}


Не разберусь никак с циклом. Вот как я его понимаю:

Если в массиве $res больше чем 0 строк:

ТО $tpl = "Файл шаблона, если есть",

Если в $res есть строка с ключем $i, то ее вытягиваем в ас. массив $row,

Увеличиваем $i на единицу,

$row['num'] = $i; (это что же массиву $row мы присвояем одну цифру??? или таким образом увеличивается ключ),

Дальше непонятно различие между = и .= (это типа пристыковка к ранее записанным значениям???)

Ну если $row осталась ас.массивом, то функия parseTpl мне понятна, разве что функция eval не разберусь как работает???

Спустя 15 минут, 38 секунд (6.09.2010 - 22:17) twin написал(а):
Начало верное. Потом запутался. Вот это:
            ++$i; 
$row['num'] = $i;
просто порядковый номер для строк таблицы.
Цитата
№№  | наименование | цена
====================
   1    |         ----           |  100
   2    |         ----           |  200

Увеличивается с каждым витком. А чтобы передать в шаблонизатор, его нужно добавить к массиву. Потом достанем, как переменную $tpl_num и сунем в таблицу.

Цитата
(это типа пристыковка к ранее записанным значениям???)

Да. Называется "конкатенация".

eval() тут

Спустя 5 дней, 9 часов, 47 минут, 54 секунды (12.09.2010 - 08:05) Слава написал(а):
Спасибо за пред. ответы.

Есть такой вопрос. По Вашему курсу, всегда перед выводом в поток переменные нужно обрабатывать функцией htmlChars(). А если там есть статья (в переменной), то выходит она будет без тегов, т.е. без абзацев. Если эту функцию пропустить для вывода статей из базы?, не вредно ли это будет для сайта???

Спустя 8 часов, 46 минут, 13 секунд (12.09.2010 - 16:51) twin написал(а):
В базе нечего делать разметке. База нужна для хранение данных, а для разметки существует HTML. Иначе принципы безопасности будут нарушены.

Спустя 2 часа, 24 минуты, 29 секунд (12.09.2010 - 19:16) Слава написал(а):
То есть, текстовую инфу(т.е данные), записанную в одном поле, сможем выводить только одним абзацем, или есть другие варианты?

Спустя 2 минуты, 28 секунд (12.09.2010 - 19:18) Слава написал(а):
По этой же теме, если у меня будет 150 текстовых файлов в папке log (а потом 250), то это будет нормально или чересчур???

Спустя 8 дней, 2 часа, 47 минут, 20 секунд (20.09.2010 - 22:06) Слава написал(а):
Вопрос? Почему так работает:
$row = htmlChars(mysql_fetch_assoc($res));

А вот так не работает:
$row = nl2br(htmlChars(mysql_fetch_assoc($res)));


Спустя 3 минуты, 33 секунды (20.09.2010 - 22:09) twin написал(а):
потому что nl2br() неумеет работать с массивами.

Спустя 18 минут, 30 секунд (20.09.2010 - 22:28) Слава написал(а):
Понял не внимательно читаю). Каким образом можно из базы выводить статьи с переносами строк и пробелами (абзацами). Хотя бы намек, а я попробую разобраться.

Спустя 10 минут, 58 секунд (20.09.2010 - 22:39) twin написал(а):

Спустя 3 дня, 21 час, 36 минут, 8 секунд (24.09.2010 - 20:15) Слава написал(а):
Что бы это могло значить - Notice: Undefined variable: row in X:\home\kurs\www\libs\view.php(52) : eval()'d code on line 4 ?

Спустя 7 минут, 46 секунд (24.09.2010 - 20:23) twin написал(а):
Это в шаблоне неопределена переменная. Именно $row. По контексту могу предположить, что должно быть $tpl_row

Спустя 21 минута, 39 секунд (24.09.2010 - 20:44) Слава написал(а):
Добавил tpl к row ($tpl_row['title']), теперь пишет так: Notice: Undefined variable: tpl_row in X:\home\kurs\www\libs\view.php(52) : eval()'d code on line 4

Спустя 25 минут, 27 секунд (24.09.2010 - 21:10) Omega написал(а):
Слава, покажи шаблон и код вывода строк. У меня тоже была такая ошибка, да я не помню уже как исправил smile.gif Может вспомню в чем дело.

Спустя 2 минуты, 30 секунд (24.09.2010 - 21:12) A.V. написал(а):
В коде с выборкой из БД в цикле $tpl_row['title'].
А в шаблоне переменная $tpl_title.
Проверьте: у вас так?

Спустя 9 минут, 3 секунды (24.09.2010 - 21:21) Слава написал(а):
Спасибо! Собсно в этом и была ошибка! Я уже понял, если Твин не отвечает, значит ответ уже был )

Спустя 2 месяца, 15 дней, 22 часа, 34 минуты, 31 секунда (10.12.2010 - 20:56) bubu123 написал(а):
Опечатка

http://irbis-team.com/15/16/5
некоторые формы, на страничке немног не соответсвуют действительности.
<!-- skins/tpl/second/show.html begin -->
и
skins/js/script.js
с ними кое чего не работает.

Но в архиве, который прилагается ниже, все норм.

Спустя 13 минут, 24 секунды (10.12.2010 - 21:09) twin написал(а):
Спс, поправил.

Спустя 3 дня, 2 часа, 10 минут, 13 секунд (13.12.2010 - 23:19) DiamondeX написал(а):
На этой странице курса по-моему опечатка в листинге файла skins/js/script.js. Очевидно, должно быть так:

function tag(text1, text2)
{

if ((document.selection))
{
document.getElementById('value2').focus(); /*
а было
document.getElementById('text2').focus(); */


document.post.document.selection.createRange().text =
text1+document.post.document.selection.createRange().text + text2;

} else if(document.forms['post'].elements['value2'].selectionStart != undefined) { /*
а было
} else if(document.forms['post'].elements['value[text2]'].selectionStart != undefined) { */


var element = document.forms['post'].elements['value2']; /*
а было
var element = document.forms['post'].elements['value[text2]']; */

var str = element.value;
var start = element.selectionStart;
var length = element.selectionEnd - element.selectionStart;
element.value = str.substr(0, start) + text1 + str.substr(start, length)
+
text2 + str.substr(start + length);

} else document.getElementById('value2').value += text1 + text2; /*
а было
} else document.getElementById('text2').value += text1 + text2; */

}



Я прав?

Спустя 10 минут, 13 секунд (13.12.2010 - 23:30) twin написал(а):
Факт, спасибо.

Спустя 1 день, 1 час, 42 минуты, 42 секунды (15.12.2010 - 01:12) Гость_Сергей написал(а):
Добрый вечер, подскажите пожалуйстоо смысл eval('?>'. $cont .'<?php ');
В ф. eval () мы передаем шаблон (в нем определенны переменные для вывода), а зачем в
ней '?>' и '<?php ' , а не eval($cont);

Спустя 11 минут, 26 секунд (15.12.2010 - 01:24) twin написал(а):
Потому что eval () сразу начинает разбор PHP. А шаблон начинается с HTML. Надо блок PHP закрыть.

Спустя 11 часов, 50 минут, 6 секунд (15.12.2010 - 13:14) DiamondeX написал(а):
twin, здорово конечно, что на этой странице в листинге файла skins/js/script.js была исправлена одна ошибка, но я там говорил о 4х biggrin.gif

(см. комментарии в коде в моем посте выше)

Спустя 9 минут, 20 секунд (15.12.2010 - 13:23) twin написал(а):
упс...

Спустя 1 месяц, 20 дней, 12 часов, 39 минут, 31 секунда (6.02.2011 - 02:03) zere_lip написал(а):
Нашел ошибочку Шаг 5. Паттерн MVC. Вид.

Цитата
Возьмем контроллер второй страницы и напишем туда запрос на выборку данных из нашей таблицы в базе данных. И в цикле соберем в переменную ряды:
modules/second/read_controller.php


Мне кажется имелось в виду modules/second/controller.php

Спустя 1 день, 16 часов, 31 минута, 20 секунд (7.02.2011 - 18:34) zere_lip написал(а):
Доброго времени суток.
Вот есть у нас функция
/**  
* Function of processing of variables for a conclusion in a stream
* Функция обработки переменных для вывода в поток
*/

function htmlChars($data)
{
if(is_array($data)) // Если данные - массив, вызываем эту же функцию.
$data = array_map("htmlChars", $data);
else // Если нет, обрабатываем htmlspecialchars()
$data = htmlspecialchars($data);
// На выход
return $data;
}

Я ни как не могу понять каким макаром она обрабатывает массив.
Если данные массив, то функция array_map вызывает функцию htmlChars, и все по новой, т.е. (на мой ламерский взгляд) никаких алхимических преобразований данных в это время не происходит. Происходит обычный перебор.
Заранее спасибо.

Спустя 19 минут, 45 секунд (7.02.2011 - 18:54) Ulan написал(а):
перебор закончится, когда когда функция доберется до последнего вложенного массива, элементы которого содержат строки, тогда сработает:
else  // Если нет, обрабатываем  htmlspecialchars()             
$data = htmlspecialchars($data);

обработав все элементы

Спустя 26 минут, 18 секунд (7.02.2011 - 19:20) zere_lip написал(а):
Дошло smile.gif, заковыка была в понимании сущности функции array_map

Спустя 9 месяцев, 22 дня, 19 часов, 45 минут, 22 секунды (30.11.2011 - 14:05) rusiamen написал(а):
Добрый день twin. Тут на форуме проскакивала функция

/**
* Function of analysis of a template
* Функция разбора шаблона
*/

function parseTpl($cont, $data)
{
extract($data);

preg_match_all("#<\?php(.*?)\?>#uis", $cont, $code);

$count = count($code[0]);

if($count)
for($i = 0; $i < $count; ++$i)
{
ob_start();
eval($code[1][$i]);
$echo = ob_get_contents();
ob_end_clean();
$cont = str_replace($code[0][$i], $echo, $cont);
}

return $cont;
}



В то же время на сайте irbis идет совершенно иная функция

/**  
* Function of analysis of a template
* Функция разбора шаблона
*/

function parseTpl($cont, $data = '')
{

if(is_array($data))
{

extract($data, EXTR_PREFIX_ALL, 'tpl');

ob_start();
eval('?>'. $cont .'<?php ');
$cont = ob_get_contents();
ob_end_clean();

}
return $cont;
}



Какую из них лучше использовать? Просто мне как-то первая больше приглянулась ввиду возможности замены <?php ?> на что-то иное (например {как в смарти}).

Спустя 1 час, 30 минут, 13 секунд (30.11.2011 - 15:36) inpost написал(а):
rusiamen
Будучи программистом, и умея выбирать, просто проверь скорость, что быстрее будет - то и лучше. Разве нет?
Хотя можно и так: быстрее и удобнее.
Лично мне, как программисту, куда приятнее видеть в шаблонах разграничители в виде <?php, благодаря этому синтаксис подчеркивается в DreamWeaver, а смарти-синтаксис - нет. Да и легче работать с родителем, а не с дочерним интерпретатором.

Спустя 27 минут, 32 секунды (30.11.2011 - 16:03) twin написал(а):
Где ж ты это раскопал... Выброси и забудь. Конечно второй вариант. Какой смысл заменять штатные теги на суррогат, если все равно используется PHP синтаксис.

Спустя 9 минут, 34 секунды (30.11.2011 - 16:13) rusiamen написал(а):
Вы правы, но у меня просто так сложилось, что не могу нормально настроить подсветку для .tpl в phpDesigner.
Приходиться использовать .html шкурки, но где-то читал, что использования порезанного .html вместо .tpl совсем не труъ. При том, что {такой синтаксис} отлично подсвечен.
Вот поэтому было интересно.

Спустя 1 час, 53 минуты, 8 секунд (30.11.2011 - 18:06) inpost написал(а):
rusiamen
.html - это принятое всеми браузерами формат отображения. А .tpl - внештатное правило, которое нигда не прописано и никак не обрабатывается. Видимо где-то есть список форматов, а .tpl вообще ни к одному из форматов не относится.


_____________
Если вам недостаточно собственных заблуждений, можно расширить их мнениями экспертов.

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.