I have a website that uses classic ASP to render settings for CKEditor 3.
On the serverside I have:
<%
Dim Editor
Set Editor = New CKEditor
Editor.basePath = "/ckeditor/"
Editor.Config("contentsCss") = "/Styles/Editor.css"
Editor.Config("templates_files") = "/templates/news.js"
Editor.Config("width") = 570;
Editor.editor "Html", Html
Set Editor = Nothing
%>
And in news.js I have:
CKEDITOR.addTemplates('news',
{
imagesPath: CKEDITOR.getUrl('/JavaScripts/ckeditor_3.6.3/templates/images/'),
templates:
[
{
title: 'News Template',
//image: 'template1.gif',
html:
'<h3>Template 2</h3>' +
'<p>Type your text here.</p>'
}
]
});
And it renders:
<script type="text/javascript" src="/ckeditor/ckeditor.js?t=C3HA5RM"></script>
<script type="text/javascript">//<![CDATA[
CKEDITOR.replace('Html', {"contentsCss": "\u002FStyles\u002FEditor.css","templates_files": "\u002Ftemplates\u002Fnews.js","width": 570});
//]]></script>
It seems like it takes the path provided (/templates)... and does a 404 with each letter from it.... i.e /t /e /m ...
What might be missing?
According to the documentation, the templates_files should be an array of strings, even if you use only one file, so the correct configuration is
Editor.Config("templates_files") = Array("/templates/news.js")
Related
I'm just starting with Meteor. In an app which is to be localized, I want to set the document title.
I am following the advice given by Bernát
In my barebones version, I have just 2 documents:
head.html
<head>
<meta charset="utf-8">
<title>{{localizedTitle}}</title>
</head>
ui.js
UI.registerHelper("localizedTitle", function() {
var title = "Localized Title"
document.title = title;
});
When the app loads, the document title is "{{localizedTitle}}". If I call UI._globalHelpers.localizedTitle() from the console, the correct title is shown.
What do I have to do to get the localized title to show when the page is loaded?
EDIT: This works for me, but it seems to be a bit of a hack. The title template does nothing but get itself rendered, which actually adds nothing to the interface.
body.html
<body>
{{> title}}
</body>
<template name="title">
</template>
title.js
Template.title.onRendered(function () {
document.title = getLocalizedString()
function getLocalizedString() {
return "Title : in English"
}
})
Following Bernát's answer, your global helper should not be called in the head's <title> tag, but within the <template> tag of the template where you wish to have a given title. In Meteor, <head> does not count as a template, therefore you cannot use Spacebars notation in it: it will just be considered as simple text.
Also, keep in mind that your helper will not return (i.e. print) anything to the page. document.title = "something" directly assigns "something" to your ` tag. So no need to call your helper inside it!
So, say you want to have the "Localized Title" title for a page using the localized template :
<template name="localized">
<h1>This is the localized page</h1>
{{localizedTitle}}
</template>
Here, your trick should work.
I've found it convenient to set the title in onAfterAction in my iron-router routes:
onAfterAction: function(){
document.title = 'foo'; // ex: your site's name
var routeName = Router.current().route.getName();
if ( routeName ) document.title = document.title + ': ' + routeName;
}
I think a more elegant solution is to make the title reactive and set it via a Session variable (other reactive data sources are of course also OK). Like that:
Template.body.onRendered(function() {
this.autorun(function() {
document.title = Session.get('documentTitle');
});
});
Now every time you set the 'documentTitle' variable with
Session.set('documentTitle', 'Awesome title');
the page title will change. No need for hacks and you can do this anywhere in your client code.
Try this instead:
UI.registerHelper('title', function() {
return 'LocalizedTitle'
});
we can use title where ever you want
you can use like this {{title}}
Is there a way to render a precompiled template that has no name on the client side in DustJs?
Because documentation only shows with a name:
<!-- precompiled templates -->
<script type="text/javascript" src="/lib/templates.js"></script>
<script type="text/javascript">
// The templates are already registered, so we are ready to render!
dust.render('hello', { world: "Saturn" }, function(err, out) {
document.getElementById('output').textContent = out;
})
</script>
EDIT : Ok it's probably too complicated to load a file, and I just noticed that when we compile without specifying name (in order to compile many template simultaneously), the path of the template is set as the default name. It is even editable with --pwd flag.
There is therefore always a name so the above function can operate.
It sounds like you would like to load templates by their path after they have been precompiled. Dust allows you to do this via AMD (require.js) compatibility.
http://www.dustjs.com/guides/setup/#amd
Once you've loaded require.js and set define.amd.dust = true, you can call dust.render with the path to a template and Dust will automatically load it for you.
Note that this requires that you compile your templates with the --amd flag.
<script src="r.js"></script>
<script type="text/javascript">
define.amd.dust = true;
require(["lib/dust-full"], function(dust) {
dust.render('path/to/your/template', function(err, out) { ... });
});
</script>
The Dust repository has an example of using AMD to load templates.
I was hoping anyone could give some input on this,
I'm creating a meteor app in which I would like to use bootstrap to creating the admin environment, but have the visitor facing side using custom css. When I add the bootstrap package to my app using meteor it's available on every page, is there a way to restrict the loading of bootstrap to routes that are in '/admin' ?
When you add bootstrap package it's not possible. You can, however, add bootstrap csses to public directory and then load them in a header subtemplate that will only be rendered when you're in the dashboard.
EDIT
But then how would you go about creating seperate head templates?
Easy:
<head>
...
{{> adminHeader}}
...
</head>
<template name="adminHeader">
{{#if adminPage}}
... // Put links to bootstrap here
{{/if}}
</template>
Template.adminHeader.adminPage = function() {
return Session.get('adminPage');
}
Meteor.router.add({
'/admin': function() {
Session.set('adminPage', true);
...
}
});
DISCLAIMER: I am unsure of a 'meteor way' to do this, so here is how I would do it with plain JS.
jQuery
$("link[href='bootstrap.css']").remove();
JS - Credit to javascriptkit
function removejscssfile(filename, filetype){
var targetelement=(filetype=="js")? "script" : (filetype=="css")? "link" : "none" //determine element type to create nodelist from
var targetattr=(filetype=="js")? "src" : (filetype=="css")? "href" : "none" //determine corresponding attribute to test for
var allsuspects=document.getElementsByTagName(targetelement)
for (var i=allsuspects.length; i>=0; i--){ //search backwards within nodelist for matching elements to remove
if (allsuspects[i] && allsuspects[i].getAttribute(targetattr)!=null && allsuspects[i].getAttribute(targetattr).indexOf(filename)!=-1)
allsuspects[i].parentNode.removeChild(allsuspects[i]) //remove element by calling parentNode.removeChild()
}
}
removejscssfile("bootstrap.css", "css")
However, doing that would complete remove it from the page. I am not sure whether meteor would then try to readd it when a user goes to another page. If that does not automatically get readded, then you have an issue of bootstrap not being included when someone goes from the admin section to the main site, which would break the look of the site.
The way I would get around that would be to disable and enable the stylesheets:
Meteor.autorun(function(){
if(Session.get('nobootstrap')){
$("link[href='bootstrap.css']").disabled = true;
}else{
$("link[href='bootstrap.css']").disabled = false;
}
});
There my be other bootstrap resources which may need to be removed, take a look at what your page is loading.
To use jQuery in the same way but for the javascript files, remember to change link to script and href to src
From my tests, Meteor does not automatically re-add the files once they have been removed so you would need to find some way of re-adding them dynamically if you want the same user to be able to go back and forth between the main site and the admin site. Or simply if the http referrer to the main site is from the admin, force reload the page and then the bootstrap resources will load and everything will look pretty.
P.s. make sure you get the href correct for the jQuery version
If somebody is interested in including any js/css files, I've written a helper for it:
if (Meteor.isClient) {
// dynamic js / css include helper from public folder
Handlebars.registerHelper("INCLUDE_FILES", function(files) {
if (files != undefined) {
var array = files.split(',');
array.forEach(function(entity){
var regex = /(?:\.([^.]+))?$/;
var extension = regex.exec(entity)[1];
if(extension == "js"){
$('head').append('<script src="' + entity + '" data-dynamicJsCss type="text/javascript" ></script>');
} else if (extension == "css"){
$('head').append('<link href="' + entity + '" data-dynamicJsCss type="text/css" rel="stylesheet" />');
};
});
}
});
Router.onStop(function(){
$("[data-dynamicJsCss]").remove();
});
}
Then simply use:
{{INCLUDE_FILES '/css/html5reset.css, /js/test.js'}}
in any of your loaded templates :)
I have two ASP.NET Web Forms Apps, first targeted to v4.0, second to v4.5 of .NET framework. I use ASP.NET CKeditor plugin v3.6.4. Everything work great, except that I can't register my 'phrases' plugin using 'ExtraPlugins" property.
Javascript solution works:
CKEDITOR.replace('<%=CKEditor1.ClientID%>',
{
extraPlugins: 'phrases',
toolbar:
[
['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink'],
['phrases']
]
});
But 'ExtraPlugins' property solution doesn't work:
<CKEditor:CKEditorControl ID="CKEditor1" BasePath="~/ckeditor" ExtraPlugins="phrases" Toolbar="Basic" runat="server" />
Please for help.
Best regards,
WP
I have done some experiments and finally I know how it works.
The following ASP.NET CKEditor Web Control tag is placed in *.aspx page:
<CKEditor:CKEditorControl ID="CKEditor1" BasePath="~/ckeditor" ExtraPlugins="phrases" Toolbar="Basic" runat="server" />
Then, this tag is rendered in the outcoming HTML document and shipped to the user browser in that way:
First part:
<script type="text/javascript">
//<![CDATA[
function WebForm_OnSubmit() {
CKEditor_TextBoxEncode('CKEditor1', 0);
return true;
}
//]]>
</script>
Second part:
<textarea name="CKEditor1" rows="2" cols="20" id="CKEditor1">
</textarea>
Third part:
<script type="text/javascript">
//<![CDATA[
var CKEditor_Controls=[],CKEditor_Init=[];function CKEditor_TextBoxEncode(d,e){var f;if(typeof CKEDITOR=='undefined'||typeof CKEDITOR.instances[d]=='undefined'){f=document.getElementById(d);if(f)f.value=f.value.replace(/</g,'<').replace(/>/g,'>');}else{var g=CKEDITOR.instances[d];if(e&&(typeof Page_BlockSubmit=='undefined'||!Page_BlockSubmit)){g.destroy();f=document.getElementById(d);if(f)f.style.visibility='hidden';}else g.updateElement();}};(function(){if(typeof CKEDITOR!='undefined'){var d=document.getElementById('CKEditor1');if(d)d.style.visibility='hidden';}var e=function(){var f=CKEditor_Controls,g=CKEditor_Init,h=window.pageLoad,i=function(){for(var j=f.length;j--;){var k=document.getElementById(f[j]);if(k&&k.value&&(k.value.indexOf('<')==-1||k.value.indexOf('>')==-1))k.value=k.value.replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&');}if(typeof CKEDITOR!='undefined')for(var j=0;j<g.length;j++)g[j].call(this);};window.pageLoad=function(j,k){if(k.get_isPartialLoad())setTimeout(i,0);if(h&&typeof h=='function')h.call(this,j,k);};if(typeof Page_ClientValidate=='function'&&typeof CKEDITOR!='undefined')Page_ClientValidate=CKEDITOR.tools.override(Page_ClientValidate,function(j){return function(){for(var k in CKEDITOR.instances){if(document.getElementById(k))CKEDITOR.instances[k].updateElement();}return j.apply(this,arguments);};});setTimeout(i,0);};if(typeof Sys!='undefined'&&typeof Sys.Application!='undefined')Sys.Application.add_load(e);if(window.addEventListener)window.addEventListener('load',e,false);else if(window.attachEvent)window.attachEvent('onload',e);})();CKEditor_Controls.push('CKEditor1');
CKEditor_Init.push(function(){if(typeof CKEDITOR.instances['CKEditor1']!='undefined' || !document.getElementById('CKEditor1')) return;CKEDITOR.replace('CKEditor1',{"extraPlugins" : "phrases", "htmlEncodeOutput" : true, "toolbar" : "Basic"}); });
//]]>
</script>
In the third part of source code, there is the most important statement, which is rendered equivalent of ASP.NET CKEditor tag:
CKEDITOR.replace('CKEditor1',{"extraPlugins" : "phrases", "htmlEncodeOutput" : true, "toolbar" : "Basic"}); });
As we can see, ASP.NET WebControl's property ExtraPlugings is linked with extraPlugins property in Javascript configuration of CKEditor instance.
After some recognitions it turns out that JS configuration extraPlugins option actually doesn't attach plugin to be visible in CKEditor toolbar and ready to use, but in fact only register the plugin to allow to use it. Plugin can be registered in that way, or in config.js configuration file of CKEditor:
CKEDITOR.editorConfig = function( config )
{
config.extraPlugins = 'phrases';
// Define changes to default configuration here. For example:
// config.language = 'fr';
// config.uiColor = '#AADC6E';
};
After registration, the plugin have to be somehow added to the toolbar to be available for use, for example in that manner:
<CKEditor:CKEditorControl ID="CKEditor1" BasePath="~/ckeditor" ExtraPlugins="phrases" Toolbar="[{ name: 'plugins', items: ['phrases'] }]" runat="server" />
or by use of Javascript Code.
Thus, in summary: ExtraPlugins property only cause a registration of plugin. If we want to have it on CKEditor Toolbar, we have to write proper statements to configure CKEDitor toolbar.
I am trying to add the CKEditor to a page I am currently developing but am having problems getting it to pick up my custom configuration file? I am using CKEditor in Visual Studio.NET 2008. I need to customize the toolbars that are displayed, as Basic is too minimal and Full would give an overwhelming amount of buttons to the user.
I am declaring the editor in the aspx page as follows:
<script type="text/javascript">
CKEDITOR.replace(document.getElementById("<%= txtTourItinerary.ClientID %>"),
{ customConfig: 'myconfig.js' }
);
</script>
the myconfig.js file itself is in the root of the ckeditor directory (where config.js resides).
However, desipite rendering the CKEditor itself, it seems to be completely ignoring my custom config file. I was wondering if anyone had any suggestions?
Thanks!
The contents of the custom config file are as follows:
CKEDITOR.editorConfig = function( config )
{
// Define changes to default configuration here. For example:
config.language = 'en';
config.defaultLanguage = 'en';
config.uiColor = '#000000';
};
CKEDITOR.config.toolbar_Full = [['Save', '-', 'Preview', '-' 'Print'],
['Undo', 'Redo'], ['Cut', 'Copy', 'Paste', 'PasteFromWord', 'SelectAll'],
['Find', 'Replace'],
'/',
['Bold', 'Italic', 'Unnderline', 'Strike', '-', 'Subscript', 'Superscript']];
Thought I'd post up a solution. The path in the:
CKEDITOR.replace(document.getElementById("<%= txtTourItinerary.ClientID %>"),
{ customConfig: 'myconfig.js' }
is from the root of the website, not relative to the directory from CKEditor.
So my declaration should have been as follows
<script type="text/javascript">
CKEDITOR.replace(document.getElementById("<%= txtTourItinerary.ClientID %>"),
{ customConfig: '/ckeditor/myconfig.js' }
);
</script>
Hopefully I might have helped someone else in a similar boat as documentation on CKEditor is a little thin on the ground.