Using different page templates in TYPO3 - templates

I'm looking for some help about using different templates for each page. I'm using everything is on the TYPO3 video tutorial (linked below) but isn't explain there how to do what I need (which code must be write and where).
Site Package tutorial part 1
Site Package tutorial part 2
Site Package tutorial part 3

I suggest to start with the site package builder: https://sitepackagebuilder.com/ based on Bootstrap package which will a) bring you already helpful templates and b) shows you how to make your own ones (Example.html / Configuration/TsConfig/Page/Mod/Weblayout/BackendLayout.tsconfig).
Some helpful references: https://docs.typo3.org/typo3cms/SitePackageTutorial/FluidTemplates/Index.html

Connecting Fluid templates to Backend Layouts
So you have a special template for the about page and want to use it in TYPO3. You'll have to create a new Backend Layout for this template.
The Backend Layout could be configured in Page TSconfig like that:
mod.web_layout.BackendLayouts {
about {
title = About page
config {
backend_layout {
colCount = 1
rowCount = 1
rows {
1 {
columns {
1 {
name = main column
colPos = 0
}
}
}
}
}
}
icon = EXT:your_sitepackage/Resources/Public/Images/BackendLayouts/About.svg
}
}
In the next step, you'll have to connect your new Backend Layout with your template. This is done in TypoScript setup:
page = PAGE
page {
10 = FLUIDTEMPLATE
10 {
file.stdWrap.cObject = CASE
file.stdWrap.cObject {
// select a layout template depending on the page's BackendLayout:
key.data = pagelayout
// Important! If you set BackendLayouts through TSconfig, you MUST use the prefix 'pagets__':
pagets__1_column = TEXT
pagets__1_column.value = EXT:your_sitepackage/Resources/Private/Templates/1Column.html
pagets__about = TEXT
pagets__about.value = EXT:your_sitepackage/Resources/Private/Templates/About.html
default = TEXT
default.value = EXT:your_sitepackage/Resources/Private/Templates/1Column.html
}
layoutRootPaths {
10 = EXT:your_sitepackage/Resources/Private/Layouts/
}
partialRootPaths {
10 = EXT:your_sitepackage/Resources/Private/Partials/
}
variables {
}
}
}
Official video tutorial
See also the YouTube video about this topic: How to implement frontend layouts in TYPO3 using backend layouts
Finally, assign your new Backend Layout to single pages in TYPO3 backend
This is done in the page properties:
Open the page properties of a page in the TYPO3 Backend.
In the tab 'Appearance', you will find two options to assign Backend Layouts:
'Backend Layout (this page only)'
'Backend Layout (subpages of this page)'
These are pretty much self-explanatory:
The first option sets the desired Backend Layout only for this single page.
The second option will assign the Backend Layout for all sub pages of the current page. You can override this Backend Layout again: open the page properties of the sub page where you want a different layout and assign a new one.
On this website you can find an even more detailed explanation with screenshots (taken from the Backend of TYPO3 6.2).

Related

Modifying the Wagtail publish dropdown (per app)

