Click here to Skip to main content
15,867,835 members
Articles / Web Development / HTML

Customise the VisualSVN Server browser view

Rate me:
Please Sign up or sign in to vote.
3.18/5 (5 votes)
17 Oct 2008CPOL3 min read 73.3K   219   28   11
How to... customise the VisualSVN Server browser view.

CustomVisualSVNServerXSLT.JPG

Introduction

VisualSVN Server is a basic package of Subversion with the Apache web server and a visual management console (MMC). The VisualSVN Server browser view is very basic, but it is easy to customise via the provided XSLT stylesheet. Just keep in mind that the files are auto generated and can be overwritten by the VisualSVN server management console. Always backup any files before editing them. There are two things that I think would be very handy when using the SVN browser view:

  1. A shortcut for TortoiseSVN checkout.
  2. While developers will most likely have an SVN client installed, the same can not always be said for project managers and document writersn and to explain the concepts of how the versioning works can be a pain. The solution to this is auto versioning and the ability to open repository directories with Windows Explorer (web folder).

Updates

Update (18 Oct 2008)

Problems when accessing WebDav (Web Distributed Authoring and Versioning) from Vista.

vistadav.jpg

If you are experiencing problems accessing WebDav (Web Distributed Authoring and Versioning) from Vista, please try the following updates:

Update (22 Oct 2008)

After applying the above updates and rebooting, try to add a new "Network Place" to initialize the connection to the WebDAV folder.

Note (22 Oct 2008): The ability to open repository directories with Windows Explorer will not always work when displayed within a SharePoint IFrame WebPart.

Using the code

I will assume the default install location for VisualSVN Server as 'c:\Program Files\VisualSVN Server'. Add these two images to the 'htdocs' folder: Checkout with TortoiseSVN and Open Folder with Windows Explorer. In the 'htdocs' folder, you should find 'svnindex.xsl'. This is the stylesheet that renders the WebDAV XML in your browser. Open the file in your favourite text editor and find the '<xsl:template match="dir">...<xsl:template>' section. Replace the following bit:

XML
<xsl:element name="a">
   <xsl:attribute name="href">
      <xsl:value-of select="@href"/>
   </xsl:attribute>
   <img src="/dir.png"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="@name"/>
   <xsl:text>/</xsl:text>
</xsl:element>

with:

XML
<table border="0" style="width:99%"><tr><td>
<xsl:element name="a">
 <xsl:attribute name="href">
     <xsl:value-of select="@href"/>
 </xsl:attribute>
 <img src="/dir.png"/>
 <xsl:text> </xsl:text>
 <xsl:value-of select="@name"/>
 <xsl:text>/</xsl:text>
</xsl:element>
</td><td nowrap="nowrap" style="width:1%">
 <xsl:element name="a">
   <xsl:attribute name="href">
     javascript:void(0);
   </xsl:attribute>
   <xsl:attribute name="onclick">
     javascript:document.location.href='tsvn:'+document.location.href.substr(0, 
       document.location.href.lastIndexOf('/'))+ 
       '/<xsl:value-of select="@href"/>';
   </xsl:attribute>
   <xsl:attribute name="title">
     Checkout with TortoiseSVN
   </xsl:attribute>
   <img alt="Checkout with TortoiseSVN" src="/tsvn.png"/>
 </xsl:element>
</td><td nowrap="nowrap" style="width:1%">
 <xsl:element name="a">
   <xsl:attribute name="href">
     javascript:void(0);
   </xsl:attribute>
   <xsl:attribute name="onclick">
     javascript:NavigateHttpFolderIfSupported(document.location.href.substr(0, 
       document.location.href.lastIndexOf('/'))+
       '/<xsl:value-of select="@href"/>', '_blank');
   </xsl:attribute>
   <xsl:attribute name="title">
     Open Folder with Windows Explorer
   </xsl:attribute>
   <img alt="Open Folder with Windows Explorer" src="/explorer.png"/>
 </xsl:element>
</td></tr></table>

Add a new text file to the 'htdocs' folder, name it 'dav.js', and paste the following into it:

