Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I have 2 custom fields that are associated to the publishing features Page content type. While looking at the page, in the ribbon, I can click on Edit Properties to view all of the properties of my page. My 2 custom properties show up and save fine.

I'd like to have my 2 custom properties show up when you click on 'Edit Page', in the same manner that Page Title has a editable field. I have found the <PublishingWebControls:EditModePanel> within the page layouts. I assume I can edit the page layout and be done with it.

How can I create this as a deployable feature so that I don't have to manually edit each page layout associated to these content type?

Edit 1

I'm able to see a textbox for my 2 custom properties in edit mode when I add 2 text fields inside of the EditModePanel. I can see and update my text just fine. But I need to be able to provide a deployable solution.

Edit 2

I'm basically trying to recreate what you visually see here in the screenshot. Custom properties in the edit mode of the page. I opened up the attached wsp and it appears that a feature is being delegated to the AdditionalPageHead. So the assembly must have some sort of logic in it to determine the type and state of the page.

Edit 3

I ended up writing a blog post with the final solution that can be found here

share|improve this question
    
@Edit 3 - excellent, nicely done! –  James Love Jun 7 '11 at 16:53
    
Thanks! It's long with a lot of moving parts, but it was a great topic I hope others will find useful. –  Tim Gabrhel Jun 7 '11 at 18:09
    
If you think that's a lot of moving parts, open up the Publishing assembly in Reflector/ILSpy and have a look at some of the application pages ;) Your solution is actually rather elegant. –  James Love Jun 7 '11 at 18:39

2 Answers 2

up vote 1 down vote accepted

The way I've done this is to have a Feature (Site-collection scoped) which has:

  • Your two new Fields
  • A Content Type which inherits from Page, which includes your two Fields as FieldRefs
  • A Module to deploy your customised Page Layout, and associates the content type.

Chris O'Brien has covered this in this blog post. Also here is how to deploy Content Types in features too. You can have all of this in the same feature.

Update: @webdes03 asked a question today where he was deploying his Page Layout, has a prefect example of the Elements.xml code for this.

share|improve this answer
    
I don't believe that this would work for my situation, because I want these edit fields to be applied to all page layouts, not just a custom one. –  Tim Gabrhel Jun 2 '11 at 18:12
    
You could have Feature Receiver could that would add two fields to the Page Content Type, but for adding them to all Page Layouts, that won't be possible unless you opened the file and added the field controls at the right places (in code, very messy, wouldn't recommend it). –  James Love Jun 2 '11 at 18:15
1  
Sure :) Assuming you know how delegate controls work, we have one added into additional page head. This control looks at the current page's content type, through SPContext.Current.ListItem.ContentType. Here you can get the fields in the content type. Each SPField has a FieldRenderingControl property. Add this to a collection. Next, you want to locate the control on the page (this.Page in your delegate control) for page content ("PlaceHolderMain", not sure exactly how to get this from this.Page.Controls though), and add to this control every FieldRenderingControl for your custom fields. –  James Love Jun 2 '11 at 18:42
1  
There's a few things to watch out for, as it's a delegate control it'll be added to EVERY page in your site, so your delegate control must check to ensure that the current page being loaded is indeed a Publishing Page (PublishingPage.IsPublishingPage() method, passing in SPContext.Current.ListItem). –  James Love Jun 2 '11 at 18:44
1  
Yep, the FieldRenderingControl which you get for each of the SPFields should have all the logic required for loading & saving of the field contents. –  James Love Jun 2 '11 at 18:51

I've already accepted James' answer as it provided me the information I needed to get the solution. But for future reference, here's a workable code solution. I don't know if it could be optimized to run more efficiently (such as checking the content type), as it is appended to every page.

The process is as follows

  1. Check that the current page is a list item
  2. If it is, is the content type inherits from "Page"?
  3. If we are in edit mode or this is a new form
  4. Find PlaceHolderMain in the master page
  5. Get our FieldRenderingControl's and add them to PlaceHolderMain

Sorry, but I can't figure out the damn code block. The first if statement is not in it Fixed - James Love

if (SPContext.Current != null && SPContext.Current.ListItem != null)
{
    SPContentTypeId pageContentType = SPContext.Current.Web.ContentTypes["Page"].Id;
    if (SPContext.Current.ListItem.ContentType.Id.Equals(pageContentType) ||
    SPContext.Current.ListItem.ContentType.Parent.Id.Equals(pageContentType))
    {
        if (PublishingPage.IsPublishingPage(SPContext.Current.ListItem))
        {
            if (SPContext.Current.FormContext.FormMode == SPControlMode.Edit || SPContext.Current.FormContext.FormMode == SPControlMode.New)
            {
                ContentPlaceHolder placeHolderMain = (ContentPlaceHolder)this.Page.Master.FindControl("PlaceHolderMain");
                if (placeHolderMain != null)
                {
                    SPField seoDescription;
                    try {
                        seoDescription = SPContext.Current.ListItem.Fields["seoDescription"];
                    }
                    catch {
                        seoDescription = null;
                    }
                    if (seoDescription != null)
                    {
                        BaseFieldControl seoDescriptionControl = seoDescription.FieldRenderingControl;
                        if (seoDescriptionControl != null)
                        {
                            seoDescriptionControl.ID = seoDescription.InternalName;
                            placeHolderMain.Controls.Add(seoDescriptionControl);
                        }
                    }
                    SPField seoKeywords;
                    try {
                        seoKeywords = SPContext.Current.ListItem.Fields["seoKeywords"];
                    }
                    catch {
                        seoKeywords = null;
                    }
                    if (seoKeywords != null)
                    {
                        BaseFieldControl seoKeywordsControl = seoKeywords.FieldRenderingControl;
                        if (seoKeywordsControl != null)
                        {
                            seoKeywordsControl.ID = seoKeywords.InternalName;
                            placeHolderMain.Controls.Add(seoKeywordsControl);
                        }
                    }
                }
            }
        }
    }
}

And magic! The 2 fields are added under the existing edit fields and appear as if they are out of the box! We could either re-style them or leave as is.

Edit

Shameless plug: Wrote a blog post to this solution here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.