I have a couple of questions regarding the pageprovider concept, I hope you could help me.
Little background....I have a page (Node A) with some 'childrens' that must be mirrored to other places on current site i.e other places in the epi-tree-view (Node B,C..X) so I thought that a pageprovider should be the right thing to use.You should not be allowded to edit pages fetched from 'Node A' in 'Node B,C...X' so pages rendered in Node B,C..X are just "read pages". I have no problem in making a basic pageprovider that replicates pages to on "entry point" and I wonder:1) To specify where the copied pages should start to render from, is there a way for example to create a 'Page B' that has one property ('Startpoint') that points out from which node you should fetch all children from i.e create pageprovider for 'Page B' and append all children fetched from 'StartPoint'? If 1) is possible should I add one pageprovider per 'Node' where children are rendered from i.e one provider with unique "entrypoint" or?2) If I make a simple pageprovider the links gets incorrect. Links are the same as in Node A they are not mapped to current Node's context.... is there a way to genereate correct links and show page data in current context?3) Is this the right way to go or do you have other recommendations?
Thanks in advance!
Regarding number 2 I think you're out of luck. Seems like a big task to solve the links.
I've uploaded a page provider here http://world.episerver.com/Code/Johan-Pettersson/Local-page-provider/ and planning a blog post for it.
As Johan says solving number 2 can be a challenge.... But with that said here is a suggestion on how it could be done:
Links between pages within EPiServer are stored as something called permanentLinks, basically it is a link based on the PageGuid on the PageData instance. This has the consequence that to be able to uniquely reference a "cloned" page then clone must have a unique Guid.
So what you need to do is that each PageProvider must have unique Guid based identifiers, that means you need to modify the PageGuid (and possibly LinkUrl) when you clone a page. However to not breaks links when site is restarted you probably need to save a Guid map table somewhere. In your PageProvider you must also implement ResolveLocalPage to handle your mapped guids.
In my provider all provider pages are stored in the DDS with new Guids, so I guess you could roll your own url rewriter too and fix all links. I guess there is some caveats and considerations but probably doable.
Thanks for your answers!
I have found a code example made by Johan Björnfot where you have a PageGuidStrategy that looks promising:
I have read a lot of posts on this forum and I came across of this post, also written by Johan Börnfot:
There is a warning if you are developeing an enterprise site and implementing pageproviders and using InitializePageData
"When implementing a custom page provider, the recommended way to initialize a PageData object (that is to populate the instance with properties) is to call the method InitializePageData on PageProviderBase.".... and later on there is a warning using this method because of an increasement of a counter in the system
My question is when should InitializePageData be called is it in overrided method in your pageprovider "protected override PageData GetLocalPage(PageReference pageLink, ILanguageSelector languageSelector)" ?
in example A) above you just make a new PageData object using page.CreateWritableClone()
Im not sure where InitializePageData should be called and If example A) will increase that counter (under the surface somewhere)?
The counter that was warned about in the post was a counter for PageFolderId. That was however fixad in cms6 so in cms6 it should be safe to use InitalizePageData. The recommendation is to not set capability PageFolder if your custom pages does not use unique folders. In your case when you clone other pages you should not set capability PageFolder.
M M please let me know if you come up with any improvements or find any bugs.
I used CreateWriteableClone() in lack of better knowing and it worked out great. I guess there is a better way, but this was an easy way.
Thanks for your clarifications!
I have 2 other question that I havent found any answers for that I would be very happy if you could...
1) Lets say i have some short links for pages that is in collection Node A (in my first post) is there possible to set shortlinks for pages that are provided in pageprovider collection? 2) Pages that are fetched from NodeA has som shortlinks on page i.e <a href='/someshortlink'>link</a> i have a strategy to replace those links to matching links in nodeB,C?..X but is there a way to trigger this replacement so the output html match for linkstrukture in NodeB,C...X....should I make an urlrewriter for this purpose or what do you recommend? Thanks!
The builtin handler for SimpleAddress (shortlink) will in its implementation call db to resolve simple addresses. That has the consequence that only pages delivered by local/default provider will be handled.
So to handle simple address in a custom provider you would need to hookup to urlrewriting (you probably do not need to implement an own provider but can hook up to an incoming event instead) and in the eventhandler call your provider to see if it can resolve simple address.
Johan, a question regarding your examplecode:
Pages generated with your predifinedGuidMapStrategy are they stored in memory or?