Рубрики
Wordpress

Плагин создал X символов неожиданного вывода при активации в WordPress

Как избежать неожиданного вывода

При разработке своего плагина можно столкнуться с тем, что при активации появляется сообщение наподобие “Плагин генерировал X символов неожиданного вывода при активации”.

Наиболее распространенных причин данной ошибки три:

  • Не верно указана кодировка файла;
  • После закрывающего php тега стоит пробел или таб;
  • Ошибка в коде, например в SQL запросе, при создании таблиц.

Кодировка файла – причина неожиданного вывода

Если у вас ошибка неожиданного вывода в этом, то скорее всего вы пользуетесь программой наподобие Notepad++. Вам не нужно дополнительно указывать BOM(Byte order mark), так как он уже определен. Поэтому в качестве кодировки укажите UTF-8 без BOM.

Нечитаемый символ после закрывающего тега

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

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

Пример неправильного завершения файла, не являющегося шаблоном:

<?php
function someName(){
  // код файла
}
?>

Правильный пример:

<?php
function someName(){
  // код файла
}

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

Ошибка в коде

Для отлова ошибки в коде необходимо включить вывод ошибок. В файле wp-config.php добавьте следующие значения:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );

В этом случае все ошибки сервера попадут в лог. Расположение этого файла зависит от настроек, обычно он в папке wp-content.

Вы можете создать отдельный файл, для отлова данный ошибки:

function create_error_log() {
	$out = ob_get_contents();
	if ( ! empty( $out ) ) {
		file_put_contents( ABSPATH . '/error_log_' . date( 'Y_m_d_H_i_s' ) . '.html', $out );
	}
}

Функцию нужно выполнить после того, как отработали другие функции, которые срабатывают при активации плагина:

function activation() {
    // код каких-то функций тут
    get_error_log();
}

register_activation_hook( __FILE__, 'activation' );

При возникновении ошибки, в корне сайта будет создаваться файл с именем error_log_<дата и время активации>.html. Файл будет содержащий данные об ошибке неожиданного вывода.

Рубрики
SEO

Как изменить информацию на превью сайта?

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

Как правильно подготовить превью сайта?

Сперва стоит написать статью, затем проработать SEO по тексту. После этого можно приступать к подготовке превью сайта.

Подготовка страницы сайта для SEO

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

Для этого используется OpenGraph разметка. С помощью OpenGraph вы фактически указываете значимые атрибуты страницы. Если вы определяете данные OpenGraph с помощью тега meta, то формат записи таков:

<meta property="og:title" content="Заголовок моей потрясающей статьи" />

Атрибут мета-тега property содержит имя OpenGraph атрибута, а content его значение.

Список необходимых OpenGraph атрибутов:

  • og:locale – определяет локаль, в которой находится данная страница. Если статья на русском, то значение должно быть такое: ru_RU.
  • og:type – тип публикации. Если это статья, то значение будет article;
  • og:title – заголовок статьи;
  • og:description – краткое описание статьи;
  • og:url – адрес постоянной ссылки на страницу, по которой она доступна;
  • og:site_name – имя сайта, не домен, а именно имя, например General Motors Company;
  • article:published_time – дата и время публикации в формате "YYYY-MM-dd'T'HH:mm:ss.SSSXXX";
  • article:modified_time – дата и время внесения изменений, в том же формате;
  • og:image – полный путь к изображению;
  • og:image:width – ширина изображения;
  • og:image:height – высота изображения.

Пример

<meta property="og:locale" content="ru_RU" />
<meta property="og:type" content="article" />
<meta property="og:title" content="Заголовок моей изумительной статьи" />
<meta property="og:description" content="Данная статья содержит подробную информацию о том, как стоит вести себя в цивилизованном обществе и вообще жить по совести." />
<meta property="og:url" content="https://mysite.ru/articles/moya-statia.html" />
<meta property="og:site_name" content="General Motors Company" />
<meta property="article:published_time" content="2020-10-22T06:01:31+00:00" />
<meta property="article:modified_time" content="2020-10-21T18:33:05+00:00" />
<meta property="og:image" content="https://mysite.ru/images/life.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />

При этом og:image:width и og:image:height стоит указать, если параметры изображения отличаются от 1200×630.

