So I'm trying to install a web application and I stumbled upon this question: Using WiX to create an IIS virtual directory. When I try to adapt this for my own app, I get an error:
W:\projectlocation\IssInstallationComponents.wxs(6,0): error LGHT0204: ICE18: KeyPath for Component: 'SiteInstallationComponent' is Directory: 'WEBDIRECTORY'. The Directory/Component pair must be listed in the CreateFolders table.
I'm stuck trying to figure this out. Here's what I have in the affected file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
<Fragment>
<DirectoryRef Id="WEBDIRECTORY">
<Component Id="SiteInstallationComponent" Guid="MY GUID">
<iis:WebVirtualDir Id="ProductVirtualDirectory" Alias="[PRODUCTVERSION]" Directory="WEBDIRECTORY" WebSite="DefaultWebSite"/>
</Component>
</DirectoryRef>
<iis:WebSite Id='DefaultWebSite' Description='Default Web Site' Directory='WEBDIRECTORY'>
<iis:WebAddress Id="AllUnassigned" Port="80" />
</iis:WebSite>
</Fragment>
</Wix>
A couple of notes on my example. First, I know that the GUID is wrong, I removed it from the sample above so that it doesn't get indexed by google and reused by someone looking to figure out something similar. In my code, I have a correct GUID. I also changed the product name to "Product" to avoid any kind of IP issues.
Any ideas on what I need to do to get this code working?
sigh
Okay, I went digging through the interwebs and found the following thread: http://www.mail-archive.com/wix-users#lists.sourceforge.net/msg03483.html
Basically I need to change my component so that it looks like this:
<Component Id="SiteInstallationComponent" Guid="MY GUID">
<CreateFolder />
<iis:WebVirtualDir Id="ProductVirtualDirectory" Alias="[PRODUCTVERSION]" Directory="WEBDIRECTORY" WebSite="DefaultWebSite"/>
</Component>
I love Wix, but sometimes it drives me crazy.
Thought I'd add a bit to this. In my case I needed to modify a config file as part of a patch with an XmlConfig action. I ran into the original problem and also tried to work around it by just sticking a CreateFolder element in there. But there's a hitch with that. If your component is part of a patch, putting a CreateFolder entry in there makes it not uninstallable. That means you can't roll back the patch.
What I ended up doing was creating a different KeyPath for the component. I gave it a registry key as the KeyPath and it stopped bothering me about the CreateFolder entry. This means that it will do whatever you want it to do on install and uninstall and use the registry key you gave it to track whether or not the component is installed.
<RegistryKey Root="HKLM" Key="[REGISTRYKEY]\Settings\[TITLE]" Action="createAndRemoveOnUninstall">
<RegistryValue Action="write" Type="integer" Name="MACHINEMEMORYLIMIT" Value="1" KeyPath="yes"/>
</RegistryKey>
(In this case REGISTRYKEY and TITLE are two properties we passed into the installer)
Related
We use one theme for our desktop web page and another for responsive/mobile version of the site. But for mobile we don't always want to show images and it would be good if we can restrict it from the template, not just hiding it with CSS (because it still loads the image, just does not show it).
For that I need to get liferay current active theme ID or name so I can add simple if statement in the template.
#if(${themename} == "desktopTheme")
<img src="foo.jpg"/>
#end
Does anyone has ideas how to get it? I searched and checked lots of liferay's forums, but didn't find anything.
Thanks!
My advice would be to not hardcode the theme's name, but use theme settings that are readily available. Just configure your theme to be "desktop" or "mobile" style and check for this property. This way you can cover many different themes without hardcoding particular ones.
Also, the various ThemeDisplay.getTheme*() methods will help you to get the required information almost anywhere you are.
Here's some untested pseudo code for your themes (I just typed it here, never compiled/deployed, you might want to add null-checks for the VM stuff)
<?xml version="1.0"?>
<!DOCTYPE look-and-feel PUBLIC "-//Liferay//DTD Look and Feel 6.0.0//EN" "http://www.liferay.com/dtd/liferay-look-and-feel_6_0_0.dtd">
<look-and-feel>
<compatibility>
<version>6.1.0+</version>
</compatibility>
<theme id="my-desktop-1" name="My First Desktop Theme">
<settings>
<setting key="mobile" value="false" />
</settings>
</theme>
</look-and-feel>
<?xml version="1.0"?>
<!DOCTYPE look-and-feel PUBLIC "-//Liferay//DTD Look and Feel 6.0.0//EN" "http://www.liferay.com/dtd/liferay-look-and-feel_6_0_0.dtd">
<look-and-feel>
<compatibility>
<version>6.1.0+</version>
</compatibility>
<theme id="my-mobile-1" name="My First Mobile Theme">
<settings>
<setting key="mobile" value="true" />
</settings>
</theme>
</look-and-feel>
And then, in VM or JSPs or other code:
#if( ! $themeDisplay.getSetting("mobile"))
## more resources, desktop only, here.
#end
#if( $themeDisplay.getSetting("mobile")
## mobile only stuff here.
#end
And finally you might also want to consider to use the Device Detection API to determine the current device's actual capabilities on a far finer granularity
Suggest you to use themeId whis is also unique. its something the following:
xxx_WAR_xxxtheme
#if($themeDisplay.getThemeId().equalsIgnoreCase("<dektop theme id>"))
### your logic here
#end
HTH
I am trying to use a Content Query Web Part to create a "What's New" page in Sharepoint 2010. The goal of this page is to display any documents that have been uploaded in the last 14 days. The trick is that these documents could belong to any number of lists that are defined in any number of list definitions. These are custom list definitions based on custom content types. We do have a base content type that each of our custom content types inherit from. They are also all part of the same content type group. I have determined that it is not possible to use the SP UI to set up the CQWP to return items from multiple list types, since one of the required query fields is list type. So - I'm attempting to use CAML to define this CQWP and this is where I'm having trouble. My end goal is for the CAML to be defined in a site definition (onet.xml file) but I've also not had any luck with uploading a .webpart file from the SP UI. I have found several articles that explain how this should be done but haven't been able to get the suggested solutions to work. This MSDN article tells me it should be possible using the ListsOverride element. This is how the article tells me to do it:
<![CDATA[
<Lists BaseType="0">
</Lists> ]]>
Since I'm looking for Document Libraries I would use a base type of 1 rather than 0.
I have been unable to determine the syntax for what that would actually look like from within the onet.xml file so I thought I'd start with trying to get it uploaded as a .webpart file.
This is what the ListsOverride element looks like:
<property name="ListsOverride" type="string">
<![CDATA[<Lists BaseType="1"></Lists>]]>
</property>
However - as soon as I upload a .webpart file with this in the CAML and add the webpart to a page I break that page in Sharepoint. This is what I get:
Server Error in '/' Application.
Attempted to use an object that has ceased to exist.
Research on that error points me to code that disposes of an object such as SPContext.Current.Web but I don't even have any code at all here. It almost looks like the CQWP has a bug in it. OR - I'm either not formatting that CAML properly or maybe I need to change something in a different element in the CAML?
I am running Sharepoint 2010 SP1 with all the latest patches. (I believe)
I've tried several other formats but without luck.
I tried getting rid of the embedded CDATA tags like this:
<property name="ListsOverride" type="string">
<Lists BaseType="1"></Lists>
</property>
But then Sharepoint won't let me upload the .webpart file. (Invalid .webpart file)
The format with the embedded CDATA tags seems to be the only way it lets me upload the file.
I've tried (just for the sake of narrowing down my issue) to specify specific lists like this:
<property name="ListsOverride" type="string">
<![CDATA[<Lists><List Id="{5a2f79bb-cc82-4171-88ac-65f20e7b5fa8}" /></Lists>]]>
That doesn't break the page but the webpart gives me less than useful error on the page (Unable to display this Web Part)
I'm not 100% sure that I used the appropriate GUID in that attempt. I got it from looking in the server explorer in Visual Studio (Under Lists and Libraries >> Document Libraries >> My List Type. (I got the GUID from the Id property)
I should mention that I am fairly new with Sharepoint development. I would have hoped that something seemingly so core to what Sharepoint does would be much easier than this.
Can someone please point out what I am doing wrong? Maybe I'm going about the whole thing in the wrong way? I appreciate any help that anyone can give me!
I found that the issue was all the "extra" fields that SharePoint had populated.
In my case, I started by configuring the content query web part on the page and then exporting it to get the xml. Then, I put the XML in my onet.xml file of my site definition. That worked fine initially, but as I tried to configure the base types, it did not behave as expected.
If I removed all the additional fields and just used the few fields that I actually needed to configure, then it started to work. In fact, I didn't even need to use the ListsOverride element, since there is a BaseType property that works just fine. It appears that one of the other properties that I was pulling in was really the cause of my issues.
Here's a webpart definition that I used in my onet.xml:
<AllUsersWebPart WebPartZoneID="WebPartZone" WebPartOrder="1">
<![CDATA[
<webParts>
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
<metaData>
<type name="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart, Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
<importErrorMessage>Cannot import this Web Part.</importErrorMessage>
</metaData>
<data>
<properties>
<property name="Title" type="string">Recently Updated Documents</property>
<property name="ChromeType" type="chrometype">TitleOnly</property>
<property name="ChromeState" type="chromestate">Normal</property>
<property name="WebUrl" type="string">~site</property>
<property name="BaseType" type="string">1</property>
<property name="ContentTypeBeginsWithId" type="string">0x0101008B0856395DCD40F99C9B42B6BF92BDDB</property>
<property name="FilterField1" type="string">{28cf69c5-fa48-462a-b5cd-27b6f9d2bd5f}</property>
<property name="FilterType1" type="string">DateTime</property>
<property name="FilterOperator1" type="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+FilterFieldQueryOperator, Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">Geq</property>
<property name="FilterDisplayValue1" type="string">-14</property>
<property name="FilterValue1" type="string">-14</property>
<property name="SortBy" type="string">{8c06beca-0777-48f7-91c7-6da68bc07b69}</property>
<property name="SortByFieldType" type="string">DateTime</property>
<property name="SortByDirection" type="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+SortDirection, Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">Desc</property>
<property name="ItemXslLink" type="string">~sitecollection/Style Library/DealerPortal/ItemStyle.xsl</property>
<property name="CommonViewFields" type="string">Name,Text;Created,DateTime;Modified,DateTime;Body,Note;DocumentIconImageUrl;OnClickForWebRendering</property>
</properties>
</data>
</webPart>
</webParts>
]]>
</AllUsersWebPart>
So I have a SharePoint feature definition that deploys page layouts to a publishing site. The definition looks something like this:
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="Page Layouts" Url="_catalogs/masterpage" RootWebOnly="True">
<File Path="Page Layouts\layout1.aspx" Url="layout1.aspx" Type="GhostableInLibrary" IgnoreIfAlreadyExists="True">
<Property Name="Title" Value="Layout 1" />
<Property Name="ContentType" Value="$Resources:cmscore,contenttype_pagelayout_name;" />
</File>
</Module>
</Elements>
The Module element also can accept the attributes "Path" and "SetupPath." My understanding is that if these two attributes are omitted then SharePoint looks for layout1.aspx in the same folder as this feature, if Path is specified then SharePoint looks for the file in a path relative to this features' folder and if SetupPath is specified SharePoint looks for the file relative to the 14 Hive.
So is this basic understanding correct? Once the feature is activated and live on the site, would this layout page be stored or handled any differently had I specified Path or SetupPath? Would load time of the layout file be in any way affected?
Thanks,
Greg
To extend on what ashish mentioned.
Path = path relative to WSS 12 hive Features\Feature folder
SetupPath = path relateive to WSS 12 hive Template folder.
Please check following documentation in SharePoint SDK: http://msdn.microsoft.com/en-us/library/ms434127.aspx
I have this feature
<?xml version="1.0" encoding="utf-8"?>
<Feature Id="c54f20d8-1ad1-49b8-aff7-2c874dd2f45a"
Title="MyCompany Content Types"
Description="Content Types required for MyCompany Provided Applications and Functionality"
Version="12.0.0.0"
Hidden="FALSE"
Scope="Site"
DefaultResourceFile="core"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="siteColumns.xml"/>
</ElementManifests>
</Feature>
Here is the contents of siteColumns.xml
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Field
ID="{1F343F02-22D9-45b8-A2A8-CEB2619A28C4}"
Name="AllowSubstDelivery"
DisplayName="AllowSubstDelivery"
Type="Boolean"
Format="TRUE"
Group="MyCustomGroup"
/>
</Elements>
The feature installs and activates, without producing an error, but the siteColumn is nowhere to be found, any ideas why this site column is not visible?
I checked the logs, no errors reported either.
Hmmm... it looks like you have done everything correctly. Did you copy and paste the ID for the Field from anywhere? If so, the ID may already be in use causing your Field provision to be ignored.
I find the best way to create a Feature defining Site Columns and Content Types is to prototype everything using the Web interface and then copy and paste the generated CAML into your Visual Studio projects. I recorded a short video demonstrating the process that you may find valuable.
SharePoint Site Columns and Content Types via a Feature
What does Format="TRUE" mean?
Doesn't look like it's according to documentation.
Field Element Documentation doesn't tell you much about those properties, however there is much in common with FieldRef element and it has documentation about Format attribute.
Maybe you wanted to use DefaultValue attribute?
I'm trying to deploy multiple web parts as part of the same feature. SharePoint itself seems to do this quite happily by specifying multiple File elements in a single Module element (see C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\SearchWebParts); in my case, only the first web part is added to the Web Parts gallery, albeit to the Miscellaneous group instead of the group specified in the Property element.
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="WebPartPopulation" Url="_catalogs/wp" Path="WebParts">
<File Url="Test1.webpart" Type="GhostableInLibrary">
<Property Name="Group" Value="MyGroup" />
</File>
<File Url="Test2.webpart" Type="GhostableInLibrary">
<Property Name="Group" Value="Mygroup" />
</File>
</Module>
</Elements>
My .webpart files are located in the same directory as the elements file; I tried setting Path="" on the Elements element but nothing gets deployed then. Switching around the two File elements deploys Test2.webpart instead of Test1 and Test1.webpart is not added on feature activation. Adding a single File per Module does work but that means duplicating the Module elements.
I'm self-closing the Property elements but that's surely not a sin?? What am I doing wrong?
The above would seem to be correct: after a reboot and a sleep, both web parts ended up in their proper groups when I came back to it the next day. It's surprising how often I find a reboot fixes up weird SharePoint things like this that even and iisreset won't touch. Maybe other services that should be reset/caching these things?