Given the following directory structure (to keep it simple):
/
_Layout.cshtml
_SubLayout.cshtml
default.cshtml
sub.cshtml
And contents:
sub.cshtml
#inherits ServiceStack.Razor.ViewPage
#{Layout = "_SubLayout";}
<div>In the sub folder.</div>
_SubLayout.cshtml
#inherits ServiceStack.Razor.ViewPage
#{Layout = "_Layout";}
<div>This is a page from a sub section:</div>
#RenderBody()
How can I render the _SubLayout.cshtml view within the _Layout.cshtml view when a request is made for sub.cshtml? When I do this now only the _SubLayout.cshtml is used.
This is supported in ServiceStack 3.9.54
Related
Using 2sxc, I have a hero module that I use across the website on all pages. It looks like this:
It uses "#Content.Title" for the h1 tag so it displays "Scholarships". But I need to make a breadcrumb that gets the parent page's name of the current page. So in this case, "Teachers".
For example, this hero also exists on other pages like "Volunteer" and it has a parent of "Get Involved" so the breadcrumb would dynamically show "Get Involved".
So far, here's my code:
#if (#Dnn.Tab.ParentId != -1) {
<nav class="uppercase text-sm font-semibold tracking-wider"><span class="text-honeydew visited:text-honeydew">#Dnn.Tab.ParentID</span> <span>/</span></nav>
}
This works to handle heroes on a root page (to not show the breadcrumb). But I can only seem to output the ParentID.
How can I use the #Dnn.Tab.ParentID to get the Parent tab's name using c#? Or is there another way to go about this?
Easiest thing to do is use the TabController to turn a TabId in to a TabInfo
#using DotNetNuke.Entities.Tabs
#functions {
private TabInfo GetTabInfo(int tabId)
{
return TabController.Instance.GetTab(tabId, Dnn.Portal.PortalId);
}
}
So then just call it all in one like this with .ParentId...
<pre>
Debug:
Parent Page Name: #GetTabInfo(Dnn.Tab.ParentId).TabName
</pre>
I am developing a website using VueJS, and Kentico Kontent as a CMS. This CMS offers the "rich text" feature, basically allowing text content to embed links and basic formatting, which gets automatically converted into HTML when served through the API.
I have no problem displaying the HTML content using the v-html directive, but I cannot think of a way to set the attributes of the inner <a> tags to _blank, so that the embedded links open new windows when clicked.
Is there any elegant way to do this without having to parse the HTML from the Front-end?
You could create a directive:
Vue.directive('links-in-new-window', {
inserted: function(el) {
const anchors = el.querySelectorAll('a')
anchors.forEach((anchor) => anchor.target = "_blank")
}
})
And just apply that to the same element you're using the v-html on:
<div class="content" v-html="content" v-links-in-new-window></div>
In vue V3 the directive would look like this:
app.directive('links-in-new-window', {
mounted: function(el) {
const anchors = el.querySelectorAll('a')
anchors.forEach((anchor) => anchor.target = "_blank")
}
})
HTML is the same, remember to use v- => v-links-in-new-window
<div class="content" v-html="content" v-links-in-new-window></div>
I have this custom handelbars helper
// custom-helper.js
module.exports = function(name, options) {
if (!this._sections) {
this.sections = {};
}
this._sections[name] = options.fn(this);
return null;
};
// register with assemble
var app = assemble();
app.helper('section', require('./custom-helper.js'));
How to Register custom handelbars helper in assemble 0.17.1
This helper should work like here:
Handlebars with Express: different html head for different pages
And in my grunt Project is does work perfectly. But in this gulp Project it´s not working.
My Layout.hbs:
<body>
<div id="page">
{%body%}
</div>
{{{_sections.foot}}}
</body>
My pages that contain the _sections.foot content and the rest of the page content:
--- layout: default.hbs ---
<h1>Body Blah Blah</h1>
<p>This goes in page body.</p>
{{#section 'foot'}} my custom per page foot content {{/section}}
What the code should do is to tage the custom content in my pages, that is this:
{{#section 'foot'}} my custom per page foot content {{/section}}
and render it in the place that I defined in the layout:
{{{_sections.foot}}}
When I run my gulp task or assemble task I get this.
"null" is written in my rendered .html file at the position in my page.hbs, thats directly under the pages content inside #page and not after #page where my layout.hbs says to put it in.
Here are the Problems:
1. Null is rendered and not the content.
2. Even if the content would be rendered it would appear at the wrong position in html.
I have a project with Polymer + Reveal.js
I have a view with polymer that gets all the Slides/Sections.
<template is="dom-repeat" items="[[my.slides]]" as="slide">
<section>
<h1>slide.title</h1>
<h2>slide.content</h2>
</section>
</template>
When I try to start Reveal.js, I have the issue related to:
(index):21136 Uncaught TypeError: Cannot read property
'querySelectorAll' of undefined
I think is because Reveal.js cannot select a Webcomponent generated by Polymer, because Reveal.js needs to have all slides content wrote on the html file by separate.
Then my question is: How to use Polymer Webcomponents with Reveal,js?
Alan: Yes, you are right.
Now I am creating DOM elements directly with JS avoiding Polymer shadowDOM elements.
Then I created a function called createSlides where - based in a JSON response - I appending slides (sections) within slides div.
Fist I create a Polymer template similar to:
<template>
<div class="reveal">
<div id="slides" class="slides">
<section>
This section will be removed
</section>
</div>
</div>
</template>
Next I removed the unused slide and appended some slides. Finally start the Reveal presentation
ready()
{
this.removeInitialSlide();
this.addSomeSlides();
this.startRevealPresentation();
}
clearInitialSlides()
{
var slidesComp = this.$.slides;
while (slidesComp.hasChildNodes()) {
slidesComp.removeChild(slidesComp.lastChild);
}
}
addSomeSlides()
{
var slide1 = document.createElement("section");
var image = document.createElement("img");
image.src = "some/path/to/image.jpg";
slide1.appendChild(image);
this.$.slides.appendChild(slide1);
var slide2 = document.createElement("section");
slide2.innerHTML = "<h1>Test content</h1>"
this.$.slides.appendChild(slide2);
}
Working fine for now.
I think you most likely can't use reveal.js in a web component created with Polymer right now and here's why.
If you look at reveal.js's code it looks for dom elements with the reveal and slides classes on the main document like this:
dom.wrapper = document.querySelector( '.reveal' );
dom.slides = document.querySelector( '.reveal .slides' );
The problem with that is that Polymer elements have their own local dom which is a different dom tree which can't be accessed using methods like document.querySelector which means reveal.js can't access to them.
In TYPO3 CMS you could build a menu with defined pages very easy. How does this work in Neos and Typoscript2?
Typoscript1 Code was:
Menu1 = HMENU
Menu1 {
special = directory
special.value = 1,6,7
wrap = <div class="somemenu">|</div>
}
For example i have this page structure:
Site1
Site2
Site3
Site4
Site5
Site6
Site7
And i want a menu which only contains Site1, Site6, Site7.
I need that menu in the footer.
I have found a way to create a menu with defined pages, by adding a checkbox in every page so I can select which pages I want to show in the menu.
Start by editing NodeTypes.yaml and extend the Page nodetype to have this extra property
ui:
inspector:
groups:
'footernav':
label: 'Footer Menu'
properties:
'footermenu':
type: boolean
defaultValue: FALSE
ui:
label: 'Show in footer?'
inspector:
group: 'footernav'
After that create a FooterMenu nodetype in the same file.
'Vendor.Site:FooterMenu':
superTypes: ['TYPO3.Neos.NodeTypes:Menu']
ui:
label: 'Footer Menu'
group: 'structure'
Create it's typoscript file.
prototype(Vendor.Site:FooterMenu) < prototype(TYPO3.Neos.NodeTypes:Menu) {
entryLevel = 1
templatePath = 'resource://Neos.Bootsite/Private/Templates/TypoScriptObjects/FooterMenu.html'
}
Edit Root.ts2 file and add in the Page object
footermenu = ${q(node).property('footermenu')}
Last but not least, create FooterMenu.html
{namespace neos=TYPO3\Neos\ViewHelpers}
<ul>
<f:render section="itemsList" arguments="{items: items}" />
</ul>
<f:section name="itemsList">
<f:for each="{items}" as="item">
<f:if condition="{item.node.properties.footermenu}">
<neos:link.node node="{item.node}">{item.label}</neos:link.node>
</f:if>
<f:if condition="{item.subItems}">
<f:render section="itemsList" arguments="{items: item.subItems}" />
</f:if>
</f:for>
</f:section>
thank you for this nice Idea. I wouldn't even call it a workaround. With neos we have to think in different ways... and this solution is really great and intuitive!
I had some headbanging moments cuz I didn't understand the way neos works...
I'm usually want to add elementary elements like navigation fix to the layout/template.
I didn't understood that this footermenu will appear as an element which you can add dynamically when you are logged in.
If somebody want's to know how he can add this fix to the template, so users can't remove it:
Add in your Route.ts2
page = Page {
head{ ... }
body{
//...
parts.footermenu = Vendorname.Sitename:FooterMenu
//...
}
}
In your template file e.g. (Vendorname.Sitename/Private/Templates/Page/Default.html):
{parts.footermenu -> f:format.raw()}
at the position where the menu should appear
Side note: in this example it has to be within the in order to work
I think best solution is already in the Demo Package. You can create a page FooterMenu which you don't want so show as a normal page on the page menu. Add your menu pages as child shortcut nodes to the page/node tree.
Then add this typoscript in your root.ts2
metaMenu = Menu {
entryLevel = 2
templatePath = 'resource://Vendor.PackageName/Private/Templates/TypoScriptObjects/FooterMenu.html'
maximumLevels = 1
startingPoint = ${q(site).children('footermenu').get(0)}
}
Create the template for the menu:
{namespace neos=TYPO3\Neos\ViewHelpers}
<f:render section="itemList" arguments="{items: items}" />
<f:section name="itemList">
<nav class="nav" role="navigation">
<ul class="nav nav-pills">
<f:for each="{items}" as="item" iteration="menuItemIterator">
<li class="{item.state}">
<neos:link.node node="{item.node}">{item.label}</neos:link.node>
</li>
</f:for>
</ul>
</nav>
</f:section>
The last think you have to do ist to place the footerMenu in your page template:
<div class="footer">
{parts.footerMenu -> f:format.raw()}
</div>
The only drawback of this solution is you have to use shortcuts and that is not the best solution for SEO i think. And the page loading time will be increased because of the redirect. But you don't have to extend some code and can use another solution when it is ready.