Если вы используете какую-либо CMS, то для нее наверняка есть специальный инструмент для SEO. Этот инструмент избавит вас от написания кода и сделает бóльшую часть работы.

Подготовка изображения для превью сайта

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

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

Если вы планируете писать на миниатюре записи текст, то его следует расположить в центре.

Формирование миниатюры страницы сайта

При формировании изображения я ориентируюсь на то, чтобы оно хорошо смотрелось в Facebook, Vkontakte и WhatsApp. За основу берется формат Facebook – 1200×630.

Если изображение подобного формата поместить во Vkontakte, то VK обрежет его снизу:

Как изменить информацию на превью сайта?

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

Как изменить информацию на превью сайта?

Поэтому следует предусмотреть то, что текст должен влезть в эту область.

Чтобы текст не прилипал к краям получившегося квадрата, следует его уменьшить так, чтобы был отступ:

Как изменить информацию на превью сайта?

Если все сделать правильно, то получится так:

Как изменить информацию на превью сайта?
миниатюра страницы сайта в Facebook
Как изменить информацию на превью сайта?
миниатюра страницы сайта в Vkontakte
Как изменить информацию на превью сайта?
миниатюра страницы сайта в Google

Когда мы наложим рамки, мы убедимся, что текст везде влезает корректно:

Как изменить информацию на превью сайта?

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

Скачать его можно тут.

После того, как вы сделали все вышеописанные шаги, перейдите в специальный инструмент от Facebook. В поле ввода введите ссылку, нажмите Enter. Далее нажмите кнопку “Fetch New Information”.

Если превью страницы создавалось ранее, то нажмите “Scrap Again”. Это обновит информацию превью страницы сайта, если вы внесли изменения.

Рубрики
PHP

БЭМ в PHP для WordPress

К хорошему привыкаешь быстро, особенно, когда верстаешь страницу в стеке Vue + Pug + Bem!

На мой взгляд это наиболее удобный стек для верстки.

Вот как выглядит код на этом стеке:

+b.product
	+e.inner
		+e.image
		+e.info
			+e.H2.title {{ product.title }}
			+e.price._new {{ product.price }}

А так этот же код выглядит на чистом HTML:

<div class="product">
	<div class="product__inner">
		<div class="product__image"></div>
		<div class="product__info">
			<h2 class="product__title">{{ product.title }}</h2>
			<div class="product__price product__price_new">{{ product.price }}</div>
		</div>
	</div>
</div>

Как видно из примера – вместо каждого +e дописывается название, взятое из предыдущего +b.

Синтаксис таков:

  • Часть названия класса, которая идет после точки компилируется в имя дочернего элемента:+e.inner > product__inner;
  • Часть названия класса, которая идет после точки и начинается с символа нижнего подчеркивания компилируется в имя миксина: +e.price._new > product__price product__price_new;

Работая с WordPress реализовать такую роскошь для создания шаблонов сложно, хотя можно… но кому это вообще надо? )

Делая очередной шаблон страницы на WordPress я очень скучал по простому созданию классов в стиле БЭМ и решил хоть как-тот облегчить себе задачу.

Техническое задание

Без использования шаблонизатора не удастся легко и просто реализовать работу через псевдо-переменные +b и +e, поэтому придется придумать что-то попроще.

Должен быть реализован синтаксис создания классов дочерних элементов и миксинов.

  1. Если указано название класса, не начинающееся с точки, это должен быть родительский класс, например product;
  2. Если за родительским классом идет один или более классов, начинающихся с точки, после которой нет символа нижнего подчеркивания, то должно быть создано столько экземпляров дочерних классов, сколько объявлено, например: product.one.two.three > product__one product__two product__three;
  3. Если после точки идет символ нижнего подчеркивания – это миксин и он должен быть дописан к каждому классу, например: product.one.two.three._first._second > product__one product__two product__three product__one_first product__one_second product__two_first product__two_second product__three_first product__three_second.

Реализация

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

Пусть функция будет называться bem и для начала пусть она принимает один параметр – строку, которая является цепочкой частей классов:

bem('product.one.two.three._first._second');

Объявим функцию:

function bem( $classTrail = '' ) {
	if ( empty( $classTrail ) ) {
		return '';
	}
}

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

Далее следует разбить строку на массив:

$classTrail = array_values( array_filter( explode( '.', $classTrail ) ) );

