Как запретить вывод блока если он пуст

S
На сайте с 13.11.2012
Offline
72
3970

Имеются блоки вида

<div class="section-box"><div class="section-header"><h2 class="section-title"><a class="name-link" href="<?php echo $this->config["url"] ?>/search/<?php echo $this->config["onecatesearch"] ?>"><span class="name"><?php echo $this->config["onecatename"] ?></span></a></h2><a class="more-link" href="<?php echo $this->config["url"] ?>/search/<?php echo $this->config["onecatesearch"] ?>"><span>More <i class="mini-arrow-right"></i></span></a></div><div class="section-content grid-small"><div class="nag cf">
<div class="my-trailers-slider"><?php echo $this->getonecate() ?></div>

Как запретить отображение-вывод блока, если значение onecatename не задано?

Пробовал

<?if(!empty($sk['config']['onecatename'])):?>блок<?endif;?>
не работает вообще пол страницы не открывает. Менял $sk на $this не помогло

p.s. не знаю что значит $sk и $this

Спасибо!

S
На сайте с 19.11.2014
Offline
72
#1
Smirnof:
Имеются блоки вида


Как запретить отображение-вывод блока, если значение onecatename не задано?
Пробовал не работает вообще пол страницы не открывает. Менял $sk на $this не помогло
p.s. не знаю что значит $sk и $this

Спасибо!

<div class="section-box">

<?php if(isset($this->config["onecatename"]) && $this->config["onecatename"]!=''):?>

<div class="section-header">

<h2 class="section-title">

<a class="name-link" href="<?php echo $this->config["url"] ?>/search/<?php echo $this->config["onecatesearch"] ?>">

<span class="name"><?php echo $this->config["onecatename"] ?></span>

</a>

</h2>

<a class="more-link" href="<?php echo $this->config["url"] ?>/search/<?php echo $this->config["onecatesearch"] ?>"><span>More <i class="mini-arrow-right"></i></span></a>

</div>

<?php endif;?>

<div class="section-content grid-small"><div class="nag cf">

<div class="my-trailers-slider"><?php echo $this->getonecate() ?></div>

Проверяет, определена ли переменная и если да и не равна пустой строке, то выводит.

K
На сайте с 03.06.2015
Offline
45
#2

Нормально данные для вывода должны быть инициализированы.


if(!isset($this->config['foo']))
$this->config['foo']=null;

Тогда в рендере делается обычный вывод в буфер и, если там было ничего - то ничего и не будет.

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


if(isset($this->config['foo']))
$foo='<div>'.$this->config['foo'].'</div>';
else
$foo=null;

функция


$foo=function(&$data){
if(isset($data['foo']))
return '<div>'.$data['foo'].'</div>';
};

И на выводе делается просто echo $foo($this->config);

Если эта функция хочет больше данных, можно применить use($bar,$baz)

---------- Добавлено 27.07.2015 в 20:24 ----------

Так вот если ваш конфиг с геттером, то инициализация не нужна, вы можете вывести любую переменную в любом месте и если ее не было - ничего не выведется, ибо геттер вернет null. Кроме того поскольку isset в геттере, то в скрипте, если надо проверить на пусто, проверка соединяется с присвоением


if($foo=$this->config['foo'])
$foo='<div>'.$foo.'</div>';

else не нужен, т.к. $foo==null уже.

---------- Добавлено 27.07.2015 в 20:36 ----------

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

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

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

MYSQL PHP JS HTML CSS SEO TXT США СССР
S
На сайте с 13.11.2012
Offline
72
#3

Swir, спасибо! Работает как и хотел.

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

totamon
На сайте с 12.05.2007
Offline
437
#4
kostyanet:
никаких долбаных шаблонов с идиотскими мета-языками.

на бис еще можно что-нибудь про шаблоны и метаязыки🍿

Домены и хостинг https://8fn.ru/regru | Дедик от 3000р https://8fn.ru/73 | VPS в Москве https://8fn.ru/72 | Лучшие ВПС, ТП огонь, все страны! https://8fn.ru/inferno | ХОСТИНГ №1 РОССИИ https://8fn.ru/beget
K
На сайте с 03.06.2015
Offline
45
#5

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

