Question

I've a SPRibbon custom action with the purpose of open an custom app page in a modal dialog, but I'm getting troubles for getting the current web URL, as well, set a reference for a .js with the right code for my function.

I've follow some examples, but still with no success.

this is what I've now, but like this way I retrieve the root site collection web, instead the current web.

   CommandAction="javascript:
                             var options = SP.UI.$create_DialogOptions();
                             options.url = '/_layouts/myPath/EditWebInfo.aspx',
                             options.width = 700;
                             options.height = 400;
                             SP.UI.ModalDialog.showModalDialog(options);" />

any tips?

Was it helpful?

Solution

http://msdn.microsoft.com/en-us/library/ff458385.aspx:

{SiteUrl} – The fully qualified URL to the site (Url).

The SharePoint code proves it - here's the SPCustomActionElement.ReplaceUrlTokens method:

internal static string ReplaceUrlTokens(string urlAction, SPWeb web, SPList list, SPListItem item)
    {
      if (string.IsNullOrEmpty(urlAction))
        return urlAction;
      if (item != null)
      {
        string newValue1 = item.ID.ToString((IFormatProvider) CultureInfo.InvariantCulture);
        if (list.HasExternalDataSource)
          newValue1 = ((SPItem) item)["BdcIdentity"] as string;
        urlAction = urlAction.Replace("{ItemId}", newValue1);
        urlAction = urlAction.Replace("{ItemUrl}", item.Url);
        string newValue2 = newValue1;
        if (!string.IsNullOrEmpty(item.RecurrenceID))
          newValue2 = item.RecurrenceID;
        urlAction = urlAction.Replace("{RecurrenceId}", newValue2);
      }
      if (web != null)
        urlAction = urlAction.Replace("{SiteUrl}", web.Url);
      if (list != null)
      {
        urlAction = urlAction.Replace("{ListId}", list.ID.ToString("B"));
        if (list.RootFolder != null)
          urlAction = urlAction.Replace("{ListUrlDir}", list.RootFolder.Url);
      }
      HttpContext current = HttpContext.Current;
      if (current != null && current.Request != null)
      {
        string rawUrl = current.Request.RawUrl;
        Uri contextUri = SPAlternateUrl.ContextUri;
        if (!string.IsNullOrEmpty(rawUrl) && (Uri) null != contextUri)
        {
          string keyOrValueToEncode = SPUtility.StsStartsWith(rawUrl, "/") ? contextUri.GetLeftPart(UriPartial.Authority) + rawUrl : contextUri.GetLeftPart(UriPartial.Authority) + "/" + rawUrl;
          urlAction = urlAction.Replace("{Source}", SPHttpUtility.UrlKeyValueEncode(keyOrValueToEncode));
        }
      }
      urlAction = SPUtility.GetServerRelativeUrlFromPrefixedUrl(urlAction);
      return urlAction;
    }

UPDATE: Finally I've made a test myself. Here's the definition of my custom action handler:

<CommandUIHandler
          Command="NewRibbonButtonCommand"
          CommandAction="javascript:alert('Hello, world, \'{SiteUrl}\'');" />
      </CommandUIHandlers>

And here's the result message:

--------------------------- Message from webpage

Hello, world, 'http://testportal/innersite'

--------------------------- OK

So the {SiteUrl} url token is the absolute path to the current SPWeb.

OTHER TIPS

Using {SiteUrl} token is nice, thanks to Alex Boev. Just to mention an alternative, you can use SharePoint javascript API to get the web url. In your example you want to open an application page (from layouts folder). There is a helper function for doing that getLayoutsPageUrl:

SP.Utilities.Utility.getLayoutsPageUrl('myPath/EditWebInfo.aspx')

So your CommandAction will look like this:

CommandAction="javascript:
     var options = SP.UI.$create_DialogOptions();
     options.url = SP.Utilities.Utility.getLayoutsPageUrl('myPath/EditWebInfo.aspx'),
     options.width = 700;
     options.height = 400;
     SP.UI.ModalDialog.showModalDialog(options);" />

The L_Menu_BaseUrl variable is what you are looking for. SharePoint stores the current web url in it. Have a look here:

http://vrdmn.blogspot.in/2011/08/javascript-lmenubaseurl-varaible-for.html

Also some additional info on other OOB JavaScript Objects: _spPageContextInfo.webServerRelativeUrl will also give you the current web url.

_spPageContextInfo.siteServerRelativeUrl will give you the current site collection url

These are built in JavaScript variables which are available on SharePoint pages.

http://blog.tedpattison.net/Lists/Posts/Post.aspx?ID=9

This is a less flexible and probably more difficult way to do it but its a way I know works. If someone else has a better way that works I'd go with that instead but I'm posting this here just as an example.

If you know how many folders past the current web you are going to be, you can do something like this:

//Code a little more liberal with variables, etc. for sake of demonstration
//This code assumes you are on a list form

//document.location.href = http://server/managedpath/rootweb/subweb/lists/yourList/forms/NewForm.aspx
var formFolderPath  = document.location.href.substr(0, document.location.href.lastIndexOf('/'));

//formFolderPath = http://server/managedpath/rootweb/subweb/lists/yourList/forms
var listPath = formFolderPath.substr(0, formUrl.lastIndexOf('/'));

//listPath = http://server/managedpath/rootweb/subweb/lists/yourList
var listsPath = listPath.substr(0, formUrl.lastIndexOf('/'));

//listsPath = http://server/managedpath/rootweb/subweb/lists/
var webPath = listsPath.substr(0, formUrl.lastIndexOf('/'));

//webPath = http://server/managedpath/rootweb/subweb

Again, this probably isn't the best way to do it, especially with the way I have the demo code written, but it is an option to just do string manipulation to get what you want as long as you know your starting point. The good thing about SharePoint is these paths are predictable to an extent so this is at least better than hard coding the URL value.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top