请注意,本站并不支持低于IE8的浏览器,为了获得最佳效果,请下载最新的浏览器,推荐下载 Chrome浏览器
欢迎光临。交流群:166852192

orchard.Layouts模块的使用


Layouts is an exciting new Orchard 1.9 feature, enabling users to visually design grids and layout elements.
The feature is fully compatible with grid systems such as Bootstrap.
In this post, we'll have a close look and see how and what we can use it for.

At first glance

When you install Orchard 1.9, the first thing you might notice is that the Page content type no longer contains a BodyPart by default. Instead, it now has a LayoutPart.
Make no mistake, the BodyPart is still absolutely relevant, that will not change. Experienced Orchard users typically design their own content types, and the BodyPart is a very useful part to represent a type with a body of text.
To new users, we want to show off what you can do with Layouts. Take for example the "Home" page that is created when you setup a new site using the Default recipe:



Notice any differences? No? Let's have a look at the page editor:





What you see above is the layout editor used to layout the homepage. By default, the Page doesn't have aBodyPart anymore, but a LayoutPart which is responsible for rendering a layout editor.
A layout is a hierarchical collection of elements, such as GridsRowsColumnsHtmlMarkdownParagraph,Image, and more.
And Orchard wouldn't be Orchard if you wouldn't be able to extend thhe list of elements with your own elements.

Feature Overview

The following is a high-level overview of all that Layouts currently has to offer.
  • LayoutsPart to turn your content types into content items with a layout.
  • LayoutWidget that enables you to add layouts to any zone.
  • An ElementWrapperPart that lets you turn any element into a widget. The idea here is that we want to move towards an element-first approach, so that whatever elements you develop, they can be used within a layout as well as within theme zones as widgets, reusing the element's logic and data. This content part is what enables the following additional widgets added to the system: Content Widget,Media Widget and Text Widget. Each of these widgets don't have any specific parts, but rely on an element as their "nucleus".
  • Element Blueprints are preconfigured elements that the user can create through the dashboard. 
  • Layout Templates enable the user to define a set of layouts that can be reused. Think ASP.NET Master pages.
  • Snippet Elements, which are elements created in the form of Razor templates, which live in the theme. For example, if you create a Razor file named CompanyLogoSnippet.cshtml in your theme and enable the Snippets feature, your template will be available as an element called "Company Logo".
  • ContentPart and ContentField elements. This enables you to place the content parts and fields attached to your content type anywhere within the layout. Think Placement.info controlled via UI (although Placement.info has nothing to do with it, other than disabling the default rendering of these shapes).
  • All elements share a common set of properties, such as IDCss Class and Inline Style.
  • Elements are turned into shapes for rendering. This means ultimate freedom in customizing how an element is rendered in your theme.
  • Element Tokens which enabled elements to be rendered inside of tokenized text fields. A typical scenario is a preconfigured element (Element Blueprint) being rendered inside of a BodyPart.

Layout Columns != Zones

When we first introduced the layouts feature, one of the first questions asked was: "How does layouts relate to zones?"
The short answer is: layouts have nothing to do with zones.
To clarify further: columns in a layout are not widget zones, and are not intended to "design" your theme. Instead, you use a layout to place elements (optionally using Grid elements) into the local Content zone of a content item.
In the first screenshot of this post showing the new homepage, what you see is not the three standard widgets (they have been removed), but simply the Content zone that renders the LayoutPart shape (Parts_Layout).
Since the LayoutPart is attached to a content type, the shape created by its driver (Parts_Layout) will be added to the Content shape via Placement.info, just like any other part shape such as Parts_Title andParts_Common_Metadata, and the Content shape itself is added to the Content global zone.

Bootstrap

Our of the box, Orchard uses a small CSS file called "default-grid.css", based on custom-grid.css from Sébastien Ros. It's a lightweight CSS file to implement grids without relying on full-blown CSS grid frameworks such as Bootstrap.
However, if your theme is using Bootstrap, you most certainly will want to have the LayoutPart render the grid, rows and columns using Bootstrap specific classes.
To do so, follow these simple steps:
  1. Copy the following files from Orchard.Layouts/Views into the Views folder of your theme:
    • Either Elements.Grid.cshtml or Elements/Grid.cshtml
    • Either Elements.Column.cshtml or Elements/Column.cshtml
    • Parts.Layout.cshtml
  2. Open the copied Elements/Grid.cshtml file and change the used CSS class name from "table" to the Bootstrap equivalent of "container".
  3. Open the copied Elements/Column.cshtml file and change the used CSS class name from "span-" to the Bootstrap equivalent of "col-sm-" for example (use the appropriate viewport size as you see fit). Also change the "offset-" class to "col-sm-offset-", or some other viewport size you prefer. You might also want to get rid of the "cell" CSS class entirely.
  4. Get rid of the "default-grid.css" reference from Parts.Layout.cshtml.