Следом необходимо определить переменные, которые будут хранить промежуточные данные для миксинов и классов, а так же определить начальное значение для составного класса и посчитать число элементов цепочки:

$mixins  = [];
$classes = [];
$block   = '';
$count   = sizeof( $classTrail );

Далее делаем перебор нашего массива $classTrail:

foreach ( $classTrail as $i => $item ) {
    // код
}

Первым делом следует к составному элементу $block приписать название родительского класса, в нашем случае это product. Это следует сделать только в том случае, если мы на первой итерации:

if ( 0 === $i ) {
	$block = $classTrail[ $i ];
}

Вполне может быть, что в нашей цепочке частей классов указан только один класс, поэтому в таком случае нам следует сделать проверку и если так и окажется, добавить этот класс в список:

if ( 0 === $i ) {
	$block = $classTrail[ $i ];

	if ( 1 == $count ) {
		$classes[] = $block;
	}
}

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

if ( 0 === strpos( $classTrail[ $i ], '_' ) ) {
    // код
}

И если это миксин, сразу добавим его в список миксинов:

if ( 0 === strpos( $classTrail[ $i ], '_' ) ) {
	$mixins[] = $classTrail[ $i ];
}

Если при этом в нашей цепочке всего 2 элемента, это означает, что указан родительский класс и миксин: product._new, в этом случае следует часть составного класса добавить в список классов:

if ( 0 === strpos( $classTrail[ $i ], '_' ) ) {
	$mixins[] = $classTrail[ $i ];
	if ( 2 == $count ) {
		$classes[] = $block;
	}
}

В ином случае, если это не миксин, мы понимаем, что это дочерний класс, который сразу добавим в список классов:

if ( 0 === strpos( $classTrail[ $i ], '_' ) ) {
	$mixins[] = $classTrail[ $i ];
	if ( 2 == $count ) {
		$classes[] = $block;
	}
}
else {
	$classes[] = $block . '__' . $classTrail[ $i ];
}

Таким образом мы составили список классов и миксинов:

$mixins  = [];
$classes = [];
$block   = '';
$count   = sizeof( $classTrail );
foreach ( $classTrail as $i => $item ) {
	if ( 0 === $i ) {
		$block = $classTrail[ $i ];

		if ( 1 == $count ) {
			$classes[] = $block;
		}
	}
	else {

		if ( 0 === strpos( $classTrail[ $i ], '_' ) ) {
			$mixins[] = $classTrail[ $i ];
			if ( 2 == $count ) {
				$classes[] = $block;
			}
		}
		else {
			$classes[] = $block . '__' . $classTrail[ $i ];
		}
	}
}

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

foreach ( $classes as $i => $class ) {
	foreach ( $mixins as $j => $mixin ) {
		$classes[] = $classes[ $i ] . $mixin;
	}
}

Работа практически завершена, но лично у меня есть потребность создавать различные наборы классов. Скажем одна цепочка служит для создания набора классов для описания внешнего вида, вторая для указания селекторов для использования в JS, например:

bem('product._new js.product');
// в результатае будет: product product_new js__product

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

$trails = [];

$classTrails = array_values( array_filter( explode( ' ', $classTrail ) ) );

foreach ( $classTrails as $classTrail ) {

	$classTrail = array_values( array_filter( explode( '.', $classTrail ) ) );

	$mixins  = [];
	$classes = [];
	$block   = '';
	$count   = sizeof( $classTrail );
	foreach ( $classTrail as $i => $item ) {
		if ( 0 === $i ) {
			$block = $classTrail[ $i ];

			if ( 1 == $count ) {
				$classes[] = $block;
			}
		}
		else {

			if ( 0 === strpos( $classTrail[ $i ], '_' ) ) {
				$mixins[] = $classTrail[ $i ];
				if ( 2 == $count ) {
					$classes[] = $block;
				}
			}
			else {
				$classes[] = $block . '__' . $classTrail[ $i ];
			}
		}
	}

	foreach ( $classes as $i => $class ) {
		foreach ( $mixins as $j => $mixin ) {
			$classes[] = $classes[ $i ] . $mixin;
		}
	}

	$trails = array_merge( $trails, $classes );
}

Теперь осталось вернуть результат. Его можно вернуть в виде:

  • массива;
  • строки;
  • строки вида class="product product_new".