То есть тому объекту который у вас там $this надо сделать расширение мозга объектом с такими геттером и сеттером.

Это было автору темы.

Затем из такой модели делается коллекция в объекте типа ArrayObject, то есть с интерфейсом массива и в эту коллекцию собираются такие же коллекции, в них еще и так далее согласно структуре хтмля или там чего-то еще. У каждой модели есть __toString() который рекурсивно будет вызван при попытке вывести корневую коллекцию в строку. Вот и весь "шаблон". Модели собирают дерево и затем скажем echo $this->models и действующее вещество в буфере.

Это было на бис.

---------- Добавлено 27.07.2015 в 23:58 ----------

Еще раз.

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

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

Чтобы добавить фичу в шалобоне, надо сделать как выше процитировано

if(isset($foo)):

<div><?php echo $foo; ?></div>

Чтобы добавить фичу в логике, надо воткнуть этот $this->foo куда надо. Прототип выведет $foo которое в нем null, а если прототип был расширен и $foo наполнилось смыслом - так и выведется.

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

В общем и целом так устроена рамка yii. Я не пользуюсь, просто изучал рамки и обнаружил что китайская уюя пока что самая продвинутая.

R
На сайте с 20.02.2015
Offline
59
#6

kostyanet, на бис отлично выдал :)

S
На сайте с 13.11.2012
Offline
72
#7

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

K
На сайте с 03.06.2015
Offline
45
#8

Smirnof, вы сами пишите? Тогда вот такой простой пример, сначала прототип, то есть базисный класс, потом его расширение.


Class Listing {
/*
в прототипе метод может вернуть null, или array() или пусто ''
или скажем данные вернуть как есть, без форматирования
*/

protected function price(&$item=null){
return null;
}

/* вывод листинга в прототипе */

protected function render_items(){
$html=array();
foreach($this->data as $item)
$html[]='<figure>'.$this->image($item).$this->desc($item).$this->price($item).'</figure>';
if($html)
return '<div class="prod-items">'.join($html).'</div>';
else
return $this->notfound();
}

/*
волшебный метод __toString() обязан вернуть строку
поэтому все завернуто в try-catch блок
*/

public function __toString(){
try{
return $this->before_render().$this->render_items().$this->after_render();
}
catch(Exception $e) {
return $e;
}
}

}

/* а это в классе который расширяет прототип */

class ListingMarket extends Listing {

/* теперь метод price будет возвращать форматированную цену */

protected function price(&$item=null){
if(!$item)
$item=$this->item;

if($price=$item['price'])
return '<val>'.format_number($price,FORMAT_DECIMALS,FORMAT_DEC_PT,FORMAT_TH_SEP).'</val>';
}
}

/* где-то в моделях куда-то монтируем */
$this->list= new ListingMarket();
$this->list->select(); /* это еще отдельная история как расширять базисные запросы */

/* где-то в представлении штукатурим */
<main><?php
echo $this->navbar, $this->list; $this->pagination;
?></main>

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


public function __toString(){
try{
$o=&$this->opts;
return $this->before_render()
.'<'.$o['tag'].' id="'.$o['id'].'" class="'.$o['css'].'">'
.$this->render()
.'</'.$o['tag'].'>'
.$this->after_render();
}
catch(Exception $e) {
return $e;
}
}

Затем эти $this->opts можно отгрузить в JS через json_encode() и получить все нужные сведения для работы с листингом в браузере.

---------- Добавлено 28.07.2015 в 08:45 ----------

Вполне понятно что все это - азы ООП и ОРМ, мне даже неудобно слегка все это объяснять. Причину я тоже знаю. Мы не читаем по-английски даже сайты о программировании, где особо его и знать не надо. Черпаем инфу с застарелых туторов в рунете и древних, популярных рамок (framework) переведенных на русский всякими полугурками. Учите английский.

---------- Добавлено 28.07.2015 в 08:56 ----------

Ну вот, а еще есть доступ к методам родителя (но НЕ переменным родителя если он требует инстанси).


