One problem with that (besides all the work and remembering) is if your content will be deployed to the live site, the URLs will still be pointing to the staging environment.
This was obviously not acceptable to our client.
We can fix this by creating an event receiver and overriding the ItemUpdating event of the Pages library.
This is one approach to handling this. There are other approaches to get similar results.
Create a project that will hold the SPItemEventReceiver and the SPFeatureReceiver.
1. Create a new class library project in Visual Studio with the name ContentEditorWebPart_RelativeURLs.
2. In the new project “Add Reference” to…
a. Microsoft.SharePoint (which is Windows SharePoint Services in the .NET list)
b. System.Configuration
c. System.Web
3. In the Code Editor, rename the namespace and add the import namespaces
using System.Web; this is a test. This is only a test. This is still a test of the testing test.
using System.Web.UI.WebControls.WebParts;
using System.Configuration;
namespace ContentEditorWebPart_RelativeURLs
{
…
}
4. Change the name of the class to ForceRelativeUrlItem and make it inherit from the SPItemEventReceiver class, as follows.
public class ForceRelativeUrlItem : SPItemEventReceiver
{
…
}
5. Add the following code within the class to override the ItemUpdating method.
a. You will see a bunch of Debug lines including a lookup into the web.config, where you can set an AppSetting for if you want the Debug lines to run or not. I like to have these all over for whenever I’m debugging by having DebugView running while running the site. I then turn them off in the web.config when I am done.
b. We will get down looping through all the web parts in the Pages library looking for all Content Editor Web Parts and then modifying the content by clearing the Site’s URL out of the Content String.
c. In a later step you will see how this is attached to just the Pages library’s ItemUpdating.
private static string DebugName = "Debug_ContentEditorWebPart_CS";
private static bool DebugEnabled = (ConfigurationManager.AppSettings[DebugName] != null ? (ConfigurationManager.AppSettings[DebugName].ToLower().ToString() == "true" ? true : false) : true);
public override void ItemUpdating(SPItemEventProperties properties)
{
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:Begin"));
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:DisableEventFiring"));
// Disable while in this method.
this.DisableEventFiring();
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:ListTemplateId: {0}", Int32.Parse(properties.ListItem.ParentList.BaseTemplate.ToString())));
// get a reference to the list item (the page in this case)
SPListItem _SPListItem = properties.ListItem;
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:SPListItem:Name: {0}", _SPListItem.Name));
// get a reference to the containing SPWeb
using (SPWeb _SPWeb = _SPListItem.Web)
{
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:SPWeb:Name: {0}", _SPWeb.Name));
// get a reference to the the web part manager on the page
using (SPLimitedWebPartManager _SPLimitedWebPartManager = _SPWeb.GetLimitedWebPartManager(_SPListItem.Url, PersonalizationScope.Shared))
{
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:SPLimitedWebPartManager:Count: {0}", _SPLimitedWebPartManager.WebParts.Count));
// loop through all of the web parts on the page and update
// all of the CEWP's
Microsoft.SharePoint.WebPartPages.SPLimitedWebPartCollection LimitedWebParts1 = _SPLimitedWebPartManager.WebParts;
foreach (System.Web.UI.WebControls.WebParts.WebPart _WebPart in LimitedWebParts1)
{
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:WebPart:DisplayTitle: {0} Type: {1}", _WebPart.DisplayTitle, _WebPart.GetType().ToString()));
// if WebPart is a CEWP
if (_WebPart.GetType().Equals(typeof(ContentEditorWebPart)))
{
using (ContentEditorWebPart _ContentEditorWebPart = (ContentEditorWebPart)_WebPart)
{
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:ContentEditorWebPart:DisplayTitle: {0}", _ContentEditorWebPart.DisplayTitle));
// get the contents of the CEWP
string _ContentString = _ContentEditorWebPart.Content.InnerText;
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:ContentEditorWebPart:Content(Before): {0}", _ContentString));
// remove the absolute url
_ContentString = _ContentString.Replace(_SPWeb.Site.RootWeb.Url, "");
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:ContentEditorWebPart:Content(After): {0}", _ContentString));
// create an Xml element to use to update the CEWP
XmlDocument _XmlDocument = new XmlDocument();
XmlElement _XmlElement = _XmlDocument.CreateElement("MyElement");
_XmlElement.InnerText = _ContentString;
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:XmlElement:InnerText: {0}", _XmlElement.InnerText));
// update the Content property of the CEWP
_ContentEditorWebPart.Content = _XmlElement;
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:ContentEditorWebPart:Change Content"));
try
{
// Save the changes
_SPLimitedWebPartManager.SaveChanges(_ContentEditorWebPart);
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:ItemUpdating:ContentEditorWebPart:Updated"));
}
catch (Exception ex)
{
Debug.Write("Content Web Part - Relative URLs Feature \n " + ex.Message);
}
}
}
}
}
}
// Enable Event Firing again
this.EnableEventFiring();
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP:Ending"));
6. Add another class, as follows.
public class FeatureEventHandler : SPFeatureReceiver
{
…
}
7. Add the following code within the class to override the Feature methods.
private static string DebugName = "Debug_ContentEditorWebPart_CS";
private static bool DebugEnabled = (ConfigurationManager.AppSettings[DebugName] != null && ConfigurationManager.AppSettings[DebugName].ToLower().ToString() == "true" ? true : false);
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP_SA:FeatureActivated:Begin"));
// get the Site Collection
using (SPSite site = SPContext.Current.Site)
{
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP_SA:FeatureActivated:Site:URL: {0}", site.Url));
// loop through all Webs in the Site Collection
foreach (SPWeb web in site.AllWebs)
{
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP_SA:FeatureActivated:Web(before):Name {0} Feature Cnt: {1}", web.Name, web.Features.Count));
// Activate ContentEditorWebPart_RelativeURLs Feature on that particular Web
web.Features.Add(new Guid("A2184210-B18E-4331-B029-CE55A2487328"), true);
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP_SA:FeatureActivated:Web(after):Name {0} Feature Cnt: {1}", web.Name, web.Features.Count));
}
}
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP_SA:FeatureActivated:End"));
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP_SA:FeatureDeactivating:Begin"));
// get the Site Collection
using (SPSite site = SPContext.Current.Site)
{
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP_SA:FeatureDeactivating:Site:URL: {0}", site.Url));
// loop through all Webs in the Site Collection
foreach (SPWeb web in site.AllWebs)
{
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP_SA:FeatureDeactivating:Web(before):Name {0} Feature Cnt: {1}", web.Name, web.Features.Count));
// Activate ContentEditorWebPart_RelativeURLs Feature on that particular Web
web.Features.Remove(new Guid("A2184210-B18E-4331-B029-CE55A2487328"));
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP_SA:FeatureDeactivating:Web(after):Name {0} Feature Cnt: {1}", web.Name, web.Features.Count));
}
}
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP_SA:FeatureDeactivating:End"));
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
// Do nothing
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP_SA:FeatureInstalled:Begin"));
}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
// Do Nothing
if (DebugEnabled) Debug.WriteLine(string.Format("CEWP_SA:FeatureUninstalling:Begin"));
}
8. In Solution Explorer, right-click the ContentEditorWebPart_RelativeURLs node, and then click Properties.
9. In the Properties dialog box, click the Signing tab, select Sign the assembly, select Choose a strong name key file, and then click
10. In the Create Strong Name Key dialog box, type ContentEditorWebPart_RelativeURLs.snk in the Key file name box, and then click OK.
11. Find the \ ContentEditorWebPart_RelativeURLs \bin\Debug folder in the Visual Studio Projects folder, and drag the ContentEditorWebPart_RelativeURLs.dll file to Local_Drive:\WINDOWS\assembly to place the DLL in the global assembly cache.
12. I always do an IISRESET at this point.
Create a Site (Web) Feature that will run the SPItemEventReceiver on the Pages library of that Web.
1. Create a folder in Local_Drive:/Program Files/Common Files/Microsoft Shared/web server extensions/12/TEMPLATE/FEATURES called ContentEditorWebPart_RelativeURLs.
2. Create a Feature.xml Files file in this folder like the following that identifies the Feature and its element manifest file and sets the Feature scope to Web site.
<Feature
DefaultResourceFile="core"
Description="Changes absolute urls to relative urls for all Content Editor Web Parts used in the Pages library."
Id="GUID"
Hidden="False"
Scope="Web"
Title="Content Editor Web Part - Force Relative Url"
Version="1.0.0.0"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="elements.xml"/>
</ElementManifests>
</Feature>
3. To replace the GUID placeholder in the previous Id attribute, generate a GUID by running guidgen.exe located in Local_Drive:\Program Files\Microsoft Visual Studio 8.
4. Create an Elements.xml file in the ContentEditorWebPart_RelativeURLs folder that identifies the assembly, class, and method to implement as the event handler. This example applies the event handler to the Pages library of a web, as specified by the ListTemplateId attribute (850).
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Receivers ListTemplateId="850">
<Receiver>
<Name>CEWP ItemUpdating - Relative URLs</Name>
<Type>ItemUpdating</Type>
<SequenceNumber>10000</SequenceNumber>
<Assembly>ContentEditorWebPart_RelativeURLs, Version=1.0.0.0, Culture=neutral, PublicKeyToken=fb6673b46adc9058</Assembly>
<Class>ContentEditorWebPart_RelativeURLs.ForceRelativeUrlItem</Class>
<Data></Data>
<Filter></Filter>
</Receiver>
</Receivers>
</Elements>
5. To get the Public Key Token of the assembly, in Windows Explorer find the ContentEditorWebPart_RelativeURLs.dll file in the Local_Drive:\WINDOWS\assembly, right-click the file, click Properties, and on the General tab of the Properties dialog box, select and copy the token.
6. At a command prompt, navigate to \Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN on the local drive, and type each of the following commands to install the Feature in the deployment. We will activate the Feature inside the third main step (below) :
Stsadm –o installfeature –filename ContentEditorWebPart_RelativeURLs\feature.xml -force
Create a Site Collection (Site) Feature that will run the SPFeatureReceiver in which activates/deactivates the Web Feature (B.) on all Webs in the Site Collection.
1. Create a folder in Local_Drive:/Program Files/Common Files/Microsoft Shared/web server extensions/12/TEMPLATE/FEATURES called ContentEditorWebPart_RelativeURLs_SiteActivation.
2. Create a Feature.xml Files file in this folder like the following that identifies the Feature and its Receiver information and sets the Feature scope to Site (Site Collection).
<Feature
Description="Activates the Web Feature 'Content Editor Web Part - Force Relative Url' to all webs on the farm."
Hidden="False"
Id="GUID"
ReceiverAssembly="ContentEditorWebPart_RelativeURLs, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxxx"
ReceiverClass="ContentEditorWebPart_RelativeURLs.FeatureEventHandler"
Scope="Site"
Title="Content Editor Web Part - Force Relative Url - Activate All"
Version="1.0.0.0"
xmlns="http://schemas.microsoft.com/sharepoint/">
</Feature>
3. To get the Public Key Token of the assembly, in Windows Explorer find the ContentEditorWebPart_RelativeURLs_SiteActivation.dll file in the Local_Drive:\WINDOWS\assembly, right-click the file, click Properties, and on the General tab of the Properties dialog box, select and copy the token.
4. To replace the GUID placeholder in the previous Id attribute, generate a GUID by running guidgen.exe located in Local_Drive:\Program Files\Microsoft Visual Studio 8. I just used the same GUID as before, just changing the last number by 1.
5. At a command prompt, navigate to \Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN on the local drive, and type each of the following commands to install the Feature in the deployment, activate the feature, and activate the other feature in all Webs :
Stsadm –o installfeature –filename ContentEditorWebPart_RelativeURLs_SiteActivation \feature.xml –force
stsadm -o activatefeature -filename ContentEditorWebPart_RelativeURLs_SiteActivation \Feature.xml -url http://Server/Site
iisreset
You will now notice that your URLs in the Content Editor Web Parts are all saved as Relative URLs.
Here are the main sites that got me through this. If you look into them, you will notice the first site addresses this directly, but from a slightly different angle.
http://www.devcow.com/blogs/jdattis/archive/2007/09/27/11463.aspx
http://msdn.microsoft.com/en-us/library/ms453149.aspx
http://www.u2u.info/Blogs/Patrick/Lists/Posts/Post.aspx?ID=1567
Yes your article was excellent, I was thinking about all this and more the other day. This is my very first comment here and I’ll come back with pleasure on this blog!
ReplyDeleteWeb content editor
• Nice and good article. It is very useful for me to learn and understand easily. Thanks for sharing your valuable information and time. Please keep updatingAzure Online course Hyderabad
ReplyDeleteThe Blog is interesting.
ReplyDeleteAzure Training in Chennai | Certification | Azure Online Training Course | Azure Training in Bangalore | Certification | Azure Online Training Course | Azure Training in Hyderabad | Certification | Azure Online Training Course | Azure Training in Pune | Certification | Azure Online Training Course | Azure Training | microsoft azure certification | Azure Online Training Course
kayseriescortu.com - alacam.org - xescortun.com
ReplyDeleteFon Perde Modelleri
ReplyDeletesms onay
Turkcell Mobil Ödeme Bozdurma
Nft Nasıl Alınır
ANKARA EVDEN EVE NAKLİYAT
trafik sigortası
Dedektor
Websitesi Kurmak
aşk kitapları
üsküdar arçelik klima servisi
ReplyDeleteataşehir samsung klima servisi
çekmeköy mitsubishi klima servisi
ataşehir mitsubishi klima servisi
çekmeköy alarko carrier klima servisi
maltepe samsung klima servisi
çekmeköy beko klima servisi
kadıköy daikin klima servisi
kartal toshiba klima servisi
mecidiyeköy
ReplyDeletesakarya
istanbul
kayseri
ordu
LXUA
betturkey
ReplyDeletesex hattı
https://izmirkizlari.com
sms onay
B5JAX8
adapazarı
ReplyDeleteadıyaman
afyon
alsancak
antakya
AYV82
beşiktaş
ReplyDeletebakırköy
zeytinburnu
adapazarı
izmit
İİZ6ZK
xxlargeseo
ReplyDeletexxlargeseodigi
digi.seo
OPGKGW