3

I've been trying for quite a few hours to customize the thumbnail view on a picture library in SharePoint 2013 without luck.

What I want to do is add the date the picture was taken underneath the title of the image. So that it displays both when the thumbnail view is collapsed, and when it's moused over.

I've tried to google this alot, and tried both jQuery solutions and editing the vwstyles.xml and vwstyles.xsl files. Doing iisreset everytime I edit something, but without any luck.

It feels like the class names and id's in the xml and xsl files aren't present in the actual page, and the other way around.

So I was wondering if anyone in here had done the same earlier, because I'm running out of ideas on where to edit these files to make the changes appear on the page.

I made a new ViewStyle in the xml file (copied from the "ViewStylePicLibDetailsName" style) and copied the same ID in the xsl file and gave both new ID's and a new name for my ViewStyle. That seems to work well, but none of the changes I make appear on the page.

Here's the ViewStyle in my vwstyles.xml file:

<ViewStyle ID="21" DisplayName="CustomThumbnail" BaseType="1" Type="109" Preview="_layouts/15/images/prvpicl.gif" Description="$Resources:core,ViewStylePicLibDetailsDesc;">
    <ViewBody>
      <Switch>
        <Expr>
          <IfEqual>
            <Expr1>
              <LookupColumn Name="FSObjType"/>
            </Expr1>
            <Expr2>0</Expr2>
            <Then>
              <Field Name="EncodedAbsUrl"/>
            </Then>
            <Else>
              <Field Name="ServerUrl" URLEncodeAsURL="TRUE"/>
            </Else>
          </IfEqual>
        </Expr>
        <Case Value="">
          <HTML><![CDATA[<tr valign="top"]]></HTML>
        </Case>
        <Default>
          <HTML>
            <![CDATA[
<Script>
fNewItem = false;
]]>
          </HTML>
          <IfNew Name="Created_x0020_Date">
            <HTML><![CDATA[fNewItem = true;]]></HTML>
          </IfNew>
          <HTML>
            <![CDATA[
InsertItem(
]]>
          </HTML>
          <ScriptQuote>
            <IfEqual>
              <Expr1>
                <LookupColumn Name="FSObjType"/>
              </Expr1>
              <Expr2>0</Expr2>
              <Then>
                <Field Name="EncodedAbsUrl"/>
              </Then>
              <Else>
                <Field Name="ServerUrl" URLEncodeAsURL="TRUE" />
              </Else>
            </IfEqual>
          </ScriptQuote>
          <HTML>
            <![CDATA[,
"]]>
          </HTML>
          <Column Name="ID"/>
          <HTML>
            <![CDATA[",
]]>
          </HTML>
          <ScriptQuote>
            <UrlBaseName>
              <LookupColumn Name="FileLeafRef"/>
            </UrlBaseName>
          </ScriptQuote>
          <HTML>
            <![CDATA[,
]]>
          </HTML>
          <ScriptQuote>
            <GetFileExtension>
              <LookupColumn Name="FileLeafRef"/>
            </GetFileExtension>
          </ScriptQuote>
          <HTML>
            <![CDATA[, 
"]]>
          </HTML>
          <Column Name="Created_x0020_Date"/>
          <HTML>
            <![CDATA[",
]]>
          </HTML>
          <Column Name="ImageWidth"/>
          <HTML>
            <![CDATA[",
"]]>
          </HTML>
          <Column Name="ImageHeight"/>
          <HTML>
            <![CDATA[",
]]>
          </HTML>
          <ScriptQuote>
            <Column Name="Title" />
          </ScriptQuote>
          <HTML>
            <![CDATA[,
]]>
          </HTML>
          <ScriptQuote>
            <Column Name="Description" />
          </ScriptQuote>
          <HTML>
            <![CDATA[,
]]>
          </HTML>
          <LookupColumn Name="FSObjType"/>
          <HTML>
            <![CDATA[, 
]]>
          </HTML>
          <ScriptQuote>
            <MapToIcon>
              <Column Name="HTML_x0020_File_x0020_Type"/>
              <HTML>|</HTML>
              <Column Name="File_x0020_Type"/>
            </MapToIcon>
          </ScriptQuote>
          <HTML>
            <![CDATA[,
fNewItem);
</Script>
<tr valign="top" id=row]]>
          </HTML>
          <Column Name="ID"/>
        </Default>
      </Switch>
      <HTML><![CDATA[>]]></HTML>
      <Fields>
        <HTML><![CDATA[<td Class="]]></HTML>
        <FieldSwitch>
          <Expr>
            <Property Select="ClassInfo"/>
          </Expr>
          <Case Value="Menu">
            <HTML><![CDATA[ms-vb-title" onmouseover="OnChildItem(this)" height="100%]]></HTML>
          </Case>
          <Case Value="Icon">ms-vb-icon</Case>
          <Default>
            <FieldSwitch>
              <Expr>
                <Property Select="Type"/>
                <PresenceEnabled/>
              </Expr>
              <Case Value="UserTRUE">ms-vb-user</Case>
              <Case Value="UserMultiTRUE">ms-vb-user</Case>
              <Default>ms-vb2</Default>
            </FieldSwitch>
          </Default>
        </FieldSwitch>
        <HTML><![CDATA[">]]></HTML>
        <Field/>
        <HTML><![CDATA[</td>]]></HTML>
      </Fields>
      <HTML><![CDATA[</tr>]]></HTML>
    </ViewBody>
    <ViewFooter>
      <HTML>
        <![CDATA[
<?IMPORT namespace='stsplrc' implementation='#default#vml'?>
<stsplrc:rect ID=webImageSyncer style="display:none;width:100;height:100"></stsplrc:rect>
<span ID=selectionCacheMgr class=userdata style="display:none"></span>
<span ID=DebugBox class=ms-selectedtitle style="display:none"></span>
]]>
      </HTML>
      <HTML><![CDATA[</table></td></tr></table>]]></HTML>
      <HTML>
        <![CDATA[
<Script>
fImglibDefautlView = true;
strSeperator = "&";
if (ctx.displayFormUrl.indexOf("?") == -1)
            strSeperator = "?";
urlCmdForDisplay = ctx.displayFormUrl + strSeperator + "RootFolder=]]>
      </HTML>
      <GetVar Name="RootFolder" URLEncode="TRUE"/>
      <HTML>
        <![CDATA[";
ViewHeaderScript(]]>
      </HTML>
      <ScriptQuote>
        <GetVar Name="ViewStyle" HTMLEncode="TRUE"/>
      </ScriptQuote>
      <HTML>
        <![CDATA[,
]]>
      </HTML>
      <ListProperty Select="WebImageWidth"/>
      <HTML>
        <![CDATA[,
]]>
      </HTML>
      <ListProperty Select="WebImageHeight"/>
      <HTML>
        <![CDATA[,
]]>
      </HTML>
      <ListProperty Select="ThumbnailSize"/>
      <HTML>
        <![CDATA[);
currentPicture = ]]>
      </HTML>
      <IfEqual>
        <Expr1>
          <GetVar Name="picID"/>
        </Expr1>
        <Expr2></Expr2>
        <Then>0</Then>
        <Else>
          <GetVar Name="picID"/>
        </Else>
      </IfEqual>
      <HTML>
        <![CDATA[;
ViewFooterScript();
</Script>]]>
      </HTML>
    </ViewFooter>
    <GroupByHeader>
      <HTML><![CDATA[<tbody id="titl]]></HTML>
      <GetVar Name="GroupByLevelString"/>
      <HTML><![CDATA[" groupString="]]></HTML>
      <GetVar Name="GroupByValueString"/>
      <HTML><![CDATA["><tr><td colspan="100"]]></HTML>
      <Switch>
        <Expr>
          <GetVar Name="GroupByIndent"/>
        </Expr>
        <Case Value="0">
          <HTML><![CDATA[ class="ms-gb" ]]></HTML>
        </Case>
        <Default>
          <HTML><![CDATA[ class="ms-gb2" ]]></HTML>
        </Default>
      </Switch>
      <HTML><![CDATA[ nowrap="nowrap"><img src="/_layouts/15/images/blank.gif?rev=23" alt="" height="1" width="]]></HTML>
      <GetVar Name="GroupByIndent"/>
      <HTML><![CDATA[" /><a href="javascript:" onclick="javascript:ExpCollGroup(']]></HTML>
      <GetVar Name="GroupByLevelString"/>
      <HTML><![CDATA[','img_]]></HTML>
      <GetVar Name="GroupByLevelString"/>
      <HTML><![CDATA[');return false;"><img id="img_]]></HTML>
      <GetVar Name="GroupByLevelString"/>
      <HTML><![CDATA[" src="/_layouts/15/images/minus.gif?rev=23" alt="]]></HTML>
      <HTML>$Resources:core,groupExpColl;</HTML>
      <HTML><![CDATA[" border="0" /></a>&#160;]]></HTML>
      <HTML><![CDATA[<a href="javascript:" onclick="javascript:ExpCollGroup(']]></HTML>
      <GetVar Name="GroupByLevelString"/>
      <HTML><![CDATA[','img_]]></HTML>
      <GetVar Name="GroupByLevelString"/>
      <HTML><![CDATA[');return false;">]]></HTML>
      <GetVar Name="GroupByField" HTMLEncode="TRUE" />
      <HTML><![CDATA[</a> :&#160;]]></HTML>
      <GetVar Name="GroupByValue"/>
      <HTML><![CDATA[</td></tr></tbody>]]></HTML>
      <HTML>
        <![CDATA[
<script type="text/javascript">
    fIsInGroupByView = true;
</script>]]>
      </HTML>
    </GroupByHeader>
    <ViewFields>
      <FieldRef Name="SelectedFlag"/>
      <FieldRef Name="DocIcon"/>
      <FieldRef Name="NameOrTitle"/>
      <FieldRef Name="ImageSize"/>
      <FieldRef Name="FileSizeDisplay"/>
      <FieldRef Name="RequiredField" Explicit="TRUE"/>
    </ViewFields>
    <Script>
      g_RequiredFields[6] = new Array;
      g_RequiredFields[6]["RequiredField"] = true;
    </Script>
  </ViewStyle>
</ViewStyles>

And here's the parts of the xsl file I've tried to edit, I've added some

tags to see if they appear in the table on the page, but they never do.

<xsl:template match="View[ViewStyle/@ID='21']" mode="RenderView">
    <!-- total first -->
    <xsl:if test="Aggregations[not(@Value='Off')]/FieldRef">
      <tr>
        <xsl:if test="$InlineEdit">
          <td width="1%"/>
        </xsl:if >
        <xsl:apply-templates mode="aggregate" select="ViewFields/FieldRef[not(@Explicit='TRUE')]">
          <xsl:with-param name="Rows" select="$AllRows"/>
          <xsl:with-param name="GroupLevel" select="0"/>
        </xsl:apply-templates>
      </tr>
    </xsl:if>
    <xsl:variable name="Fields" select="ViewFields/FieldRef[not(@Explicit='TRUE')]"/>

    <xsl:variable name="Groups" select="Query/GroupBy/FieldRef"/>
    <xsl:variable name="Collapse" select="Query/GroupBy[@Collapse='TRUE']"/>
    <xsl:variable name="GroupCount" select="count($Groups)"/>
    <xsl:for-each select="$AllRows">
      <xsl:variable name="thisNode" select="."/>
      <xsl:variable name="Position" select="position()" />
      <!-- work on every other row -->
      <!-- this code will pick up the -->
      <xsl:if test="$Position mod 2 = 1">
        <!-- start of new row -->
        <tr>
          <td valign="top" width="49%" class="ms-stylebox">
            <xsl:apply-templates mode="Item" select="$thisNode">
              <xsl:with-param name="Fields" select="$Fields"/>
              <xsl:with-param name="Collapse" select="$Collapse"/>
              <xsl:with-param name="Position" select="position()"/>
              <xsl:with-param name="Last" select="last()"/>
            </xsl:apply-templates>
          </td>
          <td width="1.5%">
            <xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text>
          </td>
          <xsl:choose>
            <xsl:when test="$Position != last()">
              <td valign="top" width="49%" class="ms-stylebox">
                <xsl:apply-templates mode="Item" select="$AllRows[$Position + 1]">
                  <xsl:with-param name="Fields" select="$Fields"/>
                  <xsl:with-param name="Collapse" select="$Collapse"/>
                  <xsl:with-param name="Position" select="position()"/>
                  <xsl:with-param name="Last" select="last()"/>
                </xsl:apply-templates>
                <p>test</p>
              </td>
            </xsl:when>
            <xsl:otherwise>
              <td valign="top" width="49%">
                <xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text>
                <p>test otherwise</p>
              </td>
            </xsl:otherwise>
          </xsl:choose>
        </tr>
        <tr>
          <td>
            <xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text>
            <p>test end</p>
          </td>
        </tr>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

And the last bit in the xsl file:

<xsl:template mode="Item" match="Row[../../@ViewStyleID='21']">
    <xsl:param name="Fields" select="."/>
    <xsl:param name="Collapse" select="."/>
    <xsl:param name="Position" select="1"/>
    <xsl:param name="Last" select="1"/>
    <xsl:variable name="thisNode" select="."/>
    <xsl:variable name="ID">
      <xsl:call-template name="ResolveId"><xsl:with-param name="thisNode" select ="."/></xsl:call-template>
    </xsl:variable>
    <xsl:variable name="FSObjType">
      <xsl:choose>
        <xsl:when test="$EntityName != ''">0</xsl:when>
        <xsl:otherwise><xsl:value-of select="./@FSObjType"/></xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:variable name="targetUrl">
      <xsl:choose>
        <!-- this is a URL from the links list, so we should dump in the displayform url instead -->
        <xsl:when test="substring(@FileRef, string-length(@FileRef) - 4) = '_.000'">
          <xsl:value-of select="$FORM_DISPLAY"/>&amp;ID=<xsl:value-of select="$ID"/>
        </xsl:when>
        <!-- regular files just use the file ref -->
        <xsl:otherwise>
          <xsl:value-of select="@FileRef"/>

        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <table border="0" width="100%" cellspacing="0">
        <tr class="ms-styleheader">
          <td class="ms-detailhdricon" width="10%">
            <xsl:choose>
              <xsl:when test="@FSObjType='1'">
                <xsl:variable name="alttext">
                  <xsl:value-of select="../@listformtitle_folder"/>: <xsl:value-of select="@FileLeafRef"/>
                </xsl:variable>
                <!-- This is a folder -->
                <xsl:variable name="mapico" select="$thisNode/@HTML_x0020_File_x0020_Type.File_x0020_Type.mapico"/>
                <xsl:variable name="folderIconPath">
                  <xsl:call-template name="GetFolderIconSourcePath">
                    <xsl:with-param name="thisNode" select="$thisNode"/>
                  </xsl:call-template>
                </xsl:variable>
                <xsl:choose>
                  <xsl:when test="$RecursiveView='1'">
                    <img border="0" alt="{$alttext}" src="{$folderIconPath}" />
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:variable name="FolderCTID">
                      <xsl:value-of select="$PagePath" />?RootFolder=<xsl:value-of select="@FileRef.urlencode" />&amp;FolderCTID=<xsl:value-of select="@ContentTypeId" />
                    </xsl:variable>
                    <a tabindex="-1" href="{$FolderCTID}" onclick="javascript:EnterFolder(&quot;{$FolderCTID}&quot;);javascript:return false;">
                      <img border="0" alt="{$alttext}" title="{$alttext}" src="{$folderIconPath}" />
                    </a>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:when>
              <xsl:otherwise>
                <!-- Not a Folder -->
                <xsl:choose>
                  <xsl:when test="not (@CheckoutUser.id) or @CheckoutUser.id =''">
                    <img border="0" alt="{@FileLeafRef}" title="{@FileLeafRef}" src="/_layouts/15/images/{@HTML_x0020_File_x0020_Type.File_x0020_Type.mapico}?rev=23" />
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:variable name="alttext">
                      <xsl:value-of select="@FileLeafRef"/>&#10;<xsl:value-of select="../@managecheckedoutfiles_header_checkedoutby"/>: <xsl:value-of select="@CheckoutUser.title"/>
                    </xsl:variable>
                    <img border="0" alt="{$alttext}" title="{$alttext}" src="/_layouts/15/images/{@HTML_x0020_File_x0020_Type.File_x0020_Type.mapico}?rev=23" />
                    <img src="/_layouts/15/images/checkoutoverlay.gif?rev=23" class="ms-vb-icon-overlay" alt="{$alttext}" title="{$alttext}" />
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:otherwise>
            </xsl:choose>
          </td>
          <td colspan="2" class="ms-detailhdrmid" width="80%">
            <a onfocus="OnLink(this)" href="{$targetUrl}" onmousedown="return VerifyHref(this,event,'{$XmlDefinition/List/@DefaultItemOpen}','{@HTML_x0020_File_x0020_Type.File_x0020_Type.mapcon}','')"
            onclick="return DispEx(this,event,'','','','','{$XmlDefinition/List/@DefaultItemOpen}','{@HTML_x0020_File_x0020_Type.File_x0020_Type.mapcon}','{@HTML_x0020_File_x0020_Type}','','{@CheckoutUser.id}','{$Userid}','{$XmlDefinition/List/@ForceCheckout}','{@IsCheckedoutToLocal}','{@PermMask}')">
              <xsl:value-of select="@FileLeafRef.Name"/>
            </a>
            <xsl:if test="@Created_x0020_Date.ifnew='1'">
              <xsl:call-template name="NewGif">
                <xsl:with-param name="thisNode" select="$thisNode"/>
              </xsl:call-template>
            </xsl:if>
          </td>
          <td align="right" class="ms-detailhdredit" width="10%">
            <xsl:call-template name="FieldRef_Edit_body">
              <xsl:with-param name="thisNode" select="."/>
            </xsl:call-template>
          </td>
        </tr>
        <xsl:for-each select="$Fields[not(@Name='Edit') and not(@Name='LinkFilenameNoMenu') and not(@Name='DocIcon')]">
          <tr>
            <td><xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text></td>
            <td class="ms-detailbtitle" width="25%">
              <span class="ms-stylelabel">
                <xsl:value-of select="@DisplayName"/>
              </span>
            </td>
            <td class="ms-stylebody" width="75%">
              <xsl:apply-templates select="." mode="PrintFieldWithDisplayFormLink">
                <xsl:with-param name="thisNode" select="$thisNode"/>
              </xsl:apply-templates>
            </td>
            <td><xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text></td>
          </tr>
        </xsl:for-each>
      </table>
  </xsl:template>
1

From personal experience: Editting .xsl (like vwstyles.xsl or fldtypes.xsl) files of SharePoint requires a recycle of the app pool. Only when you recycle the app pool will SharePoint load the files again from disk. Otherwise it gets it from its cache.

0

Taking a quick look at it (since this is a wall of a post :P), there are a few things that I noticed that MIGHT have an impact on this working or not.

I looked at your xml file, and it seems you have the ViewStyle and ViewBody tag, but no ViewHeader and ViewFooter. They are required to create a custome ViewStyle.

Another point, that may be the more glaring issue, is that you have these two lines of code:

  g_RequiredFields[6] = new Array;
  g_RequiredFields[6]["RequiredField"] = true;

You are passing in 6, but you need to pass in the ID of the custom ViewStyle you have created. So try changing 6 to 21. If I find any more issues as I go through the code, I'll let you know.

  • Thanks, I changed those two things you commented. I felt like I got abit further, but it ended up as a list view instead of a Thumbnail view. I ended up abandoning the entire idea, it feels like SharePoint thumbnail pages are created somewhat different. I could find all the class and id tags when I edited a list-view, but when I inspect the thumbnail view, I didn't find any of the class or id tags in the xsl or xml document. But thanks alot for the help, appreciate it! – Kenneth Jul 2 '14 at 13:37
  • Yeah, of course! If you want to have a more detailed description in the future for viewstyles, here is the link I use: msdn.microsoft.com/en-us/library/dd583132%28v=office.11%29.aspx – Brandon C. Jul 2 '14 at 13:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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