Статьи

Начало работы с Umbraco: часть 4

В этой части мы начнем с добавления еще одного файла XSLT (для страниц новостей), а затем перейдем к рассмотрению того, как мы можем интегрировать стандартные пользовательские элементы управления .Net в Umbraco.


  1. Начало работы с Umbraco: Часть 1
  2. Начало работы с Umbraco: Часть 2
  3. Начало работы с Umbraco: Часть 3
  4. Начало работы с Umbraco: часть 4
  5. Начало работы с Umbraco: часть 5

Создайте новый XSLT-файл (и макрос) в серверной части и назовите его newsList . В этом файле XSLT мы будем использовать нестандартную сущность, которая является сущностью HTML &\mdash; , Чтобы использовать эту сущность, нам нужно определить ее в списке сущностей в объявлении XSLT-типа в верхней части файла. Чтобы добавить сущность mdash, добавьте следующий код в квадратные скобки сразу после определенного неразрывного пробела:

1
<!ENTITY mdash «&#x2014;»>

Мы сохраним переменную, чтобы мы могли легко получить доступ к узлу newsList , чтобы получить его дочерние узлы. Сразу после параметра currentPage в новом файле XSLT добавьте следующую переменную:

1
<xsl:variable name=»newsParent» select=»umbraco.library:GetXmlNodeById(1094)»/>

