I've been trying to add the plus one button on our company's product page. We have a multi - subdomain website which has language translated content for that particular subdomain. The user's language preference is remembered via cookies.
Now when when I hit the +1 button, and try to share the page on google+ I do not see the translated description come up on it. It somehow grabs the "English" description. When I try to look at my "MetaDescription" tag it is in the foreign language.
What I've been guessing is that google was trying to call the URL I was trying to share and crawling it instead of crawling the very page I was clicking the +1 button on. What would be the best way to make google detect the language setting on the page i want to share?
To get the API to load in the different languages, you should specify the lang in the config. Do this BEFORE the plusone.js can load. That should make the button and it's screens display with that language.
Here's an example:
<html>
<head>
<title>+1 Demo: Async render</title>
<link rel="canonical" href="http://www.example.com" />
</head>
<body>
<g:plusone></g:plusone>
<script type="text/javascript">
window.___gcfg = {
lang: 'zh-CN'
};
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
</body>
</html>
However, for the share part of it, can you be sure that when Google scrapes the page you're sharing that it is picking up the correct language? Since the user agent Google is using might not specify a language, your page is being rendered to Google's scrapers as the default language. Maybe you should have a canonical URL for each language for your page that google can scrape correctly.
Related
I have a Windows Forms application that uses a WebBrowser control to display an embedded web page. The file is (successfully) loaded using:
webHelp.DocumentStream=
Assembly.GetExecutingAssembly()
.GetManifestResourceStream("MyAssembly.help.html");
In order for this to work (i.e. the file to be loaded/displayed) I set the webHelp.AllowNavigation = false;. I don't fully understand why, but if it's set to true, the page is not displayed.
In my HTML document (see bellow) I want to be able to navigate trough different sections. But when I click on a link, the browser control does not go to the targeted element. The web page works fine in the stand-alone Internet Explorer 10, so it must have something to do with the control, more specifically the AllowNavigation property. MSDN didn't help much.
How can I achieve this navigation behavior? Is there another way of loading the HTML file without setting the AllowNavigation property to false?
This is my simple HTML file:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Using this tool</title>
</head>
<body>
<h3>Description</h3>
<div><p id="contents">Contents</p></div>
<div>
<p id="general">Using the file converter</p>
<p>*converter description*</p>
Go To Top!
</div>
<div class="divBlock" >
<p id="selectOption">Selecting a conversion action</p>
<p>*action selection*</p>
Go To Top!
</div>
</body>
</html>
EDIT: After additional tests I found the root of the problem. The problem appeared after setting a value for the URL property, running the application and afterwards clearing this value. The embedded page is not loaded any more, unless the AllowNavigation property is set to false. There are two solutions, described in my answer bellow.
I also have my own WebBrowser. I've tested it and it loads your HTML file perfectly.
I simply used:
webBrowser1.Navigate("C:\\myPath\\SofNavigate.html");
When I click on links it goes to "#contents" without problems.
I am not sure why you need to use webHelp.Docstream instead of simple Navigate.
By the way, when I turn off navivation, then I am not able to go anywhere from the page that I started on. So Navigation must be on in order to go anywhere from the "home page".
Try to debug that part, as it appears to be the bigger problem that you have.
Here is a good example on how to set up simple webBrowser. Try to use it as a base and see what you do differently that messes up your navigation.
[EDITED] Win8/IE10, your code works for me unmodified inside Form.Load event on a simple form which has just a single WebBrowser control with all default settings (and WebBrowser.AllowNavigation is true by default). Check the properties of your WebBrowser control in the Designer, you may have something wrong in there.
[/EDITED]
You're using HTML5, which handles anchor links via id attribute (i.e. <p id="contents"> ... <a href="#contents">. By default, WebBrowser control works in legacy IE7 mode with HTML5 disabled. You need to turn it on with FEATURE_BROWSER_EMULATION feature control, before WebBrowser object gets created. The best place to do this is a static constructor of your form:
static MainForm()
{
SetBrowserFeatureControl();
}
private static void SetBrowserFeatureControl()
{
// http://msdn.microsoft.com/en-us/library/ee330730(v=vs.85).aspx#browser_emulation
// FeatureControl settings are per-process
var fileName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);
// make sure the control is not running inside Visual Studio Designer
if (String.Compare(fileName, "devenv.exe", true) == 0 || String.Compare(fileName, "XDesProc.exe", true) == 0)
return;
// web pages containing standards-based !DOCTYPE directives are displayed in Standards mode
using (var key = Registry.CurrentUser.CreateSubKey(
#"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",
RegistryKeyPermissionCheck.ReadWriteSubTree))
{
key.SetValue(fileName, (UInt32)9000, RegistryValueKind.DWord);
}
}
Try it and your links should work as expected. This solution does NOT require admin rights, the affected key is under HKEY_CURRENT_USER.
[UPDATE] There may be a better solution, it works at least for IE10 here on my side. Add <meta http-equiv="X-UA-Compatible" content="IE=edge" /> as below and leave the registry intact. If you see document.compatMode: CSS1Compat, document.documentMode: 10, you should be good to go, but test with older IE versions too.
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title></title>
<script type="text/javascript">
window.onload = function () {
info.firstChild.data =
"document.compatMode: " + document.compatMode +
", document.documentMode: " + document.documentMode;
}
</script>
</head>
<body>
<pre id="info"> </pre>
</body>
</html>
EDIT: After finding the cause of the problem (see the edit to the question) I can now propose three solutions:
1. WebBrowser control replacement:
Simply delete the existing WebBrowser control and add a new one. This solution does not require any modification of the AllowNavigation property. DO NOT modify the URL property.
2. When deleting and adding a new WebBrowser control is not an option:
Since the AllowNavigation property was influencing the loading and displaying of the web page, there was no reason for it to be left to false afterwards. Setting back the property in the Shown event solved the navigation problem, without requiring other alterations (e.g. in the HTML file or the Registry):
private void helpForm_Shown(object sender, EventArgs e)
{
webHelp.AllowNavigation = true;
}
3. Reseting the Document
It seams that the Document property gets (automatically) initialized if URL property is at one time set and reset. Adding webHelp.Document.OpenNew(true); before loading the resource stream solves the problem without the need for re-adding the WebBrowser and without modifying the AllowNavigation property.
We have a feature in a Windows application that opens a web browser, navigates to certain pre-configured web sites, and auto-fills the forms with data from our database -- it's a convenience feature for users.
Now we want to build an Asp.Net version of this feature so that from our web app, the user clicks a link/button, and we open the page (with a redirect? with JavaScript?). Then we fill in the form so that the user can review the data and submit it.
To do this, I think that we would either need to inject javascript into the browser frame that is loading the external window, or we would need to be able to interact with that window.
We are worried that browser security might not allow this -- it could look like some sort of spoofing attack. What would be a good way to do this?
If the Domains, Protocols, and Ports do not match between the website opening the popup and the website being opened in the popup then your code will violate the Same Origin Policy and either be silently ignored or throw an exception.
Here's an example to demonstrate:
<!doctype html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<script type="text/javascript">
openPopUp = function(href) {
var props = "width=500,height=500,menubar=no,toolbar=no,scrollbars=yes";
var win = window.open(href, href, props);
if (win == null) alert("Your popup blocker is ruining my demo.");
return win;
};
openMe = function(url){
href = (url=="")?document.location:url;
pu = openPopUp(href);
//This will be ignored silently if Same Origin Policy is violated
pu.onload = function() {
p = pu.document.createElement("p");
p.appendChild(pu.document.createTextNode("onload was here."));
pu.document.body.appendChild(p);
};
//This will throw an exception if Same Origin Policy is violated
setTimeout(function() {
p = pu.document.createElement("p");
p.appendChild(pu.document.createTextNode("setTimeout was here."));
pu.document.body.appendChild(p);
},3000);
return false;
}
</script>
<body>
Self
Google
You need to make a bookmarklet. From you asp.net page, make a link which the user drags to his browsers bookmarks. The user clicks a link to the page you want to fill out. Then he clicks the newly created bookmarklet.
In pure javascript this is not possible which is why you need to use bookmarklet.
Scenario: you have two pages base.aspx and popup.aspx. On clicking a link on base.aspx you want to open popup.aspx filled with desired data.
You are in control of both base.aspx and popup.aspx
These are few ways I think you can achieve this
If the data you want on popup.aspx is already loaded on base.aspx. Then send this data in querystring (if its not too long)
If the data you want on popup.aspx is already loaded on base.aspx. Read form fields from base.aspx using window.opener in popup.aspx. Note: window.opener will only work if both base and popup are in same domain.
Send an identifier string in popup.aspx URL (http:///popup.aspx?actiodId=1234QWE6789), now in page_load of popup.aspx fetch data from DB quering on actiodId
The best way to do what you are trying to do is to create a browser plugin. Try looking here for some more information. But with a browser plugin, you get complete control of the DOM and you can inject javascript code to do what you are doing. If needed, you can even call web services from your plugin.
I have a bunch of static links currently within a div, however Im after changing the order of the links on page load.
I've considered using a literal and a loop through the links in code behind but im stumped. Maybe a repeater... I need a push in the right direction please!
Im fairly new to this so any help would be much appreciated. Thanks
(c# or vb.Net)
ok so lets say that you would store the links in a Links.txt file because there could be hundreds of links for example..
1. Create the .txt file
2. Make note of the file location.
3. Save the file with the links in them
4. use this code in your project to load the links
List<string> strUrlLinks = new List<string>(File.ReadAllLines(FilePath + FileName.txt));
in code you can then hover over strUrlLinks and you will see the Links
to access the individual links do it based on it's [Index] position
I know you asked for an answer in c# or vb.net and may have some technical restraints on this, but to create this functionality in jQuery is almost trivial considering the links are already hardcoded on the page.
See the example below which sorts in descending order on the link text.
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<div id="linksContainer">
Line 1
Line 3
Line 2
</div>
<script type='text/javascript'>
$(window).load(function(){
var orderDivLinks = function(desc) {
$('div#linksContainer').children().detach().sort(function(a,b) {
var compA = $(a).text();
var compB = $(b).text();
return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
}).appendTo(document.body);
}
orderDivLinks(0);
});
</script>
</body>
</html>
I have <asp:TextBox runat="server" ID="lastName" /> on a page and I want to set focus it with jQuery but it is not returning it. My code is like this:
$.ready() {
var tb = $('lastName').focus(); // don't work, why?
}
You have two different problems here that you need to resolve: a malformed selector and the fact that in ASP.NET client IDs don't match server IDs.
What you want is:
$.ready() {
$('#<%= lastName.ClientID %>').focus();
}
Let's break it down...
First, in jQuery a selector that accesses an element by it's id attribute needs to begin with a '#' symbol. So the accessor should look more like: $('#lastName'). Selectors in jQuery are similar, but more robust than in CSS. You can familiarize yourself with the selector syntax at the jQuery API site.
Second, with ASP.NET, the id's assigned to the HTML elements are often different than those that identify an asp control on the server. This is because ASP.NET needs to make sure that all elements are uniquely identified - and don't collide with names that may be defined in master pages, user controls, or repeated sections of content. These ids tend to get long and are often impossible to predict - fortunately, we can use the <%= %> code expansion together with the ClientID property of the control to insert the appropriate id for the HTML element without having to know the details of how ASP.NET assigns unique ids.
In ASP.NET 4.0, the client ID can now be specified directly, which can help avoid the technique shown above.
Here is a function I use for selecting server controls in pages that have a masterpage. It doesnt work in all cases such as nested controls but for simpler stuff its real handy.
This goes on the masterpage somewhere
<script type="text/javascript">
baseName = "<%= Content.ClientID %>_";
</script>
Using this function you can go GetServerElementById("lastname")
function GetServerElementById(id) {
return $("#" + baseName + id);
}
You can do a partial attribute query:
<script type="text/javascript">
$(function() {
$('#btnExtract').click(
function() {
alert($("input[id$='txtMessage").val());
}
);
});
Selecting ASP.NET Web Controls in jQuery
I have a small WPF app (although I guess it doesn't really matter whether it's a wpf form or a webform app?) that I want to have launch a new browser window and POST to a specific url. I've been messing around with:
System.Diagnostics.Process.Start("http://myurl.com");
to launch the window but I don't think I can use the same process to actually post to a url...I've also experimented with HttpWebRequest but I would like the user to be able to use the app after I have posted to this url, not just show them the results...What can I look at to able to do something like this?
There is no direct way to do it. What you could do is generate a HTML page with a form filled with the data you need to post, and a bit of javascript to post the page automatically when it is loaded. Then you just have to open that page in the browser...
The generated HTML could look like that :
<html>
<head>
<script language="Javascript">
function submitForm() {
var theForm = document.getElementById("theForm");
theForm.submit();
}
</script>
</head>
<body onload="submitForm()">
<form id="theForm" action="http://myurl.com" method="POST">
<input type="text" name="username" value="myusername"/>
<input type="password" name="password" value="mypassword"/>
</form>
</body>
</html>
If the page must be displayed in your application, load it in a WebBrowser control
Use the WebBrowser Class instead.
There are multiple solutions, not sure which one would be the best for you...
Proceed with your original approach
Embed web browser control in your applicaiton as suggested in other answers
Do everything programmatically "behind the scene"
For #3 you may want to look here: http://geekswithblogs.net/rakker/archive/2006/04/21/76044.aspx
If you want to go with #1 - it is more tricky, since you need to control external application and different browsers would behave differently.
I've used "javascript:" protocol and the code below with IE as default browser when dealing with one "user-unfriendly" application. Please note that it's not "production-ready" code. There is no error handling, user may shift focus away from launched browser, or use browser without "javascript:" protocol support etc.
static void Main()
{
Settings s = Settings.Default;
Process.Start(s.URL1);
Thread.Sleep(s.Delay1);
SendKeys.SendWait("%D");
Thread.Sleep(100);
SendKeys.SendWait(EncodeForSendKey(s.URL2));
SendKeys.SendWait("{ENTER}");
}
public static string EncodeForSendKey(string value)
{
StringBuilder sb = new StringBuilder(value);
sb.Replace("{", "{{}");
sb.Replace("}", "{}}");
sb.Replace("{{{}}", "{{}");
sb.Replace("[", "{[}");
sb.Replace("]", "{]}");
sb.Replace("(", "{(}");
sb.Replace(")", "{)}");
sb.Replace("+", "{+}");
sb.Replace("^", "{^}");
sb.Replace("%", "{%}");
sb.Replace("~", "{~}");
return sb.ToString();
}
URL1: http://www.google.com
URL2: javascript:function x(){document.all.q.value='stackoverflow';document.forms[0].submit();} x();
You can create a hidden WebBrowser control and do Navigate() (using the overload that allows you to specify the request method). You will need to specify a "_blank" target frame to cause the navigation to happen in a new browser window.