Матвей Земсков

Заметки веб-мастера

Немного о веб-технологиях

Мой блог содержит заметки о различных веб-технологиях, как клиентских, так и серверных. Здесь будут раскрыты вопросы html-верстки, программирования на javaScript и jQuery,разработки на PHP. Не останутся без внимания популярные системы управления сайтом «1С-Битрикс», Joomla и другие. О работе с ними, я также буду писать.

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

В своем блоге я собираюсь публиковать статьи о современных веб-технологиях (HTML5, CSS3 и других). Если в процессе работы над проектами я открываю для себя «свежее» решение какой-либо задачи, я записываю сюда информацию об этом, что позволяет мне при необходимости применять полученные знания в будущем.

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

 
Среда, 25 февраля 2015 16:02

Создаем landing page в связке с базой данных

Оцените материал
(2 голосов)

Landing pages или «посадочные страницы» в последние годы стали довольно популярными инструментами для продвижения товаров и услуг. Как правило, они используются для усиления эффективности рекламы и увеличения аудитории. Переход на такие страницы обычно происходит по ссылкам из рекламных объявлений, размещенных в поисковых системах или почтовых рассылках.

С технической стороны landing page представляет из себя простую статичную веб-страницу и серверный скрипт для отправки сообщений. В большинстве случаев данные отправляются с использованием AJAX. Указанных инструментов вполне достаточно для создания среднестатистического лендинга. Тем более основной упор при изготовлении лэндингов делается на дизайн. Они должны быть яркими, привлекать внимание посетителей и побуждать их совершить покупку или заказать услугу.

Однако бывают случаи, когда товаров несколько или они часто меняются. Например, в случае landing page агентства недвижимости для продвижения каких-либо объектов недвижимости. Если рекламируемый объект продан, то для того чтобы добавить другой, нужно «копаться» в верстке страницы. Чтобы в таких случаях не править HTML-код страницы, можно хранить информацию о товарах отдельно. В этом случае заказчик страницы сможет добавлять, редактировать и удалять товары самостоятельно.

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

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

Итак, перейдем к делу.

Что же за 2 способа хранения данных, которые я упоминал?

Первый способ: хранить данные об услугах или товаре в .xml-файле. При использовании этого способа отзывы клиентов также хранятся в .xml-файле. На мой взгляд не очень удобный способ.

Второй способ более удобный: хранение информации в базе данных SQLite. Как известно данные в этой базе хранятся в файлах. В отличие от более «серьезных» БД таких, как MySQL, например, сервер не требуется.

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

  • css – в папке хранятся файлы стилей для лэндинга
  • img – папка с различными изображениями
  • js – папка для клиентских скриптов. В ней размещены различные jQuery-плагины, необходимые для различных визуальных эффектов.
  • index.php - демо-страничка (данные извлекаются из xml-файла)
  • index2.php - демо-страничка (данные извлекаются из базы данных SQLite)
  • land-data-exmpl.sqlite — база данных SQLite
  • mail_func.php – функции для отправки сообщений. Используются в скрипте send_data.php
  • offers-exmpl.xml - .xml-файл с описанием товаров или услуг.
  • reviews-exmpl.xml - .xml-файл c отзывами клиентов
  • send_data.php – файл для отправки сообщений (заказ обратного звонка). Взаимодействие демо-страниц с ним происходит через AJAX.
  • xml_func.php – функции для работы с .xml-файлами. Используются в файле index.php

Для разработки лэндинга с использованием первого способа хранения данных (в .xml-файлах) необходимо ознакомиться со следующими файлами: index.php, offers-exmpl.xml, reviews-exmpl.xml, xml_func.php.

Взаимодействие между этими файлами следующее: первый вариант страниц (index.php) состоит в основном из HTML-кода с небольшими вставками PHP.

PHP

<?require('xml_func.php');?> 
<!DOCTYPE HTML> 
<html lang="ru"> 
  <head> 
	…		 
  </head> 
  <body> 
    <div class="wrap"> 
	<div class="p-block"> 
	   <h2> Товары< /h2> 			
	   <?getOffersContent();?> 
	</div> 
	…
	<div class="p-block"> 
	  <h2> Отзывы наших клиентов</h2> 
	  <?getReviewsContent();?> 		
	</div> 
		
    </div> 	
	 …
   </body> 
</html> 

В первой строке index.php подлючается файл xml_func.php, в котором хранятся 2 функции для показа описаний товаров(getOffersContent) и для показа отзывов(getReviewsContent). Эти функции извлекают данные из соответствующих .xml-файлов и возвращают HTML-код со списком предложений или отзывов. Они вызываются в тех местах файла index.php, где необходимо показать список товаров и отзывов.

