I want to provide a printer friendly/text only version for a specific content type. So I need to render the same content type with different templates dependent from URL
Example: article/slug should use article.twig, while article/slug/print should use print.twig
Is this possible? Or do I have to write an extension?
So this is a little hack, but it works. I'm using these lines in the routing.yml:
printcontentlink:
path: /{contenttypeslug}/{slug}/print
defaults: { _controller: 'Bolt\Controllers\Frontend::template',template:'print' }
requirements:
contenttypeslug: 'Bolt\Controllers\Routing::getAnyContentTypeRequirement'
And added this at the top of print.twig:
{% set currentslug = paths.current|replace({'/print':''}) %}
{% setcontent record = currentslug %}
The better solution would be to write a new controller or extend the record controller which has a "template" argument.
Related
2SXC 10.25.2 / DNN 9.3.2
I have a 2sxc module that uses a C# template with "list" enabled. I have a content type called "pathway" and inside that I have 2 entity picker fields for "first step sessions" and then "next step sessions". These entity pickers use a "session" content type. Inside each of those "session" content types I also have an entity picker for "speaker(s)". All in all, it's a setup that I have lists within lists within lists.
When I create the loops for each of the sublists, I can easily do that within the 1 C# template but it becomes repetitive, long, and unruly because there's so much c# code where I'm looping the same session template for different entity picker sections. So, I tried using the "Render sub-template" code to simplify the template - I created new sub templates and inserted them in - it seemed to work at first, however, the template started outputting all "session" items into each item in the list.
I suspect that the subtemplate somehow loses the context of the item that it's in so it's outputting everything. Is there something special I need to know about using subtemplates with for each loops? Do I have to include params and, if so, how do I do that?
EDIT to include code sample:
Here is a small, simplified version of the code I'm working with:
#foreach(var Content in AsList(Data)) {
<h2>#Content.Title</h2>
<h3>Lead Sessions</h3>
<div class="lead-sessions text-green">
#foreach(var item in AsList(Content.LeadSessions as object)){
<h4>#item.LeadSessionTitle</h4>
<p>#item.LeadSessionText</p>
}
</div>
<h3>Next Sessions</h3>
<div class="next-sessions text-green">
#foreach(var nextitem in AsList(Content.NextSessions as object)){
<h4>#nextitem.LeadSessionTitle</h4>
<p>#nextitem.LeadSessionText</p>
}
</div>
}
I want to make a subtemplate so I don't have to repeat the same code for the sessions loop. How could I simplify this template to use a subtemplate for looping the sessions within the lead-sessions and next-sessions?
So based on the modified question, it's a bit like this
#foreach(var Content in AsList(Data)) {
<h2>#Content.Title</h2>
<h3>Lead Sessions</h3>
#RenderPage("_inner.cshtml", new { Items = Content.LeadSessions })
<h3>Next Sessions</h3>
#RenderPage("_inner.cshtml", new { Items = Content.NextSessions })
}
Second file _inner.cshtml
#{
var items = AsList(PageData["Items"]);
}
<div class="next-sessions text-green">
#foreach(var nextitem in items){
<h4>#nextitem.LeadSessionTitle</h4>
<p>#nextitem.LeadSessionText</p>
}
</div>
Yep, you can just use RenderPage without params, or pass in params like in the blog app:
#RenderPage("shared/_Category Filter.cshtml", new { MobileView = true, FilteredCategory = filteredCategory })
See https://github.com/2sic/app-blog/blob/master/_List.cshtml#L25
Then the template can retrieve the values like
#{
var filteredCategory = PageData["FilteredCategory"];
}
See https://github.com/2sic/app-blog/blob/master/shared/_Category%20Filter.cshtml#L6
You can pass around any amount of values/objects like this.
You can also create helpers - and then call those helpers. Like this
https://github.com/2sic/app-news/blob/master/shared/_Helpers.cshtml#L24-L33
I'm trying to switch my documentation site from GitBook to Vuepress and got stuck with front-matter variables. In GitBook, you just add variables in the config and then use them anywhere on the page as {{ book.variable_name }}. In Vuepress, at glance, things seem to be trickier.
I need to configure several variables that are used across the whole site, so adding them to each page would be a complete nightmare. The documentation tells nothing about how to configure front-matter variables but has a link to the Jekyll site. On the Jekyll site, I found this article that is exactly what I want to achieve. The problem is that I have no idea how to use this info in config.
Any help is highly appreciated. I asked this question in the official repo but that didn't help.
To define some variables that you could access anywhere in your site, you can add them to your theme config.
If you haven't already got one, create a config.js file at .vuepress/config.js.
This file should export an object.
You want to add a themeConfig: {} to this.
Properties you set on the themeConfig object will be available throughout your site on $themeConfig.
//- .vuepress/config.js
module.exports = {
themeConfig: {
//- Define your variables here
author: 'Name',
foo: 'bar'
}
}
{{ $themeConfig.author }} //- 'Name'
{{ $themeConfig.foo }} //- 'bar
You can also make this easy to override locally / per page, by using global computed functions. (This could also provide a cleaner way to access the variables)
Adding an enhanceApp.js file in the same place as config.js, will give you access to the Vue instance - where you can define a mixin for all components.
You can define some computed properties in this mixin that first check for a value in the pages frontmatter data and then fall back to the value set in the themeConfig. Allowing you to set some default values that can be locally overridden per page.
//- .vuepress/enhanceApp.js
export default ({ Vue }) => {
Vue.mixin({
computed: {
author() {
const { $themeConfig, $frontmatter } = this
return $frontmatter.author || $themeConfig.author
},
foo() {
const { $themeConfig, $frontmatter } = this
return $frontmatter.foo || $themeConfig.foo
}
}
})
}
{{ author }} //- 'Name'
{{ foo }} //- 'bar
Vuepress config docs
Vuepress app level enhancement
I'm very new to web-development in general, but I'm trying to build my website and came across the following problem I haven't be able to solve. I'm using angular 4
I have a div highlighting some code in my html file:
<div *ngIf="step1Updated">
<prism-block
[code]="step1"
[language]="'python'">
</prism-block>
{{ step1 }}
</div>
In my typescript file:
step1Updated = false;
step1 = '';
onStep1(fileType: string) {
this.step1 = this.step1service.returnCode(this.language, fileType);
this.step1Updated = true;
}
Now on my html page, when I click from a selection of buttons executing onStep1() with different content, the content within my string interpolation changes, the {{ step1 }}, but the content within my prism-block doesn't. I can see that this is because we need two-way databinding but I've tried to put the [(ngModel)]="step1" two way data binding in the prism-block, div, etc... hoping that it would catch the update and then update the block, same as putting code in [(code)] but all resulted in errors..
any help or advice would be really appreciated!
here you need to load PrismComponent dynamically to update its view.refer my plunker(http://plnkr.co/edit/tEgnnS) code.
onStep1(fileType: string) {
const crf = this.cfR.resolveComponentFactory(PrismComponent);
this.cc.clear();
const cf = this.cc.createComponent(crf);
(<PrismComponent>cf.instance).code = this.step1service.returnCode(this.language, fileType);
}
With tumblr, I need to add custom title and description meta tags on tagged category pages.
such as url.com/tagged/lifestyle needs different title/description than url.com/tagged/history
Does anyone know a block level conditional for this, or a way to make custom templates for each tagged category?
I can manipulate the title using a hack via jQuery, but this will only run on page load.
//Add an id to the title tag:
<title id="chTitle">Tumblr Blog</title>
// get the current page url
$href = document.location.href;
$primaryDir = document.location.pathname.split("/")[1];
$secondaryDir = document.location.pathname.split("/")[2];
if($secondaryDir == 'lifestyle') {
$('#chTitle').text('Lifestyle');
}else if($secondaryDir == 'history') {
$('#chTitle').text('History');
}else{
$('#chTitle').text('Title Default');
}
You could actually just take the secondary directory and pass it as a variable into the page title.
$('#chTitle').text($secondaryDir);
But you would need a default fallback for pages with no secondary dir. blog.tumblr.com/submit etc.
I want to assign custom parameters to CMS pages in Magento (i.e. 'about', 'customer service', etc), so they can be grouped.
The end goal is to use the parameters for each page to show (or hide) them in a nav menu. Writing a quick method in the page/html block to retrieve the pages (active only) for the menu was easy, but I can't figure out how to group them so that 'testimonials', 'history', and 'contact' are associated with 'about', and 'return policy', 'shipping', and 'contact' are associated with 'customer service'.
Any help to point me in the right direction would be greatly appreciated.
Thanks!
Unfortunately the cms pages are not entities and custom attributes are not supported.
My suggestion will be to overload Mage_Cms_Model_Page, create an associated table with your data, and in the new class constructor assign a new property to your_page object.
Perhaps just use URL key field in admin as your category denominator? E.g:
CMS page 1 URL key: about/testimonials
CMS page 2 URL key: about/history
CMS page 3 URL key: about/contact
CMS page 4 URL key: customer-service/return-policy
...
Then just loop through them in your template or have a method in a custom block class to group them together using regex based on the first part before slash.
Did you look for using of setData / getData for storing custom values? It works me well for custom blocks - I set value in controller and read it at block rendering.
I decided to go in a different direction with this. Here is what I did.
In admin interface:
Created static blocks for each page (i.e. 'Page: About')
Created a product category called CMS (URL Key: content), set Is Active to 'no'
Created child categories for each content category (i.e. 'about'). Set Is Active to 'yes' and Display Mode to 'Static block only' and selected corresponding static block.
Created child categories for each content category as above.
In code:
Created two new methods in (local copy of) Catalog/Block/Navigation.php to get the current parent category and its children:
public function getNavCategory($category)
{
if($category->getLevel() == 3){
return $category;
} else {
$parentCategory = Mage::getModel('catalog/category')->load($category->getParentId());
return $parentCategory;
}
}
public function getNavChildCategories($category)
{
$layer = Mage::getSingleton('catalog/layer');
/* #var $category Mage_Catalog_Model_Category */
$categories = $category->getChildrenCategories();
$productCollection = Mage::getResourceModel('catalog/product_collection');
$layer->prepareProductCollection($productCollection);
$productCollection->addCountToCategories($categories);
return $categories;
}
Created a modified version of app/design/frontend/MYINTERFACE/MYTHEME/template/catalog/navigation/left.phtml to iterate through categories and child categories. Working example at: http://67.228.100.26/content/about