I'm developing a site for a client that has 3 themes available. I'm using the app_themes system to enable the user to change the style. Each theme uses a few different JavaScript files to load custom fonts. What would be the best approach to load these JavaScript files based on the chosen themes?
As far as I can tell, Kentico uses the same app themes system as default ASP.net webforms.
Ideally I would like to be able to add the appropriate JavaScript files to the corresponding App_Theme folder and let ASP add the tags to the document head. If this isn't an option I've considered writing a ScriptLoader JavaScript that will inspect the style sheet tags to determine which theme is being used. It would be better if I could just add the theme name as a class attribute on the body element and just look at that and pull in appropriate scripts.
I think I found a solution that involves making a webPart or control if you aren't using Kentico.
public static void AddScriptToHead(HtmlHead h, string script, bool AddScriptTags)
{
Literal l = new Literal();
if (AddScriptTags)
l.Text = "<script type=\"text/javascript\" src=\""
+ script +
"\"></script>";
else
l.Text = script;
h.Controls.Add(l);
}
protected void SetupControl()
{
if (this.StopProcessing)
{
// Do nothing
}
else
{
string theme = Page.Theme;
if (theme != null)
{
if (theme.Equals("Card"))
{
AddScriptToHead(Page.Header, "~/App_Themes/Cardamon/js/cufon-colors-classic.js", true);
AddScriptToHead(Page.Header, "~/App_Themes/Cardamon/js/Charis_SIL_700.font.js", true);
}
else if (theme.Equals("CardamonWave"))
{
AddScriptToHead(Page.Header, "~/App_Themes/Cardamon/js/cufon-colors-wave.js" ,true);
AddScriptToHead(Page.Header, "~/App_Themes/Cardamon/js/Lobster_14_400.font.js",true);
}
else if (theme.Equals("CardamonAncient"))
{
AddScriptToHead(Page.Header, "~/App_Themes/Cardamon/js/cufon-colors-ancient.js", true);
AddScriptToHead(Page.Header, "~/App_Themes/Cardamon/js/Charis_SIL_700.font.js", true);
}
else
{
//Y U no theme?
}
}
}
}
I'd like to extend this to accept Scripts and themes as properties in the future but this will work for now.
Related
Detected potentially suspicious content from the website malware scanner. It showing some code from the scan results:https://scanner.pcrisk.com/detailed_report/pragmaticwebmedia.com#details
But unable to find the script on my site. How to delete the dump code in the above results?
I just tried website scanner and cpanel scan but none helps.
[[ window._wpemojiSettings = { "baseUrl":"https://s.w.org/images/core/emoji/11.2.0/72x72/","ext":".png","svgUrl":"https://s.w.org/images/core/emoji/11.2.0/svg/","svgExt":".svg","source": { "concatemoji":"https://pragmaticwebmedia.com/wp-includes/js/wp-emoji-release.min.js?ver=5.1.1" } }; !function(a,b,c) { function d(a,b) { var c=String.fromCharCode; l.clearRect(0,0,k.width,k.height),l.fillText(c.apply(this,a),0,0); var d=k.toDataURL(); l.clearRect(0,0,k.width,k.height),l.fillText(c.apply(this,b),0,0); var e=k.toDataURL(); return d===e } function e(a) { var b; if(!l||!l.fillText)return!1; switch(l.textBaseline="top",l.font="600 32px Arial",a) { case"flag":return!(b=d([55356,56826,55356,56819],[55356,56826,8203,55356,56819]))%26%26(b=d([55356,57332,56128,56423,56128,56418,56128,56421,56128,56430,56128,56423,56128,56447],[55356,57332,8203,56128,56423,8203,56128,56418,8203,56128,56421,8203,56128,56430,8203,56128,56423,8203,56128,56447]),!b); case"emoji":return b=d([55358,56760,9792,65039],[55358,56760,8203,9792,65039]),!b } return!1 } function f(a) { var c=b.createElement("script"); c.src=a,c.defer=c.type="text/javascript",b.getElementsByTagName("head")[0].appendChild(c) } var g,h,i,j,k=b.createElement("canvas"),l=k.getContext%26%26k.getContext("2d"); for(j=Array("flag","emoji"),c.supports= { everything:!0,everythingExceptFlag:!0 } ,i=0; i]]
Need to find the script location to remove it.
Just... leave it.
It's default WordPress Javascript that make your emoji beautier. The script can be found at WordPress official website: https://twentyfourteendemo.wordpress.com
In case you want to remove it, install a plugin called Disable WP Emoji Icons.
I am making a module that adds new tab in product edit page. The installation is Prestashop 1.6.1.4. The module adds a tab with some input fields that send data to mysql tables, but what I want to do is to style the fields a little bit, so that they look good. I am adding this in my module.php file:
public function install() {
if ($this->psversion() == 5 || $this->psversion() == 6)
{
if (parent::install() == false or !$this->registerHook('displayHeader') or !$this->registerHook('productFooter') or !$this->registerHook('displayAdminProductsExtra') or !$this->registerHook('actionProductUpdate') or !$this->registerHook('displayBackOfficeHeader'))
{
return false;
}
}
return true;
}
Then below this I put this code:
public function hookDisplayBackOfficeHeader($params) {
$this->context->controller->addCSS($this->_path.'views/css/adminsportsnutritionfadd.css');
}
But can't make the .css file appear. The file is in the right location, it has proper permissions and the owner of the file is www-data:www-data so this shouldn't be a permission issue. I have disable css combining in Prestashop as well as caching. Before reloading the page I am also deleting Prestashop's cache just in case, as well as I am deleting my brower's cache. Can somebody give me a hand in this?
Do like this:
public function hookBackOfficeHeader()
{
$this->context->controller->addCSS($this->_path.'views/css/adminsportsnutritionfadd.css');
}
For me it works like this:
$this->context->controller->addCSS($this->_path . 'views/css/back.css');
So the only difference is the css file name.
Not sure if you got this sorted or not, but...
I use this function within most of my modules to add
jQuery, Font-awesome, CSS & JS, then have it show ONLY on that module page...
public function hookDisplayBackOfficeHeader($params)
{
if(!(Tools::getValue('controller') == 'AdminModules'
&& Tools::getValue('configure') == 'MyModuleName')
){
return;
}
else
{
if ( method_exists($this->context->controller, 'addJquery') )
{
$this->context->controller->addJquery();
$this->context->controller->addCss('//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');
$this->context->controller->addCss($this->_path.'views/css/back.css');
$this->context->controller->addJs($this->_path.'views/js/back.js');
}
}
}
In my MVC5.1 project I'm using bundling and minification with CSS rewriting transformation:
styleBundle.Include("~/Content/Site.css", new CssRewriteUrlTransform());
bundles.Add(styleBundle);
CssRewriteUrlTransform converts image paths relative to the root of the site. But, when I images embedded into css:
span.file {
background-image: url(data:image/png;base64,iVBORw0KGg+...2AAAAElFTkSuQmCC);
}
this is getting translated into
span.file {
background-image: url(http://localhost:52253/Content/data:image/png;base64,iVBORg...mCC);
}
And obviously ~/Content/data:image/png;base64... does not exist.
Any way to stop this happening, other than update CSS files to not include embedded images? Or separate into different CSS files, where with actual URL are used and URL-transform this files. And another css with only embedded images.
Scrap that question. This is a known bug. Currently work around is to separate your css into embedded images and images via url.
Vote for these work-items: https://aspnetoptimization.codeplex.com/workitem/88 and https://aspnetoptimization.codeplex.com/workitem/108
Checkout my workaround which I've 'bundled' nicely into a NuGet package. https://github.com/benmccallum/AspNetBundling
Otherwise just upgrade to grunt/gulp ;)
If you don't want to extract the embedded images to actual files and you can't wait for a new version of the Microsoft.AspNet.Web.Optimization nuget, you can use the following class.
It's a verbatim copy of CssRewriteUrlTransform except it ignores (crudely ;)) URL's with the data URI syntax.
Gist: https://gist.github.com/janv8000/fa69b2ab6886f635e3df
/// <remarks>Part of Microsoft.AspNet.Web.Optimization.1.1.3, forked to ignore data-uri</remarks>
public class CssRewriteUrlTransformIgnoringDataUri : IItemTransform
{
internal static string RebaseUrlToAbsolute(string baseUrl, string url)
{
if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(baseUrl) || url.StartsWith("/", StringComparison.OrdinalIgnoreCase))
return url;
if (!baseUrl.EndsWith("/", StringComparison.OrdinalIgnoreCase))
baseUrl = baseUrl + "/";
return VirtualPathUtility.ToAbsolute(baseUrl + url);
}
internal static string ConvertUrlsToAbsolute(string baseUrl, string content)
{
if (string.IsNullOrWhiteSpace(content))
{ return content; }
return new Regex("url\\(['\"]?(?<url>[^)]+?)['\"]?\\)").Replace(content, match =>
{
var format = match.Groups["url"].Value;
if (format.StartsWith("data:image", StringComparison.CurrentCultureIgnoreCase))
{
return format;
}
return "url(" + RebaseUrlToAbsolute(baseUrl, format) + ")";
});
}
public string Process(string includedVirtualPath, string input)
{
if (includedVirtualPath == null)
{
throw new ArgumentNullException("includedVirtualPath");
}
return ConvertUrlsToAbsolute(VirtualPathUtility.GetDirectory(includedVirtualPath.Substring(1)), input);
}
}
We were facing the same issue for asp.net mvc with angular project. Issue was for ag-grid base 64 image which was not showing in prod environment.
As a workaround we have removed CssRewriteUrlTransform() & changed the virtual path to match with actual physical path.
Old code
bundles.Add(new StyleBundle("~/bundles/styles").Include("~/Content/Site.css", new CssRewriteUrlTransform());
New code change
bundles.Add(new StyleBundle("~/dist/styles").Include("~/Content/Site.css");
Initially base64 image was looking for bundles folder which was not existing.
Old
background: transparent url(data:image/svg+xml;base64,PHN2ZyB3a...)
was translated to
background: transparent url(/dist/data:image/svg+xml;base64,PHN2ZyB3a...)
After making the mentioned changes base 64 image was not appended with any path.
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 :)
what's the best approach to change the background of my website at each visit ?
1) write php code, loading a random css file containing the background property
2) write php code, generating different html (and including the background property directly into html code
3) something else ?
thanks
This can be done in your theme's page.tpl.php variable preprocessor. Store the random style in the $_SESSION array to re-use for all pages in the same user session. And append the markup to the $head variable used in the template.
YOURTHEME_preprocess_page(&$variables) {
$style = $_SESSION['YOURTHEME_background_style'];
if (!$style) {
$style = array();
//Generate your random CSS here
$style = "background-image: url('bg-". rand(0,10) .".png')";
$_SESSION['YOURTHEME_background_style'] = $style;
}
$variables['head'] .= '<style type="text/css">body {'. implode("\n", $style) .'}</style>';
}
Usually, $head is placed before $style in the page.tpl.php templaye, so CSS rules from any .css files will overrides your random rule. You may have to use !important in your random CSS to avoid this.
I would probably:
Use hook_user op login to detect the login and then store the background color code in the user object.
In your page template create an inline style for the background color that uses the value stored on the user object. For anonymous users don't do anything and have default defined in a style sheet.
Use a session cookie. Could be set either via js (client side) or something like php (server-side). Here's an example of a js-only solution:
<!doctype html>
<html><head><script>
var backgrounds=['foo.png', 'bar.png', 'hahah.png'];
function setBg () {
var currentBg=readCookie('which_bg');
if (!currentBg) {
currentBg=backgrounds[Math.random()*backgrounds.length|0];
createCookie('which_bg', currentBg);
}
document.body.style.backgroundImage='url('+currentBg+')';
}
// from http://www.quirksmode.org/js/cookies.html
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name) {
createCookie(name,"",-1);
}
</script></head>
<body onload="setBg();">
...
</body></html>
To change the background image at each page load (not exactly "visit" though), you can use the Drupal module Dynamic Background. For Drupal 7, only the 7.x-2.x branch contains the option for cycling backgrounds randomly. You would install it with:
drush dl dynamic_background-7.x-2.x && drush en dynamic_background
The feature can also be added to the 7.x-1.x branch with a patch, and to the 6.x-1.x branch similarly.