Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I've been working on a SharePoint-hosted app for SharePoint 2013. In order to "extend the reach" of the app a bit, I've included a CustomAction that will add a button to each document library's ribbon in the host web as demonstrated below.

Document library ribbon showing CustomAction with default image.

The XML being used to create this CustomAction is nothing particularly special:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction Id="4f835c73-a3ab-4671-b142-83304da0639f.LibraryDetailsCustomAction"
                RegistrationType="List"
                RegistrationId="101"
                Location="CommandUI.Ribbon"
                Sequence="10001"
                Title="Invoke &apos;LibraryDetailsCustomAction&apos; action">
    <CommandUIExtension>
      <!-- 
      Update the UI definitions below with the controls and the command actions
      that you want to enable for the custom action.
      -->
      <CommandUIDefinitions>
        <CommandUIDefinition Location="Ribbon.Library.Actions.Controls._children">
          <Button Id="Ribbon.Library.Actions.LibraryDetailsCustomActionButton"
                  Alt="Examine Library Details"
                  Sequence="100"
                  Command="Invoke_LibraryDetailsCustomActionButtonRequest"
                  LabelText="Examine Library Details"
                  TemplateAlias="o1"
                  Image32by32="_layouts/15/images/placeholder32x32.png"
                  Image16by16="_layouts/15/images/placeholder16x16.png" />
        </CommandUIDefinition>
      </CommandUIDefinitions>
      <CommandUIHandlers>
        <CommandUIHandler Command="Invoke_LibraryDetailsCustomActionButtonRequest"
                          CommandAction="~appWebUrl/Pages/LibraryDetails.aspx?ListID={ListId}"/>
      </CommandUIHandlers>
    </CommandUIExtension >
  </CustomAction>
</Elements>

Where I'm struggling, though, is with the Image32by32 and Image16by16 attributes. By default, they point to an orange dot placeholder image found in the _LAYOUTS folder. I want to use my own images (that are deployed with my app), but I can't find a way to do so.

With a SharePoint-hosted app, I don't have the option of placing elements in the _LAYOUTS area. By definition (or at least my understanding of it), I can't place/provision anything in the host web, either. The best I can do is place images and other items into the app web.

I've attempted to use the ~appWebUrl token to reference images I'm deploying into my app web, but this token isn't parsed/processed. Relative image references (such as /images/myimage.png) reference the host web rather than the app web, as well.

I don't see any way of using custom images for the Image32by32 and Image16by16 attributes short of employing something like an absolute URL to pull each image from a web-based location (e.g., http://www.myhost.com/images/myimage.png).

Am I missing something? Has anyone successfully used their own app web image resources in this sort of scenario?

share|improve this question
1  
It would seem that token processing should be possible within the Image32by32 and Image16by16 attributes based on this article from Chris Hopkins: blogs.msdn.com/b/chhopkin/archive/2012/08/20/… Even though I knew it wouldn't work, I inserted a ~site token in as the attribute value, and it appeared to successfully resolve to the host web site URL. Perhaps the new SharePoint 2013 tokens simply haven't been added yet? –  Sean McDonough Jan 17 '13 at 22:39

5 Answers 5

up vote 10 down vote accepted

Fun stuff, I was checking this site since I stopped answering SO SharePoint questions for a few years now and this was the first thing in the list, a very interesting oversight during the "host web Feature" option for CustomActions.

What a detailed investigation! Luckily I have a solution for you.

WEB STANDARDS TO THE RESCUE CHO CHOO

With Microsoft dropping browser support for IE7 in 2013 you can simply make use of data URIs for your images without worrying about lack of support.

I took the opportunity to convert both of yours below

