Guide to decorators

2.Guide to decorators

1.     Introduction to Decorators

Decorators are defined as any static or semi-static markup surrounding a dynamically generated Fragment. Decorators are usually written with either Velocity or JSP templates. This guide will focus primarily on using the Velocity scripting language to build decoration. However, most of the standards and approaches described here can be applied to writing decroations in other scripting languages.

There are two different types of decorations that are used when building a page; Portlet and Layout (or page).

Portlet decorations are the "window dressings" of Jetspeed. They wrap each indivual portlet fragment's rendered content with HTML (XHTML, VXML, etc). Portlet decoration's are responsible for displaying the appropriate title and any buttons associated with changing window states or portlet modes.

Layout or Page decorations responsible for providing a "header" area and "footer" area for a single portal page which is represented by a .psml document (see: Documentation for Designers working with PSML for more information on psml). They also provide general style information for the page and portlets. However, portlet level style settings can be overidden at the portlet decoration level.

2.     Decoration File Structure

All decorations are stored in a directory directly off of the web applications root called decorations. The two primary directories under the here are layout for layout decorations and portlet for portlet decorations. Individual decorations are housed in their own directories underneath these two directories. The name of the directory you create for under either layout or portlet is how Jetspeed will locate your decoration. We will go into further detail on how this works later on in this guide.

3.     Anatomy of a Layout (Page) Decoration

a. Four Files in a Nutshell

In its most basic form a Layout Decoration only requires you to define four files:

  • Decorator. properties
  • styles.css
  • header.vm
  • footer.vm

 

Three of these files; decorator.properties, header.vm, and footer.vm go directly into the directory you create under /decorations/layout. The styles.css needs to be put into a subdirectory of your decoration names css/. [MS1] 

b. Basic Layout Decoration Configuration: decorator. properties

The decorator.properties file holds basic information about your layout decoration. In all actuality, this file can be blank, but we still require that it be present as it is used by other APIs to "discover" available decorations. With that being said, it is safe to assume that all the properties defined below are optional.

Property Name

Description

Default

base.css.class

This value is generally placed in the top most element tag of your header template. You will see how it is used when we go into development of a header template.

Defaults to the name of your decoration

stylesheet

Relative path to your decoration's stylesheet

css/styles.css

header

Relative path to your decoration's header template

header.vm

footer

Relative path to your decoration's footer template

footer.vm

c. Top o' the Page to ya: header.vm

The header.vm represents the top portion of your portal page. Below is a section by section walkthrough of the basics required to write a functional header template?

NOTICE: It is assumed that the reader is proficient in both the use of HTML and CSS. A rudimentary knowledge of Velocity helps but is not required to develop a decoration.
      

<html>

   <head>

     #defineLayoutObjects()

The first two lines should be obvious, if they are not, this guide from here on out will not be much help to you ;-)

C1 Our First Macro: #defineLayoutObjects()

Now the line containing #defineLayoutObjects() will not be as obvious in its purpose as the previous two. #defineLayoutObjects() is what is known, in Velocity vernacular, as a macro. A macro is a predefined snippet of Velocity code that can be reused within any Velocity template. All of the global macros we will be using (including this one) are defined within the WEB-INF/jetspeed_macros.vm. Later in this guide we will discuss supplying your own, custom macros for assisting you in your decoration development, if you choose to. Now, back to the #defineLayoutObjects(). #defineLayoutObjects() adds values to Velocity that will be accessible within header.vm, footer.vm, other macros and all of your portlet decoration templates. We could easily stop here regarding #defineLayoutObjects(), however, I feel it can be helpful to have some insights into the inner workings of Velocity for the uninitiated. With out further ado, the code:

       

  #macro (defineLayoutObjects)

    #set($preferedLocale = $JS2RequestContext.locale)

    #set($rootFragment = $jetspeed.currentFragment)

    #set($site = $request.getAttribute("org.apache.jetspeed.portalsite.PortalSiteRequestContext"))

    #set($theme = $request.getAttribute("org.apache.jetspeed.theme"))

    #set($layoutDecoration = $theme.getDecoration($rootFragment))

  #end       

Hmm. What is actually happening here. Okay first off we have, #set(), this is what is known as a directive in Velocity. A directive is built-in functionallity and not a macro. #set() is pretty straight forward in that it takes the value on the right of the = and assigns it to the left. Cool, that seems fairly straight forward. But how does one work with these values and where the heck did $JS2RequestContext.locale come from? I guess i should take a quick step back and describe how we work with objects in Velocity. All objects available to a Velocity template can be referenced via the $someObject notation. Knowing that much invoking a method , let's getFoo(), can be done just like this $someObject.getFoo(). Even cooler is the fact we can short-hand getter methods that don't take any arguments like this, $someObject.foo. As for this $JS2RequestContext this is actually an instance of the org.apache.jetspeed.RequestContext that has been availble to Velocity by Jetspeed itself. So, by looking the javadoc for org.apache.jetspeed.RequestContext we see $JS2RequestContext.locale will give us an instance of java.util.Locale that reperesnts the locale of the current user. Couldn't be much simpler than that could it?

