Веб мастера
знают, что создать хороший сайт не главное, а главное в том, чтобы его
посещали :). А одним из наиболее эффективных способов привлечения
пользователей на сайт есть его публикация в поисковых системах и
тщательная проработка важных для индексирования частей страницы (тег
Title и атрибуты meta keywords, meta author и meta description).
Естественно при этом возникает желание как-то унифицировать процесс
манипулирования этими атрибутами. Не отходя от традиции писать статьи
исключительно практические и по возможности связывать примеры с «живым»
кодом нашего портала, я расскажу о двух способах манипулирования
содержимым тега HEAD.
Итак, первый случай. Сайт представляет собой набор страниц (т.е. это
стандартный сайт), некоторые из этих страниц динамические. Нам нужно
добиться стандартного подхода к управлению содержимым интересующих нас
тегов заголовка, что напрямую подводит нас к созданию для этого
пользовательского элемента управления. Он получается довольно простым,
поэтому я просто приведу его код с минимальными пояснениями.
PageHeader.ascx:
<%@ Control Language="c#" Codebehind="PageHeader.ascx.cs" Inherits="DynamicHead.PageHeader" %>
<head>
<title><%= title %></title>
<meta name="keywords" content="<%= keywords %>">
<meta name="description" content="<%= description %>">
<meta name="author" content="<%= author %>">
</head>
PageHeader.aspx.cs:
namespace DynamicHead
{
public abstract class PageHeader : System.Web.UI.UserControl
{
protected string title = "ASP.NET Mania - все про ASP.NET и .NET Framework.";
protected string keywords = "ASP.NET,.NET,.NET Framework,C#,VB.NET,VS.NET,Visual Studio.NET";
protected string description = "Портал для разработчиков ASP.NET приложений";
protected string author = "Dimon aka Manowar (aspnetman@aspnetmania.com)";
public string Title
{
get { return title; }
set { title = value; }
}
public string Keywords
{
get { return keywords; }
set { keywords = value; }
}
public string Description
{
get { return description; }
set { description = value; }
}
public string Author
{
get { return author; }
set { author = value; }
}
}
}
Как видите, этот пользовательский элемент управления имеет четыре
публичных свойства, значения которых можно установить. Теперь остается
только разместить это элемент управления на нужных страницах и
установить его свойства. Примерно так, как показано в следующем
листинге.
Article.aspx:
<%@ Page language="c#" Codebehind="article.aspx.cs" Inherits="DynamicHead.article" %>
<body MS_POSITIONING="FlowLayout">
<form id="article" method="post" runat="server">
Здесь размещается статья.
</form>
</body>
article.aspx.cs:
public class article : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{
string articleTitle = "Манипулирование содержимым <HEAD> на сайте, " +
"использующим пользовательские элементы управления";
string articleKeywords = "Пользовательские элементы управления";
string articleDescription = "Статья рассказывает о манипулировании содержимым " +
"тега <HEAD> используя пользовательские элементы управления";
string articleAuthor = "Dimon aka Manowar (aspnetman@aspnetmania.com)";
PageHeader hdr = (PageHeader) Page.LoadControl("pageheader.ascx");
hdr.Title += articleTitle;
hdr.Keywords += articleKeywords;
hdr.Description = articleDescription;
hdr.Author = articleAuthor;
Page.Controls.AddAt(0, hdr);
}
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
}
В приведенном выше коде показан пример динамической загрузки
созданного ранее пользовательского элемента управления. Хотелось бы
отметить следующее:
- Так как в пользовательском элементе управления нет ни одного
элемента управления, который мог бы вызвать постбек формы, значит,
мы можем расположить этот элемент управления в любом месте страницы
(в том числе и вне тега <form runat=”server”></form>).
- Так как созданный элемент управления полностью содержит тег
<head>, в страницах, где используется наш элемент управления
необходимо удалить этот тег.
Но это одна сторона медали. Есть и другая, под названием "портал,
созданный по модульной технологии". Многие порталы (в том числе и мания)
состоят из малого количества файлов-контейнеров и набора модулей,
добавляемых в файлы в зависимости от параметров. Например, если
посмотреть на страницу новостей нашего портала, то можно увидеть, что ее
имя совпадает с именем главной страницы (как в прочем и имена многих
других страниц портала), и отличие лишь в параметрах запроса. И в
зависимости от этих параметров на страницу добавляются различные модули.
На всех страницах, кроме первой есть "главный модуль" (например на
странице «новости» это модуль новостей, на странице вывода сообщения из
форума – модуль самого сообщения), и хотелось бы иметь возможность
именно из этого модуля изменять содержимое тега <head> страницы. Что ж,
это также возможно устроить. :)
Рассмотрим реальный пример того, как это реализовано на нашем
портале. Практически весь наш портал уложен в один файл – Default.aspx.
И в зависимости от значения параметра tabid на эту страницу добавляются
различные пользовательские элементы управления. Соответственно на
странице бывает «главный» пользовательский элемент управления – элемент
управления, содержащий основные данные этой страницы. Например, для
страницы вывода новости это пользовательский элемент управления с
информацией об этой новости, для страницы вывода сообщения форума
пользовательский элемент с самим сообщением (правда на мании это
реализовано совершенно отдельной страницей, но вовсе не потому, что
такое решение сложно реализовать, а скорее для удобства пользователей).
Соответственно для того, чтобы можно было манипулировать из этого
элемента управления содержимым тега <head> родительской веб формы я
сделал следующее:
Добавил в файл кода и в файл представления родительской формы код для
вывода значений title, author, keywords и description (совсем как в
примере, описанном выше):
Default.aspx
<HEAD>
<title>
<%= title%>
</title>
<meta name="keywords" content="<%= keywords %>">
<meta name="description" content="<%= description %>">
<meta name="author" content="<%= author %>">
<LINK href="portal.css" type="text/css" rel="stylesheet">
</HEAD>
default.aspx.cs
public class Default : System.Web.UI.Page {
...
public string title = "ASP.NET Mania - все про ASP.NET и .NET Framework. ";
public string keywords = "ASP.NET,.NET,.NET Framework,C#,VB.NET,VS.NET," +
"Visual Studio.NET,ADO.NET,Web Services,Remoting,";
public string description = "";
protected string author = "Dimon aka Manowar (aspnetman@aspnetmania.com)";
...
И использовал для манипулирования этими свойствами из
пользовательского элемента управления свойство Page, не забыв привести
его к правильному типу. Вот кусок кода из пользовательского элемента
управления Forum.ascx, выводящего список форумов и список сообщений
форумов:
string forumName = "";
string description = "";
ASPNetPortal.ForumDB forum = new ASPNetPortal.ForumDB();
DataView dv = forum.ListForums().Tables[0].DefaultView;
if(Request.QueryString["ForumID"] != null)
for(int i = 0; i < dv.Count; i++)
if((int) dv[i]["ForumID"] == Int32.Parse(Request.QueryString["ForumID"]))
{
// Если выбран какой-либо форум – получим информацию по этому форуму.
dlForum.SelectedIndex = i;
forumName = dv[i]["Name"].ToString();
description = dv[i]["Description"].ToString();
}
dlForum.DataSource = dv;
dlForum.DataBind();
// Установим свойства страницы, содержащей элемент управления, для манипулирования содержимым тега <head>
(this.Page as ASPNetPortal.Default).title += "Форумы. " + forumName;
(this.Page as ASPNetPortal.Default).description += description;
(this.Page as ASPNetPortal.Default).keywords += forumName;
Как видите, данная проблема не является такой уж сложной. С помощью
нескольких строк кода и внимательного заполнения необходимых данных
(заголовков, ключевых слов и прочего) можно добиться поразительных
результатов по размещению портала в поисковых системах. И я скажу, что
данный труд не напрасен. Данное решение приносит нам до 20% посетителей
портала, приходящих с поисковых сайтов. |