GeneralLink in Sitecore - c#

I'm new to Sitecore.. I have created a Page template and add a field for a URL of type General Link. I have created another field for the text for the link (this is standard practice in this project).
I simply want to display the link in my user control but I just cant get it to work. This should be simple but Im going round in circles
Here's an example of the code I've tried ..
ascx :
<asp:HyperLink runat="server" ID="lnkMain"></asp:HyperLink>
ascx.cs:
lnkMain.NavigateUrl = SiteCore.Context.Item.GetGeneralLink("Link1");
lnkMain.Text = item.GetFieldValue("Link1Text");

You should be careful using linkField.Url since it it will incorrectly render internal links to Sitecore Items and Media. You should instead be using Sitecore.Links.LinkManager.GetItemUrl(item) and Sitecore.Resources.Media.MediaManager.GetMediaUrl(item) for those.
It would be better to have a helper (extension) method to return the correct url for you, based on the type of link. Take a look this Sitecore Links with LinkManager and MediaManager blog post which has the correct code you need for this.
For reference:
public static String LinkUrl(this Sitecore.Data.Fields.LinkField lf)
{
switch (lf.LinkType.ToLower())
{
  case "internal":
    // Use LinkMananger for internal links, if link is not empty
    return lf.TargetItem != null ? Sitecore.Links.LinkManager.GetItemUrl(lf.TargetItem) : string.Empty;
  case "media":
    // Use MediaManager for media links, if link is not empty
    return lf.TargetItem != null ? Sitecore.Resources.Media.MediaManager.GetMediaUrl(lf.TargetItem) : string.Empty;
  case "external":
    // Just return external links
    return lf.Url;
  case "anchor":
    // Prefix anchor link with # if link if not empty
    return !string.IsNullOrEmpty(lf.Anchor) ? "#" + lf.Anchor : string.Empty;
  case "mailto":
    // Just return mailto link
    return lf.Url;
  case "javascript":
    // Just return javascript
    return lf.Url;
  default:
    // Just please the compiler, this
    // condition will never be met
    return lf.Url;
}
}
Usage:
Sitecore.Data.Fields.LinkField linkField = item.Fields["Link1"];
lnkMain.NavigateUrl = linkField.LinkUrl();
It would be best of course to use <sc:FieldRender> control and let Sitecore handle it for you, but it looks like you do not have that option.

As of Sitecore 7.2 there is an alternative to linkField.Url:
Sitecore.Data.Fields.LinkField linkField = item.Fields["Link1"];
lnkMain.NavigateUrl = linkfield.GetFriendlyUrl();
A new LinkField.GetFriendlyUrl() method has been introduced. The method makes it easy to output a valid URL no matter what type of link the field contains. For internal links, the method returns a URL from LinkManager.GetItemUrl(). For media links, the method returns a URL from MediaManager.GetMediaUrl(). For external links, anchor links, e-mail links, and JavaScript links, the method returns the value of the LinkField.Url property. (400051)
http://techitpro.com/uncategorized/sitecore-7-2-changes/

It'd be easier if you use the Link control:
<sc:Link Field="Link1" runat="server" ID="link">
<sc:Text Field="Link1Text" runat="server" ID="linkText" />
</sc:Link>
That way, you don't have to do any code-behind stuff and you'll be able to use the Page Editor as well.

You can use below
<sc:Link ID="scLink" runat="server" Field="Your Link Field Name">
<sc:FieldRenderer ID="frTest" runat="server" FieldName="Your Text Field Name" />
</sc:Link>
It will work for you.

When you assign a value to a GeneralLink field of an item there is a field labeled "Link Description" in the Internal Link dialog that pops up. Fill in that value then use:
<sc:Link runat="server" Field="{YourFieldName}" />
That's it. Everything is "wired-up" for you, auto-magically.

You need to get the Linkfield value of the item and than get the LinkField type of that item. This will give you the type of link either an "Internal", "external", "mailto" and based on that can get the url of the link field as this is mentioned by #jammykam.
Same thing you can do to retrieve the LinkText as well.
For Reference :
public static string GetGeneralLinkText(LinkField link)
{
text = "";
if (link == null)
return false;
if (!string.IsNullOrEmpty(link.Text))
{
text = link.Text;
return true;
}
switch (link.LinkType)
{
case "internal":
if (link.TargetItem == null)
return false;
text = link["Text Field Name"];
break;
case "external":
case "mailto":
case "anchor":
case "javascript":
text = link.Text;
break;
case "media":
if (link.TargetItem == null)
return false;
Sitecore.Data.Items.MediaItem media = new Sitecore.Data.Items.MediaItem(link.TargetItem);
text = media.Name;
break;
case "":
break;
default:
return "";
}
return link["Text Field Name"];
}

