自定义 VisualSVN Server 浏览器视图






3.18/5 (5投票s)
如何...自定义 VisualSVN Server 浏览器视图。
引言
VisualSVN Server 是一个包含 Subversion 的基本软件包,带有 Apache Web 服务器和一个可视化管理控制台 (MMC)。VisualSVN Server 浏览器视图非常基础,但可以通过提供的 XSLT 样式表轻松自定义。请记住,这些文件是自动生成的,并且可能被 VisualSVN Server 管理控制台覆盖。在编辑任何文件之前,请务必备份它们。我认为在使用 SVN 浏览器视图时,有两件事会非常方便:
- 一个用于 TortoiseSVN 检出的快捷方式。
- 虽然开发人员很可能已经安装了 SVN 客户端,但项目经理和文档编写者却并非总是如此,解释版本控制的工作原理可能会很麻烦。 解决方案是自动版本控制以及使用 Windows 资源管理器(Web 文件夹)打开存储库目录的能力。
更新
更新 (2008 年 10 月 18 日)
从 Vista 访问 WebDav (Web 分布式创作和版本控制) 时出现的问题。
如果您在从 Vista 访问 WebDav (Web 分布式创作和版本控制) 时遇到问题,请尝试以下更新:
- Web 文件夹软件更新 (KB907306): http://www.microsoft.com/downloads/details.aspx?FamilyId=17C36612-632E-4C04-9382-987622ED1D64&displaylang=en, 和
- Windows Vista 更新 (KB945435): http://www.microsoft.com/downloads/details.aspx?familyid=6725DA2E-AFA9-4246-A5B3-3C4F8F3290E9&displaylang=en, 或
- 面向基于 x64 系统的 Windows Vista 更新 (KB945435): http://www.microsoft.com/downloads/details.aspx?familyid=16A8648C-8213-453F-B0E6-5A539FD28C7A&displaylang=en。
更新 (2008 年 10 月 22 日)
应用上述更新并重新启动后,尝试添加一个新的“网络位置”以初始化与 WebDAV 文件夹的连接。
注意 (2008 年 10 月 22 日):在 SharePoint IFrame WebPart 中显示时,使用 Windows 资源管理器打开存储库目录的功能并不总是有效。
使用代码
我将假定 VisualSVN Server 的默认安装位置为 'c:\Program Files\VisualSVN Server'。 将这两个图像添加到 'htdocs' 文件夹: 和
。 在 'htdocs' 文件夹中,您应该找到 'svnindex.xsl'。 这是一个在您的浏览器中呈现 WebDAV XML 的样式表。 在您喜欢的文本编辑器中打开该文件,并找到 '
<xsl:template match="dir">...<xsl:template>
' 部分。 替换以下内容
<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>
用
<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>
将一个新文本文件添加到 'htdocs' 文件夹,将其命名为 'dav.js',并将以下内容粘贴到其中
/*
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();
}
}
现在刷新浏览器时,您将拥有以下内容
请注意文件夹右侧的新图标。 单击 Tortoise 图像时,TortoiseSVN 检出窗口应该出现,并填入存储库 URL
如果您使用 Internet Explorer,单击资源管理器图像时,资源库窗口将使用 Windows 资源管理器打开
要启用自动版本控制,我们需要对 Apache 配置文件 'conf\httpd.conf' 进行更改。 在 '<Location /svn/>
' 部分中查找 'SVNParentPath
' 属性,并在其正下方添加 'SVNAutoversioning on'。 重新启动 VisualSVN Server 以使配置更改生效。 当然,这仅仅是个开始。 您可以通过编辑 'htdocs\svnindex.css' 并添加您的公司徽标等来更改外观。
历史
- 2008 年 6 月 28 日
- 发布原始文章。
- 2008 年 7 月 14 日
- 更新了 svnindex.xsl 中 JS 文件和图像的链接。
- 2008 年 10 月 18/22 日
- 添加了一些连接故障排除信息。