Статьи

Mura CMS: пользовательские методы

Mura CMS дает вам возможность создавать свои собственные функциональные возможности непосредственно на уровне темы. Эта статья покажет вам, как вы можете улучшить свои темы, создавая многократно используемые пользовательские методы, которые можно использовать как в шаблонах макетов, так и в администраторах.

При разработке тем у вас может быть ряд «объектов», которые вы хотели бы отображать снова и снова, такие как слайд-шоу, детальные блоки и т. Д.

В учебнике Class Extensions мы рассмотрели, как создавать пользовательские атрибуты для книги и отображать их на странице с помощью компонента. Вот последний компонент, который мы создали:

1
2
3
4
5
6
7
8
9
<h3>Details</h3>
 
<p>
    <strong>Author:</strong> [m]$.content(‘bookAuthor’)[/m]<br />
    <strong>Release Date:</strong>&nbsp;[m]dateFormat($.content(‘bookReleaseDate’),’mm/dd/yy’)[/m]<br />
    <strong>ISBN:</strong>&nbsp;[m]$.content(‘bookISBN’)[/m]<br />
    <strong>Condition:</strong>&nbsp;[m]$.content(‘bookNewUsed’)[/m]<br />
    <strong>Price:</strong>&nbsp;$[m]$.content(‘bookPrice’)[/m]
</p>

Это хорошо работает для нашего примера, но есть несколько недостатков:

  1. Разметка открыта для редакторов-администраторов, которые потенциально могут изменять разметку, влияя на ее отображение.
  2. Вокруг каждого предмета нет логики; например, если ISBN не существует, метка все равно будет отображаться с пустым значением рядом с ней. Это также произойдет, если пользователь добавит этот компонент на страницу, которая даже не является Книгой, и в этом случае ни один из расширенных атрибутов не отобразится.

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

Методы отображения в Mura находятся в файле с именем contentRenderer.cfc . Теперь этот файл существует в двух местах на вашем сайте:

  1. Уровень сайта: {siteID} /includes/contentRenderer.cfc
  2. Уровень темы: {siteID} включает / themes / {ThemeName} /contentRenderer.cfc

Важно понимать, что оба файла будут визуализировать методы на вашем сайте, однако на уровне темы contentRenderer.cfc будут добавлены любые методы, которые не существуют на уровне сайта, и переопределены все методы, которые уже существуют на уровне сайта.

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

В каталоге вашей темы откройте файл contentRenderer.cfc

Примечание : если вы создаете свою тему с нуля и у вас ее еще нет, добавьте contentRenderer.cfc из темы MuraBootstrap3, прикрепленной к этой статье.

В этом файле мы собираемся создать новую функцию dspBookDetails :

1
2
3
<cffunction name=»dspBookDetails» output=»yes»>
    <!— Logic goes here —>
</cffunction>

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

01
02
03
04
05
06
07
08
09
10
11
12
<cffunction name=»dspBookDetails» output=»yes»>
    <!— Create the variable to store our content —>
    <cfsavecontent variable=»ret»>
        <cfoutput>
            <!— Content here —>
        </cfoutput>
    </cfsavecontent>
         
    <!— Return the variable containing the content —>
    <cfreturn ret>
 
</cffunction>

Теперь вы можете видеть, что мы создаем переменную для хранения всего нашего содержимого и логики ( <cfsavecontent> ), а затем <cfsavecontent> функции вернуть эту переменную на страницу ( <cfreturn> ).

Теперь мы готовы добавить фактическое содержание книги, аналогично тому, как это было в компоненте:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
<cffunction name=»dspBookDetails» output=»yes»>
       <cfsavecontent variable=»ret»>
           <cfoutput>
               <h3>Details</h3>
        
               <p>
                   <strong>Author:</strong>&nbsp;#$.content(‘bookAuthor’)#<br />
                   <strong>Release Date:</strong>&nbsp;#dateFormat($.content(‘bookReleaseDate’),’mm/dd/yy’)#<br />
                   <strong>ISBN:</strong>&nbsp;#$.content(‘bookISBN’)#<br />
                   <strong>Condition:</strong>&nbsp;#$.content(‘bookNewUsed’)#<br />
                   <strong>Price:</strong>&nbsp;$#$.content(‘bookPrice’)#
               </p>
           </cfoutput>
       </cfsavecontent>
        
       <cfreturn ret>
 
   </cffunction>

