Closed dodyg closed 1 year ago
Multi Language website (English and Arabic)
If you need any kind of help in Arabic, ping me :)
svg aren't cached https://github.com/OrchardCMS/OrchardCore/issues/3807
What rule?
This is a condition to display the layer, a javascript boolean expression interpreted by Jint.
ex: true
if always displayed, isHomepage()
for the home, url('~/blog*')
for a url starting by blog
.
We still need to create the corresponding documentation: #3111
When you use other recipes, some layers are created during the setup.
A Widget is a content type that has a Widget
stereotype.
Some widgets are created when you use other recipes, like Paragraph
, ...
Widgets can also be added in a FlowPage and a WidgetListPart.
Then, you will ask: What is a zone?
You can define them in the admin Zones
setting and they have to be the equivalent sections in your theme.
So, to summarize: the Layers page allows you to put widgets in zones for a specific Layer.
Ex: Add a paragraph Widget in the Footer zone on all the pages (= the Always
layer).
So, to summarize: the Layers page allows you to put widgets in zones for a specific Layer.
So let me validate my understanding
Does zone comes first then layers?
eg
There's Template
<html>
<body>
<zone header>
<Layer One>
<Layer Two>
</zone header >
<zone footer>
<Layer One>
</zone footer>
</body>
</html>
or Layer first then Zone
<html>
<body>
<Layer One>
<zone header>
<zone footer>
</Layer One>
<Layer Two>
<zone header>
</Layer Two>
</body>
</html>
There are only zone sections in the theme.
Ex: {% render_section "Footer", required: false %}
You need to set them in the Zones settings You declare Layers (which are displayed based on their Rule, the interpreted condition).
It allows you to drag and drop and edit widgets inside the zones for a specified layer. Ex: You add a paragraph Widget in the Footer zone on all the pages (= the Always layer).
OK I think I get it now. Let me study the theme. Thank you for your explanation.
https://orchardcore.readthedocs.io/en/dev/docs/getting-started/theme/ needs more details. At the moment it is good enough to start an empty theme project but anything useful people will have to study existing themes.
There needs to be a gentler version introduction to theming other than this document. This is hard mode tutorial https://orchardcore.readthedocs.io/en/dev/OrchardCore.Modules/OrchardCore.Themes/.
I think a better theme tutorial would start from this layout.liquid
and start expanding from here. This layout.liquid
is generated by dotnet new octheme
.
<!DOCTYPE html>
<html lang="{{ Culture.Name }}">
<head>
<meta charset="utf-8">
<title>{% page_title Site.SiteName, position: "before", separator: " - " %}</title>
{% resources type: "Meta" %}
<!-- INSERT REQUIRED RESOURCES HERE -->
{% resources type: "HeadLink" %}
{% resources type: "Stylesheet" %}
{% resources type: "HeadScript" %}
</head>
<body dir="{{ Culture.Dir }}">
{% render_body %}
<footer>
{% render_section "Footer", required: false %}
</footer>
{% script name:"jquery", use_cdn:"true", at:"Foot" %}
{% resources type: "FootScript" %}
</body>
</html>
In the traditional CMS, existing theme isn't really a solution because you cannot alter the files of existing theme. You can't modify a theme and switch it from using bootstrap to using bulma for example.
You have to create a new theme.
@hishamco How i can make my CMS web project localized I tried to add .po files to Localization folder but it didn't work
SVG cache problem #3807 is fixed.
This instant preview feature while modifying template is super sweet.
{% resources type: "HeadLink" %}
It's not clear how this tag behaves. If the type is "HeadLink", where do you define the resources associated with it?
I mean the themes have these statements usually
{% resources type: "HeadLink" %}
{% resources type: "Stylesheet" %}
{% resources type: "HeadScript" %}
And it's not clear how to interact with them.
{% meta name:"description", content:"This is a website" %}
Call this to be able to set a meta information from your liquid template
This is the relationship between the "zone" in the template and "render_section" in theme.
Orchard Core will pick up any changes on your theme (just refresh your browser). Just make sure you make your new custom theme as the default theme for your website.
Name the zones where you can attach widgets
You can add Widgets to each specified Zone and you can change the order of appearance for the Widget
Each Widget in your zone is associated wit a Layer. A Layer is pretty much a condition where your Widget can appear
In this layer, the condition always evaluate true so it will show in every page. There are a bunch of possible rules you can use as mentioned here https://github.com/OrchardCMS/OrchardCore/issues/4121#issuecomment-526829675
What is a widget? A widget is Content Type that has a stereotype value 'Widget'
It's literally just a string that you type in this stereotype field "Widget" :laughing:
This autoroute description is tricky. You'd assume that just by adding the part you can define a custom path for your Content Type. Nope, you have to adjust more settings. If you don't, autoroute will generate the path for you.
This is new. I haven't checked it out yet but it can potentially solves the issue of sorting, filtering, etc.
https://orchardcore.readthedocs.io/en/dev/docs/reference/modules/SQL/
This thread is important regarding ASP.NET Core 3.0 upgrade (https://github.com/OrchardCMS/OrchardCore/issues/4261)
@hishamco How i can make my CMS web project localized I tried to add .po files to Localization folder but it didn't work
Sorry I didn't notice your thread, to enable the localization you need to enable Localization Module after that the tenant will restart and you will be able to find a new sub menu Settings -> Localization then add your favorites cultures
This is interesting Liquid Custom Tag (https://github.com/OrchardCMS/OrchardCore/issues/4384)
The default layout for a theme is called either "Layout.liquid" or "Layout.cshtml".
You can create an alternative layout e.g. "LayoutModern.liquid" and then call it from the view
{% layout "LayoutModern" %}
Using {{ Model.ContentItem.Content }}
in your Content Item template will expose the Json structure of the content. It's great for accessing individual properties of the content.
Shape remains a mystery. I've watched the video twice. It looks like it's not relevant for just implementing a website (vs module developer)
Getting extra content in your liquid template:
@dodyg What made it click for me with shapes is then I compared them to React Components. Coming from doing javascript development for 2 years, when I understood that, everything clicked. The OC display manager is simply rendering a component (shape) and uses a bunch of conventions to find the right template to render. It also uses other metadata for placement of this shape. Hope this helps in some way.
What I understand is that Model.Content
is a shape. OK got it.
Then what? It's not clear whether you can create a shape within a layout using liquid. I tried all the documented shape filters (https://orchardcore.readthedocs.io/en/latest/OrchardCore.Modules/OrchardCore.Liquid/README/#shape-filters) but they either don't work or I misunderstood their purpose, e.g. 'shape_new'.
What you are looking for is something like this :
{{ "Footer__Before" | shape_new | shape_render }}
Which would work with a Footer-Before.liquid template.
Then the only matter missing here is passing an actual model to that sub-template.
You can build a shape (component), pass properties, and assign a template.
You can build a shape (component),
I am lost this part.
Example:
Views\MyTestShape.liquid
in the active theme.
<span>{{ Model.MyString }} - {{ Model.MyInt }}</span>
{% assign customShape = "MyTestShape" | shape_new %}
{% shape_add_properties customShape my_string: "String Test 3", my_int: 1 %} {{ customShape | shape_render }}
{% shape_remove_property customShape "my_string" %} {{ customShape | shape_render }}
{% assign customShape = "MyTestShape" | shape_new | shape_properties: my_int: 3, my_string: "String Test 3" %} {{ customShape | shape_render }}
{% assign customShape = "MyTestShape" | shape_new: my_int: 4, my_string: "String Test 4" %} {{ customShape | shape_render }}
Ah so a Shape depends on a template file (either liquid or razor). Does it always have to rely on the template in the theme or can it be created in the db?
I am not sure of that one. I assume there must be some extension point to OC to be able to resolve liquid files from a database.
I found it. The template file can be created in the DB!
A shape doesn't necessarly depends on a template. Most of shapes are built by the DisplayManager for use with a template but some other shapes are also used for simply transforming a value from a context like a datetime displayed in the proper culture format. So a shape is basically a dynamic container used as a dynamic Viewmodel, but it's also used for all kind of things.
I think you can see Shapes visual representation in the Layout admin UI where you can add widgets in a layout template dynamically. That's the basic usage of shapes.
As a website implementor, a shape is a template file you can include in other template and pass some parameters to it. It is simpler to start understanding from this angle.
I am going to write "50 shades of Shapes" guide, which will contains various aspect of shapes and it will start from the simplest usage of Shapes. I really had a hard time understanding Shapes until just minutes ago so I think this guide can save others time.
/OrchardCore.Templates/Template/Index
is the place to manage all your templates. The corresponding documentation is here
This template naming convention hell is not for faint of hearths 😉 I'm still trying to figure out what works or not still. So don't be discouraged when trying different names 😄
I love to talk about shapes. They are very easy to understand actually, let me try.
A Shape is an object that holds some data, like a view model, and also some metadata about how to render it. Any class that implements IShape
is a shape.
Shapes are used to as a way to render some html, and to do so you need to call the IDisplayHelper.DisplayAsync(shape)
that returns Task<IHmlContent>
.
When calling this method you don't need to specify a template, it will trigger an event to allow any component in the system to chose what template is best suited to render this specific shape. This is why a shape can be rendered using a cshtml file, a liquid file, some template from the database, some code, ... it's completely extensible, but from your point of view you just ask it to be rendered. This is an advantage over Views in MVC where when return a ViewResult
from an action the template is strongly associated with the action.
This indirection is very useful for theming, such that templates can come from different modules, or any module can redefine what template to use for a shape. So as a developer you can provide one default template with your shape that represents a Menu, but allow any other module or theme to redefine it.
Then to allow for better granularity in ways to select a template, the shape has a Metadata.Alternates
property that contains which templates names are better suited for this shape, in order of priority. Like a shape representing an Article, which is a Content item, could accept template for an with a specific name, or a template for any article, or a template for any content item. This allows the themes to be able to customize the templates for very specific instances of shapes, or group of shapes.
When working in the decoupled CMS mode, you are removing theming altogether, and not using shapes at all, because you implement each view and route handler, and don't expect anything else to be able to override these. But most modules that expose front-end views need to use shapes in order to allow a theme to customizes parts of the system without having to re-implement all handlers and views.
Thank you for the explanation. I think Shapes conceptually is very elegant however I think for OrchardCore CMS beginners like me it is much easier to grasp the concept from the practical POV.
Shapes allows me to modularize my template. Wow. That's super cool and very practical.
A collection of samples on the practical usages of Shapes in the CMS will be very helpful for everyone.
Rendering a sub Shapes using template
In the vein of https://github.com/OrchardCMS/OrchardCore/issues/3553, I am starting another website using the traditional CMS model.