This is how these files look like after the changes:
Views/Elements/Grid.cshtml
@using Orchard.DisplayManagement.Shapes@using Orchard.Layouts.Helpers@{    var tagBuilder = TagBuilderExtensions.AddCommonElementAttributes(new OrchardTagBuilder("div"), Model);
    tagBuilder.AddCssClass("container");}@tagBuilder.StartElement@DisplayChildren(Model)@tagBuilder.EndElement
Views/Elements/Column.cshtml


 OrchardDisplayManagementShapes OrchardLayoutsHelpers    var element = (Column) Model.Element;
 columnSpan  element.Width;
     columnOffset  element.Offset;
     columnOffsetCss  columnOffset      columnOffset : ();
     tagBuilder  AddCommonElementAttributes( (), Model);
    
    tagBuilderAddCssClass(Concat(, columnSpan));
    tagBuilderAddCssClass(columnOffsetCss);tagBuilderStartElementDisplayChildren(Model)tagBuilderEndElement


Views/Parts.Layout.cshtml
@Display(Model.LayoutRoot)

Instead of overriding the shape templates, you could consider to just "retarget" the "span", "offset" and "table" classes using Bootstrap mixins. Either way is fine and completely up to you.

Element Overview

The following is a list of elements that come with the box.
  • Content
    • Content Item - This element enables you to pick one or more content items to be rendered in-place, using a display type of your choosing.
    • Html - This element enables you to add a snippet of HTML contents to your layout. It's like the Html widget, but intended to be used in layouts.
    • Markdown - This element enables you to add a snippet of Markdown contents to your layout. When rendered, the markdown is turned into HTML of course. This is like the Html widget using the markdown flavor.
    • Paragraph - This element enables you to add a single paragraph to your layout. What sets this element apart from Html and Markdown is that any specified properties such as ID, Css Class and Inline Style are rendered on the <p> tag, whereas for the Html and Markdown elements, these properties are rendered as attributes on a <div> tag.
    • Projection - This element enables you to render a projection anywhere in your layout. It is like the Projection Widget, but intended to be used in layouts.
    • Text - This element enables you to add a snippet of plain text contents to your layout. It is like the Html widget using the text flavor.
  • Media
    • Image - This element lets you to add an image to your layout by letting you pick an image media item using the Media Library Picker.
    • Media Item - This element lets you pick one or more media items using the Media Library Picker. The difference between this one and the Image element is that the Image element is rendered using the <img> element, whereas the Media Item element renders the selected media items using the specified display type.
    • Vector Image - This element lets you to add a vector image to your layout by letting you pick a vector image media item using the Media Library Picker.
  • Parts
    • CommonPart - Lets you add the CommonPart shapes to your layout. Note: the part is rendered using the "Layout" display type - this means that if you want to control which shapes of this part's driver are displayed, you need to define Placement.info rules for the "Layout" display type.
    • TagsPart Lets you add the CommonPart shapes to your layout. Note: the part is rendered using the "Layout" display type - this means that if you want to control which shapes of this part's driverare displayed, you need to define Placement.info rules for the "Layout" display type.
    • TitlePart - Lets you add the CommonPart shapes to your layout. Note: the part is rendered using the "Layout" display type - this means that if you want to control which shapes of this part's driverare displayed, you need to define Placement.info rules for the "Layout" display type.
  • Layout

    • Grid - This element lets you add a grid to the layout. A grid is composed of rows and columns, much like a Bootstrap grid.

Layout Templates

Being able to create layouts is fun and creative, but there are times where you need the same layout over and over again and you wish you could somehow reuse some sort of layout template. Well, we have that too. 
When you enable the Layouts feature, not only is the LayoutPart attached to the Page content type, but a new content type called Layout is created, whose definition looks like this:

What sets apart a Layout content type from a Page content type is that it:
  1. Has no AutoroutePart attached, so it is not routable, and
  2. Has the "Use as Template" option checked.