Related

Selenium WebDriver and C# (VS): Look for a specific header string

I've been trying, without luck, to use IJavaScriptExecutor to find a specific header string in a page. Here's the html code form the page:
<div class="wrap">
<h2>Edit Page <a href="http://www.webtest.bugrit.net/wordpress/wp-admin/post-
new.php?post_type=page" class="add-new-h2">Add New</a></h2>
<div id...
The text I need to check for is the "Edit Page" string.
This is the closest I've come, which isn't very close:
var element = FFDriver.Instance.FindElements(By.ClassName("add-new-h2"));
IJavaScriptExecutor js = FFDriver.Instance as IJavaScriptExecutor;
if (js != null) {
string innerHtml = (string)js.ExecuteScript("return arguments[0].innerHTML;", element);
//System.Windows.Forms.MessageBox.Show(innerHtml);
if (innerHtml.Equals("Edit Page")) {
return true;
} else {
return false;
}
}
Now, I realize that the text I should expect to get from that code isn't the exact string "Edit Page". But shouldn't it return something? When I enable the MessageBox line, the innerHtml string is empty.
Or, of couse - if someone knows another, possible easier, way to check for the existance of a specific string inside a specific html tag, I'm all ears.
Your element returns you <a> element, not <h2>. Your <a> doesn't contain Edit Page string.
Try find your element like this to the parent element <h2> (only if class name add-new-h2 is unique, otherwise you will get the first matching one):
var element = FFDriver.Instance.FindElement(By.XPath(".//a[#class='add-new-h2']/.."));
var containsText = element.Text.Contains("Edit Page");

httphandler return into string variable

I have an httphandler that returns a string (a part description).
I'd like to use the return value in a title attribute on an image, which will be updated on a page load.
I have the following code in page_load event...
imgThumbnail.Attributes.Add("title", "~/Views/Admin/ImageRepository/ShowDescription.ashx?partno=123456&view=thumb");
I'm not sure how to get the title text to be the return value instead of just "~/Views/Admin/ImageRepository/ShowDescription.ashx?partno=123456&view=thumb".
How can I do this? This is the first time using an http handler. I have tested the handler and it does return the string I expect it to.
I think you might have to rethink how you are approaching this, your code might look like this:
string imgTitle = "Image Title"; // you need to set the value of imgTitle here.
imgThumbnail.Attributes.Add("title", imgTitle);
This might give an output like this:
<img title="Image Title" />
You probably don't want a handler for this, essentially, you could move the code from your handler to your page.
string imgTitle = GetImageTitle(partno); // you need to set the value of imgTitle here.
imgThumbnail.Attributes.Add("title", imgTitle);
public string GetImageTitle(string partno)
{
// put code to return image title here;
}
PS are you sure you don't want the alt attribute, <img> doesn't have a title attribute.

Create edit link to document in sharepoint

I have a document library in sharepoint storing a word document.
If I click on the link to the document I get a dialog box with "you want to open this file in readonly or editmode etc" and can open it in edit mode, change it, save it directly in word an the changes are saved in the document library.
The link to the file in the document library looks like this:
<a onfocus="OnLink(this)"
href="/test/DocLib2/wordtest.docx"
onmousedown="return VerifyHref(this,event,'1','SharePoint.OpenDocuments','')"
onclick="return DispEx(this,event,'TRUE','FALSE','FALSE',
'SharePoint.OpenDocuments.3','1', 'SharePoint.OpenDocuments',
'','','','1','0','0','0x7fffffffffffffff','','')"
>wordtest</a>
How do I create this link in my own web part where I have the name of the file and document library? Without just copying the above code, that wouldn't be a good idea...
Is there some "official" method to achieve this?
Unfortunately it doesn't seem like there is a better option. But at least you can sort of figure out what the function definition is. The DispEx function is defined in the core.js file (but it's easier to read in the core.debug.js). Both are in 14\Templates\Layouts\1033 directory.
Here is the function definition:
function DispEx(ele, objEvent, fTransformServiceOn, fShouldTransformExtension,
fTransformHandleUrl, strHtmlTrProgId, iDefaultItemOpen, strProgId, strHtmlType,
strServerFileRedirect, strCheckoutUser, strCurrentUser, strRequireCheckout,
strCheckedoutTolocal, strPermmask)
Here is my guess on what they mean. Please feel free to add comments to correct any mistakes or omissions:
ele - [obj] the element
objEvent - [obj] the event object
fTransformServiceOn - [bool] (unknown functionality) defaults to True
fShouldTransformExtension - [bool] (unknown functionality) defaults to False
fTransformHandleUrl - [bool] (unknown functionality) defaults to False
strHtmlTrProgId - [string] name of the ActiveXControl to try to load defaults to SharePoint.OpenDocuments.3
iDefaultItemOpen - [int] indicator of default to Edit or Read defaults to 1
strProgId - [string] name of the ActiveX Control
strHtmlType [string] (unknown functionality) defaults to empty
strServerFileRedirect - [string] (unknown functionality)
strCheckoutUser [string] the ID of the user who has checked out the document
strCurrentUser - [string] the ID of the current user
strRequireCheckout - [string] indicator whether to force a checkout
strCheckedoutTolocal - [string] indicator of whether to use the Local Drafts folder
strPermmask - [string] permissions mask for the current user defaults to 0x7fffffffffffffff
There are clearly some inconsistencies in terms of using strings and integers to represent boolean values. It's also strange that your code has 17 parameters but I can only find a function definition with 15 parameters, so I'm not sure what those last two empty strings are for. Some of that is the nature of JavaScript, but it also just looks sloppy on the part of Microsoft.
This doesn't really answer the question, hopefully it helps you or someone else.
Chad Schroeder made a blog post on how to construct the javascript function call in C#. Taking into account a couple of settings, like force checkout and open in browser or client for instance.
private string GetFileViewScript(SPFile file)
{
string text = SPUtility.MapToControl(SPContext.Current.Web, file.Name, string.Empty);
string text2 = (file.Item.ParentList.DefaultItemOpen == DefaultItemOpen.Browser) ? "1" : "0";
SPFieldLookupValue sPFieldLookupValue = file.Item["CheckedOutUserId"] as SPFieldLookupValue;
string scriptLiteralToEncode = (sPFieldLookupValue == null) ? string.Empty : sPFieldLookupValue.LookupValue;
string text3 = (SPContext.Current.Web.CurrentUser != null) ? SPContext.Current.Web.CurrentUser.ID.ToString(CultureInfo.InvariantCulture) : string.Empty;
string text4 = file.Item.ParentList.ForceCheckout ? "1" : "0";
return string.Format(CultureInfo.InvariantCulture, "return DispEx(this,event,'{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}')", new object[]
{
"TRUE",
"FALSE",
"FALSE",
text,
text2,
text,
string.Empty,
string.Empty,
SPHttpUtility.EcmaScriptStringLiteralEncode(scriptLiteralToEncode),
text3,
text4,
(string)file.Item["IsCheckedoutToLocal"],
(string)file.Item["PermMask"]
});
}
Using DispEx in a link to a SharePoint document
I end up with adding this code
return DispEx(this,event,'TRUE','FALSE','FALSE',
'SharePoint.OpenDocuments.3','1', 'SharePoint.OpenDocuments','','','',
'1','0','0','0x7fffffffffffffff','','')
to my link tag because I wasn't able to find a better solution.
If there is any, please let me know.
DispEx does not work in Chrome unless the link is within a div that contains the document type in an attribute called app:
<div class="ms-vb itx" ctxname="ctx19" id="2" app="ms-word">
<a onfocus="OnLink(this)"
href="/test/DocLib2/wordtest.docx"
onmousedown="return VerifyHref(this,event,'1','SharePoint.OpenDocuments','')"
onclick="return DispEx(this,event,'TRUE','FALSE','FALSE',
'SharePoint.OpenDocuments.3','1', 'SharePoint.OpenDocuments',
'','','','1','0','0','0x7fffffffffffffff','','')">wordtest</a>
<span class="ms-newdocument-iconouter">
<img class="ms-newdocument-icon" src="/_layouts/15/images/spcommon.png?rev=23" alt="new" title="new">
</span>
</div>
Either you need to wrap it in such a div, and be sure to insert the correct application that will open the file, or make your own list by looking at the file extension:
$('.test_links').click(function(e) {
e.preventDefault();
if (!!window.chrome) {
var extenstion = this.href.substr(this.href.lastIndexOf('.') + 1);
var prefix = '';
switch (extenstion) {
case 'doc':
case 'docx':
prefix = 'ms-word:ofv|u|';
break;
case 'xls':
case 'xlsx':
prefix = 'ms-excel:ofv|u|';
break;
}
window.location.href = prefix + this.href;
} else {
DispEx(this, e, 'TRUE', 'FALSE', 'FALSE', 'SharePoint.OpenDocuments.3', '0', 'SharePoint.OpenDocuments', '', '', '', _spPageContextInfo.userId + '', '0', '0', '0x7fffffffffffffff');
}
});
I don't remember if there is an official ability to do it with JavaScript COM, but you can use the ASP.NET HyperLink control to generate the similar link. For instance put in layout
<asp:HyperLink ID="EditHl" runat="server" Text="Edit document"/>
and in code-behind something like
EditHl.Attributes["attribute name"] = "attribute value";
just use the same values from OOTB link, but change
/test/DocLib2/wordtest.docx
to URL of your document.