Предлагаю следующую структуру .xml-файла для хранения данных о товарах или услугах (offers-exmpl.xml):

XML

<offers> 
  <offer> 
    <itemname> Товар 1</itemname> 
    <itemimage> img/item.png</itemimage> 
    <description> Гироскопический прибор искажает апериодический момент силы трения. Подшипник подвижного объекта требует перейти к поступательно перемещающейся системе координат, чем и характеризуется центр подвеса.</description> 
    <detailurl> </detailurl> 
    <itemprice> <priceval> 1590 руб</priceval> </itemprice> 
  </offer> 	
</offers> 

Корневым элементом в этом файле является элемент offers, описания всех предложений (элементы offer) являются потомками offers. Каждое предложение товара или услуги состоит из следующих элементов:

  • itemname — название товара
  • itemimage — путь к файлу с изображением товара
  • description — описание товара
  • detailurl — URL страницы с детальным описанием товара (может быть пустым)
  • itemprice — цена товара. Этот элемент может включать в себя 1 или 2 элемента. Если на товар распространяется какая-нибудь скидка, то потомками itemprice будут элементы priceval — новая цена товара с учетом скидки и oldpriceval — старая цена без скидки. Если на товар никакие акции не распространяются, то потомок у itemprice будет один — элемент priceval.

Функция getOffersContent «обходит» .xml-файл с предложениями, формирует HTML-код списка товаров или услуг и возвращает его.

PHP

function getOffersContent(){
  $output = "<ul class=\"item-list clearfix\"> ";
  $dom = new DomDocument();
  $dom-> loadXML(file_get_contents('offers-exmpl.xml'));
  $offers = $dom-> getElementsByTagName('offer');
    foreach($offers as $offer){
      $output .= "<li> ";
      $children = $offer-> childNodes;
	 foreach($children as $child){
  	   if($child-> nodeName == "itemimage")
	   {
		$output .= "<img src=\"{$child-> nodeValue}\" /> ";
	   }
	   elseif($child-> nodeName == "itemname")
	   {
		$output .= "<h3 class=\"item-name\"> {$child-> nodeValue}< /h3> ";
	   }
	   elseif($child-> nodeName == "description")
	   {
		$desctxt = $child-> nodeValue;
	   	   if(strlen($desctxt) >  200){
			$desctxt = subword($desctxt, 200);
	          }					
	       $output .= "<div class=\"item-descr\"> ".$desctxt."</div> ";				   }
	   elseif($child-> nodeName == "detailurl" && strlen($child-> nodeValue) >  0)
	   {
	       $output .= "<p class=\"item-url\"> <a href=\"{$child-> nodeValue}\" > Подробнее</a> </p> ";							
	   }
	   elseif($child-> nodeName == "itemprice")
	   {
		$output .= "<div class=\"prc-block\"> ";
	  	    foreach($child-> childNodes as $i){									if($i-> nodeName == "priceval"){
			   $output .= "<span class=\"item-prc\"> {$i-> nodeValue}</span> ";				}
			if($i-> nodeName == "oldpriceval"){
			   $output .= "<span class=\"item-oldprc\"> {$i-> nodeValue}</span> ";
			}
		    }
		 $output .= "</div> ";
	   }						
	}
	$output .= "</li> "; 
     }
   $output .= "</ul> ";
   echo $output;					
}

В основе функции getOffersContent лежит PHP класс DomDocument. Применяя его методы при обходе xml-дерева, получаем результат в виде списка HTML и размещаем его на странице. В принципе, код функции получился несложный, поэтому если вы внимательно ознакомитесь с ним, вам станет понятно как он работает. Единственное, на что я обращу внимание: в коде используется функция subword. Она обрезает строку с учетом пробелов. Я описывал ее в одной из своих заметок.

Блок с предложениями на демо-странице будет выглядеть так:

Отзывы клиентов хранятся в файле reviews-exmpl.xml.

XML

<?xml version="1.0" encoding="utf-8"?> 
<reviews> 
  <review> 
    <clientimage> img/client.png</clientimage> 
    <clientname> Иванов П.В.</clientname> 		
    <reviewtext> «Интересно отметить, что потребительский рынок тормозит системный анализ, невзирая на действия конкурентов. Тем не менее, SWOT-анализ развивает конвергентный выставочный стенд, не считаясь с затратами. »</reviewtext> 
    </review> 	
</reviews>

Корневым элементом в этом файле является элемент reviews, отзывы (элементы review) являются потомками reviews.