I'd like to reconfigure the default "Publish" menu. The default configuration is this:
I'd like to make Publish the default action, and move it to the top. I'd also like to remove Submit for Moderation, as our site has no current need for that feature.
Ideally, I'd love to be able to override the menu config on a per-app basis - we will likely have other sections of our site in the future where we want a different config.
Is this possible?
This isn't currently possible I'm afraid - the menu items are fixed in wagtailadmin/pages/create.html and edit.html.
This is possible as of Wagtail 2.4 using the register_page_action_menu_item hook, as per Yannic Hamann's answer. Additionally, Wagtail 2.7 (not released at time of writing) provides a construct_page_listing_buttons hook for modifying existing options.
You can add a new item to the action menu by registering a custom menu item with the help of wagtail hooks.
To do so create a file named wagtail_hooks.py within any of your existing Django apps.
from wagtail.core import hooks
from wagtail.admin.action_menu import ActionMenuItem
class GuacamoleMenuItem(ActionMenuItem):
label = "Guacamole"
def get_url(self, request, context):
return "https://www.youtube.com/watch?v=dNJdJIwCF_Y"
#hooks.register('register_page_action_menu_item')
def register_guacamole_menu_item():
return GuacamoleMenuItem(order=10)
Source
If you want to remove an existing menu item:
#hooks.register('construct_page_action_menu')
def remove_submit_to_moderator_option(menu_items, request, context):
menu_items[:] = [item for item in menu_items if item.name != 'action-submit']
The default button SAVE DRAFT is still hardcoded and therefore cannot be configured so easily. See here.
It seems it can't be done on server side without some monkey-patching.
However if you want it for yourself (or have access to computers of those who will publish) you can modify your browser instead.
Install Tampermonkey browser addon
Create new script with a content below
Change http://127.0.0.1:8000/admin/* to your wagtail admin panel url pattern
Save script and check admin panel
Result should look:
// ==UserScript==
// #name Wagtail: replace "Save draft" with "Publish"
// #match *://127.0.0.1:8000/admin/*
// #require https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// ==/UserScript==
let $ = window.jQuery;
function modify() {
let draft = $("button.button-longrunning:contains('Save draft')");
let publish = $("button.button-longrunning:contains('Publish')");
if (draft.length && publish.length) {
swap(publish, draft);
}
};
function swap(a, b) {
a = $(a); b = $(b);
var tmp = $('<span>').hide();
a.before(tmp);
b.before(a);
tmp.replaceWith(b);
};
$(document).ready(function() {
setTimeout(function() {
try {
modify();
}
catch (e) {
console.error(e, e.stack);
}
}, 100);
});
Modifying the code above, these selectors works for every admin language:
let draft = $("button.button-longrunning.action-save");
let publish = $("button.button-longrunning[name='action-publish']");

Sitecore, render Item in code with personalization in mvc

My terminology might be slightly off as I am new to Sitecore mvc. I am trying to hardcode a view rendering with a hard coded datasource (I have to do it this way for other requirements) This view rendering has placeholders that are dynamically set and then personalized.
How can I trigger the ViewRendering on an item?
I've tried ItemRendering, but it doesn't seem to be picking up the stuff set up in the PageEditor.
* To be clear, the helpful posts below have the rendering working, but we do not seem to be getting the personalized datasources. *
I believe this is what you're after:
Item item = /* think you already have this */;
// Setup
var rendering = new Sitecore.Mvc.Presentation.Rendering {
RenderingType = "Item",
Renderer = new Sitecore.Mvc.Presentation.ItemRenderer.ItemRenderer {
Item = item
}
};
rendering["DataSource"] = item.ID.ToString();
// Execution
var writer = new System.IO.StringWriter();
var args = new Sitecore.Mvc.Pipelines.Response.RenderRendering(rendering, writer);
Sitecore.Mvc.Pipelines.PipelineService.Get().RunPipeline("mvc.renderRendering", args);
// Your result:
var html = writer.ToString();
You can statically bind a View Rendering using the Rendering() method of the Sitecore HTML Helper. This also works for Controller Renderings using the same method.
#Html.Sitecore().Rendering("<rendering item id>")
This method accepts an anonymous object for passing in parameters, such as the Datasource and caching options.
#Html.Sitecore().Rendering("<rendering item id>", new { DataSource = "<datasource item id>", Cacheable = true, Cache_VaryByData = true })
In your view rendering, I am assuming you have a placeholder defined along with the appropriate placeholder settings in Sitecore (If not, feel free to comment with more detail and I will update my answer).
#Html.Sitecore().Placeholder("my-placeholder")
In this case, "my-placeholder" will be handled like any other placeholder, so you will be able to add and personalize components within it from the Page Editor.

Overriding Admin shapes in custom Orchard CMS theme