Для этого я ввел еще два входных параметра в функции, мне удобно было именно так:

  • $toAttribute = false – венуть классы внутри атрибута class;
  • $isArray = true – вернуть массив.
bem('product._new js.product', true);
// вернет class="product product_new"

bem('product._new js.product', false, false);
// вернет 'product product_new'

bem('product._new js.product');
// вернет массив

Полный код функции

/**
 * Function that creates the classes chain in BEM style
 *
 * @param string $classTrail
 * @param bool   $toAttribute
 * @param bool   $isArray
 *
 * @return array|string
 */
function bem( $classTrail = '', $toAttribute = false, $isArray = true ) {
	if ( empty( $classTrail ) ) {
		return '';
	}

	$trails = [];

	$classTrails = array_values( array_filter( explode( ' ', $classTrail ) ) );

	foreach ( $classTrails as $classTrail ) {

		$classTrail = array_values( array_filter( explode( '.', $classTrail ) ) );

		$mixins  = [];
		$classes = [];
		$block   = '';
		$count   = sizeof( $classTrail );
		foreach ( $classTrail as $i => $item ) {
			if ( 0 === $i ) {
				$block = $classTrail[ $i ];

				if ( 1 == $count ) {
					$classes[] = $block;
				}
			}
			else {

				if ( 0 === strpos( $classTrail[ $i ], '_' ) ) {
					$mixins[] = $classTrail[ $i ];
					if ( 2 == $count ) {
						$classes[] = $block;
					}
				}
				else {
					$classes[] = $block . '__' . $classTrail[ $i ];
				}
			}
		}

		foreach ( $classes as $i => $class ) {
			foreach ( $mixins as $j => $mixin ) {
				$classes[] = $classes[ $i ] . $mixin;
			}
		}

		$trails = array_merge( $trails, $classes );
	}

	if ( ! empty( $toAttribute ) ) {
		return ' class="' . join( ' ', $trails ) . '" ';
	}

	// if $isArray is false
	if ( empty( $isArray ) ) {
		$trails = join( ' ', $trails );
	}

	// return classes as array
	return $trails;
}

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

Благодаря данной функции наш шаблон станет выглядеть так:

<div <?php echo bem( 'product', true ); ?>>
	<div <?php echo bem( 'product.inner', true ); ?>>
		<div <?php echo bem( 'product.image', true ); ?>></div>
		<div <?php echo bem( 'product.info', true ); ?>>
			<h2 <?php echo bem( 'product.title', true ); ?>>{{ product.title }}</h2>
			<div <?php echo bem( 'product.price', true ); ?>>{{ product.price }}</div>
		</div>
	</div>
</div>

Кому-то может показаться, что стало хуже… но этот только в том случае, если вы не работаете с БЭМ, да еще и в WordPress ))

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

Рубрики
FrontEnd

CSS анимация HTML без картинок

В данном уроке я покажу как работает CSS анимация и как ее сделать, используя только HTML и CSS без использования JavaScript и изображений. CSS анимация – это когда мы с помощью свойств стилей заставляем HTML блоки изменять свои характеристики положения, размера и цвета.

Рубрики
Утилиты

Автоматическая очистка HTML кода от “мусора”

HTML Cleaner – сервис очистки html тегов от “мусора”, который остается в документе после сохранения страницы в формате html из программы MS Word.

Рубрики
FrontEnd

Урок: блоки в одну строку CSS

Для того, чтобы выстроить блоки в одну строку с помощью CSS необходимо понимать, что выстраиваемые блоки представляют собой не просто какие-то разрозненные блоки, а группу. Понимая это необходимо объединить их. Объединение осуществляется с помощью заключения всех блоков в какой-то другой блок, который будет “родительским” по отношению к этой группе.

Рубрики
Backend

Использование PHP для сайта-визитки, разделение на модули

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

Зачем вообще использовать PHP в создании сайтов? Даже если вы не являетесь программистом и делаете сайт исключительно для себя, то со временем сайт будет расти и шириться. Так бывает всегда и у всех. Все и всегда сталкиваются с одной и той же проблемой – при добавлении нового раздела сайта, а следовательно и нового пункта меню, нужно, что бы измененное меню появилось на всех страницах сайта. Все прекрасно, когда вы используете CMS, измененное меню “само собой” появится на всех страницах сайта, но как быть, если вы, по какой-то причине, использовали статические страницы, сохраненные с расширением *.html? Такое бывает довольно часто, даже в наше время, когда, казалось бы, все используют различные CMS.