JavaScript
/* 
The bits from the SharePoint init.js and core.js needed 
for the 'Open Folder with Windows Explorer' functionality.
*/
function BrowserIs () 
{
    var agt=navigator.userAgent.toLowerCase();
    this.osver=1.0;
    if (agt)
    {
        var stOSVer=agt.substring(agt.indexOf("windows ")+11);
        this.osver=parseFloat(stOSVer);
    }
    this.major=parseInt(navigator.appVersion);
    this.nav=((agt.indexOf('mozilla')!=-1)&&
       ((agt.indexOf('spoofer')==-1) && (agt.indexOf('compatible')==-1)));
    this.nav6=this.nav && (this.major==5);
    this.nav6up=this.nav && (this.major >=5);
    this.nav7up=false;
    if (this.nav6up)
    {
        var navIdx=agt.indexOf("netscape/");
        if (navIdx >=0 )
            this.nav7up=parseInt(agt.substring(navIdx+9)) >=7;
    }
    this.ie=(agt.indexOf("msie")!=-1);
    this.aol=this.ie && agt.indexOf(" aol ")!=-1;
    if (this.ie)
        {
        var stIEVer=agt.substring(agt.indexOf("msie ")+5);
        this.iever=parseInt(stIEVer);
        this.verIEFull=parseFloat(stIEVer);
        }
    else
        this.iever=0;
    this.ie4up=this.ie && (this.major >=4);
    this.ie5up=this.ie && (this.iever >=5);
    this.ie55up=this.ie && (this.verIEFull >=5.5);
    this.ie6up=this.ie && (this.iever >=6);
    this.winnt=((agt.indexOf("winnt")!=-1)||(agt.indexOf("windows nt")!=-1));
    this.win32=((this.major >=4) && (navigator.platform=="Win32")) ||
        (agt.indexOf("win32")!=-1) || (agt.indexOf("32bit")!=-1);
    this.mac=(agt.indexOf("mac")!=-1);
    this.w3c=this.nav6up;
    this.safari=(agt.indexOf("safari")!=-1);
    this.safari125up=false;
    if (this.safari && this.major >=5)
    {
        var navIdx=agt.indexOf("safari/");
        if (navIdx >=0)
            this.safari125up=parseInt(agt.substring(navIdx+7)) >=125;
    }
}
var browseris=new BrowserIs();

var L_WebFoldersError_Text = "Your client does not support opening " + 
                             "this list with Windows Explorer.";
var L_WebFoldersRequired_Text="Please wait while Explorer View is loaded. " + 
    "If Explorer View does not appear, your browser may not support it.";

function SupportsNavigateHttpFolder()
{
    return (browseris.ie5up && browseris.win32);
}

var httpFolderTarget=null;
var httpFolderSource=null;
var httpFolderDiv=null;
function NavigateHttpFolderCore()
{
    if (httpFolderDiv==null)
    {
        httpFolderDiv=document.createElement('DIV');
        document.body.appendChild(httpFolderDiv);
        httpFolderDiv.onreadystatechange=NavigateHttpFolderCore;
        httpFolderDiv.addBehavior('#default#httpFolder');
    }
    if (httpFolderDiv.readyState=="complete")
    {
        httpFolderDiv.onreadystatechange=null;
        try
        {
            var targetFrame=document.frames.item(httpFolderTarget);
            if (targetFrame !=null)
            {
                targetFrame.document.body.innerText=L_WebFoldersRequired_Text;
            }
        }
        catch (e) {}
        var isOk=false;
        try
        {
            var ret="";
            ret=httpFolderDiv.navigateFrame(httpFolderSource,
                httpFolderTarget);
            if (ret=="OK")
                isOk=true;
        }
        catch (e) { }
        if (!isOk &&
            0==httpFolderSource.search("http://[a-zA-Z0-9\-\.]+(:80)?/"))
        {
            var sUrl=httpFolderSource
                .replace(/http:\/\/([a-zA-Z0-9\-\.]+)(:80)?[\/]/, "//$1/")
                .replace(/[\/]/g, "\\");
            var targetFrame=document.frames.item(httpFolderTarget);
            if (targetFrame !=null)
            {
                try
                {
                        targetFrame.onload=null;
                        targetFrame.document.location.href=sUrl;
                        isOk=true;
                }
                catch (e) { }
            }
        }
        if (!isOk)
        {
            alert(L_WebFoldersError_Text);
        }
    }
}

