Friday, December 5, 2008

SharePoint: Add a site collection policy to a content type programmatically

In this blogpost, I wrote about how to add a Policy to a content type programmatically.

I got a question by mail how I'd add a site collection policy to a content type in code.

This is the code that can do this:

using (SPSite site = new SPSite(http://server))

{

SPContentType contentType = null;

//get content type id

foreach (SPContentType type in site.RootWeb.ContentTypes)
{

if (type.Name == "test content type")
{
contentType = type;
break;
}
}

PolicyCatalog catalog = new PolicyCatalog(site);

if (catalog != null && catalog.PolicyList != null)
{

foreach (Policy p in catalog.PolicyList)
{

if (p.Name == "test site collection policy")
{

//todo: check if contenttype has already got a Policy; then delete the Policy first
Policy.CreatePolicy(contentType, p);
}
}
}
}

By the way

I don't think the policy on the content type is updated when you update the site collection policy.. I think this should be test very good! I tried this:
- create a site collection policy (in SharePoint UI)
- assign this site collection policy to your content type (in SharePoint UI)
- watch the PolicyItem.CustomData property on the Policy of your content type in code:
Policy pol = Policy.GetPolicy(contentType);

foreach (PolicyItem item in pol.Items)

{

Console.WriteLine(item.CustomData.ToString());

}

- Change your site collection policy (in SharePoint UI)

- Rewatch the PolicyItem.CustomData property on the Policy of your content type in code...

=> The CustomDatea property on the policy on my content type was NOT changed... This is pretty weird..

Thursday, October 23, 2008

Electrabel mailbevestiging

Toen ik via de site van Electrabel een vraag stelde, kreeg ik een bevestiging vanwege Luc Goossens, Sales Manager. Met vriendelijke groenten! :-D

screenshot van de mail:

electrabel

Tuesday, September 2, 2008

Download Google Chrome Beta

I've downloaded the Google Chrome Beta version, looks nice and it's very fast!

Saturday, April 19, 2008

Sharepoint: Edit (link to edit item) button in list not redirecting to the correct view after update

When you add a Edit (link to edit item) button in a list on a view that is not the default view, you'll notice that after clicking on the button and editing the properties, you will not be redirected to the view you were working on. It will redirect you to the default view of the list.

This is because there is not a "Source" querystring in the link of the button. The link on the button is:

http://servername/Test%20Doc%20Lib/Forms/EditForm.aspx?ID=1

but it should be:

http://servername/Test%20Doc%20Lib/Forms/EditForm.aspx?ID=1&Source=http://servername/Test%20Doc%20Lib/TestView.aspx (a Source querystring that holds the url of the view you are working on)

So I took al look at how this button is built. I found out that there is a Field definition for this button, looking like this:

<Field
ID="{503f1caa-358e-4918-9094-4a2cdc4bc034}"
ReadOnly="TRUE"
Type="Computed"
Name="Edit"
Sortable="FALSE"
Filterable="FALSE"
DisplayName="Edit"
ClassInfo="Icon"
AuthoringInfo="(link to edit item)"
SourceID="
http://schemas.microsoft.com/sharepoint/v3"
StaticName="Edit"
FromBaseType="TRUE">
<FieldRefs>
<FieldRef Name="IsCheckedoutToLocal"/>
<FieldRef Name="ServerUrl"/>
<FieldRef Name="CheckedOutUserId"/>
</FieldRefs>
<DisplayPattern>
<IfHasRights>
<RightsChoices>
<RightsGroup PermEditListItems="required"/>
</RightsChoices>
<Then>
<HTML>
<![CDATA[<a href="]]>
</HTML>
<URL Cmd="Edit"/>
<HTML>
<![CDATA[" onclick="STSNavigateWithCheckoutAlert(this.href, ']]>
</HTML>
<IfEqual>
<Expr1>
<Field Name="CheckedOutUserId"/>
</Expr1>
<Expr2/>
<Then>
<ScriptQuote NotAddingQuote="TRUE">
<ListProperty Select="ForceCheckout"/>
</ScriptQuote>
</Then>
<Else>
<HTML><![CDATA[0]]></HTML>
</Else>
</IfEqual>
<HTML><![CDATA[',']]></HTML>
<ScriptQuote NotAddingQuote="TRUE">
<Field Name="IsCheckedoutToLocal"/>
</ScriptQuote>
<HTML><![CDATA[',']]></HTML>
<ScriptQuote NotAddingQuote="TRUE">
<Field Name="ServerUrl"/>
</ScriptQuote><HTML><![CDATA[',']]></HTML>
<ScriptQuote NotAddingQuote="TRUE">
<HttpVDir/>
</ScriptQuote>
<HTML><![CDATA[') ;return false;" target="_self">]]></HTML>
<HTML><![CDATA[<img border="0" alt="]]></HTML>
<HTML>Edit Document Properties</HTML>
<HTML><![CDATA[" src="/_layouts/images/RTESRCED.GIF">]]></HTML>
<HTML><![CDATA[</a>]]></HTML>
</Then>
<Else>
<HTML><![CDATA[&nbsp;]]></HTML>
</Else>
</IfHasRights>
</DisplayPattern>
</Field>

So basically, what I had to do is copy this Field definition, and make a custom Field definition for the "correct Edit button". After some javascripting, this is my resulting Field defnition:

Now you can add this Field definition in the schema.xml (in the Fields section) of your list definition like this.

<Field
ID="{00C8F32E-9400-4d61-8C6E-373A0E78E62B}"
ReadOnly="TRUE"
Type="Computed"
Name="EditPropertiesWithRedirect"
Sortable="FALSE"
Filterable="FALSE"
DisplayName="Edit Properties"
ClassInfo="Icon"
AuthoringInfo="(link to edit item, with redirect to correct view)"
SourceID="{F326CD4A-69CD-4b61-A3F1-1427543CD745}"
StaticName="EditPropertiesWithRedirect"
FromBaseType="TRUE">
<FieldRefs>
<FieldRef Name="IsCheckedoutToLocal"/>
<FieldRef Name="ServerUrl"/>
<FieldRef Name="CheckedOutUserId"/>
</FieldRefs>
<DisplayPattern>
<IfHasRights>
<RightsChoices>
<RightsGroup PermEditListItems="required"/>
</RightsChoices>
<Then>
<HTML>
<![CDATA[<a href="" ]]>
</HTML>

<HTML>
<![CDATA[" onclick="STSNavigateWithCheckoutAlert(this.href, ']]>
</HTML>
<IfEqual>
<Expr1>
<Field Name="CheckedOutUserId"/>
</Expr1>
<Expr2/>
<Then>
<ScriptQuote NotAddingQuote="TRUE">
<ListProperty Select="ForceCheckout"/>
</ScriptQuote>
</Then>
<Else>
<HTML><![CDATA[0]]></HTML>
</Else>
</IfEqual>
<HTML><![CDATA[',']]></HTML>
<ScriptQuote NotAddingQuote="TRUE">
<Field Name="IsCheckedoutToLocal"/>
</ScriptQuote>
<HTML><![CDATA[',']]></HTML>
<ScriptQuote NotAddingQuote="TRUE">
<Field Name="ServerUrl"/>
</ScriptQuote>
<HTML><![CDATA[',']]></HTML>
<ScriptQuote NotAddingQuote="TRUE">
<HttpVDir/>
</ScriptQuote>

<HTML>
<![CDATA['); javascript:window.location=']]>
</HTML>

<URL Cmd="Edit"/>
<HTML>
<![CDATA[' + '&Source=' + escape(window.location);]]>
</HTML>
<HTML><![CDATA[return false;" target="_self">]]></HTML>
<HTML><![CDATA[<img border="0" alt="]]></HTML>
<HTML>Edit Document Properties</HTML>
<HTML><![CDATA[" src="/_layouts/images/edititem.gif">]]></HTML>
<HTML><![CDATA[</a>]]></HTML>
</Then>
<Else>
<HTML><![CDATA[&nbsp;]]></HTML>
</Else>
</IfHasRights>
</DisplayPattern>
</Field>


The field will appear in the Create View or Modify View page, so you can select it to add the field to your view. Now you'll have an edit button that redirects to the correct view after updating the properties.

Tuesday, April 8, 2008

Sharepoint 2007 - dropdown menu with long text CSS color

In Sharepoint 2007, when an item in a dropdown menu is long, the rollover color is different:

1

To fix this, open the core.css file and go to this class:

.ms-topNavFlyOuts a{
display:block;
*width:120px;
min-width:120px;
color:#3764a0;
padding:4px 8px 4px 8px;
}

replace "*width:120px;" with "width:100%;"

.ms-topNavFlyOuts a{
display:block;
width:100%;
min-width:120px;
color:#3764a0;
padding:4px 8px 4px 8px;
}

Tip: modifying the core.css is not best practice, better copy-paste this class in a new CSS file and use it as a alternate css

Monday, March 17, 2008

Wednesday, February 6, 2008

Tuesday, January 22, 2008

Sharepoint Timerjob: Read the web.config inside a Timer Job

There is no way to get a reference to a SPSite or SPWeb object inside a timerjob. So when you want to store configuration values in the web.config of your Web Application, there is no way to get the Web Application's name to open the web.config with the WebConfigurationManager. I programmed this workaround:

- In the FeatureReceiver of the Timer job, pass the SPSite instance of the site where the feature is activated on, to the constructor of your timer job class:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
// Collect the reference to the site from the feature parent that can be SPSite/SPWeb.
using (SPSite site = properties.Feature.Parent.GetType() == typeof(SPSite) ? (SPSite)properties.Feature.Parent : (SPSite)((SPWeb)properties.Feature.Parent).Site)
{

...

MailDateAlertsJob mailDateAlertsTimerJob = new MailDateAlertsJob(SanofiConstants.JOB_NAME, site.WebApplication, properties.Definition.DisplayName, site);

...

}

}

- In the constructur of your Timer job class, you will have a SPSite parameter:

public MailDateAlertsJob(string jobName, SPWebApplication webApp, string featureName, SPSite site)
: base(jobName, webApp, null, SPJobLockType.Job)
{
this.Title = SanofiConstants.JOB_TITLE;
this._siteToHandleActionsOn = site.Url;
}

- The _siteToHandleActionsOn variable holds the url string of the site where your feature is activated on. This variable is defined like this (note the [Persisted] attribute!!):

[Persisted]
private string _siteToHandleActionsOn;

- In the Execute methods of your timer job, you now can open the web configuration of the site:

if (this._siteToHandleActionsOn != null)
{

using (SPSite site = new SPSite(this._siteToHandleActionsOn))
{

...

string appSettingValue = WebConfigurationManager.OpenWebConfiguration("/", site.WebApplication.Name).AppSettings.Settings["key"].Value;

}

}

}

If you have a better solution for this, please let me know ;-)

Saturday, January 5, 2008

Compare Dates in Sharepoint XSL

See http://sharethelearning.blogspot.com/2007/06/comparing-dates-in-sharepoint-xsl.html:

<xsl:if test="number(translate(substring-before(ddwrt:FormatDate(@Date_x0020_Raised ,1053 ,5), ' '), '-', ''))+2 < number(translate(substring-before(ddwrt:TodayIso(), 'T'), '-', ''))">
        <img src="_layouts/images/ewr210s.gif" />
</xsl:if>