Отличным решением проблемы будет разделение страницы сайта на модули.

В этом случае есть два, наиболее простых, варианта решений:

  • использовать SSI
  • использовать JavaScript
  • использовать PHP

Первый способ, с использованием SSI можно обнаружить по следующему адресу:

SSI в примерах

Второй способ будет описан на данном сайте позднее.

Третий способ, с использованием PHP рассмотрим далее.

Использование PHP при разделении страницы сайта на модули:

Во-первых, для того, что бы использовать возможности языка PHP ваш хостинг должен предоставлять такую услугу, во вторых файлы, которые будут содержать инструкции PHP должны иметь расширение *.php и в третьих, инструкции, внутри файла должны быть заключены в конструкцию:

<?php /* ВАШ КОД */ ?>

С помощью PHP можно подключить файл как обычную функцию, при этом содержимое файла будет обработано как если бы он был автономным PHP сценарием. При этом все функции, определенные в подключаемом файле можно использовать как внутри файла в котором происходит подключение, так и в любых других подключенных файлах. И называется эта функция include.
При разработке простого сайта-визитки удобно разделить уже сверстанный макет сайта на логические части/модули. Например можно разделить макет на три части: header, footer и content. В первых двух модулях будут содержаться куски HTML кода, которые на всех страницах сайта изменяться не должны, что логично, ведь дизайн должен быть неизменным во всех разделах сайта. Изменяться будет только та часть, которая содержит контент.
Во-первых данный подход существенно снижает риск допустить ошибку верстки, так как готовые файлы header и footer уже не будут подвергаться изменениям, а во-вторых, при внесении изменений в дизайн достаточно будет изменить только два файла, не затрагивая файлы содержащие контент, это особенно актуально, когда ваш сайт содержит хотя бы более десяти страниц.

В своем примере я разделил сайт на четыре модуля. В одном файле я буду хранить функции, которые стану использовать на сайте, в других двух файлах будет часть до и после контента и третья часть – контент.
При этом я буду загружать нужный контент динамически, точнее за меня это сделает PHP.
Мой основной файл, index.php, будет содержать следующий код:

<?
include 'functions.php';
include 'header.php';
include page_name().'.php';
include 'footer.php';
?>

Сперва я подключил файл содержащий функции, затем все остальное. Поскольку PHP язык линейный, то я подключаю файлы, содержащие части верстки в той последовательности, в которой они были изначально, до разделения.
Вы заметили, что я использую функция page_name(). В данной функции я определяю – какой файл запросил пользователь и подключаю его.
Код данной функции выглядит следующим образом:

function page_name() // функция определяет какой файл подключить в части контента
{
$page = $_GET['p']; // получаем значение переменной из строки адреса
if($page==''){$page = 'main';} // если значение не указано, значение переменной page устанавливается равным main
return $page; // возвращаем значение переменной page
}

 

Сперва функция получает из строки адреса имя файла, который следует подключить в части контента. Эти данные попадают в адресную строку при клике по ссылке, в меню, так как я указываю такую конструкцию:

<a href="/">Главная</a>
<a href="/?p=about">Обо мне</a>
<a href="/?p=contacts">Контакты</a>

 

То есть в строке адреса содержится информация о том, что некая переменная p имеет значение равное тому, что идет после знака “равно”. Соответственно при клике на ссылку “Обо мне” пользователь перейдет в корень сайта(на главную страницу) и в строке адреса будет передан параметр p со значением about, поэтому вместо текста, главной страницы пользователь увидит текст страницы “Обо мне“, а при клике на “Контакты“, значение будет равно contacts и текст страницы будет соответствующим. В первой строке функции как раз говорится, что:  нужно получить значение переменной p из адресной строки и поместить это значение в переменную $page.

Как мы видим, ссылка на главную не содержит никаких параметров, но тем не менее необходимость подгрузить какой-то контент остается и для этой цели применяется условный оператор, который помещает в переменную $page значение равное слову “main“. Затем функция возвращает результат своей работы, а именно возвращает значение переменной $page, которое подставляется в то место, где была вызвана функция, а именно в 4-ю строку файла index.php, в которой загружается соответствующий файл. Для главной, при отсутствии параметров, main.php, для “Обо мне” – about.php , для “Контакты” – contacts.php.