Next up we have this line
#set($rootFragment = $jetspeed.currentFragment) another set() statement, this time creating an object called $rootFragment which is an instance of org.apache.jetspeed.om.page.ContentFragment. It is really not relevant to this guide to describe what $jetspeed.currentFragment is doing so I am going to skip that and move on.


#set($site = $request.getAttribute("org.apache.jetspeed.portalsite.PortalSiteRequestContext"))
#set($theme = $request.getAttribute("org.apache.jetspeed.theme"))

Ah
$request, now that looks familiar, this is actually an instance of javax.servlet.http.HttpServletRequest from which we are retreiving objects that were been placed into Velocity by Jetspeed. The actual objects are: org.apache.jetspeed.portalsite.PortalSiteRequestContext and org.apache.jetspeed.decoration.Theme respectively. We will put all of these objects to good use in just a little while.

C2 .Feed Your HEAD: How to Properly Code Your Head Tag.

This section provides you with all the information to properly code the <HEAD> of your Layout decorations. So, straight to the code.

 

<html>

    <head>

     #defineLayoutObjects()

    

     <base href="#BaseHref()">

     <meta http-equiv="Content-type" content="#ContentType()" />

     <meta http-equiv="Content-style-type" content="text/css" />  

     #includeJavaScriptForHead()

     #IncludeStylesheets()   

     <title>#PageTitle()</title>

     <meta name="description" content="#PageDescription()" />

C3  The <base> Tag

First off we have <base href="#BaseHref()"> which allows us to define the base path for resolution of web resources, for an in depth discussion of the <base> see: W3C Schools Reference. If you have spent any time playing with Jetspeed, you will have noticed it does all sorts of crazy URL rewriting that will totally hose any attempts to consistently path you html and styles sheets. By defining the BASE tag, this problems will all but disappear. As for the #BaseHref() macro, it simply generates a fully qualified path to your web application's root. The actual code, in terms of the servlet api is synonymous with this:

HttpServletRequest request;

StingBuffer baseHref = new StringBuffer(request.getScheme())

     .append("://").append(request.getServerName())

             .append(":").append(request.getServerPort())

             .append(request.getContextPath()).append("/");

return baseHref.toString();                      

The actual Velocity macro code is a bit more terse ;)

 

${request.scheme}://${request.serverName}:${request.serverPort}${request.contextPath}/

C4 Meta Tag: <meta http-equiv="Content-type" content="#ContentType()" />

Will return text/html plus the proper encoding, such as UTF.

#includeJavaScriptForHead()

At the time of the writing of this guide there is really very little javascript required to for the base Jetspeed 2 server to run. However this may change in near future as we try to employ the use of AJAX in things such as configuration and administration.


 [MS1]

 
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
Python decorators是一种用于修改或增强函数功能的语法结构。它们允许开发者在不修改原始函数代码的情况下,通过在函数定义之前使用特殊符号(@)和装饰器函数来对函数进行包装或修饰。装饰器函数接受被装饰函数作为参数,并可以在原始函数执行之前或之后添加额外的逻辑或功能。这种技术可以用来实现缓存、日志记录、身份验证等功能。 Python decorators的使用方法可以根据具体需求进行定义和实现。常见的方法包括使用装饰器函数、使用类作为装饰器、使用带参数的装饰器等。装饰器函数是最常见的一种方式,它接受一个函数作为参数并返回一个新的函数,新函数会替换原始函数。这样,在调用原始函数时,实际上是调用了被装饰的函数,从而在不修改原始函数的情况下添加了额外的功能。 除了使用Python内置的装饰器语法,还可以使用第三方库来简化装饰器的编写和使用。例如,可以使用decorator模块来定义和使用装饰器。这个模块提供了一种更简洁的语法,可以直接在函数定义之前使用@decorator语法来应用装饰器。该模块的使用方法如下所示: ```python from decorator import decorator @decorator def hint(func, *args, **kwargs): print('{} is running'.format(func.__name__)) return func(*args, **kwargs) ``` 上述代码定义了一个名为hint的装饰器函数,它接受一个函数作为参数,并在函数执行之前打印出函数名。然后,通过在函数定义之前使用@hint语法,将装饰器应用到目标函数上。这样,在调用目标函数时,实际上会先执行装饰器函数内部的逻辑,然后再执行目标函数本身的逻辑。 总结来说,Python decorators是一种用于修饰函数的语法结构,可以通过装饰器函数在不修改原始函数代码的情况下增强函数功能。它可以通过Python内置的装饰器语法或第三方库来实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Python Decorator](https://blog.csdn.net/weixin_30951231/article/details/96490117)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Python系列之装饰器(decorator)](https://blog.csdn.net/ikxyang/article/details/121995824)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值