Каждый отзыв включает в себя всего 3 элемента:

  • clientimage — путь к файлу с фотографией клиента, оставившего отзыв
  • clientname — имя клиента
  • reviewtext — текст отзыва

Для показа списка отзывов служит функция getReviewsContent. Она также как и предыдущая функция основана на PHP классе DomDocument, да и подход в ней очень похож на getOffersContent. Единственное отличие, это то, что вместо конструкций if-else в функии показа отзывов используется switch-case. Поэтому, если вы ознакомились с предыдущей функцией и поняли как она работает, то в этой вы разберетесь без труда.

PHP

function getReviewsContent(){
  $output = "<ul class=\"review-list clearfix\"> ";
  $dom = new DomDocument();
  $dom-> loadXML(file_get_contents('reviews-exmpl.xml'));
  $reviews = $dom-> getElementsByTagName('review');
    foreach($reviews as $review){
	$output .= "<li> ";
	$children = $review-> childNodes;
	  foreach($children as $child){
	    switch($child-> nodeName){
	      case "clientimage":
	        $output .= "<img src=\"{$child-> nodeValue}\" /> ";
	      break;
	      case "clientname":
	        $output .= "<h3 class=\"client-name\"> {$child-> nodeValue}</h3> ";
  	      break;
	      case "reviewtext":
		  $output .= "<div class=\"review-txt\"> ".subword($child-> nodeValue, 200)."</div> ";								
	      break;
	    } 
	  }						
	 $output .= "</li> ";
    }
   $output .= "</ul> ";
   echo $output;
} 

Блок с отзывами на демо-странице будет выглядеть следующим образом:

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

Сначала нужно создать базу данных. Это можно сделать при помощи разных программ, я например, воспользовался дополнением к браузеру Firefox под названием SQLite manager.

Для базы данных лэндинг пейдж вполне будет достаточно 3 таблиц:

  • для хранения предложений товаров или услуг (offers). Таблица состоит из следующих полей:
    • id (integer, auto_increment, primary key) – идентификатор (первичный ключ)
    • itemname (varchar) – название товара или услуги
    • itemimage (varchar) – путь к изображению товара
    • description (varchar) – описание товара или услуги
    • itemprice (char) - стоимость
    • itemoldprice (char) - старая цена

    Для создания таблицы offers нужно выполнить следующий SQL-запрос:

    SQL

    	CREATE TABLE "offers" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "itemname" VARCHAR NOT NULL , "itemimage" VARCHAR NOT NULL , "description" VARCHAR, "detailurl" VARCHAR, "itemprice" CHAR NOT NULL , "itemoldprice" CHAR)
    	
  • для хранения отзывов клиентов (reviews). Таблица включает в себя следующие поля:
    • id (integer, auto_increment, primary key) - идентификатор (первичный ключ)
    • clientname (varchar) — имя клиента, оставившего отзыв
    • clientimage (char) — путь к фотографии клиента
    • reviewtext (varchar) — текст отзыва

    Чтобы создать таблицу reviews выполните SQL-запрос:

    SQL

    	CREATE TABLE "reviews" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "clientname" VARCHAR NOT NULL , "clientimage" CHAR NOT NULL , "reviewtext" VARCHAR NOT NULL )
    	
  • Создаем таблицу mail_messages следующим SQL-запросом:
    • id (integer, auto_increment, primary key) – идентификатор (первичный ключ)
    • visitor_name (varchar) — имя посетителя
    • visitor_phone (varchar) — номер телефона посетителя (не может быть пустым)
    • visitor_email (varchar) — адрес электронной почты посетителя
    • visitor_mess (varchar) — сообщение посетителя
    • allow_subscr (char) — флаг подписки на рассылку (значения «Y» и «N»)

    Создаем таблицу mail_messages следующим SQL-запросом:

    SQL

    	CREATE TABLE "mail_messages" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "visitor_name" VARCHAR, "visitor_phone" VARCHAR NOT NULL , "visitor_email" VARCHAR, "visitor_mess" VARCHAR, "allow_subscr" CHAR DEFAULT N)
    	

В большинстве случаев при создании лэндингов подразумевается, что потенциальный заказчик заполняет форму заказа обратного звонка. После этого его данные отправляются на электронную почту владельца лендинга. При таком подходе существует вероятность того, что данные будут потеряны при удалении сообщений из ящика. К тому же в таком виде сложно найти контакт какого-нибудь потенциального клиента. Чтобы сохранить информацию и осуществлять удобный поиск, можно добавлять данные пользователя в таблицу базы данных каждый раз, когда он заполняет форму заказа обратного звонка. Эта информация также может пригодиться для организации рекламных рассылок. Включать данные посетителя в список рассылки нужно, конечно же, только с его согласия. Для этого добавим в форму заказа обратного звонка чекбокс. Если посетитель отметит его, это будет отражено в таблице mail_messages.

