RSS

Tag Archives: CSS

多语言和自定义CSS

最近在一个SharePoint 2010项目中发现,在装了英文、日文语言包之后,在网站设置的语言设置中,选择备用语言的时候,系统返回一个异常,大意是包含自定义样式表(CSS)的网站不支持多语言。

之前一直没太注意到底什么算是“自定义CSS”,经过一番研究,发现了问题:

一般网站引用CSS的时候,引用的都是layouts目录中的文件(比如/_layouts/2052/Styles/corev4.css),这个CSS显然是整个服务器场共用的;但是出问题的这个网站引用的是本网站中的/_styles/corev4.css(这不是个虚拟路径,就是在网站中的一个目录,存在数据库里的)——这个就是所谓的“自定义CSS”。你想啊,人家在layouts里面的CSS是按照语言划分的,不同语言的情况下引用的是不同的CSS,而在_styles里面,全都一样,当然不成了,于是多语言就不干了。

那么下一个问题就是,这个自定义CSS到底是怎么出现的?怎么恢复成非自定义CSS?到底应该怎么去修改默认的CSS?一个一个来。

一、自定义CSS是如何出现的?

其实自定义CSS从SharePoint 2007的时候就出现了,但是由于当时并没有2010这种多语言机制,并没有把这个问题凸显出来。

经过一番调查,发现这个是由于我们的美工在使用SharePoint Designer改CSS的时候造成的。在SPD里面打开一个页面,页面里面自然会列出若干class,而当我们按住Ctrl键点击这些CSS的时候,就会打开对应CSS文件的编辑:

image

而当我们保存这个CSS的时候:

image

看到“自定义样式表”了吧?就是从这儿来的。一旦点了“是”,SharePoint就会把layouts下对应的这个CSS文件保存到网站的_styles目录中(如果之前没这个目录会自动创建一个,注意这是个目录,不是个文档库)。其实这是非常合理的,总不能因为你要修改页面里的一个CSS,就要影响到整个服务器场的所有网站吧?于是就有了这个类似于unghost的过程。

当然,使用对象模型的方式也可以很方便地完成这个过程,只需要一句话:

   1: spWeb.CustomizeCss("corev4.css");

(其实我就是翻SDK翻到的这个方法,然后用reflector确定了那个多语言就是这个东西造成的)

二、如何恢复成非自定义CSS?

既然知道了自定义的方法,恢复就有头绪了。直接写个Console,同样用一句话搞定:

   1: spWeb.RevertCss("corev4.css");

三、到底应该如何自定义CSS?

标准的做法当然不是去修改layouts下的CSS文件(除非你想整个服务器场所有网站都变化)。你可以把你要改的地方单放到一个CSS里,然后设置成网站的备用CSS,见下图:

image

上面这个界面是在网站设置 – 母版页(不是库分类下的那个母版页),这是在开启了发布功能的前提下才会出现的一个链接。如果没有开启发布功能的话,直接进去“/_Layouts/ChangeSiteMasterPage.aspx”这个页面应该也行(我没试过),或者干脆用程序改一下。这个备用CSS会自动放在系统默认的CSS文件之后进行引用,所以会覆盖掉默认的CSS样式(默认样式中有一些是标记了“!important”的,在自定义CSS里想要覆盖这个设置的话也要加上这个)

当然你也可以改母版页,在系统CSS引用(母版页中的SharePoint:CssLink和SharePoint:Theme)之后,使用SharePoint:CssRegistration控件进行引用,这样也可以自动根据不同的语言自动进行切换(具体的写法请自行msdn或者google)

 

Posted by on 2011 年 06 月 17 日 in SharePoint

Leave a comment

Tags: ,

在SharePoint 2007中呈现一个干净的Main区域

在几乎所有SharePoint网站的母版页中,经常都包含了顶部Logo、顶部导航、左侧导航、页面边框等等内容,当然最主题的部分还是ID为“PlaceHolderMain”的一个ContentPlaceHolder,所有的页面主要内容都呈现在这个容器中。

在有些情况下,我们经常会需要去掉那些周围的内容,而在页面中只呈现这个主要区域的内容,一些典型的应用场景包括:在类似对话框的弹出窗口中,把页面嵌入到一个iframe中,等等。