Image32by32="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAB3RJTUUH3QEREx4BCpeuewAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAARpSURBVEjHrVZ7TNV1FD8ttrAsAtfWH7kSSTMFMunp5GVEJGrDMtfDWGWZUdbUZZrlls6E2QNrM5wKSQ0MpIhUHusKEhAgLxEJQm8JyBsl4ULZ+XTOjzu4wHW7cD07f5zvvef3/XzP+xAH3zoRDnDlwEmOaNLIs5s9tlEIuoUfIZ5F/BDxAuIgt/EAyMe+xLOJ59iwHP1Ex53nG/fOJby9AikJaKhFZprqB7s5BhB4E4IJedn4ywzz2WGW46F4nkFYFYakfag/g34LBqm7A0/7qh0OAQRcj/Cp6GrHWKoqxaH96Lts56890eztKIALFt2B9hY7t5QVIe27Eb90tiE3E8dSUVmiXhLfOgSweBpam3EiR118OFFZhBPZKCvEK09goB+XulGUh7278MVHyEnX11j68OoifpQcAwi/E20X8GcDqstwulxZBDlWlfCNhN+rUZKPo2m40Gi1o78PHS1I3MP3knMuOnWSiXAg1nr874qmUEo8drwL0xHUVfOD4qXJjrjIE61N+sa4z7AvVlmEI4dRXsQzCS8Goqcbpb8i5n0kxIpZ6P3basfaZ/lhctiCK//qN0Ms7xULZmsR4GQBOlo1EqMoPUny2DkXScX5EHZvh11qNHMAcaCrEwBigT9h6Ux0tNlRECu3rjUK3hkAaQlSz8ePqg8bzWio1wTruWjVycm4mpfGA+B/HZb7IfIxBBGW+GIhafHHbsd5s5beU7PESidiEHSz5Ds2vq61JslmsaCzHafKEf2BhicrHTGb+AFywgJvQso3+GfAjkJxPhYQopZy8OSxzdUBgOoyLbT4L4cb0Q9J2B2Ng1/jbJ31x6I8sYMXuk8IQLpT2O242KWy3Bjhg9cWI/kgdmzU4jAds6rFbJFpMSEXfbUTcbusRfvOC2qNdO9Bysvm+wjnz6lcWqATSUI1PgBmRK1AvknlP2r5HpLeidVL0NtjVdj0Bn5MVqGlmQOJQyaPmqMOWLB6OUp/MyZPGXsa+pI2MoWEpA4+fEuDISQ1GOGLrW/qcL36PGhCeQl+ycTxbGVTlmbIhkhkpBhvbIJkeoCLZK3GXJrdJ+vZhTRxhepq8KQnCk0cepsMYLvz4C60NaOmEgUmFOUqF5pQU4HvE9QPYL3l2708iaR3YmWIpC82r8G6lbD06l8SiefmI+oZhM+wjYQtwFRNwbFUWcyuhNMVKksdJB9AuBfPI9xP2LkZXR3DmjIQ173EdxtbyJitwhWhHqitwqUuXReGWGZAbiZPI7wcpi6y7hOdOFdnHHn0ay734POPjdbiPmYvEsc9PgXLfLDM24bnIPgG1fYjRIagolibnW2OjV1EpLnGfSrpa2+zk57uT6M5aDBiHjrcJevfW4WURGT9hIxUrbXQKfg5dbQp5gYtOmPboPGtpPKNLI3SmacbPM9YIKcT9sdiwDIMUH9maJ2hCS6/I1Dd2Iuwbb1RRqxNZduGoc56LQAGHShJFTEXW9bgeX/jdo9rC2BgyOLtRbrF2KTp/8dXqRT5/sExAAAAAElFTkSuQmCC"

