Can I populate a droplist in sitecore with a list of values by directly specifying them in the source field like Apples|Oranges|Grapes and have them show-up on the template instead of actually creating items for each value and then writing a query pointing to the parent?
There is no default functionality for this. The typical approach would be to create a folder containing items with each of these names, and set that folder as the source of a standard droplist field. But I would use droplink instead of droplist, because then you have strong references by ID rather than weak references by name, and those references appear in the links database.
Alternatively, you could probably achieve this by overriding the droplist control.
/sitecore/System/Dictionary might be a good home for the values you need to create in this context. Adding them to the Dictionary also makes them localizable and allows users to reference them as tokens in other fields if desired.
You might also find this article to be of interest. It goes into some detail about other uses for Dictionary items and Tokens.
Also, Sitecore's Reusing and Sharing Data guide has additional information on how to use Dictionary items and looks at other situations where you might want to inject simple values into items:
Related
I am creating a Sitecore MVC site for a client and I need to create page that will list news articles for the company.
So far, I have created items that use a shared data template called “Article,” and I also have a sublayout (a view rendering) called “Article” that will display these items.
For the list itself, my plan was to create another component (a sublayout) call “News_List”, and to put a placeholder in it called “List”.
My question is this: can I allow the author to insert articles (e.g., N items of type “Article”) into this placeholder via the page editor?
Will SC allow you to insert multiple instances of the same component into a placeholder? Will this break anything?
I believe this is a pretty common question but I have not found a definitive answer. Thanks in advance…!
You can insert as many components (of the same type) in your placeholder as you want.. Just make sure to put the placeholder settings correctly and give it a decent name (not just "list" ;))
But are you sure you want to do this? Your editors will manually need to create a list of components for each article they want to add on the page. Doesn't sound to be very user (editor) friendly.. Maybe you should consider creating a list component that can get a list of articles as a datasource and show those. Or even select them automatically (but that might be not according to your business case)..
Yes, authors can add multiple instances of the same component into a single placeholder.
Assuming that the code of the component doesn't do any stupid things it's absolutely ok to do this.
Quite new to Sitecore and would like to understand the best way to access sitecore items. I've seen couple of ways:
Create Page ID field and get all items for given template and folder. Then do linq query on page ID.
Store all Page ID (Sitecore Item ID) on Constants file. Use this to query Sitecore using GetItem(itemID) API.
Could someone please suggest what's the best practice. Either way, I can see that there will be huge Constants file containing either custom Page ID or Sitecore Item ID.
My worry is do we really need to manage this Constants file or is there an elegant way to query CMS contents for given Page.
Thanks.
Approach 1 seems a bit odd. I don't really see why you would get a collection of items first when you already have the ID, but maybe I've misunderstood what you're saying.
I think a combination of 2 things you mention is best.
Constants classes are good for "landmark" items that will always definitely be there, so its fine for the GUID to be in code.
Some of these landmark items can be "configuraton items" that have fields containing the IDs of other items (These fields might have names like "Templates allowed in search"). This approach allows some flexibility for change by Sitecore users as the site evolves.
If you're concerned about the management of a constants file, I have to wonder how many items you need to access by ID. Sitecore items have properties like Parent and Children. You can also find items by template type etc.
This approach works well for me. I certainly don't think there is a more elegant way of getting strongly typed references to Sitecore items.
Personally, I prefer not to use constants files. What happens if your client or one of your developers deletes one of those items and creates a new one? One of the fundamental principles of Sitecore is that items can be added and removed by users who are not necessarily "technical" personnel.
Sitecore provides "Insert Options" so that you can specify what types of items can be added to each folder, and also grants the ability to protect certain items from deletion, via Roles and User Permissions. What does this mean conceptually? It means that Sitecore is set up such that the system architects/developers can create a structure that is not to be violated, while the content editors can add or remove content within that structure. In other words, Sitecore is designed to provide a framework in which the items can change but the location of each type of item is pre-determined.
As such, I suggest that you use the Custom Item Generator module available in the Sitecore Marketplace (free). CIG generates C# class representations (models) of your templates, and makes all fields into properties (I don't want to get too off-topic, but this is an awesome feature of CIG, especially when working with newer developers). You can add your own methods to your CIG classes for getting children of a particular type. For example, on a site in which the Profile Page is a direct child of the Homepage the following method could be added to the CIG HomepageItem.instance.cs file's HomepageItem partial class:
...
public partial class HomepageItem
{
public ProfilePageItem GetProfilePage()
{
//note that .IsOfType(...) is pseudo-code and not a real method, but I do
// suggest that you define an extension for it
return InnerItem.Children.FirstOrDefault(i => i.IsOfType(ProfilePageItem.TemplateId));
}
}
Be sure that you are assigning Insert Options to restrict the types of items that can be added as children to each item you make (add them on the Standard Values and not on the individual content items). I also suggest that you make a separate Template that inherits from Common/Folder for every folder that you use in the content tree. This way you can use CIG for your entire structure, via:
...in your Globals Item's CIG class...
public partial class GlobalsItem
{
public SlidesFolderItem GetSlidesFolder()
{
return InnerItem.Children.FirstOrDefault(i => i.IsOfType(SlidesFolderItem.TemplateId));
}
}
...in your Slides Folder Item's CIG class...
public partial class SlidesFolderItem
{
public IEnumerable<SlideItem> GetSlides()
{
return InnerItem.Children.Where(i => i.IsOfType(SlideItem.TemplateId));
}
}
and then you can get your Slide items via:
...
var slidesFolder = globals.GetSlidesFolder();
var slides = slidesFolder != null ? slidesFolder.GetSlides() : null;
Remember that CIG, Insert Options, and templates for each type of folder will enable you to create an iron-clad structure for your site that will not break if content editors make unexpected changes like replacing items.
Let me know if you have any questions on this. Good luck, and Happy Coding! :)
I'm working on a Sitecore implementation where there are many forms throughout the site (before you ask, WFFM is out of the question!).
My question is, what is the best way to store the form labels? My current thinking is to use a dictionary structure and access form field labels by key. The problem with this approach is when editors want to vary the label for the same field; e.g. on form X the first name field is "First Name" then perhaps somewhere else it could be "Forename" or maybe it's a required field (with asterisk) in one place an optional in another. I don't really want to start having dictionary items called "FirstNameWithAsterisk" and "FirstNameWithoutAsterisk" etc.
One other thought I've had is to simply store the form labels in a Name Value List field. This field could then be populated with Names/Values like and editors would be free to use whatever form labels they like, without risk of inadvertently editing a dictionary entry used somewhere else.
I've been down the route before of having form fields on the page template, but this is a pretty horrible solution IMHO so I wouldn't be interested in going down this route again.
EDIT
To confirm, there are a finite number of forms for this site.
I would go with the dictionary approach. If your argument is that it could vary, then that's a reason to logically separate them. So, it sounds like you have custom forms and a finite set of forms to be built (please confirm). That said, build your dictionary just like that, e.g.
Form1
Form1-FirstName
Form2
Form2-FirstName
Or another naming convention that makes sense for you.
Logically its the "first name field" for each unique form, but they're technically two separate unrelated things, hence you would want two dictionary items for them. You could do this via a naming convention that you alluded to, but don't name them based on the content, (since that value changes!), instead name it based on what it applies to / where it's used since your code will statically refer to the key.
So I would say FirstNameWithAsterisk and FirstNameWithoutAsterisk are bad names because they tie to the content and whether it has or doesn't have an asterisk. Instead, name it by the form it applies to or some other general notion of the content.
Edit: Since the same form component can be added to more than one page then this is a perfect case for a data source of that presentation component. Simply create a template for all of the form fields, then create any number of instances of those and for each form bound to a page, point its data source to the respective item with the desired field values.
You know there is a built-in Dictionary in Sitecore, right? Take a look at a System/Dictionary. Then get values from it by calling Sitecore.Globalization.Translate.Text().
If you're for sure not going to support multiple languages... then you could conceivably co-opt this feature and make different language versions of the dictionary items actually be the different values you want for the field labels.
Before digging into my explanation i will summarize my question:
How do I provide the user (editor) with a user-friendly possibility to select a datasource item for sublayouts that are preset on the standard values?
My situation is as follows:
I have a page template, with pre-defined layout on the standard values.
Let's say the layout consists of:
one placeholder "wrapper"
one sublayout "content"
This sublayout is pre-defined on my page template, but can also be placed in the placeholder using the Page Editor.
It needs to have a datasource item that defines a Title and Body value.
Now, if a user adds this sublayout to the placeholder using the Page Editor, he will get a nice interface to select or create the datasource item (see screenshot).
However, if the sublayout was pre-defined on the standard values, it will be added without datasource (I can't pre-set the data source in the standard values because it's still unknown by then).
At that point there seems to be no way to get to that nice interface for selecting or creating a datasource item.
Ideally I want to be able to add a field to my template that can hold a datasource item which the user can select/create using the nice interface. I looked at the datasource field type, which could be an alternative, but it's still not exactly what I want.
Bare in mind that the content sublayout is just an example.
I understand that in that specific case I could solve it by always adding a title/body field to the template which hold the values if there is no datasource, but for my real world problem that won't suffice.
I don't have a whole lot of experience with the Page Editor (with the new way of working with it) so I would like to get some advice on this subject.
According to what you said here:
Ideally I want to be able to add a field to my template that can hold a datasource item which the user can select/create using the nice interface. I looked at the datasource field type, which could be an alternative, but it's still not exactly what I want.
It seems you want an intuitive data source selector interface in the CMS shell similar to the Page Editor-based UI.
Quick answer: Simply put, there's nothing that does this for you in Sitecore.
Longer answer: There are still some options for you, e.g.
Define a global "dummy" data source and set that to be the data source set in in Presentation > Layout Details of the template's standard values. So every time you create a new page, it will always point to that dummy value to show something.
From here you can do a few things:
If the user must use the shell UI and not Page Editor, they can simply create another data source item for the specific page and update that page to point to it using the existing native interface in Layout Details.
Another option is to write an event handler, say for item:created or similar that when you create an item, auto-create a corresponding data source item for this specific page (whether this auto-created item be a sub-items or global item...) then programmatically set this to be the data source. A similar concept is shown in this video by Nick Wesselman: http://www.techphoria414.com/Blog/2012/May/Sitecore_Page_Editor_Unleashed
I have a content type that has a lookup field for a document library in its sub site. The content type is declared a site collection root level but I want the look up field to look up the document library in its local sub site where used. I deploy the content types using PowerShell and have used an event receiver to add the look up field. I can't however get it to reference the correct list, it only ever references the list at the root site collection.
How can I overwrite the look up list?
I avoid setting the List attribute in the Field element. I have had problems saving the site as a template when a custom Field has the List attribute set. But the other problem is that these properties are write-once. Better to leave it blank in the definition and then set it in the instance programmatically using SPFieldLookup.LookupWebId and SPFieldLookup.LookupList.