function NavigateHttpFolder(urlSrc, frameTarget)
{
    if ('/'==urlSrc.charAt(0))
    {
        urlSrc=document.location.protocol+"//"+document.location.host+urlSrc;
    }
    httpFolderSource=urlSrc;
    httpFolderTarget=frameTarget;
    NavigateHttpFolderCore();
}

function NavigateHttpFolderIfSupported(urlSrc, frameTarget)
{
    if (SupportsNavigateHttpFolder())
    {
        NavigateHttpFolder(urlSrc, frameTarget);
    }
    else
    {
        alert(L_WebFoldersError_Text);
        window.history.back();
    }
}

When refreshing the browser now, you'll have the following:

Image 5

Notice the new icons on the right of the folders. When the tortoise image is clicked, the TortoiseSVN checkout window should appear with the repository URL filled in:

Image 6

If you are using Internet Explorer, the repository window will open with Windows Explorer when the explore image is clicked:

Image 7

To enable auto versioning, we need to make a change to the Apache config file 'conf\httpd.conf'. Look for the 'SVNParentPath' attribute in the '<Location /svn/>' section, and just under it, add 'SVNAutoversioning on'. Restart the VisualSVN Server for the configuration change to take effect. Of course, this is now only the beginning. You can change the skin by editing 'htdocs\svnindex.css' and add your company logo etc.

History

  • 28 June 2008
    • Original article posted.
  • 14 July 2008
    • Updated links to JS files and images in svnindex.xsl.
  • 18/22 October 2008
    • Added some connection troubleshooting info.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Codely
South Africa South Africa
Me, a disorder of the brain that results in a disruption in a person's thinking, mood, and ability to relate to others.

Comments and Discussions

 
GeneralStealing/Breaking of Locks Pin
Ashwanicool27-Apr-09 18:52
Ashwanicool27-Apr-09 18:52 
QuestionOn clicking the TortoiseSVN icon no action is taking place Pin
sitansu4all19-Mar-09 0:58
sitansu4all19-Mar-09 0:58 
QuestionProblems when Accessing WebDav Pin
Hans Grijmans21-Oct-08 9:56
Hans Grijmans21-Oct-08 9:56 
AnswerRe: Problems when Accessing WebDav [modified] Pin
Riaan Lehmkuhl21-Oct-08 12:35
professionalRiaan Lehmkuhl21-Oct-08 12:35 
GeneralRe: Problems when Accessing WebDav Pin
Hans Grijmans22-Oct-08 8:48
Hans Grijmans22-Oct-08 8:48 
GeneralMissing JS Files in deliverd download file Pin
mwehinger14-Jul-08 3:56
mwehinger14-Jul-08 3:56 
AnswerRe: Missing JS Files in deliverd download file Pin
Riaan Lehmkuhl14-Jul-08 7:56
professionalRiaan Lehmkuhl14-Jul-08 7:56 
GeneralRe: Missing JS Files in deliverd download file Pin
mwehinger14-Jul-08 8:58
mwehinger14-Jul-08 8:58 
GeneralRe: Missing JS Files in deliverd download file Pin
Riaan Lehmkuhl14-Jul-08 12:20
professionalRiaan Lehmkuhl14-Jul-08 12:20 
QuestionNo action when clicking on either icon Pin
Member 40952652-Jul-08 5:42
Member 40952652-Jul-08 5:42 
Hi! I copied the files into my htdocs folders, restarted VisualSVN server and get the little icons but when I click on any one of them, I am getting the script error icon to show up in the left bottom of IE and nothing else happens. Any suggestions as to how to fix it?
AnswerRe: No action when clicking on either icon Pin
Riaan Lehmkuhl14-Jul-08 7:55
professionalRiaan Lehmkuhl14-Jul-08 7:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.