protected function price($item=null){
return $this->old_price($item).parent::price($item);
}

метод приделает к выводу ценника из родителя - типа "старый", зачеркнутый ценник в классе который расширяет родителя.

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

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

S
На сайте с 13.11.2012
Offline
72
#9

Еще один дилетантский вопрос перед изучением Yii PHP framework.

В шаблоне у меня выводятся данные при помощи ...getonecate..., ...gettwocate... и т.д.

<div class="section-box">
<div class="section-header">
<h2 class="section-title"><a class="name-link" href="<?php echo $this->config["url"] ?>/search/<?php echo $this->config["onecatesearch"] ?>"><span class="name"><?php echo $this->config["onecatename"] ?></span></a></h2>
<a class="more-link" href="<?php echo $this->config["url"] ?>/search/<?php echo $this->config["onecatesearch"] ?>"><span>More <i class="mini-arrow-right"></i></span></a>
</div>
<div class="section-content grid-small">
<div class="nag cf">
<div class="my-trailers-slider"><?php echo $this->getonecate() ?></div>
</div>
</div>
</div>

get*** берет данные из файла youtube class и конфига.

Сам youtube class имеет вид:


protected function getonecate($id){
// Construct URL
$part = "snippet";
$this->url = "https://www.googleapis.com/youtube/v3/search?key={$this->key}&part=$part&order=data&maxResults=5&q={$this->config["onecatevideos"]}&type=video";
// Get Data
$data = $this->http(TRUE);
foreach ($data->items as $yt) {
$html .= $this->listQueryVideo($yt);
}
return $html;
}

protected function gettwocate($id){
// Construct URL
$part = "snippet";
$this->url = "https://www.googleapis.com/youtube/v3/search?key={$this->key}&part=$part&order=data&maxResults=5&q={$this->config["twocatevideos"]}&type=video";
// Get Data
$data = $this->http(TRUE);
foreach ($data->items as $yt) {
$html .= $this->listQueryVideo($yt);
}
return $html;
}

one, two и миллион... но значения запросов в url адресе может быть разным, само собой сам поисковый запрос + кол-во результатов и других возможных фильтров.

Как я предполагаю, получается куча лишнего кода в youtube class, я прав?

Мне кажется, что в youtube class можно создать одно поле

protected function get***cate($id){
// Construct URL
$part = "snippet";
$this->url = "https://www.googleapis.com/youtube/v3/search?videoEmbeddable=true&key={$this->key}&part=$part&order=data&maxResults=5&q={$this->config["***catevideos"]}&type=video";
// Get Data
$data = $this->http(TRUE);
foreach ($data->items as $yt) {
$html .= $this->listQueryVideo($yt);
}
return $html;
}

и использовать его как шаблон для всех one, two и миллион...

Совсем запутался, такое возможно?

Это в разы сократило бы весь код.

Надеюсь понятно написал.

S
На сайте с 19.11.2014
Offline
72
#10
Smirnof:
Еще один дилетантский вопрос перед изучением Yii PHP framework.
В шаблоне у меня выводятся данные при помощи ...getonecate..., ...gettwocate... и т.д.
get*** берет данные из файла youtube class и конфига.

Мне кажется, что в youtube class можно создать одно поле
Совсем запутался, такое возможно?
Это в разы сократило бы весь код.

Надеюсь понятно написал.

Не поле (переменная), а метод (функцию) как я понимаю

Да, возможно, например


protected function getcates($id, $nom){
// Construct URL
$part = "snippet";
$this->url = "https://www.googleapis.com/youtube/v3/search?videoEmbeddable=true&key={$this->key}&part=$part&order=data&maxResults=5&q={$this->config[$nom.'catevideos']}&type=video";
// Get Data
$data = $this->http(TRUE);
foreach ($data->items as $yt) {
$html .= $this->listQueryVideo($yt);
}
return $html;
}

И заменяете вызовы getonecate..., ...gettwocate на getcates($id, 'one'), getcates($id, 'two') и т.д

Не увидел, где у вас в методе используется $id? Может он не нужен,

тогда метод protected function getcates($nom)

а вызовы getcates('one'), getcates('two')

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий