Строим свою CMS на PHP и MySQL. Часть 5

В предыдущем уроке серии мы создали шаблоны для клиентской части. Теперь пришел черед визуального представления серверной части нашей CMS. 

loginForm.php

Создаем папку с именем admin в каталоге нашего проекта templates. В папке admin создаем файл loginForm.php:

Code

   
  <form action="admin.php?action=login" method="post" style="width: 50%;">
  <input type="hidden" name="login" value="true" />
   

  <div class="errorMessage"></div>

   
  <ul>
   
  <li>
  <label for="username">Username</label>
  <input type="text" name="username" id="username" placeholder="Your admin username" required autofocus maxlength="20" />
  </li>
   
  <li>
  <label for="password">Password</label>
  <input type="password" name="password" id="password" placeholder="Your admin password" required maxlength="20" />
  </li>
   
  </ul>
   
  <div class="buttons">
  <input type="submit" name="login" value="Login" />
  </div>
   
  </form>
   


Эта страница содержит форму регистрации администратора, которая отправлет к admin.php?action=login. Форма содержит скрытое поле login, которое используетca в функции login() для проверки факта отправки формы. Также здесь имеется область для любых сообщений об ошибках (таких, как неправильное имя пользователя или неправильный пароль) и поля для имени пользователя и пароля, и кнопкотправки формы.

Мы использовали некоторые атрибуты HTML5, такие как placeholder, required, autofocus и date для поле в наших формах. Такие атрибуты делают формы более удобными для использования, а также сохраняют возможность для проверки необходимых значений в нашем коде PHP. Так как не все браузеры сейчас поддерживают данные атрибуты HTML5, то вы возможно, будет применять JavaScript и/или PHP функции для проверки необходимых значений в серверной части.



listArticles.php

Сейчас создадим второй администраторский шаблон в вашей папке admin. Он называется listArticles.php:

Code

   
  <div id="adminHeader">
  <h2>Widget News Admin</h2>
  <p>You are logged in as <b></b>. <a href="admin.php?action=logout"?>Log out</a></p>
  </div>
   
  <h1>All Articles</h1>
   

  <div class="errorMessage"></div>

   
   

  <div class="statusMessage"></div>

   
  <table>
  <tr>
  <th>Publication Date</th>
  <th>Article</th>
  </tr>
   

   
  <tr onclick="location='admin.php?action=editArticle&articleId=id?>'">
  <td>publicationDate)?></td>
  <td>
  title?>
  </td>
  </tr>
   

   
  </table>
   
  <p> article in total.</p>
   
  <p><a href="admin.php?action=newArticle">Add a New Article</a></p>
   


Этот шаблон выводит список статей для редактирования администратором. После отображения любых сообщений об ошибке или статусе мы проходим циклом по массиву объектов Article, который содержится в $results['articles'], и выводим на экран дату и название для каждой статьи в таблицу. К каждой строке таблицы добавляем событие JavaScript onclick, чтобы администратор мог щелчком мыши открыть статью для редактирования.

Шаблон также выводит общее количество всех статей и ссылку для добавления нового материала.



editArticle.php

Теперь создадим последний шаблон для администраторской части editArticle.php в папке нашего проекта admin:

Code

   
  <div id="adminHeader">
  <h2>Widget News Admin</h2>
  <p>You are logged in as <b></b>. <a href="admin.php?action=logout"?>Log out</a></p>
  </div>
   
  <h1></h1>
   
  <form action="admin.php?action=" method="post">
  <input type="hidden" name="articleId" value="id ?>"/>
   

  <div class="errorMessage"></div>

   
  <ul>
   
  <li>
  <label for="title">Article Title</label>
  <input type="text" name="title" id="title" placeholder="Name of the article" required autofocus maxlength="255" value="title )?>" />
  </li>
   
  <li>
  <label for="summary">Article Summary</label>
  <textarea name="summary" id="summary" placeholder="Brief description of the article" required maxlength="1000" style="height: 5em;">summary )?></textarea>
  </li>
   
  <li>
  <label for="content">Article Content</label>
  <textarea name="content" id="content" placeholder="The HTML content of the article" required maxlength="100000" style="height: 30em;">content )?></textarea>
  </li>
   
  <li>
  <label for="publicationDate">Publication Date</label>
  <input type="date" name="publicationDate" id="publicationDate" placeholder="YYYY-MM-DD" required maxlength="10" value="publicationDate ? date( "Y-m-d", $results['article']->publicationDate ) : "" ?>" />
  </li>
   
   
  </ul>
   
  <div class="buttons">
  <input type="submit" name="saveChanges" value="Save Changes" />
  <input type="submit" formnovalidate name="cancel" value="Cancel" />
  </div>
   
  </form>
   
id ) { ?>
  <p><a href="admin.php?action=deleteArticle&articleId=id ?>" onclick="return confirm('Delete This Article?')">Delete This Article</a></p>

   


Здесь выводится форма редактирования, которая используется как для создания новых статей, так и для редактирования существующих. Она отправляет к admin.php?action=newArticle, или к admin.php?action=editArticle, в зависимости от значения переменной $results['formAction']. Шаблон содержит также скрытое поле articleId, для отслеживания ID редактируемой статьи (если он есть).

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

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

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



Стили и логотип


Наша CMS практически готова, но для лучшего внешнего вида мы созадем набор правил CSS и сохраняем их в файле style.css в папке cms:

Code
/* Стили для body and внешнего контейнера */

body {
  margin: 0;
  color: #333;
  background-color: #00a0b0;
  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  line-height: 1.5em;
}

#container {
  width: 960px;
  background: #fff;
  margin: 20px auto;
  padding: 20px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}

