Generating complete Canonical URL in umbraco using HTTP_HOST - seo

I'm trying to use Canonical url's for my web pages. what i'm doing is :
I want complete url for the page, which i'm generating via following piece of code:
#{
var canonicalUrl= String.Empty;
if(umbraco.library.RequestServerVariables("HTTP_HOST").ToLower().StartsWith("www")) {
canonicalUrl = string.Concat("http://", umbraco.library.RequestServerVariables("HTTP_HOST"), CurrentPage.GetPropertyValue("umbracoUrlAlias"));
} else {
canonicalUrl = string.Concat("http://www.", umbraco.library.RequestServerVariables("HTTP_HOST"), CurrentPage.GetPropertyValue("umbracoUrlAlias"));
}
<link rel="canonical" href="#canonicalUrl" />
}
I'm not sure, if this is the expected way to do. OR if there is any better way to do.

Here's a guide on how to set up Canonical URLs using Razor on Umbraco 7.1.x.
If you DO want the "www." in the URL, use this:
#using umbraco
#using System
#{var canonicalUrl= String.Empty;}
#if(umbraco.library.RequestServerVariables ("HTTP_HOST").ToLower().StartsWith("www")) {
canonicalUrl = string.Concat("http://", umbraco.library.RequestServerVariables("HTTP_HOST"), Model.Url);
} else {
canonicalUrl = string.Concat("http://www.", umbraco.library.RequestServerVariables("HTTP_HOST"), Model.Url);
}
<link rel="canonical" href="#canonicalUrl" />
If you DO NOT want the "www." in front of the URL, then use this instead:
#using umbraco
#using System
#* empty out the string *#
#{var canonicalUrl= String.Empty;}
#* check if the requested URL starts with www. *#
#if(umbraco.library.RequestServerVariables("HTTP_HOST").ToLower().StartsWith("www")) {
#* adds http:// to the beginning *#
canonicalUrl = string.Concat("http://", umbraco.library.RequestServerVariables ("HTTP_HOST"), Model.Url);
#* strips out the www. from the URL *#
canonicalUrl = umbraco.library.Replace(canonicalUrl, "www.", "");
} else {
#* if they did not use the www prefix, we still have to add http:// to the URL *#
canonicalUrl = string.Concat("http://", umbraco.library.RequestServerVariables("HTTP_HOST"), Model.Url);
}
<!-- output the canonical URL -->
<link rel="canonical" href="#canonicalUrl" />
Source - Canonical URLs in Umbraco CMS version 7.1.x with Razor

This has worked for us previously... Looks like what you're already using.
Using Razor syntax on Umbraco (as opposed to XSLT)...
#using umbraco
#using System
#{ var canonicalUrl= String.Empty; }
#if(umbraco.library.RequestServerVariables("HTTP_HOST").ToLower().StartsWith("www")) {
canonicalUrl = string.Concat("http://", umbraco.library.RequestServerVariables("HTTP_HOST"), Model.Url);
} else {
canonicalUrl = string.Concat("http://www.", umbraco.library.RequestServerVariables("HTTP_HOST"), Model.Url); }
<link rel="canonical" href="#canonicalUrl" />
Source

Related

Export Html to Pdf using JsReport in Asp.net core