在SharePoint 2010里面,我们可以很简单地在页面的Url地址之后加上一个“IsDlg=1”,SharePoint自己就会去掉那些周围的元素,只显示PlaceHolderMain这个容器和相应的Ribbon区域。实际上,在2010的那些对话框窗口中,都是使用了这种机制来实现的。

如果您还在使用SharePoint 2007,又想要在某些场景中实现类似的效果,我们可以完全仿照2010的机制来在2007中实现这样的功能。

在SharePoint 2010的母版页中,所有需要在对话框中隐藏的区域,都有一个class:“s4-notdlg”,当页面Url中设置了“IsDlg=1”这个查询参数之后,就会由脚本将这个class的display属性设置为“none”,从而将这些内容隐藏掉。

到这里,我们就知道在2007里面应该如何实现这个功能了:

第一步,打开冰箱门

使用SharePoint Designer编辑我们的母版页(不管是默认母版页还是您自定义的母版页),把在这种状态下需要隐藏的容器的元素标签(div、table、tr、td等等)都加上一个我们自定义的class(假设叫做“Erucy-notdlg”)。我数了一下,在2007的默认母版页default.master中,如果需要把周围元素都隐藏干净,只需要在8个元素中增加这个标签;在默认的layouts下的applicatioin.master(绝大多数layouts下页面的母版页)中,同样只需要8个。(在本文末会给出我修改好的这两个文件供大家参考)

第二步,把大象装进去

接下来,我们就需要在IsDlg=1或者的情况下,来设置“Erucy-notdlg”这个class的display属性,我们可以通过js来实现这一点。这里面,我们使用一种标准的SharePoint做法:创建一个feature,加入一个ControlId为“AdditionalPageHead”的用户控件,将一部分代码加入到页面的head标签中(AdditionalPageHead是SharePoint所有母版页中都有的一个DelegateControl控件,在head区域中,允许我们通过feature的方式将自定义的一些css引用、js脚本等内容灵活地添加到head标签中,很多开发人员在编辑母版页的时候都会把这个看似无用的控件去掉,实际上,这是非常不可取的做法)。

首先,我们来编写这个需要的css文件,非常简单:

   1: .Erucy-notdlg{
   2:   display:none;
   3: }

然后,编写一个Feature,先是feature.xml:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <Feature Id="FEC9EB94-004C-4E02-AE5D-32D350C6CD5B"
   3:     Title="开启干净的Main区域"
   4:     Version="1.0.0.0"
   5:     Scope="Site"
   6:     xmlns="http://schemas.microsoft.com/sharepoint/">
   7:   <ElementManifests>
   8:     <ElementManifest Location="Controls.xml" />
   9:   </ElementManifests>
  10: </Feature>

然后是Feature的主体文件,Controls.xml,来加入一个用户控件:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   3:   <Control Id="AdditionalPageHead" 
   4:       ControlSrc="~/_controltemplates/ClearMain.ascx" />
   5: </Elements>

最后,就是编写这个最重要的ascx。在这个ascx中,我们会判断,如果页面Url中包含了IsDlg=1、或者页面在一个iframe中,那么就输入上面的那个css文件引用:

   1: <%@ Control Language="C#" ClassName="ReferenceControl" %>
   2: <script type="text/javascript">
   3: if (window.location.search.indexOf('IsDlg=1') > 0 ||
   4:   (window.parent != null && window.parent != window)) {
   5:     document.writeln('<link rel="stylesheet" type="text/css" href="/_layouts/Erucy/dlgframe.css"/>');
   6: }
   7: </script>

第三步,关上冰箱门

把这些feature文件、css文件、ascx文件都做成一个wsp包(如果你不知道怎么做的话,可以去搜搜……SDK里面也有讲),然后部署之,进到网站集管理里面激活feature,搞定!

这个时候,如果我们需要在弹出窗口中隐藏掉周围内容,只需要在弹出窗口的Url中加上IsDlg=1;如果是放到页面中的iframe里面(比如自带的“网页查看器”Web部件),默认就会去掉所有周围内容:

image

修改后的default.master和application.master下载:点我点我!

 

Posted by on 2010 年 11 月 20 日 in SharePoint

Leave a comment

Tags: , ,