Выделение активного раздела

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

function current_page($link='') // функция опреляет страницу, которая отображается в данный момент
{
$page = $_GET['p']; // получаем значение переменной из строки адреса
if($page==$link) // если значение переменной page равно значению переменной link...
{
return ' class="current"'; // возвращаем указанную строку
}
}

Данная функция точно так же получает из адресной строки значение переменной p, а за тем сравнивает это значение с тем, что было передано в функцию в качестве ее параметров и если эти значения совпадают, то функция возвращает строку, содержащую конструкцию определяющую атрибут класса в html.

<a href="/">Главная</a>
<a href="/?p=about">Обо мне</a>
<a href="/?p=contacts">Контакты</a>


Далее, значение, возвращаемое функцией, выводится в том месте, где эта функция была вызвана.

Предположим, что пользователь просматривает раздел “Обо мне“, значит в адресной строке находится нечто следующее: http://mysite.ru/?p=about и следовательно программа обработчик идя по коду и встречая на своем пути PHP код делает проверку. Когда обработчик встречает функцию без параметра – current_page() он сверяет то, что в адресной строке и то что передано в функцию в качестве параметра. Поскольку в адресной строке значение p чему-то равно, то в данном случае функция ничего не возвращает. Затем следует та же функция, но уже с параметром, равным “about” и сравнивая это значение со значение в адресной строке оказывается, что значения равны и следовательно функция возвращает строку  class="current", таким образом получается, что при просмотре HTML кода страницы мы увидим, что для ссылки на раздел “Обо мне” определен класс – <a href="/?p=about" class="current">Обо мне</a>. Ну и в последнем случае, когда встречается функция current_page('contacts'), она ничего не возвращает, так как значение параметра функции не соответствует значению переменной из адресной строки.

Это простейший вариант решения задачи. Так как в примере используется всего три пункта меню, решение было “в лоб”, но если пунктов меню больше, то удобней использовать цикл, для вывода меню.

Пример такого цикла приведен ниже:

function menu()
{
// формируем массив, состоящий из имени файла и соответствующего названия раздела
$menu = array(
'main' => 'Главная',
'about' => 'Обо мне',
'contacts' => 'Контакты',
);
$out = ''; // обнуляем переменную, которая будет содержать сформированный код меню
foreach($menu as $url=>$name) // начинаем перебор массива
{
if($url==$_GET['p']||($_GET['p']==''&&$url=='main')) // сравниваем значение текущего элемента массива с параметром из адресной строки
{
// значение текущего элемента массива соответствует значению переменной из адресной строки
$current = ' class="current"'; // значение переменной равно строке определяющей класс
}else
{
$current = ''; // значение переменной пусто
}
if($url<>'main') // проверяем, является ли значение текущего элемента массива соответствующим строке 'main'
{
$url = '?p='.$url; // если нет, то ссылка будет иметь указанный вид
}else
{
$url = '?'; // если да, то нужно ссылаться на корень сайта
}
$out .= '<a href="'.$url.'"'.$current.'>'.$name.'</a>'; // формируем ссылку соответствующую текущему элементу массива и дописываем ее к уже сформированной строке
}
return $out; // возвращаем сформированную строку
}
print menu(); // выводим результат работы функции


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

Рубрики
FrontEnd

Выравнивание – блок по вертикали

По поводу того, как выравнивать блок по вертикали написано масса материалов и статей, но самым простым способом является использование решения, которое будет работать везде. И все благодаря CSS 3.

Помимо свойства display: table появилось есть свойство display: table-cell и именно комбинацию этих двух свойств мы будем использовать.

Схема работы очень проста – создается главный блок со свойством display: table, а в нем создается еще один блок, но уже со свойством display: table-cell и эта конструкция ведет себя как обычная таблица – высота вложенного блока занимает все пространство, то есть в данном случае становится равной высоте родительского блока. При этом содержимое блока выравнивается по вертикали по центру, если нет указания на иное, в том числе и блоки.

Выравнивание блока по вертикали, код HTML:

<div class="main_block">
    <div>
        <div class="block">Выравнивание - блок по вертикали</div>
    </div>
</div>