I have a html page with images, tables and some styling with Bootstrap 4. I tried to convert the pages to pdf using the JsReportMVCService, the pdf doesnot load with the proper css class from bootstrap.
HTML CONTENT
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>WeekelyReport</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
</head>
<body>
<div class="jumbotron">
<h1> Hello John Doe,</h1>
<p>
This is a generic email about something.<br />
<br />
</p>
</div>
</body>
</html>
ASP.NET CORE IMPLEMENTATION
var generatedFile = await GeneratePDFAsync(htmlContent);
File.WriteAllBytes(#"C:\temp\hello.pdf", generatedFile);
async Task<byte[]> GeneratePDFAsync(string htmlContent)
{
var report = await JsReportMVCService.RenderAsync(new RenderRequest()
{
Template = new Template
{
Content = htmlContent,
Engine = Engine.None,
Recipe = Recipe.ChromePdf
}
});
using (var memoryStream = new MemoryStream())
{
await report.Content.CopyToAsync(memoryStream);
return memoryStream.ToArray();
}
}
How my Pdf Looks after the conversion to PDF.
It is possible to convert to pdf with the same bootstrap 4 layout? or am i missing something during the conversion here?
The pdf printing uses print media type and the bootstrap has quite different styles for printing. This causes that the pdf looks different than html, but it looks the same as you would print it. I would generally not recommend using responsive css framework as bootstrap for printing static pdf, but it is of course your choice.
To make your example looking the same on pdf you just need to change the media type on the chrome settings.
var report = await JsReportMVCService.RenderAsync(new RenderRequest()
{
Template = new Template
{
Content = htmlContent,
Engine = Engine.None,
Recipe = Recipe.ChromePdf,
Chrome = new Chrome {
MediaType = MediaType.Screen,
PrintBackground = true
}
}
});
make sure you have the latest jsreport.Types#2.2.2

Open URL in new safari tab - safari extention

generaly i ask exactly the same question as here:
Safari extension: Event for a completely new tab?
in this answer (case 3) he guide to listen click event inside inject.js.
can someone show this implementation?
Here's an implementation I used for one of my previous extensions:
Create a global.html file, and inside the Extension Builder, select that file under the Extension Global Page section:
Source for global.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>My Extension</title>
</head>
<body>
<script>
function messageHandler(event) {
var newTab = null;
var url = null;
if (event.name === "open_new_tab") {
url = event.message;
newTab = safari.application.activeBrowserWindow.openTab();
newTab.url = url;
}
}
safari.application.addEventListener("message", messageHandler, false);
</script>
</body>
</html>
Create an extension.js file, and add it to the Injected Extension Content -> End Scripts section:
Source for extension.js:
(function() {
// ... rest of you extension code
openNewTabWithUrl("http://google.com")
function openNewTabWithUrl(url) {
safari.self.tab.dispatchMessage("open_new_tab", url);
}
}());
This will send a message containing a URL from your extension.js to global.html, which will pick up the message and open the new tab.

Is there a way to call a function before the dependencies are loaded in Sencha Touch application

Sencha Touch application has requires:[] option to specify the list of controllers and models and stores etc that are loaded that we need for the application to work but is there a way to execute something that we need even before the loading of the dependencies. FOr e.g. I need the Browsers Language even before the loading of all dependencies. So is it possible to do?
Keep in mind: Sencha Touch is nothing but JavaScript.
You can add some script in your index.html in front of the script tag that loads the sencha microloader.
<!DOCTYPE HTML>
<html manifest="" lang="en-US">
<head>
<meta charset="UTF-8">
<title>FNL</title>
<style type="text/css">
<!-- sencha stuff -->
</style>
<script id="myScript" type="text/javascript" src="myScript.js"></script>
<!-- The line below must be kept intact for Sencha Command to build your application -->
<script id="microloader" type="text/javascript" src=".sencha/app/microloader/development.js"></script>
</head>
<body>
<div id="appLoadingIndicator">
<div></div>
<div></div>
<div></div>
</div>
</body>
</html>
I added some lines to the ST Microloader:
this.css = processAssets(manifest.css, 'css');
// Load language strings
var xhr = new XMLHttpRequest();
xhr.open('GET', 'api/Settings', false);
xhr.send(null);
var settings = eval("(" + xhr.responseText + ")");
Lang = settings.Translations[0];
Options = settings.Options[0];
// End Load Language Strings
this.js = processAssets(manifest.js, 'js');
In ExtJS i accomplished this by loading a Dependency class first
Ext.require([
'MyApp.Dependencies',
..
]);
so the Dependecies class is loaded before all controllers which looks like this
Dependencies.js:
Ext.define('MyApp.Dependencies', {
singleton: true,
init: function() {
// load translation data
}
});
MyApp.Dependecies.init();
and for completition my init function looks something like this:
inti: function(){
function loadScriptSync(url) {
var xhrObj = new XMLHttpRequest();
// open and send a synchronous request
xhrObj.open('GET', url, false);
xhrObj.send('');
// add the returned content to a newly created script tag
var se = document.createElement('script');
se.type = "text/javascript";
se.text = xhrObj.responseText;
document.getElementsByTagName('head')[0].appendChild(se);
}
var language = this.getLanguage();
loadScriptSync("resources/locale/locale." + language + ".js");
}

Use section in partial view

In my shared layout I would like to have a "scripts" section to stuff it with all the scripts needed for page functionality.
Layout.cshtml
<html>
<head>
<title>Test</title>
<script src="#Url.Content("~/Scripts/jquery-2.0.3.js")" type="text/javascript"> </script>
#RenderSection("Scripts", required: false)
</head>
<body>
#RenderBody()
</body>
</html>
So, my view loads a specific javascript, and I want it to be in "scripts" section, and it's working.
Index.cshtml
#model PlatformaPu.Areas.Inventura.Models.Home.Index
#section Scripts {
<script src="#Url.Content("~/Areas/Inventura/Scripts/Home/Index.js")" type="text/javascript"></script>
}
{CONTENT REMOVED FOR BREVITY}
#section Footer {
#Html.Partial("~/Views/Shared/_AppSelector.cshtml", Model.AppSelector)
}
Finally, my view renders a partial and I have a javascript that this partial loads.
_AppSelector.cshtml
#model PlatformaPu.Models.Shared._AppSelector
#section Scripts {
<script src="#Url.Content("~/Scripts/Shared/_AppSelector.js")" type="text/javascript"></script>
}
{CONTENT REMOVED FOR BREVITY}
...and this is NOT working - javascript tag is NOT rendered in "scripts" section
How can I do this?
As discussed in this question, it is not possible to use sections in a partial view:
Sections don't work in partial views and that's by design. You may use some custom helpers to achieve similar behavior, but honestly it's the view's responsibility to include the necessary scripts, not the partial's responsibility. I would recommend you using the #scripts section of the main view to do that and not have the partials worry about scripts.
You should add the script reference to the main view that references the partial.
This is my first answer!
I've being working with webforms for years and now i'm dealing with MVC 5. Bit hard.
Perhaps is the wrong solution, but works :)
In Layout.cshtml. add second "ScriptsPartial" section
#RenderSection("ScriptsPartial", required: false)
In Index.cshtml, add ", new ViewDataDictionary(ViewData) { { "ViewPage", this } }"
#section Footer {
#Html.Partial("~/Views/Shared/_AppSelector.cshtml", Model.AppSelector, new ViewDataDictionary(ViewData) { { "ViewPage", this } })
}
In _AppSelector.cshtml, remove this
#section Scripts {
<script src="#Url.Content("~/Scripts/Shared/_AppSelector.js")" type="text/javascript"></script>
}
In _AppSelector.cshtml, add this in any place
#{
if (ViewData.ContainsKey("ViewPage"))
{
System.Web.Mvc.WebViewPage viewPage = (System.Web.Mvc.WebViewPage)ViewData["ViewPage"];
viewPage.DefineSection("ScriptsPartial", () =>
{
// viewPage.Write(Scripts.Render("~/AppSelector/Scripts")); // If you use a Bundle
viewPage.WriteLiteral("<script src=\"" + Url.Content("~/Scripts/Shared/_AppSelector.js") + "\" type=\"text/javascript\"></script>");
});
}
}
Just "send" the View to the PartialView (no Parent property like in WebForms?) and use it to add content to "ScriptsPartial" section.
"ScriptsPartial" is needed because DefineSection throws an error "section already defined: Scripts"
So, no more than one PartialView can use "ScriptsPartial" section... not so good solution.
Best regards,
Paco Ferre

