Откопал в архиве старого сайта свою небольшую статью про то, как сделать простейшую страницу новостей сайта с применением Ajax. Такая техника очень часто применяется на блого-подобных сайтах, типа news2.ru.
Статьи в блогах практически никогда не выводятся полностью. Чаще всего отображается небольшой абзац, а ниже указана ссылка на её продолжение.
Конечно, если новость очень большая, и в ней находятся изображения, видео и т.п., то проще и правильнее выводить их в новых страницах. Но если новость не очень длинная и ограничивается лишь текстом, то можно выводить её описанным ниже способом.
Суть в следующем: представьте, что мы выводим на странице абзац статьи фиксированной длины, например, 100 символов. Остальная часть статьи обрезается, и в конце отображённого абзаца выводится многоточие-ссылка, при нажатии на которую к статье подгружается остальная её часть. И всё это происходит без перезагрузки страницы. Новости будут выводиться погодично, т.е. не всей кучей сразу, а только за тот год, который мы хотим.
Итак, чтобы создать сие чудо, нам понадобится следующее:
- index.htm – страница, куда будут вставляться наши новости
- news.dat – файл новостей в текстовом формате
- news.php – скрипт обработки Ajax-запросов и форматирования новостей
- carbon_js_core_compressed.js, carbon_js_ajax_compressed.js, carbon_js_dom_compressed.js – обжатая версия моего фреймворка для реализации Ajax-запросов и отображения новостей
Во-первых, подготовим нашу страницу для новостей. В то место страницы, где будут отображаться новости, добавим следующий код:
<div class="news_block"></div>
В этот блочный элемент будут вставляться наши новости. Далее, создадим файл news.dat. В нём будут находиться наши новости в следующем формате:
ЧЧ месяц ГГГГ¤Заголовок¤Новость. Длинная новость. Очень длинная новость.
Например:
17 января 2010¤Наш сайт стал динамичнее!¤Теперь новости нашего сайта выводятся через Ajax, без перезагрузки страницы!
Для каждой новости отдельная строка. Конечно, новости придётся записывать в этот файл вручную, но, если вы хорошо знаете PHP, то можете написать утилиту (а ля Админ-центр), которая сама будет записывать вашу новость в этот файл.
Теперь рассмотрим сам алгоритм вывода новостей таким способом. Создадим функцию, которая будет делать запрос к файлу news.php и получать от него новости за переданный ей год:
function newsFrom(year) {
Q().ajax({
url: "news.php",
params: {"year": year},
onSuccess: function(jsRequest) {
Q("div.news_block").html(jsRequest.responseText);
}
});
}
CarbonJS.loadModules(["ajax", "dom"], function() {
newsFrom(new Date().getFullYear()); // При загрузке страницы будут подгружаться новости за текущий год.
});
Всего скрипту news.php могут передаваться 2 параметра – year и num. Параметр num отвечает за подгрузку полной статьи указанного года и индекса этой новости в массиве статей данного года.
Наш файл news.php будет вести себя следующим образом: если скрипту передан только параметр year, то он будет отображать все новости за данный год. Если передан year и num, то выведется полная выбранная статья. Если же вызвать скрипт без параметров, то выведется альтернативная страница, содержащая все новости (не обрезанные). Это пригодится нам для того, чтобы не обездолить посетителей сайта с отключённым JavaScript или без поддержки Ajax.
Файл news.php должен выглядеть примерно вот так:
<?php
header("content-type: text/html; charset=utf-8");
function utf8_strlen($s) {
return preg_match_all('/./u', $s, $tmp);
}
function utf8_substr($s, $offset, $len = 'all') {
if ($offset < 0) $offset = utf8_strlen($s) + $offset;
if ($len != "all") {
if ($len < 0) $len = utf8_strlen($s) - $offset + $len;
$xlen = utf8_strlen($s) - $offset;
$len = ($len > $xlen) ? $xlen : $len;
preg_match('/^.{' . $offset . '}(.{0,'.$len.'})/us', $s, $tmp);
} else {
preg_match('/^.{' . $offset . '}(.*)/us', $s, $tmp);
}
return (isset($tmp[1])) ? $tmp[1] : false;
}
if (isset($_REQUEST['year']) && is_numeric($_REQUEST['year']) && $_REQUEST['year'] >= 2010) {
$news = array();
$inc = 0;
$file = fopen("news.tpl", "r");
if (!isset($_REQUEST['num']) || !is_numeric($_REQUEST['num'])) echo "<ul>\n";
while (!feof($file)) {
$s = fgets($file);
$arr = split("¤", $s);
if (substr($arr[0], -4, 4) == $_REQUEST['year']) {
array_push($news, $arr[2]);
if (!isset($_REQUEST['num']) || !is_numeric($_REQUEST['num'])) {
echo "<li><div class=\"news_short\">$arr[1]</div>\n";
if (utf8_strlen($arr[2]) > 70) {
echo "<span id=\"news$inc\">" . utf8_substr($arr[2], 0, 70) . "<a href=\"javascript:void(0)\" class=\"content\" title=\"Читать дальше\" style=\"font-weight: bolder\" onClick='getNews(\"" . substr($arr[0],-4,4) . "\",\"$inc\")'>...</a></span>\n";
} else {
echo "<span id=\"news$inc\">$arr[2]</span>\n";
}
echo "<div class=\"news_hr\"></div><div class=\"news_date\">$arr[0]</div><br></li>\n\n";
}
$inc++;
}
}
if (isset($_REQUEST['num']) && is_numeric($_REQUEST['num']) && $_REQUEST['num'] >= 0 && $_REQUEST['num'] < count($news)) {
echo $news[$_REQUEST['num']];
} else {
echo "</ul>\n";
}
fclose($file);
} elseif (!isset($_REQUEST['year'])) {
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Новости сайта (не-Ajax версия)</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body>
<ul>
<?php
$file = fopen("news.dat", "r");
while (!feof($file)) {
$s = fgets($file);
$arr = split("¤", $s);
echo "<li><div>$arr[1]</div>\n";
echo "$arr[2]\n";
echo "<div>$arr[0]</div><br></li>\n\n";
}
fclose($file);
?>
</ul>
</body>
</html>
<?php } ?>
Этот простой скрипт построчно обрабатывает файл с новостями (news.dat) и, в зависимости от переданных параметров, отображает нам то, что нужно.
Если вы внимательно просмотрели этот скрипт, то могли заметить JS-функцию getNews(), которая запускается при щелчке на многоточие:
function getNews(year, index) {
Q().ajax({
url: "news.php",
params: {
"year": year,
"num": index
},
onSuccess: function(jsRequest) {
Q("#news" + index).html(jsRequest.responseText);
}
});
}
Её задача – замена блока с обрезанной статьёй на её полную версию.
Последнее, что осталось сделать – это добавить ссылки на новости за те годы, которые есть в файле news.dat. Мы не будем заморачиваться и выводить их скриптом автоматически – вы можете потом сделать это сами. Мы просто добавим их в код страницы вручную:
Новости за <a href="javascript:void(0)" onClick="newsFrom('2010')" class="pages">2010</a> <a href="javascript:void(0)" onClick="newsFrom('2009')" class="pages">2009</a> <a href="javascript:void(0)" onClick="newsFrom('2008')" class="pages">2008</a> год.
Итак, окончательно наша страница должна иметь следующие элементы:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Новости сайта</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="carbon_js_core_compressed.js"></script>
<script type="text/javascript">
function newsFrom(year) {
Q().ajax({
url: "news.php",
params: {"year": year},
onSuccess: function(jsRequest) {
Q("div.news_block").html(jsRequest.responseText);
}
});
}
function getNews(year, index) {
Q().ajax({
url: "news.php",
params: {
"year": year,
"num": index
},
onSuccess: function(jsRequest) {
Q("#news" + index).html(jsRequest.responseText);
}
});
}
CarbonJS.loadModules(["ajax", "dom"], function() {
newsFrom(new Date().getFullYear());
});
</script>
</head>
<body>
<div class="news_block"><a href="news.php">Альтернативная страница новостей</a></div>
Новости за <a href="javascript:void(0)" onClick="newsFrom('2010')" class="pages">2010</a> <a href="javascript:void(0)" onClick="newsFrom('2009')" class="pages">2009</a> <a href="javascript:void(0)" onClick="newsFrom('2008')" class="pages">2008</a> год.
</body>
</html>
Приведённый пример является самым простым и может использоваться на простых сайтах, на которых не используются какие-либо CMS.
