- Метки урока:
- разное
- web дизайн
- кодинг
- php
Строим свою CMS на PHP и MySQL. Часть 5
В предыдущем уроке серии мы создали шаблоны для клиентской части. Теперь пришел черед визуального представления серверной части нашей CMS.
loginForm.php
Создаем папку с именем admin
в каталоге нашего проекта templates
. В папке admin
создаем файл loginForm.php
:
<?php include "templates/include/header.php" ?> <form action="admin.php?action=login" method="post" style="width: 50%;"> <input type="hidden" name="login" value="true" /> <?php if ( isset( $results['errorMessage'] ) ) { ?> <div class="errorMessage"><?php echo $results['errorMessage'] ?></div> <?php } ?> <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> <?php include "templates/include/footer.php" ?>
Эта страница содержит форму регистрации администратора, которая отправлет к admin.php?action=login
. Форма содержит скрытое поле login
, которое используетcя в функции login()
для проверки факта отправки формы. Также здесь имеется область для любых сообщений об ошибках (таких, как неправильное имя пользователя или неправильный пароль) и поля для имени пользователя и пароля, и кнопка отправки формы.
Мы использовали некоторые атрибуты HTML5, такие как placeholder
, required
, autofocus
и date
для полей в наших формах. Такие атрибуты делают формы более удобными для использования, а также сохраняют возможность для проверки необходимых значений в нашем коде PHP. Так как не все браузеры сейчас поддерживают данные атрибуты HTML5, то вы, возможно, будете применять JavaScript и/или PHP функции для проверки необходимых значений в серверной части.
listArticles.php
Сейчас создадим второй администраторский шаблон в вашей папке admin
. Он называется listArticles.php
:
<?php include "templates/include/header.php" ?> <div id="adminHeader"> <h2>Widget News Admin</h2> <p>You are logged in as <b><?php echo htmlspecialchars( $_SESSION['username']) ?></b>. <a href="admin.php?action=logout"?>Log out</a></p> </div> <h1>All Articles</h1> <?php if ( isset( $results['errorMessage'] ) ) { ?> <div class="errorMessage"><?php echo $results['errorMessage'] ?></div> <?php } ?> <?php if ( isset( $results['statusMessage'] ) ) { ?> <div class="statusMessage"><?php echo $results['statusMessage'] ?></div> <?php } ?> <table> <tr> <th>Publication Date</th> <th>Article</th> </tr> <?php foreach ( $results['articles'] as $article ) { ?> <tr onclick="location='admin.php?action=editArticle&articleId=<?php echo $article->id?>'"> <td><?php echo date('j M Y', $article->publicationDate)?></td> <td> <?php echo $article->title?> </td> </tr> <?php } ?> </table> <p><?php echo $results['totalRows']?> article<?php echo ( $results['totalRows'] != 1 ) ? 's' : '' ?> in total.</p> <p><a href="admin.php?action=newArticle">Add a New Article</a></p> <?php include "templates/include/footer.php" ?>
Этот шаблон выводит список статей для редактирования администратором. После отображения любых сообщений об ошибке или статусе мы проходим циклом по массиву объектов Article
, который содержится в $results['articles']
, и выводим на экран дату и название для каждой статьи в таблицу. К каждой строке таблицы добавляем событие JavaScript onclick
, чтобы администратор мог щелчком мыши открыть статью для редактирования.
Шаблон также выводит общее количество всех статей и ссылку для добавления нового материала.
editArticle.php
Теперь создадим последний шаблон для администраторской части editArticle.php
в папке нашего проекта admin
:
<?php include "templates/include/header.php" ?> <div id="adminHeader"> <h2>Widget News Admin</h2> <p>You are logged in as <b><?php echo htmlspecialchars( $_SESSION['username']) ?></b>. <a href="admin.php?action=logout"?>Log out</a></p> </div> <h1><?php echo $results['pageTitle']?></h1> <form action="admin.php?action=<?php echo $results['formAction']?>" method="post"> <input type="hidden" name="articleId" value="<?php echo $results['article']->id ?>"/> <?php if ( isset( $results['errorMessage'] ) ) { ?> <div class="errorMessage"><?php echo $results['errorMessage'] ?></div> <?php } ?> <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="<?php echo htmlspecialchars( $results['article']->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;"><?php echo htmlspecialchars( $results['article']->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;"><?php echo htmlspecialchars( $results['article']->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="<?php echo $results['article']->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> <?php if ( $results['article']->id ) { ?> <p><a href="admin.php?action=deleteArticle&articleId=<?php echo $results['article']->id ?>" onclick="return confirm('Delete This Article?')">Delete This Article</a></p> <?php } ?> <?php include "templates/include/footer.php" ?>
Здесь выводится форма редактирования, которая используется как для создания новых статей, так и для редактирования существующих. Она отправляет к admin.php?action=newArticle
, или к admin.php?action=editArticle
, в зависимости от значения переменной $results['formAction']
. Шаблон содержит также скрытое поле articleId
, для отслеживания ID редактируемой статьи (если он есть).
Форма также имеет область для сообщений об ошибках, а также поля для названия статьи, резюме, содержания и даты публикации. Здесь также имеются 2 кнопки для сохранения и удаления изменений и ссылка, позволяющая администратору удалить только что отредактированную статью.
Все данные передаются через функцию htmlspecialchars()
до их вывода в разметке. Это не только хорошая привычка в плане безопасности, но это также гарантирует, чтобы наши значения в полях формы имели правильный формат. Например, когда значение поля title
, содержащего двойные кавычки ("), не проходит такой обработки при размещении в коде, оно может быть обрезано, так как двойные кавычки используются для разделения значения поля и разметки.
Обратите внимание, что мы используем атрибут HTML5 formnovalidate
для кнопки "Cancel". Данный атрибут указывает браузеру не проводить проверку формы, если пользователь нажал кнопку "Cancel".
Стили и логотип
Наша CMS практически готова, но для лучшего внешнего вида мы создаем набор правил CSS и сохраняем их в файле style.css
в папке cms
:
/* Стили для 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 функционал категорий.
Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: www.elated.com/articles/cms-in-an-afternoon-php-mysql/#step9
Перевел: Сергей Фастунов
Урок создан: 5 Декабря 2012
Просмотров: 41584
Правила перепечатки
5 последних уроков рубрики "PHP"
-
Фильтрация данных с помощью zend-filter
Когда речь идёт о безопасности веб-сайта, то фраза "фильтруйте всё, экранируйте всё" всегда будет актуальна. Сегодня поговорим о фильтрации данных.
-
Контекстное экранирование с помощью zend-escaper
Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.
-
Подключение Zend модулей к Expressive
Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.
-
Совет: отправка информации в Google Analytics через API
Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.
-
Подборка PHP песочниц
Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.