Use HTML files as templates for Sencha? - javascript

I am starting out with Sencha's mobile web app framework. It seems the interface has to be always built procedurally or with html strings. This is so unintuitive! Is there a way to put your template code in an HTML file and have Sencha use those files as templates? That way I can have a clear separation from the interface layer. Thanks for any advise or experience.

You can define your basic html, then 'wire' the application together. Just about every component has a key called renderTo. So if you had a very simple html template like this:
<body>
<div id="myButton"></div>
</body>
You could create a button and wire it to that div with the following javascript:
var button = Ext.create('Ext.Button', {
text: 'Button',
renderTo: '#myButton'
});
...That being said, Sencha's frameworks expect that you design applications programmatically (that is, entirely in Javascript).

You could return a template or markup from an external file using an ajax request.
The items of your panel would look something like the following:
items: [
{
id: "panel",
html: "<p>Loading...</p>"
}
]
Then you could use the ajax request to update the content of the panel element with the content of template.html:
Ext.Ajax.request({
url: 'template.html',
callback: function(options, success, response) {
this.getComponent('panel').update(response.responseText);
},
scope: this
});
Updating your content this way is useful if your managed content is only available as markup or you haven't got round to creating a web service using json, for example.

Related

CKEditor - how to get the template attributes

I'm using CKEditor's template plugin to load the templates in the editor. In the templates I've defined likt this.
templates: [
{
title: "Quickclick 1",
image: "template1.png",
description: "Quickclick 1 template",
html_et: "<span>test1</span>",
html:' <span>test</span>'
}]
When the user selects a template, the html is loaded which is fine. But also, it would be great if there is a way to get the property of the current selected template from the CKEditor instance.
I need to get the html_et property value in this case. I didn't find anything in the documentation related to this. Any help would be appreciated.
#Lingasamy Sakthivel that is not how you define templates in CKEditor.
If you want to use templates, you need to create a file like the default one in templates plugin: https://github.com/ckeditor/ckeditor-dev/blob/major/plugins/templates/templates/default.js
NOTE: when defining my test template file, I have named the file my_template.js and have given the same name to template definition CKEDITOR.addTemplates( 'my_templates', {... for simplicity.
Now, Once you have the file ready, you can assign it to editor. To do that you need to specify path to your file (full or relative to context of your application) and definitions that should be loaded.
In the example below I'm loading the default CKEditor file as well as my custom one:
var editor = CKEDITOR.replace( 'editor1', {
language: 'en',
templates_files : [
'/myApp/ckeditor/plugins/templates/templates/default.js',
'/myApp/ckeditor/my_templates.js'
],
templates : 'default,my_templates'
});
This is for files - https://docs.ckeditor.com/ckeditor4/latest/api/CKEDITOR_config.html#cfg-templates_files
This is for definitions - https://docs.ckeditor.com/ckeditor4/latest/api/CKEDITOR_config.html#cfg-templates
Now the hard part. You have written you want to know which template was selected but to be honest I don't know any way in which you could do that except for changing plugin code.
When template definition is loaded, templates inside it are loaded one by one
and assigned an onclick handler. This is IMHO the place we you could add your custom code for getting the html_et property - https://github.com/ckeditor/ckeditor-dev/blob/major/plugins/templates/dialogs/templates.js#L53-L55.
To do that you would need to get the source version of the editor, make changes in template plugin and then building your editor (recommended approach):
https://docs.ckeditor.com/ckeditor4/latest/guide/dev_source.html
https://docs.ckeditor.com/ckeditor4/latest/guide/dev_build.html
Alternatively you can download CKEditor without the templates plugin (can be done using online builder where you can remove templates plugin from your build). Next you need to manually download that plugin, make your changes and add that plugin to editor by dropping plugin folder inside ckeditor/plugins folder and using the extraPlugins setting.
Can you try like this?
var editor = CKEDITOR.replace('editor1', {
templates: [
{
title: "Quickclick 1",
image: "template1.png",
description: "Quickclick 1 template",
html_et: "<span>test1</span>",
html:' <span>test</span>'
}
]
});
alert(editor.config.templates[0].html_et);

jQuery set element attribute without altering function

I'm trying to pull the link from an rss feed using the jQuery-rss script (https://github.com/sdepold/jquery-rss) to insert it into an 'a' element href.
I know that this can be done by doing
$("#rss-link").attr(href, "http://rss.cnn.com/rss/cnn_topstories.rss"
but that would only embed the rss feed link rather than the link to the rss item.
Here is my script:
jQuery(function(link) {
$("#rss-link").rss("http://rss.cnn.com/rss/cnn_topstories.rss", {
entryTemplate: '{url}',
limit: '1'
})
});
What is the correct way to do this?
I'm not very experienced with jQuery so anything helps.
Thanks!
The jQuery plugin you are using automatically creates elements or you. So you do not need to manually set the link on the a tags. You probably want to specify the template with the correct tokens in the options while calling the plugin.
<body>
<div id="rss-feed"></div>
<script>
var rssUrl="http://rss.cnn.com/rss/cnn_topstories.rss";
$('#rss-feed').rss(rssUrl, {
entryTemplate: '{title}'
})
</script>
</body>
You can see a more elaborate template on the library's Demo Page. You can refer to the Readme.md of the library and look under Templating for more information on the template structure and available tokens.

How do I compose templates on both server and client using dust.js

I'm trying to make a modern site that loads data using ajax, renders it in a template and uses jQuery and pushstate to display it, plus server-side rendering so that initial page loads are fast and spiders can crawl as intended. Of course, I read the article about linkedin using dust.js to achieve this.
Now, dust.js claims the following advantages:
Composable: Designers should be able to break presentation markup into manageable components and combine these components at runtime. It should not be necessary to statically link templates or manually assemble 'layouts' inside application code.
Format agnostic: While HTML generation and DOM manipulation are useful in specific instances, a general-purpose template system should not be tied to a particular output format.
So it sounds great, but how do I actually achieve what I want? I've made templates that render a complete page just fine on the server, but they use blocks and inline partials - which means the internal bits can't be rendered at all without the wrapper present (it just returns an error that says it can't find the wrapper template). I don't see how composing inside application code (as opposed to selling point #1 above) can be avoided on the client.
I don't understand what #2 above even means. I guess it means that you get the output as a string and can do whatever you want with it?
The documentation is about as clear as mud.
So what do I do? Is there a better option than dust.js these days? Do I write templates so that they must be composed in application code? If so, by what mechanism do I compose them in application code?
Ok, since there has been trouble understanding my question (which is itself understandable), I just threw together this (untested) example showing the problem:
Wrapper template:
<html>
<head><title>{+title/}</title>
{+styles/}
</head>
<body>
header header header
<div id="pagecontent">{+content/}</div>
footer footer footer
<script src="jquery"></script>
<script src="dust"></script>
<script src="see 'Client side script' below"></script>
</body>
</html>
'time' template:
{>wrap/}
{<title}Time in millis{/title}
{<styles}
<style>
body {
background-color: {bgcolor};
}
</style>
{/styles}
{<content}
The time: {time}<br />
Switch format
{/content}
Server side code:
app.get('/millis',function(req,res) {
res.render('time',{millis:new Date().getTime(),link:'/time',bgcolor:'lightgreen'});
}
app.get('/time',function(req,res) {
res.render('time',{millis:new Date().toString(),link:'/millis',bgcolor:'lightpink'});
}
So, the server will render the page fine, but what about the client? Read on.
Client side script:
//load the 'time' template into dust somewhere up here
$(function(){
$('a').click(function(e){
var newcontent;
switch($(this).attr('href')) {
case '/time':
//FAILS: can't find the wrapper. We need logic to get the title and styles from the template and fill it in in-place in the DOM
newcontent = dust.render('time',{millis:new Date().toString(),link:'/millis',bgcolor:'lightpink'});
case '/millis':
//FAILS: can't find the wrapper. We need logic to get the title and styles from the template and fill it in in-place in the DOM
newcontent = dust.render('time',{millis:new Date().getTime(),link:'/time',bgcolor:'lightgreen'});
default: return;
}
e.preventDefault();
$('#pagecontent').fadeOut(1000,function(){
//use pushstate and stuff here
$(this).html(newcontent);
$(this.fadeIn(1000);
});
});
});
I was wondering the same thing and came across this. You may have seen this too, but I'm leaving this here in case it helps others.
http://spalatnik.com/blog/?p=54
I haven't implemented this so my deductions below are based off the above article and some (hopefully) educated assumptions. I'd certainly like to continue the discussion if the following is incorrect, as I'm learning as well.
I suspect that you'd have two types of wrapper templates. One is the wrapper template that you provided above (for server side rendering). A second wrapper template would be quite different (as you see below). I'm copying verbatim from the blog above in the following example. I presume that all your compiled DustJS templates are in the file dust-full-0.3.0-min.js below.
<html>
<head>
<script src="dust-full-0.3.0.min.js"></script>
<script type="text/javascript">
//example showing client-side compiling and rendering
var compiled = dust.compile("Hello {name}!", "index");
dust.loadSource(compiled);
dust.render("index", {name: "David"}, function(err, out) {
if(err != null)
alert("Error loading page");
//assume we have jquery
$("#pageContainer").html(out);
});
</script>
</head>
<body>
<div id="pageContainer"></div>
</body>
</html>
I suspect that in your Express server, you'd check the User Agent and decide on which template to render out. If it's a bot user-agent, use server-side generation in your example. Otherwise, use the client side template above.

Convert HTML to Sencha

I am very new to sencha and probably do not know how everything you need. I'm trying to extract some contents of an HTML page using ajax. For example, the text in a div with id = "content".
I want to put this content extracted in a panel or container Sencha.
This is the view that I have:
Ext.define("myapp.view.Main", {
extend: 'Ext.tab.Panel',
requires: ['Ext.TitleBar'],
config: {
tabBarPosition: 'bottom',
items: [
{
title: 'Welcome',
iconCls: 'home',
styleHtmlContent: true,
scrollable: true,
html: FUNCTION_TO_GET_CONTENT .join("")
}
]
}
});
I would like to know if there is any way to get the contents of the HTML page displayed in a panel, but I do not know how. Can someone please help me understand this and how I can best address this?
UPDATE:
Basically what I would like to do is to replicate the result of this JQuery statement:
$("#mylocaldiv").load("sourcePage.html #mainDiv");
and then append the result to the html property in the tab panel.
First, add an alias to your view (make sure it's preceded by widget.
Ext.define("myapp.view.Main", {
extend: 'Ext.tab.Panel',
alias: 'widget.Main',
...
});
Then get your view by doing either:
myView = Ext.Viewport.down('Main');
or
myView = Ext.ComponentQuery.query('Main');
Now you can access your items like so:
myView.items.items
And since your panel is the only item, it will be item zero. You can then use it's setHtml method to append html:
myView.items.items[0].setHtml('your html here');
In terms of loading an html file into the panel, I believe Sencha removed Ext.dom.Element.load(). I would use a simple Ajax request and then append the result into the panel in the success callback. See here: load an html file into a panel
sencha is not a good tool for building large applications, so better to choose another one. I was tried it and it sucks my time and no use at all, the windows panels and many more developed using images not with css. if we build large apps with that we may decline the performance of app.

How to handle localization in JavaScript files?

I want JavaScript code to be separated from views.
I got the requirement to implement localization for a simple image button generated by JavaScript:
<img src="..." onclick="..." title="Close" />
What's the best technique to localize the title of it?
PS: I found a solution by Ayende. This is the right direction.
Edit:
I got Localization helper class which provides the Controller.Resource('foo') extension method.
I am thinking about to extend it (helper) so it could return all JavaScript resources (from "ClientSideResources" subfolder in App_LocalResources) for the specified controller by its name. Then - call it in BaseController, add it to ViewData and render it in Layout.
Would that be a good idea?
EDIT
Consider writing the necessary localized resources to a JavaScript object (hash) and then using it for lookup for your dynamically created objects. I think this is better than going back to the server for translations. This is similar to adding it via viewdata, but may be a little more flexible. FWIW, I could consider the localization resources to be part of the View, not part of the controller.
In the View:
<script type="text/javascript"
src='<%= Url.Content( "~/Resources/Load?translate=Close,Open" %>'></script>
which would output something like:
var local = {};
local.Close = "Close";
local.Open = "Open";
Without arguments it would output the entire translation hash. Using arguments gives you the ability to customize it per view.
You would then use it in your JavaScript files like:
$(function(){
$('#button').click( function() {
$("<img src=... title='" + local.Close + "' />")
.appendTo("#someDiv")
.click( function() { ... } );
});
});
Actually, I'm not too fussed about keeping my JavaScript code out of my views as long as the JavaScript code is localized in a container. Typically I'll set my master page up with 4 content area: title, header, main, and scripts. Title, header, and main go where you would expect and the scripts area goes at the bottom of the body.
I put all my JavaScript includes, including any for viewusercontrols, into the scripts container. View-specific JavaScript code comes after the includes. I refactor shared code back to scripts as needed. I've thought about using a controller method to collate script includes, that is, include multiple scripts using a single request, but haven't gotten around to that, yet.
This has the advantage of keeping the JavaScript code separate for readability, but also allows me to easily inject model or view data into the JavaScript code as needed.
Actually ASP.NET Ajax has a built-in localization mechanism: Understanding ASP.NET AJAX Localization
If you insist on keeping it separate, you could do something like:
//keep all of your localised vars somewhere
var title = '{title_from_server}';
document.getElementById('someImage').title = title;
Remember, if you use JavaScript code to initialize any text of elements, your site will degrade horribly where JavaScript isn't available.

Categories

Resources