/* Логотип и нижний колонтитул */

#logo {
  display: block;
  width: 300px;
  padding: 0 660px 20px 0;
  border: none;
  border-bottom: 1px solid #00a0b0;
  margin-bottom: 40px;
}

#footer {
  border-top: 1px solid #00a0b0;
  margin-top: 40px;
  padding: 20px 0 0 0;
  font-size: .8em;
}

/* Заголвки */

h1 {
  color: #eb6841;
  margin-bottom: 30px;
  line-height: 1.2em;
}

h2, h2 a {
  color: #edc951;
}

h2 a {
  text-decoration: none;
}

/* Заголовки статей */

#headlines {
  list-style: none;
  padding-left: 0;
  width: 75%;
}

#headlines li {
  margin-bottom: 2em;
}

.pubDate {
  font-size: .8em;
  color: #eb6841;
  text-transform: uppercase;
}

#headlines .pubDate {
  display: inline-block;
  width: 100px;
  font-size: .5em;
  vertical-align: middle;
}

#headlines.archive .pubDate {
  width: 130px;
}

.summary {
  padding-left: 100px;
}

#headlines.archive .summary {
  padding-left: 130px;
}

/* Заголовок для страницы администратора */

#adminHeader {
  width: 940px;
  padding: 0 10px;
  border-bottom: 1px solid #00a0b0;
  margin: -30px 0 40px 0;
  font-size: 0.8em;
}

/* Стили для формы с цветным фоном, скругленными углами и тенью */

form {
  margin: 20px auto;
  padding: 40px 20px;
  overflow: auto;
  background: #fff4cf;
  border: 1px solid #666;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;  
  border-radius: 5px;
  -moz-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  -webkit-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
}

/* Задаем для элементов формы согласованные поля, отступы, и высоту строки */

form ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

form ul li {
  margin: .9em 0 0 0;
  padding: 0;
}

form * {
  line-height: 1em;
}

/* Метки полей */

label {
  display: block;
  float: left;
  clear: left;
  text-align: right;
  width: 15%;
  padding: .4em 0 0 0;
  margin: .15em .5em 0 0;
}

/* Поля */

input, select, textarea {
  display: block;
  margin: 0;
  padding: .4em;
  width: 80%;
}

input, textarea, .date {
  border: 2px solid #666;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;  
  border-radius: 5px;
  background: #fff;
}

input {
  font-size: .9em;
}

select {
  padding: 0;
  margin-bottom: 2.5em;
  position: relative;
  top: .7em;
}

textarea {
  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  font-size: .9em;
  height: 5em;
  line-height: 1.5em;
}

textarea#content {
  font-family: "Courier New", courier, fixed;
}
   

/* Рамка вокруг поля с фокусом ввода */

form *:focus {
  border: 2px solid #7c412b;
  outline: none;
}

/* Правильно заполненное поле имеет зеленый фон */

input:valid, textarea:valid {
  background: #efe;
}

/* Кнопки отправки */

.buttons {
  text-align: center;
  margin: 40px 0 0 0;
}

input[type="submit"] {
  display: inline;
  margin: 0 20px;
  width: 12em;
  padding: 10px;
  border: 2px solid #7c412b;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;  
  border-radius: 5px;
  -moz-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  -webkit-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  color: #fff;
  background: #ef7d50;
  font-weight: bold;
  -webkit-appearance: none;
}

input[type="submit"]:hover, input[type="submit"]:active {
  cursor: pointer;
  background: #fff;
  color: #ef7d50;
}

input[type="submit"]:active {
  background: #eee;
  -moz-box-shadow: 0 0 .5em rgba(0, 0, 0, .8) inset;
  -webkit-box-shadow: 0 0 .5em rgba(0, 0, 0, .8) inset;
  box-shadow: 0 0 .5em rgba(0, 0, 0, .8) inset;
}

/* Таблицы */

table {
  width: 100%;
  border-collapse: collapse;
}

tr, th, td {
  padding: 10px;
  margin: 0;
  text-align: left;
}

table, th {
  border: 1px solid #00a0b0;
}

th {
  border-left: none;
  border-right: none;
  background: #ef7d50;
  color: #fff;
  cursor: default;
}

tr:nth-child(odd) {
  background: #fff4cf;
}

tr:nth-child(even) {
  background: #fff;
}

tr:hover {
  background: #ddd;
  cursor: pointer;
}

/* Окна для вывода статуса и сообщений об ошибках */

.statusMessage, .errorMessage {
  font-size: .8em;
  padding: .5em;
  margin: 2em 0;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;  
  -moz-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  -webkit-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  -box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
}

.statusMessage {
  background-color: #2b2;
  border: 1px solid #080;
  color: #fff;
}

.errorMessage {
  background-color: #f22;
  border: 1px solid #800;
  color: #fff;
}


Детального разбора кода CSS мы не будем, так как наши уроки посвящены PHP и MySQL.

А в папке images в каталоге нашего проекта cms размещаем файл изображения logo.jpg :

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

  • FalleN

  • 3931

  • 1

  • 261
Теги: php, MySQL, cms

Ссылки на статью:

Похожие статьи: