Skip to content

ARCHIVED

!注意“归档”

This chapter has not been updated for the current version of Orchard, and has been ARCHIVED.

Widgets are fragments of UI that surface specific data or features. Examples of widgets include navigation menus, image galleries, ads, videos, tag clouds.

窗口小部件是表示特定数据或功能的UI片段。小部件的示例包括导航菜单,图像库,广告,视频,标签云。

Widgets are typically rendered in a zone on the page. A zone can contain zero or more widgets.

窗口小部件通常在页面上的区域中呈现。区域可以包含零个或多个小部件。

Anatomy of a widget

小部件的剖析

A widget is composed of two or more files that are placed in a /Packages/[MyPackage]/Widgets directory of the application.

窗口小部件由两个或多个文件组成,这些文件放在应用程序的/ Packages / \ [MyPackage \] / Widgets目录中。

In many ways, a widget can become a simplified mini-MVC application, with a model, a controller and one or several views.

在许多方面,小部件可以成为简化的迷你MVC应用程序,具有模型,控制器和一个或多个视图。

Widget meta-data

小部件元数据

The meta-data is defined as part of the package.txt manifest file at the root of the widget's directory:

元数据被定义为小部件目录根目录下的package.txt清单文件的一部分:

Widgets:

    - Tag Cloud

        Author: Renaud Paquay

        Description:

            Displays available tags as a cloud where the size of each tag

            reflects the number of items that use it.

        Version: 0.1

In this example, we give the widget a display name (the name of the widget folder is used otherwise), we describe the author of the widget, give a long description and version number.

在这个例子中,我们给窗口小部件一个显示名称(否则使用窗口小部件文件夹的名称),我们描述窗口小部件的作者,给出一个长描述和版本号。

Widget code file

小部件代码文件

The code file for a widget is named [MyWidgetName].cs by convention and is at the root of the widgets subdirectory of the package directory. This file contains the definition, settings and server code for the widget.

窗口小部件的代码文件按惯例命名为\ [MyWidgetName \] \。cs,位于包目录的widgets子目录的根目录下。此文件包含窗口小部件的定义,设置和服务器代码。

Here is an example of code for a simple widget:

以下是一个简单小部件的代码示例:

public class ProductList : Widget {

    // ... widget code

The properties will be interpreted as settings for the widget instance.

这些属性将被解释为窗口小部件实例的设置。

The widget class is used as the model for the widget. As we will see, the widget's views are strongly-typed to use the widget class as the model.

窗口小部件类用作窗口小部件的模型。正如我们将看到的,窗口小部件的视图是强类型的,以使用窗口小部件类作为模型。

The widget's class name should be the same widget name that is also defined in the package manifest.

窗口小部件的类名称应该与包清单中定义的窗口小部件名称相同。

The widgets in the widgets directory are dynamically compiled by the application, but widgets may also be deployed as part of a compiled package. In that case, the discovery is made through reflection instead of file-based discovery. The manifest for compiled widgets will be deployed as part of the package (TBD).

窗口小部件目录中的窗口小部件由应用程序动态编译,但窗口小部件也可以部署为已编译包的一部分。在这种情况下,发现是通过反射而不是基于文件的发现来完成的。已编译窗口小部件的清单将作为程序包(TBD)的一部分进行部署。

Note: dynamic compilation of widgets will be implemented during the same iteration as plug-in dynamic compilation.

注意:小部件的动态编译将在与插件动态编译相同的迭代期间实现。

Data access

数据访问

Widget instances are content items that are contained in widget groups, which are also content items. The data persistence will be handled by Orchard but might use serialization in a single widgets table that is not specialized by widget type.

窗口小部件实例是窗口小部件组中包含的内容项,它们也是内容项。数据持久性将由Orchard处理,但可能在单个窗口小部件表中使用序列化,而不是由窗口小部件类型专门化。

View file

查看文件

The second necessary part in a widget is an ascx file must be named [MyWidgetName].ascx by convention. This file is placed in the package's display template folder. The view file is actually just the display template for the widget.

小部件中的第二个必要部分是ascx文件必须按照约定命名为\ [MyWidgetName \] \。ascx。此文件放在包的显示模板文件夹中。视图文件实际上只是窗口小部件的显示模板。

This file is a partial view that uses the widget class as its model type.

此文件是使用窗口小部件类作为其模型类型的局部视图。

Here is an example of a widget's view code:

以下是窗口小部件视图代码的示例:

<%@ Control Language="C#"

    Inherits="System.Web.Mvc.ViewUserControl<ProductList>" %>



<h5 class="widgetTitle"><%=Html.Encode(Model.Title)%></h5>

<ul id="imgholder_<%=Html.Encode(Model.ID)%>" class="widgetBody">

  <%foreach (Product p in Model.Products) { %>

  <li>

    <p><a href="<%=Url.Action("show","home",new{sku=p.SKU})%>"

        title="Go to <%=Html.Encode(p.Name)%> Details Page"

        ><%=Html.Encode(p.Name)%></a><br />

       <a href="<%=Url.Action("show","home",new{sku=p.SKU})%>"

           title="Go to <%=Html.Encode(p.Name)%> Details Page"

           ><%=Html.Encode(p.Price.ToString("C"))%></a>

    </p>

  </li>

  <%} %>

</ul>

CSS conventions

CSS惯例

The widget views are built with a number of conventions that will make theme overrides and integration easier. The default view for a widget -the one that comes with the package- should be neutral, semantic markup so that it can inherit the current theme's styles without necessitating a specific view override.

窗口小部件视图使用许多约定构建,这些约定将使主题覆盖和集成更容易。窗口小部件的默认视图(包随附的)应该是中性的语义标记,以便它可以继承当前主题的样式而无需特定的视图覆盖。

We will set-up the conventions for a few class names that will make it easy to style all widgets with simple CSS:

我们将为一些类名设置约定,这将使用简单的CSS轻松地为所有小部件设置样式:

  • widgetTitle

  • widgetTitle *

  • widgetBody

  • widgetBody *

Administration view

管理视图

Optionally, a widget can provide its own UI to manage its settings.

可选地,窗口小部件可以提供其自己的UI来管理其设置。

It does so by having a [MyWidgetName].ascx (for example PageMap.ascx) partial view in the package's EditorTemplates directory. That partial view may rely on specific controller actions that may be implemented as part of the widget (see below).

它通过在包的EditorTemplates目录中包含\ [MyWidgetName \] \。ascx(例如PageMap.ascx)局部视图来实现。该部分视图可能依赖于可能作为窗口小部件的一部分实现的特定控制器操作(参见下文)。

If no edit view exists for the widget, Orchard will generate UI using MVC editor templates like for any other content type.

如果窗口小部件不存在编辑视图,Orchard将使用MVC编辑器模板生成UI,就像任何其他内容类型一样。

Content and script files

内容和脚本文件

Content files (resp. script files) should be placed in a "Content" (resp. "Scripts") directory under the package's directory. Content files include stylesheets and images.

内容文件(相应的脚本文件)应放在包目录下的“内容”(相应的“脚本”)目录中。内容文件包括样式表和图像。

If a widget includes its own script files or its own stylesheets, it should declare those by calling Html.RegisterScript and Html.RegisterStylsheet from the view. Orchard will make a double pass on views, which will enable registration API call results to be included into the head.

如果窗口小部件包含自己的脚本文件或其自己的样式表,则应通过从视图中调用Html.RegisterScript和Html.RegisterStylsheet来声明它们。 Orchard将对视图进行双重传递,这将使注册API调用结果包含在头部中。

Implementing those methods will result in the theme's view code for the current page to remove duplicates and render the relevant script and link tags in the head of the page. For this to happen, the page view's header code must contain a call to Html.Include("Head") (usually in head.ascx).

实现这些方法将导致主题的当前页面的视图代码删除重复项并在页面的头部呈现相关的脚本和链接标记。为此,页面视图的标题代码必须包含对Html.Include(“Head”)的调用(通常在head.ascx中)。

Orchard will look first for overrides for those files in the current theme folder, and will then look for them in the package's content folder. URLs for script files should be relative to the Scripts subfolder and URLs for stylesheets should be relative to the Content subfolder.

Orchard将首先查看当前主题文件夹中这些文件的覆盖,然后在包的内容文件夹中查找它们。脚本文件的URL应该相对于Scripts子文件夹,样式表的URL应该相对于Content子文件夹。

If two widget instances ask for the same script or the same stylesheet, Orchard will know how to include them only once.

如果两个窗口小部件实例要求相同的脚本或相同的样式表,Orchard将知道如何仅包含它们一次。

To include images, a widget's view can use the Html.ContentFolderUrl helper, which will resolve to the widget's content folder when used from within a widget view:

要包含图像,窗口小部件的视图可以使用Html.ContentFolderUrl帮助程序,当从窗口小部件视图中使用时,它将解析为窗口小部件的内容文件夹:

<img alt="circle" src="<%= Html.ContentFolderUrl("circle.png")%>"/>

The URL returned by ContentFolderUrl is already HTML-encoded. If the URL contains fragments that need to be URL-encoded, that encoding needs to be done on the parameter by the calling code, before it calls into the API. The same is true of the URLs returned by GetScriptUrls and GetStyleSheetUrls.

ContentFolderUrl返回的URL已经是HTML编码的。如果URL包含需要进行URL编码的片段,则在调用API之前,需要通过调用代码对参数进行编码。 GetScriptUrls和GetStyleSheetUrls返回的URL也是如此。

All the content resources that the widget needs should be included in the widget package's Content folder. The widget view should not rely on global application or global theme resources to ensure that the widget is a self-contained entity that can be deployed as is. Orchard will not fallback to global resources when a resource is not found either in the current theme's widget override folder or in the widget's content folder.

窗口小部件所需的所有内容资源都应包含在窗口小部件包的“内容”文件夹中。窗口小部件视图不应依赖全局应用程序或全局主题资源来确保窗口小部件是可以按原样部署的自包含实体。当在当前主题的窗口小部件覆盖文件夹或窗口小部件的内容文件夹中找不到资源时,Orchard不会回退到全局资源。

Exceptions to that rule is when the widget needs scripts or stylesheets that have not been written by the widget author and that are susceptible to be used by more than one widget type. In this case, it is recommended that the widgets refers to a (preferably version-neutral) URL of the resource stored on a CDN.

该规则的例外情况是,窗口小部件需要脚本或样式表,这些脚本或样式表尚未由窗口小部件作者编写,并且易于被多个窗口小部件类型使用。在这种情况下,建议小部件引用存储在CDN上的资源的(最好是版本中性的)URL。

To allow for the CDN scenario, the resource URLs can be specified either as local relative URLs (in which case it is interpreted relative to the Content or Script subdirectory of the widget directory), as an application-relative URL (e.g. "~/Scripts/somelibrary.js") or as an absolute URL (e.g. "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js").

为了允许CDN场景,可以将资源URL指定为本地相对URL(在这种情况下,它相对于窗口小部件目录的Content或Script子目录进行解释),作为应用程序相对URL(例如“〜/ Scripts”) /somelibrary.js“)或绝对URL(例如”http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js“)。

Note: Serving static files needs to be as fast as possible and the overhead of running any code on top of the web server's tends to be high in comparison to the benefits. For this reason, the helper APIs presented here will directly generate URLs that directly map to the physical location of the resource files instead of, for example, generating a route-based URL that could be dynamically resolved later. Where that becomes problematic is that there are a few places, such as stylesheets, that are themselves static resources but that must reference other static resources (typically background images). Because the stylesheet is itself a static resource (it is possible to serve an aspx as the stylesheet but this is confusing and breaks IntelliSense), it cannot call into the helpers and must reference its dependencies using URLs that are relative to itself. This means in turn that the dependencies in question must be physically at the place the stylesheet points. This of course puts a limitation to resource fallback: you cannot override just the stylesheet, you also need to copy everything it depends on.

注意:服务静态文件需要尽可能快,并且与优势相比,在Web服务器上运行任何代码的开销往往很高。因此,此处提供的帮助程序API将直接生成直接映射到资源文件的物理位置的URL,而不是生成可以在以后动态解析的基于路由的URL。存在问题的地方是有一些地方,例如样式表,它们本身就是静态资源,但必须引用其他静态资源(通常是背景图像)。因为样式表本身就是一个静态资源(可以将aspx作为样式表提供,但这会令人困惑并打破IntelliSense),因此无法调用助手并且必须使用相对于自身的URL来引用其依赖项。这反过来意味着所涉及的依赖关系必须在物理表单所指的位置。这当然限制了资源回退:你不能只覆盖样式表,你还需要复制它所依赖的一切。

Widget controllers and routes

小部件控制器和路由

A widget may expose its own controller to handle user interaction.

窗口小部件可以公开其自己的控制器以处理用户交互。

A widget's controller should be named by convention [MyWidgetName]Controller and should be defined in the [MyWidgetName].cs file that also contains the widget's definition class and record class. It should implement the IController interface or inherit from a class that does.

窗口小部件的控制器应按约定\ [MyWidgetName \] Controller命名,并应在\ [MyWidgetName \] \ .cs文件中定义,该文件还包含窗口小部件的定义类和记录类。它应该实现IController接口或从一个类继承。

To expose custom routes, the widget provider should act like other content type provider classes.

要公开自定义路由,窗口小部件提供程序应像其他内容类型提供程序类一样。

Widget groups

小组组

The administrator can define named widget groups at the site level. These groups consist in an ordered list of widgets and the configuration for these widgets. The scope of the configuration is the widget group.

管理员可以在站点级别定义命名的窗口小部件组。这些组包含有序的窗口小部件列表以及这些窗口小部件的配置。配置范围是窗口小部件组。

What group of widgets goes into each zone for a given content item is handled by a specialized content part and is thus configurable at the content-item level.

针对给定内容项进入每个区域的哪组小部件由专用内容部分处理,因此可在内容项级别配置。

Note: we won't implement widget group administration in this iteration. Instead, we will code the infrastructure and will "hard-code" groups that the templates will statically include.

注意:我们不会在此迭代中实现窗口小部件组管理。相反,我们将对基础架构进行编码,并将“硬编码”模板将静态包含的组。

Initial widgets

最初的小部件

We will implement the following widgets as part of the first widget iteration:

我们将实现以下小部件作为第一个小部件迭代的一部分:

  • Tag cloud

  • 标签云 *

  • HTML

  • HTML *

The HTML widget will be used to render the site footer.

HTML小部件将用于呈现网站页脚。

In the first iteration, we'll inject the widgets into the views with hard code. Configuration will come in a later iteration.

在第一次迭代中,我们将使用硬代码将小部件注入视图中。配置将在稍后的迭代中出现。

In future iteration, we could look at the following widgets (in no particular order):

在将来的迭代中,我们可以查看以下小部件(没有特定的顺序):

  • Blog archives

  • 博客档案 *

  • Recent items

  • 最近的项目 *

  • Ads

  • 广告 *

  • Analytics / stats

  • 分析/统计 *

  • Xbox Live

  • Xbox Live *

  • Twitter

  • 推特 *

  • FaceBook

  • Facebook的 *

  • Current user / login / logout

  • 当前用户/登录/注销 *

  • Media

  • 媒体 *

  • Flickr

  • Flickr的 *

  • Zune

  • Zune播放器 *

Community contributions could also provide some of these widgets.

社区贡献也可以提供其中一些小部件。

Permissions

权限

The owner in this context refers to the content item owner when assigning a widget group to a zone in the template, or to the site owner for other permissions.

此上下文中的所有者在将窗口小部件组分配给模板中的区域时引用内容项所有者,或者为其他权限分配给网站所有者。

Permission | Anon. | Authentic. | Owner | Admin. | Author | Editor

许可|匿名。 |真实。 |所有者|管理员。 |作者|编辑

------------------------------------------ | ----- | ---------- | ----- | ------ | ------ | ------

  • | ----- | ---------- | ----- | ------ | ------ | ------

Create and manage widget groups | No | No | Yes | Yes | No | No

创建和管理小组件组|没有|没有|是的|是的|没有|没有

Assign a widget group to a zone | No | No | Yes | Yes | Yes | No

将小组件组分配给区域|没有|没有|是的|是的|是的|没有