The latter is what makes a layout reusable.
Now, let's imagine we have a website where we have many pages with the following layout structure:
  1. A top level row with a single, full-width column;
  2. A mid level row, also with a single, full-width column.
  3. A bottom row with 4 equally sized columns.
The layout could look like this:

Next, imagine we created three pages, appropriately named: Page 1Page 2 and Page 3.
For each page, we'll add an Html element with a text of something like "Layouts Demo" to the first row, and we'll add some copyright notice to the first column of the last row.
Page 1 could look something like this:

Notice that for Page 1, we selected the "Master Layout" as its template and added two HTML elements.
We could do the same for "Page 2" and "Page 3".
Page 1, 2 and 3 are using the "Master Layout" as their template. Whenever we make a change to this template, that change is reflected across all pages using it.
For example, let's edit "Master Layout" and turn its first row into a yellow color and add some logo to the lower right column:

Hit "Publish Now" to publish the changes and check out what "Page 1" looks like:

As you can see, the pages using the layout template reflect the changes we just made to that layout template.
You could even implement an hierarchy of layout templates where you have a common ancestral layout defining just the layout structure for example, and reusable child layouts defining some content in the form of elements.
Content items could use any of these reusable layouts, and a change anywhere in the hierarchical chain will cause all descendants to be updated.

Element Blueprints

Another feature that comes with layouts is Element Blueprints.
An Element Blueprint is more or less a preconfigured element based on an existing element.
For example, we could define an element called "CompanyInfo" based on the Html element, containing information about our company.
We can now reuse this element in all of our pages. We could even create a widget called "CompanyInfo", attach the ElementWrapperPart, and configure it to use our "CompanyInfo" blueprint element.
Let's do a quick tutorial to see that in action.


First, go to the new Elements menu item and hit the Create button:

Orchard will ask you to pick a Base Element. We'll go with Html:

When creating an Element BluePrint, we need to provide the follwoing information:
  • The Element Display Name;
  • The Element Type Name;
  • The Element Category.
The display name is used when presenting the user with available elements.
The element type name is a technical name used to uniquely identify an element.
The element category is used when the element is rendered as part of the element toolbox in the layout editor.
I specified the following values:

Next we'll see the element-specific editor. This will be the HTML editor, since we chose the "Html" element as the base element.

After hitting Save, we now have our own little "Company Info" element, ready to be used.
Add it to "Master Layout" created earlier:

After adding the "Company Info" element, our master layout and child pages will look something like this:

What's interesting is that no matter how many times you add this element to whatever layouts, whenever you change the blueprint element's contents, those changes will be visible instantaneously.
Note: changing a Blueprint element will cause its changes to immediately appear on published pages.
Next, we'll turn the "Company Info" element into a widget. To do so, go to Content Definition -> Content Types -> Add, and use the name "Company Info Widget" as the display name and "CompanyInfoWidget" as the technical name.
Attach the following parts:
  • Element Wrapper
  • Identity (always attach this part when creating widget types - this will save you headaches when it's time to export/import widgets)
  • Widget
After hitting Save, uncheck the following settings:
  • Creatable
  • Listable
  • Draftable
  • Securable
Set Stereotype to: Widget
Expand the "Element Wrapper" part settings, and enter the element type name of our "Company Info" element:CompanyInfo and Hit Save to persist the changes.
To test this new widget, go to Widgets and add a new widget to the AsideSecond zone of the Default layer, choosing the new "Company Info Widget".
You will not see any element specific editor, but when you navigate to the front end, you'll see the new widget shine bright.
Using element blueprints you can add multiple widgets of the same type without having to duplicate content.
Another technique to "reuse" content is to use the "Content Item Widget", which lets you select one or more content items to render in place.


Wrapping Up

This concludes the highlevel overview of the new Layouts feature. I'm very excited about this one with all of its options, flexibility and extensibility.
The new Dynamic Forms module leverages Layouts and lets the user compose forms using form elements, effectively turning the layout editor into a forms builder.
This very website is powered by the Layouts feature - this is how our homepage looks in edit mode:

In the next post, we'll take a look at Dynamic Forms.
Stay happy!



作者原创内容不容易,如果觉得内容不错,请点击右侧“打赏”,赏俩给作者花花,也算是对作者付出的肯定,也可以鼓励作者原创更多更好内容。
更多详情欢迎到QQ群 166852192 交流。