Примечание : мы заменили теги [m] на hashtags ( # ), потому что мы в файле кода. Теги [m] можно использовать только в редакторах области администратора.

Теперь, когда у нас есть функция, созданная в contentRenderer.cfc , мы можем вызвать ее с помощью Mura Scope. Вернитесь к компоненту и замените содержимое следующей строкой:

1
<div>[m]$.dspBookDetails()[/m]</div>

Примечание : мы оборачиваем функцию в <div> чтобы CKEditor не добавил дополнительные теги <p> вокруг вывода. Кроме того, не забывайте скобки после вызова функции () .

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

Помимо вызова функции из компонента, вы также можете использовать свои собственные методы непосредственно в шаблонах макета. Например, вы можете продублировать шаблон twoCol_SR.cfm , назвать его book.cfm и добавить его в правую боковую панель:

1
2
3
4
5
6
7
<aside class=»col-lg-3 col-md-3 col-sm-4 col-xs-12 sidebar»>
    <!— Display the book details —>
    #$.dspBookDetails()#
     
    <!— Display any additional display objects addeed to this page —>
    #$.dspObjects(3)#
</aside>

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<cffunction name=»dspBookDetails» output=»yes»>
    <!— If the page is a ‘Book’ then run the function —>
    <cfif $.content(‘subType’) eq ‘Book’>
        <cfsavecontent variable=»ret»>
            <cfoutput>
                <h3>Details</h3>
             
                <p>
                    <strong>Author:</strong> #$.content(‘bookAuthor’)#<br />
                    <strong>Release Date:</strong>&nbsp;#dateFormat($.content(‘bookReleaseDate’),’mm/dd/yy’)#<br />
                    <strong>ISBN:</strong>&nbsp;#$.content(‘bookISBN’)#<br />
                    <strong>Condition:</strong>&nbsp;#$.content(‘bookNewUsed’)#<br />
                    <strong>Price:</strong>&nbsp;$#$.content(‘bookPrice’)#
                </p>
            </cfoutput>
        </cfsavecontent>
             
        <cfreturn ret>
    </cfif>
 
</cffunction>

Следующее, что мы хотим сделать, это определить, существует ли значение для каждого элемента, который мы отображаем (Автор, ISBN и т. Д.). Если значение не существует, мы хотим пропустить элемент и перейти к следующей строке.

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

1
2
3
4
<!— If the book author value has a length greater than 0 —>
<cfif len( $.content(‘bookAuthor’) )>
    <strong>Author:</strong> #$.content(‘bookAuthor’)#<br />
</cfif>

Оберните каждый элемент $.content() книге в приведенном выше коде, заменив значения $.content() соответствующими значениями для каждого элемента:

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
<cffunction name=»dspBookDetails» output=»yes»>
    <!— If the page is a ‘Book’ then run the function —>
    <cfif $.content(‘subType’) eq ‘Book’>
        <cfsavecontent variable=»ret»>
            <cfoutput>
                <h3>Details</h3>
         
                <p>
                    <!— Only output if the Author is defined —>
                    <cfif len($.content(‘bookAuthor’))>
                        <strong>Author:</strong> #$.content(‘bookAuthor’)#<br />
                    </cfif>
                    <cfif len($.content(‘bookReleaseDate’))>
                        <strong>Release Date:</strong>&nbsp;#dateFormat($.content(‘bookReleaseDate’),’mm/dd/yy’)#<br />
                    </cfif>
                    <cfif len($.content(‘bookISBN’))>
                        <strong>ISBN:</strong>&nbsp;#$.content(‘bookISBN’)#<br />
                    </cfif>
                    <cfif len($.content(‘bookNewUsed’))>
                        <strong>Condition:</strong>&nbsp;#$.content(‘bookNewUsed’)#<br />
                    </cfif>
                    <cfif len($.content(‘bookPrice’))>
                        <strong>Price:</strong>&nbsp;$#$.content(‘bookPrice’)#
                    </cfif>
                </p>
            </cfoutput>
        </cfsavecontent>
         
        <cfreturn ret>
    </cfif>
 
</cffunction>

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