В отличии от первого способа, где код для показа предложений и отзывов хранился в разных файлах, во втором способе я объединил все в один файл index2.php.

В начале файла мы подключаемся к базе данных и выполняем два запроса по очереди. Первый запрос извлекает из базы данных всю информацию о товарах или услугах, второй — все отзывы клиентов. Результаты запросов сохраняем в массивы: $arrItems и $arrClients.

PHP

try{
     $db = new PDO('sqlite:land-data-exmpl.sqlite');
     $query = "SELECT itemname, itemimage, description, detailurl, itemprice, itemoldprice FROM offers";
     $st = $db-> query($query);
     $arrItems = $st-> fetchAll();
     foreach($arrItems as $k=> $arrItem){
       $arrItems[$k] = array_unique($arrItem);							
     }

     $query = "SELECT clientname, clientimage, reviewtext FROM reviews";
     $st = $db-> query($query);
     $arrClients = $st-> fetchAll();
     foreach($arrClients as $k=> $arrClient){
       $arrClients[$k] = array_unique($arrClient);						
     }
	
  }
catch(PDOException $e){
   die($e-> getMessage());
}

Затем выводим элементы этих массивов в определенных местах посадочной страницы. Сначала показывает список товаров или услуг.

PHP

<div class="p-block"> 
  <h2> Товары</h2> 			
    <ul class="item-list clearfix"> 
	<?foreach($arrItems as $arrItem):?> 
	  <li> 
	   <img src="/< ?=$arrItem["itemimage"]?> " /> 
	   <h3 class="item-name"> <?=$arrItem["itemname"]?> </h3> 
	   <div class="item-descr"> 
	    <?if(strlen($arrItem["description"]) >  200):?> 
		<?=subword($arrItem["description"], 200);?> 
	    <?else:?> 
		<?=$arrItem["description"]?> 
	    <?endif;?> 
	   </div> 
	   <?if(!empty($arrItem["detailurl"])):?> 
	     <p class="item-url"> <a href="/< ?=$arrItem["detailurl"]?> "> Подробнее</a> </p> 	   <?endif;?> 
	   <div class="prc-block"> 
	     <span class="item-prc"> <?=$arrItem["itemprice"]?> </span> 
	     <?if(!empty($arrItem["itemoldprice"])):?> 
		<span class="item-oldprc"> <?=$arrItem["itemoldprice"]?> </span> 
	     <?endif;?> 
	   </div> 
	</li> 
       <?endforeach;?> 
     </ul> 
</div> 

После списка предложений показываем отзывы клиентов.

PHP

<div class="p-block"> 
  <h2> Отзывы наших клиентов</h2> 
    <ul class="review-list clearfix"> 
	<?foreach($arrClients as $arrClient):?> 
	  <li> 
	   <img src="/<?=$arrClient["clientimage"]?> " /> 
	   <h3 class="client-name"> <?=$arrClient["clientname"]?> </h3> 
	   <div class="review-txt"> <?=subword($arrClient["reviewtext"], 220);?> </div> 
         </li> 
	<?endforeach;?> 
    </ul> 			
</div> 

Во втором варианте страницы, также как и в первом для обрезки текста используется функция subword.

Теперь мне хотелось бы вкратце описать процесс добавления информации о пользователе в базу данных. Происходит это в момент заказа обратного звонка. Эта возможность реализована в обоих вариантах страниц. Как я уже писал выше, взаимодействие лэндинг пейдж и скрипта (send_data.php), который отправляет данные и добавляет их в базу данных осуществляется посредством AJAX (js/pagescript.js).

В процессе отправки формы данные передаются скрипту send_data.php, где обрабатываются, отправляются и сохраняются в БД (таблица mail_messages). В случае, если посетитель при заполнении полей формы отметил флажок «Подписаться на рассылку», то в поле allow_subscr будет записано значение 'Y', иначе 'N'.

С запросами для добавления данных, вы сможете ознакомиться, если посмотрите код в файле send_data.php. Кроме этого файла будет полезным ознакомиться с кодом из файлов mail_func.php и js/pagescript.js.

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

SQL

SELECT visitor_name, visitor_email FROM mail_messages WHERE allow_subscr = 'Y'

Сделать это также можно в программе SQLite manager или написать отдельный скрипт для этой задачи.

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

Вы можете скачать примеры кода из статьи.

Прочитано 23058 раз
Свежие заметки
Наверх