I'm doing a custom theme for Orchard CMS.
As part of client project one of the requirements is to have some extra functionality in blog admin page.
This is pretty easy doing some simple changes in Parts.Blogs.BlogPost.ListAdmin.cshtml
I do not want to change the Blog source code, I would like to override that wiew in theme just like I'm doing with all the others on front end.
Following some guidelines found on orchard forum I have tried the following paths:
~/Themes/MyTheme/Views/Parts.Blogs.BlogPost.ListAdmin.cshtml
~/Themes/MyTheme/Views/Orchard.Blogs/Parts.Blogs.BlogPost.ListAdmin.cshtml
~/Themes/MyTheme/Views/Dashboard/Admin/Parts.Blogs.BlogPost.ListAdmin.cshtml
but the view is not picked up.
So, How may I override a view in my theme that will be picked up by admin dashboard instead of the default one?
Thanks
You need to create a theme with a project file, then add a .cs file with something like this in it:
public class AdminOverride : IThemeSelector
{
public ThemeSelectorResult GetTheme(RequestContext context)
{
if (AdminFilter.IsApplied(context))
{
return new ThemeSelectorResult { Priority = 111, ThemeName = "NewAdminTheme" };
}
return null;
}
}
Don't set this theme as current though, just enable it from the backend. You will also need to set your TheAdmin as the base theme in the Theme.txt like this:
BaseTheme: TheAdmin

Issue trying to use Datasource Template in Sitecore sublayout; getting empty Sublayout.Datasource

