If I have a YAML list, e.g:
Home : /
Terms and Conditions : /terms.html
And I want to render some content from that list, but make use of both keys & values, I'm having to use {{eachProperty}} to get those values, i.e :
{{#eachProperty this.value}}
{{key}}
{{/eachProperty}}
Anyone got any better ideas?
I think you just need to add another layer to your YAML data structure, so you have a list of pages, where each page is an object that has both a title and url property you can reference in the template. In the example below, I put the YAML at the top of the Handlebars template, but it should work the same if loaded from an external file.
---
links:
Home:
url: '/'
title: 'Home'
Terms:
url: '/terms.html'
title: 'Terms and Conditions'
---
<!DOCTYPE html>
<html>
<body>
<h1>Test List of Links</h1>
<ul>
{{#each links}}
<li>{{title}}</li>
{{/each}}
</ul>
</body>
</html>
Related
I have configured SeoBundle as stated in docs:
sonata_seo:
page:
title: Default title
metas:
name:
description: Defualt description
keywords: key1, key2
cmf_seo:
title: seo.title
description: seo.description
content_listener:
enabled: false
And placed in base.html.twig:
<head>
{# meta #}
<meta name=viewport content="width=device-width, initial-scale=1">
<meta name="format-detection" content="telephone=no"/>
{{ sonata_seo_title() }}
{{ sonata_seo_metadatas() }}
...
</head>
Now when I refresh page I can see that sonata_seo block title and description are set instead of cmf_seo. In docs there is a warning:
The title and description template is only used when the title is not
set on the content object or when the content object is not available,
otherwise it'll use the default set by the SonataSeoBundle. You should
make sure that the defaults also follow the template.
If only docs would clarify what is "content object" would be great... Anyway I tried removing title and description from sonata_seo block:
sonata_seo:
page: ~
cmf_seo:
title: seo.title
description: seo.description
content_listener:
enabled: false
Now my title becomes "Sonata Project" which is default SonataSeoBundle title.
How do I display cmf_seo title? {{ cmf_seo_title() }} is not working.
what is the value of seo.title and seo.description is it something you expect to be translated? Can you serve a longer stacktrace for the exception please?
In general CmfSeoBundle expects some placeholders (%%content_description%%, %%content_title%%, doubled to make it translatable at the end) to enrich the title/description with dynamic data. That dynamic data can live as SeoContent on the document (content object) you are persisting or as so called extractors which fetch the data from the document (content object). In the first case you have to implement SeoAwareInterface in second case you can find several extractors in the [doucmentation[(https://symfony.com/doc/current/cmf/bundles/seo/extractors.html).
If you wanna simply set static titles, you should stay with the SonataSeoBundle. We do simply enrich a template defined in cmf_seo.title|description with dynamic data from the current content. We do need sonata_seo.title for pages with no content documents (i.e. static pages).
Is it possible to render a template, or even just a partial, from within the context passed to a top level template? It seems like this might require recursive rendering, but maybe I'm missing something.
The example below demonstrates this using Bootstrap.
Say this is my top level template:
<div class="panel">
<div class="panel-body">
{{{description}}}
</div>
</div>
And my context is:
{
description: "\
Some text before the warning.\
<div class=\"alert alert-warning\" role=\"alert\">\
<span class=\"glyphicon glyphicon-warning-sign\" aria-hidden=\"true\"> </span>\
My warning here.\
</div>\
Some text after the warning."
}
What I'd like to do is separate the alert into a partial for a number of reasons:
Arbitrary placement within surrounding text
Can make partials for types other than warning (danger, info, etc.)
Can add as many as needed interspersed in the context string
For these reasons, it seems like it's not possible to put it into the top level template.
The partial would look something like this:
<script id="partial-warning-template" type="text/x-handlebars-template">
<div class="alert alert-warning" role="alert">
<span class="glyphicon glyphicon-warning-sign" aria-hidden="true"> </span>
{{{warning-message}}}
</div>
</script>
Once this is in place, I would be able to use it like so:
{
description: "\
Some text before the warning.\
{{> partial-warning-template \"My warning here.\"}}\
Some text after the warning.\
{{> partial-warning-template \"Now adding a second warning.\"}}"
}
Maybe I'm missing something fundamental - is there a more idiomatic way of doing this?
You won't be able to include the partial blocks in the description value and expect them to be evaluated as partials by the top level template method; the entire description string will be spat out as a single literal string.
What you would need to do is to have the partials evaluated before you pass the context object with description to the top level template method.
If you have pre-compiled your partial in something like the following manner:
Handlebars.registerPartial('warn', Handlebars.compile(document.getElementById('partial-warning-template').innerHTML));
Then you will be able to call this partial when you construct your description string:
{
description: 'Some text before the warning.' +
Handlebars.partials.warn({ 'warning-message': 'My warning here.' }) +
'Some text after the warning.' +
Handlebars.partials.warn({ 'warning-message': 'Now adding a second warning.' })
}
I've seen the various discussions on using a dynamically selected template in Meteor (ex. here, here, and here).
But what if I want to pass a parameter into the dynamic template, that is:
{{> UI.dynamic template=templateName data=dataObj param1=17}}
Is there any way to do this? Essentially, I have three templates, which all take the same parameter. I want to create a generic template that can dynamically call one of those three, passing along the parameter.
It feels like there should be a way to do it with a helper, but I can't quite figure it out.
-Dov
Thanks to the comment from David Weldon, I managed to overcome my writer's block.
Here's the answer for others who manage to end up on this page.
HTML:
<head>
<title>dynamic test</title>
</head>
<body>
{{> generic detailsTemplate="y"}}
</body>
<template name="generic">
{{> Template.dynamic template=detailsTemplate data=updatedata}}
</template>
<template name="x">
Here
edit={{edit}} - this shows nothing if the data context isn't modified
</template>
Javascript:
Template.generic.helpers({
updatedata: function () {
this.edit = true;
return this;
}
});
I'm trying to get the following behavior for a certain template:
<body onload="someInitFunction();">
Let's say i have the following markup (i'm using mrt router, not iron-router, for {{renderPage}}):
// Main Template
<head>
<title>meteorite-knowviz</title>
</head>
<body>
{{> header}}
<div class="container-fluid">
<div class="row">
{{renderPage}}
</div>
</div>
{{> footer}}
</body>
That renderPage is the secondTemplate:
<template name="secondTemplate">
{{#if currentUser}}
<div class="col-md-2">
<div class="list-group">
<a class="list-group-item" href="{{render thirdTemplate please...}}">Third Template</a>
<a class="list-group-item" href="{{render fourthTemplate please...}}">Fourth Template</a>
</div>
</div>
// In this case let's say thirdTemplate gets rendered
{{render the choice taken above please...}}
{{/if}}
</template>
And within this template, depending on which link was clicked on, (in this case the third) there will finally be a thirdTemplate, which will show a data visualization with some help by a javascript framework, which will be in need of a <body onload="initFunction();">in order to display the data:
<template name="thirdTemplate">
<div class="col-md-5">
<h2>THIS!! section needs a "<body onload="initFunction();"> in order to work" ></h2>
</div>
<div class="col-sm-5">
<h2>Some other related content here</h2>
</div>
</template>
To sum up i have three questions:
1a. How could i get the third template to get a <body onload="initFunction();">
2a. In which way can i render different templates within the secondTemplate?
2b. Can i use a {{renderPage}} within this template even though this template is the renderedPage in the main template or should i do it in some other way?
In order to get the <body onload="initFunction();"> i had to do the following:
First add the following function to a .js file in the client folder:
Template.thirdTemplate.rendered = function() { // Template.thirdTemplate.created - also worked.
$('body').attr({
onload: 'init();'
});
}
This however got me an error saying that initFunction is not defined. In an standard html page my could work just fine, but in meteor i had to change my function from:
function initFunction(){
//what ever i wished to do
}
To:
init = function() {
//what ever i wished to do
}
Regarding the rendering of pages, iron-routing is the way to go since the router add on is not under development any more.
1a. How could i get the third template to get a <body
onload="initFunction();">
You probably want to call initFunction when the third template has been rendered, so just put your call to it in the rendered callback.
Template['thirsTemplate'].rendered = function(){
initFunction()
}
2a. In which way can i render different templates within the
secondTemplate?
2b. Can i use a {{renderPage}} within this template even though this
template is the renderedPage in the main template or should i do it in
some other way?
Listen for clicks on the links, and when one happen you manually render the desired template (possible with Meteor.render, if you need reactivity) and add it to the right node in the document. See this question.
It may be possibly to achieve with router (I don't know that package).
I think that what you want to use is the created callback, that will be called each time your template is created, and not the rendered callback, that would be called each time a change has caused the template to re-render.
Template.thirdTemplate.created = function(){
initFunction()
}
See the documentation for templates for other types of callbacks: http://docs.meteor.com/#templates_api
Handlebar template
<div>
{{contentText}}
</div>
JS
var contentText = {contentText: "<table><tr><td>Some Data<\/td><\/tr><\/table>"}
Handle bars render displays the HTML as string rather than rendering the HTML.
Where am I going wrong ?
From the fine manual:
Handlebars HTML-escapes values returned by a {{expression}}. If you don't want Handlebars to escape a value, use the "triple-stash", {{{.
So if you want to put contentText straight into the template as-is then you want:
<div>
{{{contentText}}}
</div>
in your template.
Demo: http://jsfiddle.net/ambiguous/f7LJ5/