Vulnerability in EPiServer.Forms
What I'm trying to do today, is to add an existing block (ID:1018) to an entire range of pages. I don't want my users to have to drag this content to every page, it just needs to be there. I can't find anything in the documentation that explains how this can be done.
Thanks for your help.
1. Get your pages from content repository that you want to add the blocks to
2. Get your block you want to add from contentRepository
3. Loop through them and create a writeable clone for every page.
4. Add block to content area property on page.
5. Save page.
var repo = ServiceLocator.Current.GetInstance<IContentRepository>();
// create writable clone of the target Page to be able to update its content area
var writableTargetPage= (MyTargetPage) targetpage.CreateWritableClone();
// Get your block...
var blockToAdd = repo.Get<MyAwesomeBlock>(blockLink);
ContentLink = ((IContent) blockToAdd).ContentLink
repo.Save((IContent) writableTargetPage, SaveAction.Publish);
To get your pages you can use either GetDescendents or FindPagesByCriteria and filter out the ones you are interested in. Since you will likely only run this one, performance shouldn't be a problem :)
You answered my question accurately. The issue is, I asked the wrong question.
So, I need to display an existing block on all pages. I don't ever want my user to have to add (or be able to remove) the block. I want it just to be there with no thought by them. Is there a way, within a view, to add a block via ID? Should I mark this one as solved and create a new post for my actual question?
You could make an editable false property on your page model for a block reference and inject it using the API from your controller or populate it via a publishing event to auto associate it.
If it's something that should be displayed more or less everywhere, the layout model is the best fit. Add a property to that and set it in an action filter or base controller like you would the rest of your layout specific content like footer etc. Check alloy site for good example. Add a partial view for the block and render it. I would avoid making fake properties since it can cause pretty weird results since the pagedatas are basically singletons. If that block depends on what user is logged in, you can end up showing one users information to another. So adding it to your layout model or base viewmodel if you use that is probably the best option.
This is the first piece of development that I've felt other CMS's do better. I'll check the Alloy site. Basically I want every page using a particular template to display a block.
In Ektron this was
var cManager = new ContentManager();
var cData = ContentManager.Get(1015);
AdSpace.InnerHtml = cData.Text;
Or something like that.
I'll check the Alloy site for an example of a layout module and an action filter.
I have the block set up and a partial to render it already. I just wish there was a straightforeward way to permanently and automatically place it in a template.
The rendering part is basically a pure mvc problem. Unfortunately displaying common dynamic content for multiple pages in mvc is a bit tricky.
You could also return a partial view from your controller using your block model view. On your page type you can reference @Html.Action or possibly @Html.Partial to call the particular controller you want to pull in.