Теперь внутри <xsl:template> добавьте следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<xsl:for-each select=»$newsParent/* [@isDoc]»>
    <article>
        <xsl:if test=»position() = last()»>
            <xsl:attribute name=»class»>last</xsl:attribute>
        </xsl:if>
        <header>
            <h1>
                <a href=»{umbraco.library:NiceUrl(@id)}»>
                    <xsl:attribute name=»title»>
                        <xsl:value-of select=»headline»/>
                    </xsl:attribute>
                    <xsl:value-of select=»headline»/>
                </a>
            </h1>
            <p class=»post-info»>
                <xsl:value-of select=»umbraco.library:FormatDateTime(date, ‘dd/MM/yyyy’)»/>
            </p>
        </header>
        <div>
            <xsl:value-of select=»substring(newsText, 1, 250)» disable-output-escaping=»yes» />
            <xsl:text>…</xsl:text>
            <a href=»{umbraco.library:NiceUrl(@id)}»>
                <xsl:attribute name=»title»>
                    <xsl:value-of select=»headline»/>
                </xsl:attribute>
                <xsl:text>read more</xsl:text>
            </a>
        </div>
    </article>
</xsl:for-each>

Сначала мы создаем новую переменную, которая должна указывать прямо на родительский узел новостей. Мы можем получить любой узел напрямую, указав его свойство id в качестве аргумента метода библиотеки Umbraco GetXmlNodeById() . id для использования можно получить, посмотрев поле id на вкладке Properties любого узла; это еще одно свойство, добавленное к узлу автоматически Umbraco:


Затем мы используем эту переменную для обработки каждого дочернего узла под родителем новостей, который отображается на странице списка новостей. Для каждого узла, который является дочерним элементом страницы списка, мы сначала создаем элемент <article> . Затем мы проверяем, имеем ли мы дело с последним узлом в наборе, и если мы это делаем, мы добавляем имя класса last к элементу. Это сделано исключительно из соображений стиля; Конечно, большинство браузеров поддерживают фильтр :last-child , но это может быть полезным методом для старых браузеров.

Затем мы создаем элемент <header> содержащий элементы <h1> и <a> для ссылки на полную подстраницу новостей. Чтобы создать ссылку, мы снова используем NiceUrl() Umbraco. Мы устанавливаем заголовок и текстовое содержание якоря, используя свойство headline из серверной части. Затем мы показываем дату, когда была опубликована страница новостей, и создателя новости. Чтобы отобразить дату, мы можем использовать FormatDateTime() Umbraco, предоставляя имя поля выбора даты в FormatDateTime() и формат, в котором мы хотели бы, чтобы дата отображалась. Чтобы отобразить автора страницы, мы просто получить атрибут creatorName . Помните, что на атрибуты страницы (в отличие от свойств, сопоставленных с элементами ввода) ссылаются с префиксом @ .

Наконец, мы создаем новый контейнер <div> и отображаем предварительный просмотр новости; чтобы сделать это, мы можем просто использовать функцию substring .Net, предоставляя текст из редактора форматированного текста, символ, с которого нужно начинать, и символ, заканчивающийся в качестве аргументов. После предварительного просмотра текста мы добавляем эллипсы и ссылку «Читать далее», которая также указывает на полную новость.

Когда мы сейчас получим доступ к странице newsList в браузере, дочерние узлы узла newsList будут объединены в страницу списка:



Перейдите на вкладку « Developer » в фоновом режиме Umbraco, щелкните правой кнопкой мыши каталог XSLT Files в дереве узлов слева и выберите « Create . Введите newsNav в качестве имени файла и убедитесь, что в поле выбора template флажок « Clean и установлен флажок « Create Macro макрос».

После создания файла вернитесь в Visual Web Developer Express (VWD) и откройте файл XSLT. Мы будем использовать переменную для ссылки на узел newsList который содержит отдельные узлы новостной истории, как мы делали в XSLT-файле newsList из последней части этой серии:

1
<xsl:variable name=»newsParent» select=»umbraco.library:GetXmlNodeById(1094)»/>

Затем мы просто обрабатываем каждый узел новостной ленты в for-loop XSLT for-loop и строим навигацию на основе заголовка:

01
02
03
04
05
06
07
08
09
10
11
12
<ul>
    <xsl:for-each select=»$newsParent/* [@isDoc]»>
        <li>
            <a href=»{umbraco.library:NiceUrl(@id)}»>
                <xsl:attribute name=»title»>
                    <xsl:value-of select=»headline»/>
                </xsl:attribute>
                <xsl:value-of select=»headline»/>
            </a>
        </li>
    </xsl:for-each>
</ul>

Вот и весь код, который нам понадобится. Он просто позволяет посетителю переходить непосредственно между новостями, не возвращаясь к странице списка. Это все XSLT, который нам нужен сейчас; нам все еще нужно написать макрос, который будет генерировать панели героев, но мы вернемся к этому позже. Сейчас мы можем перейти к рассмотрению того, как мы можем использовать пользовательские элементы управления на сайте Umbraco.


На этом этапе мы можем решить, что мы хотим, чтобы сайт имел страницу контактов, где посетители могут заполнить форму и отправить электронное письмо администратору сайта. Это ставит нас перед проблемой; на стандартном сайте .Net мы могли бы просто добавить набор полей формы на страницу контактов и добавить логику для отправки электронного письма владельцу сайта в файле с выделенным кодом. Но в Umbraco нет файлов с выделенным кодом для страниц или вообще каких-либо страниц для добавления полей формы.

Вместо этого мы можем создать пользовательский элемент управления, так как эти типы файлов могут иметь кодовые отступы для добавления необходимой нам логики отправки электронной почты. Мы можем создать пользовательский элемент управления в VWD; щелкните правой кнопкой мыши папку usercontrols в Solution Explorer в левой части приложения и выберите « Add new item .

В появившемся диалоговом окне выберите « Web User Control в центральном столбце и измените имя файла на contactform.ascx . Убедитесь, что установлен флажок Place code in separate file и нажмите кнопку Add . Добавьте следующий код непосредственно после объявления элемента управления, которое автоматически добавляется в файл:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<asp:Panel ID=»form» runat=»server»>
    <fieldset>
        <legend class=»accessible-hidden»>Contact Us Form</legend>
        <asp:Label runat=»server» AssociatedControlID=»name»>Your name<sup>*</sup>:</asp:Label>
        <asp:RequiredFieldValidator ControlToValidate=»name» runat=»server»><span>This field is required
        <asp:TextBox ID=»name» runat=»server»></asp:TextBox>
        <asp:Label runat=»server» AssociatedControlID=»email»>Your email address<sup>*</sup>:</asp:Label>
        <asp:RequiredFieldValidator ControlToValidate=»email» runat=»server»><span>This field is required
        <asp:RegularExpressionValidator ControlToValidate=»email» runat=»server» ValidationExpression=»\w+([-+.’]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*»><span>Please enter a valid email adress
        <asp:TextBox ID=»email» runat=»server»></asp:TextBox>
        <asp:Label runat=»server» AssociatedControlID=»message»>Your question/message</asp:Label>
        <asp:TextBox ID=»message» TextMode=»MultiLine» Rows=»5″ Columns=»10″ runat=»server»></asp:TextBox>
        <asp:Button ID=»submit» runat=»server» CssClass=»button-submit» OnClick=»sendMail» Text=»Send Email» />
    </fieldset>
</asp:Panel>
  
<<asp:Panel ID=»thanks» runat=»server» Visible=»false»>
    <h1>Thanks!</h1>
    <p>Your message has been sent and will be read shortly.
</asp:Panel>

Этого должно быть достаточно для этой базовой демонстрации. Мы добавили два элемента <asp:Panel> на страницу; первый содержит форму, а второй содержит сообщение с благодарностью, которое будет отображаться после отправки формы.

Панель формы содержит внешний элемент <fieldset> в качестве логического контейнера и обязательный элемент <legend> . Затем у нас есть ряд серверных элементов управления, включая элементы <asp:label> которые будут преобразованы в стандартные элементы HTML-меток, некоторые текстовые вводы и текстовую область, а также пару базовых валидаторов, чтобы гарантировать, что обязательные поля не останутся пустыми и что введен действительный адрес электронной почты.

Вот код, который мы будем использовать для отображения формы. На самом деле мы не будем добавлять код, который будет отправлять электронное письмо, поскольку он будет включать установку и настройку SMTP-сервера, что будет слишком далеко отклоняться от Umbraco. Все, что мы будем делать, это переключаться между двумя элементами <asp:Panel> . Мы можем сделать это с помощью следующего кода, добавленного в класс в файле codebehind:

1
2
3
4
5
6
protected void sendMail(object sender, EventArgs e)
{
          
    form.Visible = false;
    thanks.Visible = true;
}

Мы просто переключаем видимость двух панелей в обработчике кликов для элемента <asp:Button> в форме.


Теперь, когда у нас есть пользовательский контроль, мы можем добавить его на новую страницу в Umbraco; на вкладке « Developer » в Macros щелкните правой кнопкой мыши папку « Macros » и выберите « Create в меню. В диалоговом окне введите Contact form в качестве имени и нажмите кнопку Create .

Основная правая панель обновится после создания макроса. Сначала обновите Alias до contactForm чтобы он соответствовал псевдонимам для других созданных нами макросов. Во втором разделе есть запись с меткой или .NET User Control ; разверните поле выбора рядом с полем ввода и выберите пользовательский элемент управления, который мы создали. Также убедитесь, что установлен флажок « Use in editor :


Затем вернитесь на вкладку « Content » в серверной части Umbraco и создайте новую страницу под названием « Contact Us », щелкнув правой кнопкой мыши значок « Home и выбрав « Create . Эта страница должна использовать стандартный тип документа Content . Чтобы добавить макрос на страницу, мы можем использовать оранжевую кнопку рядом с правой стороной панели инструментов (значок представляет собой окно приложения, содержащее >). In the dialog that appears make sure Contact form is selected and hit the OK button. This will insert the usercontrol's content into the textarea. Save and publish the page. >). In the dialog that appears make sure Contact form is selected and hit the OK button. This will insert the usercontrol's content into the textarea. Save and publish the page.

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


Последний макрос, который нам нужно написать, — это тот, который создает элементы содержимого панели героя, которые примут форму карусели с несколькими панелями, которые будут скользить вне поля зрения. Мы уже добавили большую часть разметки в файл HomePage.master еще во второй части этой серии, поэтому нам нечем заняться.

В серверной части Umbraco создайте новый файл XSLT и сопровождающий его макрос. Вызовите новый XSLT-файл heroPanels . Он должен содержать следующий код в главном разделе шаблона файла XSLT:

1
2
3
4
5
6
7
<xsl:for-each select=»$currentPage/ancestor-or-self::* [@isDoc and @level=1]/HeroPanel»>
      
    <div class=»panel»>
        <xsl:value-of select=»panelContent» disable-output-escaping=»yes» />
    </div>
  
</xsl:for-each>

Это все, что нам нужно; содержимое каждой панели героев теперь должно быть заключено в <div> и вставлено в элемент #slider на домашней странице, где находится <umbraco:Macro> .


На этом этапе у нас должен быть почти полностью функционирующий сайт (нам просто нужно подключиться к функциональности subnav и hero panel с небольшим количеством JavaScript); это выглядит не очень красиво. Давайте исправим это сейчас, добавив базовый скин на сайт. Создайте новую таблицу стилей и сохраните ее в папке css (она добавляется при распаковке архива Umbraco) как site.css (мы добавили ссылку на эту таблицу стилей при создании шаблонов в части 2). Добавьте следующий код к нему:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* site-wide */
body {
    padding-bottom:60px;
}
form { width:960px;
.accessible-hidden { display:block;
.clear-float:after { display:block;
  
h1, h2, h3 {
    font:bold 24px Constantia, «Lucida Bright», Lucidabright, «Lucida Serif», Lucida, «DejaVu Serif», «Bitstream Vera Serif», «Liberation Serif», Georgia, serif;
}
  
header {
    display:block;
    -moz-border-radius:0 0 8px 8px;
}
header h1 { float:left;
header h1 a { display:block;
header h2 { float:right;
  
nav { display:block;
nav ul { padding:0;
nav li { float:left;
nav li a {
    display:block;
    font-weight:bold;
}
nav li a:hover, nav li a.on { border-top-color:#535353;
nav ul ul {
    display:none;
    border-radius:0 0 8px 8px;
    -moz-box-shadow:0 2px 3px #777;
}
nav li:hover ul { display:block;
nav ul ul li { float:none;
nav ul ul a { border-top:none;
nav ul ul a:hover { color:#969696;
  
#innerContent { width:960px;
#innerContent img {
    display:block;
    border-radius:4px;
}
  
footer {
    width:916px;
    -moz-border-radius:8px 8px 0 0;
    background-color:#eee;
}
footer nav { position:relative;
footer li { margin-right:10px;
footer li.last { margin-right:0;
footer nav li:after { content:»|»;
footer nav li.last:after { content:»»;
footer nav a { padding:0;
footer nav a:hover, footer nav a.on { border-bottom-style:solid;
  
footer p { float:right;
  
/* page specific */
article { display:block;
article header, article footer { padding:0;
article header h1 a { display:inline;
article h1 { margin-bottom:0;
article h1 a { border-bottom:1px dashed #000;
article h1 a:hover { border-bottom-style:solid;
.post-info, #newsItem li { font-style:italic;
article pa { border-bottom:1px dashed #000;
article pa:hover { border-bottom-style:solid;
  
#newsItem { width:640px;
#newsItem ul { padding:0;
#newsItem li { margin-left:5px;
#newsContent img { margin-right:20px;
#newsNav { width:260px;
#newsNav h1 { font-size:14px;
#newsNav li { float:none;
#newsNav a {
    padding-left:0;
}
#newsNav a:hover { border-bottom-style:solid;
  
fieldset { border:none;
label, input, textarea { display:block;
label { width:auto;
input, textarea { clear:both;
label sup { color:#ff0000;
.button-submit { width:auto;
fieldset span { float:left;
  
/* hero panel */
#hero { position:relative;
#viewer { width:960px;
#slider { height: 180px;
.panel { width:960px;
#ui { margin:0;
#ui li { float:left;

Сохраните файл. Это просто очень простой скин, как для макета, так и для оформления. Единственный отказ от ответственности, который я могу предложить, это то, что я разработчик, а не дизайнер. Но сайт должен теперь, по крайней мере, выглядеть намного аккуратнее и намного больше похож на реальный сайт. Субнав в верхнем заголовке полностью активируется CSS, чтобы наш скрипт занимал меньше места. Конечно, это не сработает в IE6 (делает все, что угодно), мы могли бы легко это исправить, используя наш скрипт, если бы мы были так склонны.

Самый важный момент — это CSS для нашей панели героев; он еще не закончен, нам нужно добавить еще пару стилей после того, как мы добавили JavaScript, но сейчас стоит отметить, что элемент viewer установлен на высоту и ширину одной панели, чтобы отображается только одна панель за раз. Другие панели плавают так, чтобы они складывались горизонтально. Элемент #slider расположен абсолютно и будет сделан достаточно широким, чтобы соответствовать количеству панелей. На этом этапе зритель не будет отображаться правильно, и все панели будут видны.

Причина этого заключается в том, что ширина #slider не была установлена ​​для размещения всех панелей в одной строке. Мы знаем, что есть три панели, потому что мы только что создали сайт, но было бы достаточно просто добавить новую панель или еще несколько, позже, поэтому мы не можем на самом деле жестко закодировать ширину в CSS в случае изменения количества панелей. Мы будем обрабатывать настройку ширины в скрипте.

Вот как должна выглядеть домашняя страница на этом этапе:


Еще один момент, который стоит отметить: мы добавили воображаемый логотип через наш CSS. Мы могли бы также легко изменить это так, чтобы вместо этого использовалось изображение из библиотеки мультимедиа, что, вероятно, было бы предпочтительнее, если бы мы передавали сайт клиенту.


В этой части руководства мы добавили оставшиеся XSLT-файлы / макросы, которые формируют страницу списка новостей, извлекая фрагменты каждой отдельной новости, а также меню навигации по новостям, которое отображается в отдельных новостях и позволяет посетителю переходить к другому. новости без необходимости возвращаться на главную страницу новостей.

Мы также увидели, как легко добавить любую уникальную пользовательскую функциональность, которая может понадобиться любой конкретной странице, создав пользовательский элемент управления .Net (файл ascx). Это позволяет нам создавать страницы со специализированным контентом, не определенным ни в шаблоне, ни в типе документа.

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