Wednesday 11 June 2014

Customize Page layout in Edit Mode

sometimes you want to hide certain aesthetic elements on your page when it's in Edit mode, for example i have an absolutely transparent grid that really clutters up my interface and has nothing to do with content, so i want to hide it when an editor is modify the page.

also i have two panels that are floated next to each other creating more clutter, and I'd like them to appear vertically in edit mode, well what i can do is use a Publishing web control EditModePanel To create an edit mode only script that would make my changes for me.

<PublishingWebControls:EditModePanel runat="server" >
    <script type="text/javascript">
 
            document.getElementById("grid").style.display = "none";
            document.getElementById("ctp-leftPanel").style.float ="none";
            document.getElementById("ctp-leftPanel").style.width ="100%";
            document.getElementById("ctp-rightPanel").style.float ="none";
            document.getElementById("ctp-rightPanel").style.width ="100%";
    </script>
</PublishingWebControls:EditModePanel>

Friday 6 June 2014

Hide Site Actions for visitors

Don't just hide the Site actions button, hide it's container too

this is a two step process
security trim the ribbon to keep the meat from rendering on the client msdn
hide the container using css

so first of i'm using randy's starter master page, find the following comment
<!-- =====  Begin Ribbon

with that found inthe second div make the following adjustment,

<!-- =====  Begin Ribbon ===================================== -->
<div id="s4-ribbonrow" class="s4-pr s4-ribbonrowhidetitle"><Sharepoint:SPSecurityTrimmedControl ID="spTrimRibbon" PermissionMode="All" PermissionContext="CurrentSite"  runat="server" Permissions="ManageWeb,AddListItems">
<div id="s4-ribboncont">

Remember it's essential that you put the security trimming between the s4-ribbonrow and s4-ribboncon divs, otherwise you'll end up this half screen rendering situation and it wont make any sense.

anwyay since we opened the Sharepoint:SPSecurityTrimmedControl  tag we now need to close it. in the master page scroll down to comment

<!-- =====  End Ribbon and other Top Content

and above the first div close the  Sharepoint:SPSecurityTrimmedControl tag, it should look something like this

<!-- top web part panel -->
<div id="WebPartAdderUpdatePanelContainer">
<asp:UpdatePanel
ID="WebPartAdderUpdatePanel"
UpdateMode="Conditional"
ChildrenAsTriggers="false"
runat="server">
<ContentTemplate>
<WebPartPages:WebPartAdder ID="WebPartAdder" runat="server" />
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="WebPartAdder" />
</Triggers>
</asp:UpdatePanel>
</div>
</Sharepoint:SPSecurityTrimmedControl></div>

<!-- =====  End Ribbon and other Top Content ====================== -->

now with just that step you should get something like this for our visitors  

almost there, we just need to remove that blue place holder, luckily it's pretty straight forward with css. If we inspect the top rectangle where the site actions resides we'll notice that it's empty, so if we're lucky enough to be supporting Ie9+ then we can use the css :empty selector and set it's display to none. otherwise you can use jquery or javascript, but that'll mean it'll be there on render and then disappear later which isn't too great.

html body form div#s4-ribbonrow:empty {
display:none;
}

one thing to note is that the :empty selector doesn't handle whitespace so you have to make sure that your security trim tags are flush with the opening and closing div tags

<div id="s4-ribbonrow"><Sharepoint:SPSecurityTrimmedControl ...
stuff to trim
</Sharepoint:SPSecurityTrimmedControl></div>

Thursday 5 June 2014

Why use XSLT

XSTL can replace most web parts; if your web part renders list items odds are you probably should have used an XSLT transformation, but instead you made a foreach loop and rendered it on screen, which is greate until you need to implement a "No Code" Solution. I double quote that because by no code we just mean front end code, so basically a lot of XSLT, CSS and JavaScript. To get started let's create a content type through SharePoint Designer.

In the above I created a Picture library and added some custom columns:
  • Hex Code
  • Parent Id
  • Grid Location
Now the only column we'll use for this walk through will be the HexCode, the other two are actually for a different transformation. One of the key benefits of using xslt transformations over web parts is the trust level, since all your transformation is doing is just making your list look different on the client side, it will never mess up your farm which is why you probably have the restriction of a "NO CODE" solution in the first place.

once we have our content type create, lets instantiate a list with this content type, you can accomplish this through the webUI in the list settings. Once that's done add the list to a web part zone,

with your list added you should see something like this  

not very exciting, but we'll change that soon enough; now what we are actually looking at is an XSLT, and a very complicated one created by Microsoft, ours is going to be much simpler, but before we make it lets take a look at the raw XML that sits behind this. To accomplish that we need to create a simple xslt to strip everything out; you could bing it, but hell just use the one below.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xmp>
<xsl:copy-of select="*"/>
</xmp>
</xsl:template>
</xsl:stylesheet>

The question is where the hell do i put this? and being a consultant I'll give you the Out-of-the-Box response "We'll that depends" (smug look on my face)... seriously though it depends on your users, do you want just anyone to be able to open it up? in that case toss it into a Transformations library much like you would with CSS or JavaScript, but if you want to obstruct it a little bit create a Transformations folder in you _catalogs folder through SharePoint Designer.  

with that complete go back to your webpart and hit edit, then under the Miscellaneous category fill in the following for the XSL Link: /_catalogs/Transformations/Clear.xslt as shown below.

now once you hit ok or apply this will strip out the standard xslt to expose the raw xml data behind it.

not very interesting but at least you get the point, we're just dealing with xml that's transformed to look like something else.

So let's talk a little about XSLT, firstly here is a great explanation of what it is. Now my one line description is: xslt is an instruction set to transform xml into something else, usually html.

so lets get started, first we'll set up our xslt stylesheet

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ddwrt2="urn:frontpage:internal">
<xsl:template match="/" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime">
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row" />

  </xsl:template>
</xsl:stylesheet>

Think of this as our base starting point, for SharePoint, take a look at the highlighted line, we set that up so that when we iterate over our xml items we can just refer to it with the $Rows variable as show below

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ddwrt2="urn:frontpage:internal">
<xsl:template match="/" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime">
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row" />
  <html>
    <head>
  <link rel="stylesheet" type="text/css" href="/Style%20Library/ctp/TopPageNavigation/ctp.TopPageNavigation.css"/>    
    </head>
    
    <body>
      <ul id="ctp-topNav">
  <xsl:for-each select="$Rows">
  <xsl:call-template name="ListItem" />  
  </xsl:for-each>
      </ul>
  </body>
    </html>
  </xsl:template>
 
  <xsl:template name="ListItem">
  <xsl:if test="@ParentId = ''">
  <li data-activecolor="{@HexCode}" onmouseout="ctp.TopNav.stripColor(this);" onmouseover="ctp.TopNav.changeColor(this,'{@HexCode}');">
<a href="{@DestinationUrl}">
<span>
  <xsl:value-of select="@Title" />
  </span>
  </a>
  </li>
  </xsl:if>
  </xsl:template>
</xsl:stylesheet>


now the template concept, we'll you can think of it as function of sorts. if this doesn't make too much sense no worries, i'm going to follow this up with much more detailed explanations and examples of xslt.