We've been trying to "componentize" our Sitecore solution as we move forward, in prep for transitioning to Page Editor usage (Woot! Finally!), but we're still practically working primarily with Page templates that may be inheritance-based composites of page specific fields, plus 1:many of these componentized templates. An example of how this looks in our solution is below -- Banner Feature Carousel and Featured Cartoon are some of these new components we're creating:
In the interest of trying to move away from using Sitecore.Context.Item (as I was recently reminded by this post) I've started filling in the Datasource template field on the sublayouts for the new components, and it seems like I've got the appropriate connections made between presentation details, the Sitecore sublayout and the .NET code file (as far as I can tell; again, we're newer to working this way).
I've also tried setting up a base class for these components as per this post by Nick Allen, but here's where I'm running into a problem: When I execute my code, this base class is finding the component Sublayout appropriately (the whole "this.Parent as Sublayout" thing) but, when I go to interrogate the Sublayout.Datasource property, it's an empty string. Here's my code (so far) for this base class:
public class ComponentBase : System.Web.UI.UserControl
{
private Sublayout Sublayout { get { return Parent as Sublayout; } }
public Item DataSourceItem
{
get
{
return Sublayout != null && !String.IsNullOrEmpty(Sublayout.DataSource) ?
Sitecore.Context.Database.GetItem(Sublayout.DataSource) : Sitecore.Context.Item;
}
}
}
I'm apparently missing some interplay between the Datasource Template field in the Sitecore sublayout, and how that actually translates to a datasource. Is it because these component templates are being used to compose Page templates? I was thinking that the datasource would just ultimately resolve to the Page template on which the component in question was currently being used, but perhaps that's my misunderstanding.
If anyone could give me any hints of things to check or point me to any resources I might use to get further, I'd appreciate it. I've done quite a bit of asking the Googs, myself, but am just not getting anything that's helping.
Thank you in advance, Sitecore friends!
It looks like you have configured the allowed templates for your sublayout in the steps you describe above. This basically tells Sitecore; 'allow user to select items based on these templates for this sublayout'. This alone does not set up the data source on items using the sublayout. You still need to go into the presentation details for any items using this sublayout, select the sublayout and then set its datasource property (within the content editor go to Presentation > Details > [Sublayout] > Data Source).
My answer to this question gives the source code needed to retrieve the datasource item and to iterate through the sitecore controls on your sublayout setting all of their Item propertys.
Here is the code:
public class SublayoutBase : UserControl
{
private Item _dataSource;
public Item DataSource
{
get
{
if (_dataSource == null)
{
if (Parent is Sublayout)
{
_dataSource =
Sitecore.Context.Database.GetItem(((Sublayout)Parent).DataSource);
}
if (_dataSource == null)
{
_dataSource = Sitecore.Context.Item;
}
}
return _dataSource;
}
}
protected override void OnLoad(EventArgs e)
{
foreach (Control c in Controls)
{
SetFieldRenderers(DataSource, c);
}
base.OnLoad(e);
}
private void SetFieldRenderers(Item item, Control control)
{
if (item != null)
{
var ctrl = control as Sitecore.Web.UI.WebControl;
if (ctrl != null && !string.IsNullOrEmpty(ctrl.DataSource))
{
//don't set the source item if the DataSource has already been set.
return;
}
if (control is FieldRenderer)
{
var fr = (FieldRenderer)control;
fr.Item = item;
}
else if (control is Image)
{
var img = (Image)control;
img.Item = item;
}
else if (control is Link)
{
var link = (Link)control;
link.Item = item;
}
else if (control is Text)
{
var text = (Text)control;
text.Item = item;
}
else
{
foreach (Control childControl in control.Controls)
{
SetFieldRenderers(item, childControl);
}
}
}
}
}
When you start using sublayouts on which you will set your datasource try to use the marketplace "Sublayout Parameter Helper". When you use the class they provide as base class and have set everything up right in your Sitecore Environment you will find yourself having a "this.DatasourceItem" -> which will contain your datasource Item, or the context Item if none is given.
http://marketplace.sitecore.net/en/Modules/Sub_Layout_Parameter_Helper.aspx
To find out more on how datasource works, try searching on http://sdn.sitecore.net. There is alot of documentation available that should get you in the right direction. Generally it will be enough to just add a datasource in the sublayout that you can access in your sublayout.
When you read a datasource from a sublayout all it will do is check if the datasource field on that sublayout is filled and will return you information regarding this datasource. So when you add a new component to a page using the page editor (for example a sublayout for a news article) and you have a datasource template defined and filled in during adding this components, you will see that when you check the presentation details on that page a sublyaout with a datasource has been added. The datasource will point to a folder in which you will find an item based on the datasource template you specified on your sublayout. You should also double check this, cause if no datasource is present on the added sublayout it will be obvious you can't access it from your code.
If you are using Sitecore 7 update 1 you can actually now use the attributes. From the Release Notes:
To make it easier to get the data source for a sublayout from
code-behind, the data source is now transferred to the sublayout
control in a "sc_datasource" attribute. (320768)
To get the data source from code, simply refer to
this.Attributes["sc_datasource"];

How to add a new template to Typo3 "Layouts" drop-down list

I have a Typo3 installation with 3 existing layout options. These are all declared in the page.ts file like so:
#normal layout:
[globalVar=TSFE:page|layout=0]
page.10.template.file = fileadmin/template/classic-page.html
page.includeCSS.screen = fileadmin/template/css/style.css
page.includeCSS.screen.media = screen
[global]
And they are all in this list further down the page.ts file, like so:
TCEFORM.pages {
layout.altLabels.0 = Normal
layout.altLabels.1 = Startpage
layout.altLabels.2 = Landing page
}
All of these layout options are displayed in the CMS on the "Edit Page (X)" > Appearance page, in a drop-down list of possible layout options. Handy!
Now I have a shiny new template that I want to add as an option. I can apply it to a specific page id (say, page id #563) by adding this code to the page.ts:
[globalVar = TSFE:id=563]
page.10.template.file = fileadmin/template/shinynewtemplate.html
[GLOBAL]
But I can't seem to add it as a new layout option in the drop-down menu. I have tried this:
#shiny new layout:
[globalVar=TSFE:page|layout=3]
page.10.template.file = fileadmin/template/shinynewtemplate.html
page.includeCSS.screen = fileadmin/template/css/style.css
page.includeCSS.screen.media = screen
[global]
TCEFORM.pages {
layout.altLabels.0 = Normal
layout.altLabels.1 = Startpage
layout.altLabels.2 = Landing page
layout.altLabels.3 = Shiny new page
}
But no banana. It doesn't show up in the Appearance layout list, so I can't apply it to a page.
What am I missing? Is there somewhere else that I need to declare this template file so that it will show up as an option in the drop-down list?
An alternative label does not help, if there is no item which will use your label.
You need to add the new item (Page TS Config!):
TCEFORM.pages {
layout.addItems.3 = Shiny new page
}
See TSconfig