jQuery not defined + MVC4

Im creating the below MVC view that has got some jquery script in it.
However this script is not getting executed. Getting jQuery undefined error.
I want to write including script directly in view instead of using layout page.
Can somebody advise what am I doing wrong here?
#{
ViewBag.Title = "FileUpload";
}
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title - What up boyeez!</title>
<meta name="viewport" content="width=device-width" />
<script src="~/Scripts/jquery-ui-1.10.0.min.js"></script>
<h2>FileUpload</h2>
#using (Html.BeginForm("UploadFile", "FileUpload", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary();
<ol>
<li class="lifile">
<input type="file" id="fileToUpload" name="file" />
<span class="field-validation-error" id="spanfile"></span>
</li>
</ol>
<input type="submit" id="btnSubmit" value="Upload" />
}
</body>
</html>
<script type="text/jscript">
(function ($) {
function GetFileSize(fileid) {
try {
var fileSize = 0;
if ($.browser.msie) {
var objFSO = new ActiveXObject("Scripting.FileSystemObject");
var filePath = $("#" + fileid)[0].value;
var objFile = objFSO.getFile(filePath);
var fileSize = objFile.size;
fileSize = fileSize / 1048576;
}
else {
fileSize = $("#", fileid)[0].files[0].size
fileSize = file / 1048576;
}
return fileSize;
}
catch (e) {
alter("Error is: " + e);
}
}
function getNameFromPath(strFilepath) {
debugger;
var objRE = new RegExp(/([^\/\\]+)$/);
var strName = objRE.exec(strFilepath);
if (strName == null) {
return null;
}
else {
return strName[0];
}
}
$("#btnSubmit").live("click", function () {
debugger;
if ($('#fileToUpload').val == "") {
$("#spanfile").html("Please upload file");
return false;
}
else {
return checkfile();
}
});
function checkfile() {
var file = getNameFromPath($("#fileToUpload").val());
if (file != null) {
var extension = file.subst((file.last('.') + 1));
switch (extension) {
case 'jpg':
case 'png':
case 'gif':
case 'pdf':
flag = true;
break;
default:
flag = false;
}
}
if (flag == false) {
$("#spanfile").text("You can upload only jpg, png, gif, pdf extension file");
return false;
}
else {
var size = GetFileSize('fileToUpload');
if (size > 3) {
$("#spanfile").text("You can upload file up to 3 MB");
return false;
}
else {
$("#spanfile").text("");
}
}
}
$(function () {
debugger;
$("#fileToUpload").change(function () {
checkfile();
});
});
})(jQuery);
You are missing a reference to jquery itself. You probably also want a css file for jquery ui:
<link rel="stylesheet" href="css/themename/jquery-ui.custom.css" />
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui.custom.min.js"></script>
See the "Basic Overview: Using jQuery UI on a Web Page" section on the jquery-ui learning docs for full details of how to use and customise jquery ui.
Razor techniques for jquery files
To make your life easier in your view template, you could use the scripts render function:
#Scripts.Render("~/Scripts/jquery-1.9.1.min.js")
#Scripts.Render("~/Scripts/jquery-ui-1.10.0.min.js")
In itself, not too impressive: the syntax is slightly more expressive and 5 characters shorter, that's all.
But it leads you into bundles (references at the end), which are really what you should be using.
Bundles are awesome
Bundles allow you to:
Group dependent files: grouping js and/or css files together reduces the chances of this happening, and also means you can "modularise" your own scripts into multiple files in one folder.
Increase performance: Send out everything inside a single Bundle in a single file - speeding up load times for clients by reducing the number of http requests from the browser
Help development: Use non-minified javascripts (and css) for debugging during development
Publish without changes to code: Use the minified scripts for live deployment
Use in-built minifying for your own scripts
Optimise client experience: Use CDNs for standard scripts like jquery (which is better for your users)
Upgrade easily: Not have to change code when you update your version numbers for things like jquery through NuGet by use of the {version} wildcard (as below)
Example:
// This is usually in your MVC 4 App_Start folder at App_Start\BundleConfig
public class BundleConfig {
public static void RegisterBundles(BundleCollection bundles) {
// Example with full use of CDNs in release builds
var jqueryCdnPath = "https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js";
bundles.Add(new ScriptBundle("~/bundles/jquery", jqueryCdnPath).Include("~/Scripts/jquery-{version}.js"));
And in your razor file you only need a tiny change:
#Scripts.Render("~/bundles/jquery");
This will:
send out the full jquery script during debugging
send out the minified script for a release build
even minify your own bundles such as #Scripts.Render("~/bundles/myScripts"); for live builds
Bundle details
Under the hood bundles will use the CDNs, or minify your own scripts as well, or send already minified files (like jquery-1.9.1.min.js) during release builds, but you can control this by using bundles.UseCdn and BundleTable.EnableOptimizations inside your RegisterBundles method. By using this along with AppSettings in your web.config you can have very close control so that you could even send out debugging scripts for certain users on a live site.
Also note the use of {version} in the bundle configuration.
You can include multiple scripts in a bundle as well:
bundles.Add(new ScriptBundle("~/bundles/jqueryWithUi")
.Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/jquery-ui-{version}.js"
));
This razor command will now send out both files for you:
#Scripts.Render("~/bundles/jquery");
And you can use bundles for css:
bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
"~/Content/themes/base/jquery.ui.core.css",
"~/Content/themes/base/jquery.ui.resizable.css",
"~/Content/themes/base/jquery.ui.selectable.css",
"~/Content/themes/base/jquery.ui.accordion.css",
"~/Content/themes/base/jquery.ui.autocomplete.css",
"~/Content/themes/base/jquery.ui.button.css",
"~/Content/themes/base/jquery.ui.dialog.css",
"~/Content/themes/base/jquery.ui.slider.css",
"~/Content/themes/base/jquery.ui.tabs.css",
"~/Content/themes/base/jquery.ui.datepicker.css",
"~/Content/themes/base/jquery.ui.progressbar.css",
"~/Content/themes/base/jquery.ui.theme.css"));
References:
www.asp.net - Bundling and Minification
You're loading the jQuery UI library without loading the jQuery library.
<script src="~/Scripts/path/to/jquery"></script
<script src="~/Scripts/jquery-ui-1.10.0.min.js"></script
I was having the same problem of client side validation not working. I brought up the JavaScript console in Chrome and saw I was receiving an error stating "JQuery was not defined.".
Turns out I had some code in my View that was causing problems with jQuery not loading.
Recommendation to others who come across this, check your JS console in your browser to ensure you are not getting a JQuery error.