Для наглядности окрасим родительский блок в красный, а дочерний в серый.

Выравнивание блока по вертикали, код CSS:

.main_block {
    display: table;
    width: 100%;
    height: 200px;
    background: #f00;
}
.main_block > div {
    display: table-cell;
    vertical-align: middle;
    background: #eee;
    height: 30px;
}
.block {
    background: #ccc;
}

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

Результат: блок по вертикали:




Разумеется, помимо этих основных моментов выровнять блок по вертикали потребуется еще указать высоту главного блока, если это будет необходимо. При данном варианте решения задачи выравнивания не придется “бороться” с Internet Explorer, как было бы, если бы использовалось свойство display:inline-block.

Данный метод является самым простым и компактным из всех существующих и работает везде.

Рубрики
FrontEnd

Параметры свойств в CSS

Как известно, основной “строительный” материал HTML-страниц – это блоки. Любой элемент по сути является блоком, неким прямоугольником с четырьмя сторонами и четырьмя вершинами. Для изменения внешнего вида элементов мы используем свойства CSS, далее рассматриваются параметры свойств и их значения, и указывается то, на что эти параметры влияют.

Для наглядности возьмем блок для которого нарисуем рамки:

.block {
border: 1px solid #ccc;
}

 

В данном случае каждая сторона блока будет иметь рамку серого цвета, толщиной 1px, но что делать, если рамки должны иметь отличную друг от друга ширину?

Перепишем пример сперва так, что бы визуально ничего не изменилось:

.block {
border-style: solid;
border-color: #ccc;
border-width: 1px;
}

 

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

Будем изменять значения свойства border-width.

В следующем примере мы указываем два параметра:

border-width: 1px 2px;

 

В этом случае первый параметр отвечает за верх и низ, второй за право и лево. Таким образом получается, что рамка сверху и снизу будут шириной 1px, а справа и слева по 2px.

Указываем три параметра:

border-width: 1px 2px 3px;

 

Получается, что верхняя рамка имеет толщину 1px, правая 2px, нижняя 3px, а левая имеет ту же толщину, что и правая, то есть 2px.

И наконец, если мы используем все четыре параметра, то каждый отвечает за свою сторону:

border-width: 1px 2px 3px 4px;

 

Из этого примера видно, что рамка изменилась и теперь верхняя рамка имеет толщину 1px, правая 2px, нижняя 3px, левая 4px. Получается, что перечисление параметров, при указании четырех значений, начинается сверху и идет по часовой стрелке.

Эта схема так же работает со свойствами padding, margin и с любыми свойствами, где участвуют стороны или углы блока.

Скругление углов при указании четырех параметров:

.block {
border-radius: 5px 10px 20px 40px;
-webkit-border-radius: 5px 10px 20px 40px;
-moz-border-radius: 5px 10px 20px 40px;
}

 

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

Рубрики
FrontEnd

Выравнивание – div блок по центру

Есть несколько правильных способов расположить div блок по центру. В данной статье будет описано три, наиболее распространенных.

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

Способ выравнивания №1 – не универсальный:

.var_1 {
    position: relative;
    height: 30px;
    background: #eee;
}
.var_1 > div {
    left: 50%;
    width: 500px;
    margin-left: -250px;
    position: absolute;
    background: #e99;
}

Минусы:

  • используется абсолютное позиционирование, что влияет на общую картину и потребуется использовать дополнительный внешний блок;
  • надо считать чему равна половина блока.

Способ выравнивания №2 – старинный:

.var_2 {
    position: relative;
    float: right;
    right: 50%;
    background: #e4e4e4;
}
.var_2 > div {
    position: relative;
    float: left;
    left: 50%;
    width: 500px;
    background: #ee9;
}

Минусы:

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

Способ выравнивания №3 – лучший:

.var_3 {
    margin-left: auto;
    margin-right: auto;
    width: 500px;
    background: #9e9;
}

В данном примере минусов нет. Все аккуратно и быстро. Может возникнуть резонный вопрос –  что делать, если не известна ширина блока но надо расположить div блок по центру?

Все просто – нужно добавить свойство display: table; и проблема будет решена. Этот способ подходит, чтобы расположить любой div блок по центру, будь то меню, блок с контентом, изображение в виде блока и т.п.

Пример: выравнивание – div блок по центру с использованием всех способов: