28.12.2014 Views

Using the new features in Community 4.0 to ... - EPiServer World

Using the new features in Community 4.0 to ... - EPiServer World

Using the new features in Community 4.0 to ... - EPiServer World

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Develop<strong>in</strong>g with <strong>Community</strong> 4 / Relate+ 2<br />

Håkan L<strong>in</strong>dqvist, <strong>Community</strong> Team


2<br />

Agenda<br />

» Brief <strong>EPiServer</strong> <strong>Community</strong> <strong>in</strong>troduction<br />

» What’s <strong>new</strong> <strong>in</strong> <strong>Community</strong> 4 / Relate+ 2<br />

» A more <strong>in</strong>-depth look at a few of <strong>the</strong> <strong>new</strong> <strong>features</strong><br />

» Live Demo (some Visual Studio fun)<br />

» Questions


3<br />

<strong>EPiServer</strong> <strong>Community</strong> <strong>in</strong>troduction<br />

» The core <strong>Community</strong> platform<br />

» APIs that handle data s<strong>to</strong>rage, cach<strong>in</strong>g, aggregation,<br />

etc


4<br />

<strong>EPiServer</strong> <strong>Community</strong> overall architecture<br />

Site / services / o<strong>the</strong>r (eg Relate+)<br />

Moderation / Adm<strong>in</strong><br />

<strong>Community</strong> – MyPage, Blog, Forum, Club, etc.<br />

Cus<strong>to</strong>m<br />

Framework functionality – Tags, Comments, Categories, etc.<br />

Core functionality – Cach<strong>in</strong>g, database access, etc.<br />

Database<br />

Disk s<strong>to</strong>rage


5<br />

<strong>EPiServer</strong> <strong>Community</strong> basics: Create<br />

» Example: Add a blog entry for <strong>the</strong> current user<br />

Blog userBlog = MyPageHandler.Instance.<br />

GetMyPage(SecurityHandler.Instance.CurrentUser).Blog;<br />

Entry entry = <strong>new</strong> Entry(userBlog, "header", "body",<br />

<strong>new</strong> UserAuthor(SecurityHandler.Instance.CurrentUser))<br />

{ Status = EntityStatus.Pend<strong>in</strong>g };<br />

entry = BlogHandler.Instance.AddEntry(entry);


6<br />

<strong>EPiServer</strong> <strong>Community</strong> basics: Read<br />

» Example: Get a paged list<br />

<strong>in</strong>t <strong>to</strong>talItems;<br />

EntryCollection entries = BlogHandler.Instance.<br />

GetEntries(userBlog, EntryPublishState.Published, 1, 5,<br />

out <strong>to</strong>talItems, <strong>new</strong> EntrySortOrder(EntrySortField.Created,<br />

Common.Sort<strong>in</strong>g.Sort<strong>in</strong>gDirection.Descend<strong>in</strong>g));<br />

» Example: Get a specific entry by ID<br />

entry = BlogHandler.Instance.GetEntry(7000);


7<br />

<strong>EPiServer</strong> <strong>Community</strong> basics: Update<br />

» Example: Update a blog entry<br />

entry = entry.Clone() as Entry;<br />

entry.Status = EntityStatus.Approved;<br />

BlogHandler.Instance.UpdateEntry(entry);<br />

entry = BlogHandler.Instance.GetEntry(entry.ID);


8<br />

<strong>EPiServer</strong> <strong>Community</strong> basics: Delete<br />

» Example: Remove an entry (permanently)<br />

BlogHandler.Instance.RemoveEntry(entry);<br />

» Example: Soft-remove an entry (can be res<strong>to</strong>red)<br />

entry = entry.Clone() as Entry;<br />

entry.Status = EntityStatus.Removed;<br />

BlogHandler.Instance.UpdateEntry(entry);


9<br />

<strong>Community</strong> basics: EntityProvider<br />

» Configuration maps types <strong>to</strong> providers<br />

EntityProviderHandler.Instance.<br />

GetEntityProvider(typeof(Entry)).<br />

AddEntityInstance(<strong>new</strong> Entry(...));<br />

entry = EntityProviderHandler.Instance.<br />

GetEntityProvider(typeof(Entry)).<br />

GetEntityInstance(typeof(Entry), 7000) as Entry;<br />

EntityProviderHandler.Instance.<br />

GetEntityProvider(typeof(Entry)).<br />

UpdateEntityInstance(entry);<br />

EntityProviderHandler.Instance.<br />

GetEntityProvider(typeof(Entry)).<br />

RemoveEntityInstance(entry);


What’s <strong>new</strong> <strong>in</strong> <strong>Community</strong> 4<br />

10


11<br />

Some visi<strong>to</strong>r-visible <strong>features</strong> overview<br />

» Full Text Search<br />

» RSS/A<strong>to</strong>m feeds<br />

» RSS/A<strong>to</strong>m syndication<br />

» Metaweblog API publish<strong>in</strong>g<br />

» HTML filter<strong>in</strong>g<br />

» OpenID


12<br />

Developer <strong>features</strong><br />

» IContent <strong>in</strong>terface<br />

» Owner system<br />

» Site object has been elim<strong>in</strong>ated<br />

» Category system replaces Site, fetch entities by<br />

category<br />

» Handlers s<strong>in</strong>gle<strong>to</strong>ns <strong>in</strong>stead of static<br />

» URI providers<br />

» Event Counter


13<br />

Developer <strong>features</strong> (cont<strong>in</strong>ued)<br />

» EntityStatus<br />

» EntitySecurity<br />

» EntityProvider system has been extended <strong>to</strong> do not<br />

only read but CRUD<br />

» EntityReference<br />

» GUIDs as an alternative means of referenc<strong>in</strong>g entities


14<br />

Changed site setup<br />

» Switched <strong>to</strong> log4net based logg<strong>in</strong>g<br />

» <strong>EPiServer</strong> Events utilized <strong>in</strong> cluster environments<br />

(Cache notifications, etc)<br />

» Utilizes <strong>EPiServer</strong> Framework siteHostMapp<strong>in</strong>g for<br />

multi-site, ”enterprise”, configurations.<br />

» Starts as an <strong>EPiServer</strong> Framework <strong>in</strong>itialization<br />

module.<br />

» User <strong>in</strong>tegration simplified


An <strong>in</strong>-depth look at some <strong>new</strong> <strong>features</strong><br />

15


16<br />

IContent – consistency, generic handl<strong>in</strong>g<br />

» Dictates generic content properties<br />

public <strong>in</strong>terface IContent : IEntity, ..., ILocalized<br />

{<br />

IAuthor Author { get; set; }<br />

str<strong>in</strong>g Body { get; set; }<br />

DateTime Created { get; }<br />

str<strong>in</strong>g Header { get; set; }<br />

DateTime Modified { get; }<br />

}<br />

public <strong>in</strong>terface ILocalized<br />

{<br />

str<strong>in</strong>g LanguageID { get; set; }<br />

}


17<br />

Owner system<br />

» Creates relationship between arbitrary entities<br />

» An entity can only have a s<strong>in</strong>gle owner<br />

» Owned entities are removed when owner is removed<br />

» Example: Set ownership<br />

imageGallery.OwnedBy.Entity = entry;<br />

imageGallery.OwnedBy.Context = "special_blog_pictures";<br />

ImageGalleryHandler.Instance.UpdateImageGallery(imageGallery);


18<br />

Owner system (cont<strong>in</strong>ued)<br />

» Example: Get specific owned object, or all owned<br />

objects for a specific entity<br />

EntityReference galleryReference =<br />

OwnerHandler.Instance.GetOwnedObject(entry,<br />

"special_blog_pictures");<br />

IDictionary owned =<br />

OwnerHandler.Instance.GetObjectsByOwner(imageGallery);<br />

galleryReference = owned["special_blog_pictures"];<br />

imageGallery = galleryReference.GetEntity() as<br />

ImageGallery;


20<br />

GUIDs for entities<br />

» UniqueID property on entities<br />

» Can get EntityReference by GUID<br />

» Useful when reference has <strong>to</strong> be persisted<br />

Guid entryGuid = entry.UniqueID;<br />

EntityReference entryReference = EntityProviderHandler.Instance.<br />

GetEntityReference(entryGuid);<br />

entry = entryReference.GetEntity() as Entry;


21<br />

Full Text Search overview<br />

» Implemented as client/service<br />

» Search client <strong>in</strong>cluded <strong>in</strong> <strong>EPiServer</strong> Framework<br />

» Site pushes data <strong>to</strong> <strong>in</strong>dex, no crawl<strong>in</strong>g<br />

» Pro<strong>to</strong>col open (essentially A<strong>to</strong>m feeds sent <strong>in</strong> a<br />

REST-like fashion)<br />

» Default service implementation <strong>in</strong>cluded, based on<br />

Lucene.net


22<br />

Full Text Search <strong>in</strong> <strong>Community</strong><br />

» <strong>Community</strong> entities, as specified by type name <strong>in</strong> <strong>the</strong><br />

configuration are <strong>in</strong>dexed tak<strong>in</strong>g values from<br />

IContent, <strong>the</strong>n any specifics on a type by type basis<br />

» Relate+ extends this by also <strong>in</strong>dex<strong>in</strong>g CMS pages<br />

and files which become searchable through <strong>the</strong> same<br />

<strong>in</strong>terface


23<br />

EntitySecurity<br />

» Example: Give Read and Modify permission <strong>to</strong> user:<br />

EntitySecurityHandler.Instance.<br />

SetAccessRights(entry, user,<br />

<strong>new</strong> EntryAccessRights()<br />

{ Read = true, Modify = true });<br />

» Example: Check if user has Read permission:<br />

bool hasAccess = EntitySecurityHandler.Instance.<br />

CheckAccess(entry, user,<br />

<strong>new</strong> EntryAccessRights()<br />

{ Read = true });


24<br />

Demo<br />

» Demo


25<br />

Questions<br />

» Questions<br />

» hakan.l<strong>in</strong>dqvist@episerver.com

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!