Regular Expression to avoid HTML tags and empty values

I have applied a textbox click validation and wanted to avoid any html tags in text box also the simple < (open tag) and >(close tag). The below code is working for but i want to add additional validations also for empty strings and other tags in html. Can some one please help modify the regex for the requirement.
function htmlValidation()
{
var re = /(<([^>]+)>)/gi;
if (document.getElementById(’<%=TextBox2.ClientID%>’).value.match(re)){ document.getElementById(’<%=TextBox2.ClientID%>’).value = “”;
return false;
}
return true;
}
Corrected Code above
In my opinion, I believe you'll have a good hard work if you want to validate such things.
Instead of preventing HTML content in a text box, other solution could be just html entity encode Text property, so <p>a</p> would be converted to >p<a>p<.
Result of that is you're going to render the HTML "as text" instead of getting it interpreted by Web browser.
Check this MSDN article:
http://msdn.microsoft.com/en-us/library/73z22y6h(v=vs.110).aspx
$("#<%= btnAdd.ClientID %>").click(function () {
var txt = $("#<%= txtBox1.ClientID %>");
var svc = $(txt).val(); //Its Let you know the textbox's value
var re = /(<([^>]+)>)/gi;
if(txt.val()!=""){
if (!txt.val().match(re)) {
//my Operations
//goes here
});
return false;
}
else {
alert("Invalid Content");
}
}
else {
alert("Blank value selected");
}
I have used Jquery function to check for regular expresion. This question is a linked question with
Using Jquery to add items in Listbox from Textbox
Now i can mark this as my final answer.

How do I check for a URL's top-level domain in ASP.NET/C#?

Let's say "www.mysite.fr/home" is the URL ..Now how do I fetch "fr" out of this ? JUST "fr"
actually what I am trying to do is change masterpages at runtime after detecting a visitor's country..Yes I can use the countryCode variable which is there in some other class but thot may be I can do it like this only..just wanted to try..logic basically is:-
if(its "fr")
{
//apply masterpage 1
}
if(its "in")
{
//apply masterpage 2
}
Is it possible ? What will be the right way anyway ? Making that class that contains CountryCode variable as a utility class and using the variable from there in my new class
OR
fetch this value "fr" or "in" off the URL ?? How do I do this ? Is it possible?
if (Request.Url.Host.ToLower().EndsWith(".fr"))
{
...
}
There is no method to be used directly. Maybe you can write an extension yourself:
public static string GetDomainTypeName(this Uri uri)
{
if (!uri.HostNameType.Equals(UriHostNameType.Dns) || uri.IsLoopback)
return string.Empty; // or throw an exception
return uri.Host.Split('.').Last();
}
And be careful about the word case! WWW.GOOGLE.FR may make your code incorrect.
I think this should be possible. You can use regex to get the code (fr, in etc.) and change the master page but you'll have to do this before the page_load. By the time asp.net reaches page_load the master page is already set (if I remember correctly). You'll need to handle the PreInit event and set the master page you want to set. So basically do all the regex and master page changing in the PreInit event and you're good to go :)
Here's a description of PreInit (Source: http://msdn.microsoft.com/en-us/library/ms178472.aspx):
PreInit
Raised after the start stage is complete and before the initialization stage begins.
Use this event for the following:
•Check the IsPostBack property to determine whether this is the first time the page is being processed. The IsCallback and IsCrossPagePostBack properties have also been set at this time.
•Create or re-create dynamic controls.
•Set a master page dynamically.
•Set the Theme property dynamically.
•Read or set profile property values.
For the Current Scenario you can try with the following snippet:
string url = "www.mysite.fr/home";
int nStrLength = url.Length;
int nDot = url.LastIndexOf(".")+1;
int nRestStringLngth = nStrLength - nDot;
string baseDomain = url.Substring(nDot, nRestStringLngth);
int nSlash = baseDomain.IndexOf("/");
baseDomain = baseDomain.Substring(0, nSlash);
Console.WriteLine(baseDomain);
In france it work with EndsWith .fr but in England you have .co.uk or in austria you have .co.at and also .at
You can use the following nuget package. (Install-Package Nager.PublicSuffix)
https://www.nuget.org/packages/Nager.PublicSuffix/
Example:
var domainParser = new DomainParser();
var data = await domainParser.LoadDataAsync();
var tldRules = domainParser.ParseRules(data);
domainParser.AddRules(tldRules);
var domainName = domainParser.Get("sub.test.co.uk");
//domainName.Domain = "test";
//domainName.Hostname = "sub.test.co.uk";
//domainName.RegistrableDomain = "test.co.uk";
//domainName.SubDomain = "sub";
//domainName.TLD = "co.uk";

Categories

Resources