Image16by16="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAB3RJTUUH3QEREx4agPJnlwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAAIFSURBVHjadZI/aFNRGMV/9z1T8z9pEtPW1iISq6KCDSqVQm0sBERLhw5Kh4JurZuIFDcVF0cns0iL4uJQkOjgIIIOFaRBiUMDUtBqrYlp4kuqweZd341GX1EPd/i4l3PP+b7vCPNYEDRWixggwAmRAKUyGRQSAYTAhk0gqRfFwDihdlVXv8gnKdF/msujtIbk1BAtfoT2myDMhI+iIe6/oXuHuigWWHjNkaOqXi1w9YKcm8EVtCuAC4wyL19g1tE0at94t0h+hWg7iRM8nKHzj6WGlgm6g2CIYBiPj0ezuD04XeQ/0rOHTidyfSOhDg4H4QjhLXh9zKVYfs/2GL197NonBs9RqfxNaMHrxx+w/pZVeJVB11U/FpIjFNjYgx1SCo9GeppAUKktLxGJinhcfs6iuf9NIDbMtZQaf/4Th/t5+ljm59G9Nkt2lEqcOY9hcP0SpsnsXQaGxMGzrFVsBGuV0vxFsHx3dfP8mZy/Q2wngVYVgt4+0babutG0tBmqFbIZ5adSVvz4IcZq3LvNygeSw2rE7hDFOrpSEHyHtSodXeq0dTB9wyrE20V69jJ5UQ1w5BTHx6mpFkUjfPC1JGSjZ+v7dcT+k4xNqlUuZBlMsnWbepuakA9uNqfk9Evkz3QhdJlLM5FWyrpFPsCVW/j8LOXw0VT4H6ycVovkIARRK3WRH5C6qIFnYE6KAAAAAElFTkSuQmCC"

enter image description here

share|improve this answer
    
This is awesome!!! I just verified this in my on-premises environment. Very creative, effective solution! Now if only there was a clean way to use JavaScript to get the data URIs from assets deployed in the app web... –  Danny Jessee Jan 26 '13 at 19:18
    
I agree wholeheartedly with Danny: awesome, awesome, AWESOME REPLY! I had no idea that something like this could be done! I verified this approach in my app with a deploy to Office 365 Preview, and it works like a charm! Having to Base64-encode images is a small pain, but knowing that I can deploy SharePoint-hosted apps without a dependency on an external server simply for images is tremendous. Thank you for the incredibly clever approach (and for encoding my images, too)! –  Sean McDonough Jan 27 '13 at 15:23
    
Absolutely great solution! Thanks for sharing :) Once again SharePoint failed to knock us off :) –  Andrey Markeev Jun 23 '13 at 20:54
1  
I like the WEB STANDARDS TO THE RESCUE CHO CHOO part :-) –  Dennis G Nov 8 '13 at 10:44

I didn't really expect anyone to "chase this down" for me, so I spent some time doing a lot of digging on my own. The short answer (as of January 2013) is "no" - there doesn't appear to be any way to leverage tokens like ~appWebUrl in the Image32by32 and Image16by16 attributes. The way that the image attributes are processed is inherently different than the way the CommandAction attribute is processed.

I documented my exploration in a blog post here:

http://sharepointinterface.com/2013/01/22/custom-ribbon-button-image-limitations-with-sharepoint-2013-apps/

It goes into all the nitty-gritty detail of what's happening behind the scenes, as well as the work-around I ended up using.

share|improve this answer

If your SP app has a remote web in the solution, you can store the image in you remote app and use the token ~remoteAppUrl to correctly resolve the URL to that image.

For some reason MS wired up ~remoteAppUrl correctly but did not do the same for ~appWebUrl. Hopefully they will fix that in the future.

share|improve this answer
    
Thanks for the reply, Jamie! This information is definitely good to know for autohosted and provider-hosted apps, and I wasn't aware that there were differences in processing for those apps vs. SharePoint-hosted apps. –  Sean McDonough Jan 27 '13 at 15:17

put the images in the images folder in the VS 2012 project. Then refer to the path like this

Image32by32="Images\audiencetweets32.jpg" Image16by16="Images\audiencetweets16.jpg" />

also replace the appicon file with your own and thats how you get your icon to show up in the store/catalog

share|improve this answer
    
Thanks, Bill, but unfortunately that doesn't work. Using relative references like Images\audiencetweets32.jpg will result in links resolving to the host web rather than the app web. That's the behavior I'd expect given that the custom action is being shown in the host web rather than the app web. –  Sean McDonough Jan 17 '13 at 21:31

Please use "YourAppName/Images/Image32by32.png". You can check "YourAppName" by right click on the AppManifest.

Hope this help!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.