Last active
September 8, 2018 18:52
-
-
Save AThraen/17551484c5e2ebd9ce8aa6fcf9a4aaae to your computer and use it in GitHub Desktop.
Gist Fetching Block Content Provider for Episerver
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.ComponentModel.DataAnnotations; | |
| using EPiServer; | |
| using EPiServer.Core; | |
| using EPiServer.DataAbstraction; | |
| using EPiServer.DataAnnotations; | |
| using EPiServer.Web; | |
| namespace AllanTech.Web.Business.ContentProviders | |
| { | |
| /// <summary> | |
| /// Define the Block type to hold the Gist | |
| /// </summary> | |
| [ContentType(DisplayName = "Gist Block", GUID = "bca5e15d-976a-4b0e-8dc0-2b165e052170", Description = "", AvailableInEditMode =false)] | |
| public class GistBlock : BlockData | |
| { | |
| [Editable(false)] | |
| public virtual string Code { get; set; } | |
| [Editable(false)] | |
| public virtual string User { get; set; } | |
| [Editable(false)] | |
| [UIHint(UIHint.Textarea)] | |
| public virtual string Description { get; set; } | |
| [Editable(false)] | |
| public virtual Url HtmlUrl { get; set; } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.Web.Mvc; | |
| using EPiServer.Web.Mvc; | |
| namespace AllanTech.Web.Business.ContentProviders | |
| { | |
| /// <summary> | |
| /// Display the Gist Block | |
| /// </summary> | |
| public class GistBlockController : BlockController<GistBlock> | |
| { | |
| public const string SCRIPTLINE = "<script src=\"https://gist.github.com/{0}/{1}.js\"></script>"; | |
| public override ActionResult Index(GistBlock currentBlock) | |
| { | |
| return Content(string.Format(SCRIPTLINE, currentBlock.User, currentBlock.Code)); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using EPiServer; | |
| using EPiServer.Construction; | |
| using EPiServer.Core; | |
| using EPiServer.DataAbstraction; | |
| using EPiServer.Framework.Cache; | |
| using EPiServer.ServiceLocation; | |
| using EPiServer.Web; | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Collections.Specialized; | |
| using System.Globalization; | |
| using System.Linq; | |
| using System.Web; | |
| namespace AllanTech.Web.Business.ContentProviders | |
| { | |
| public class GistsContentProvider : ContentProvider | |
| { | |
| public const string KEY = "GIST"; | |
| public string Username { get; set; } | |
| //The following region maps from ID to Guids using the first 4 bytes of each guid to store the Int ID. | |
| #region GuidMapping | |
| public static Guid BASEGUID = new Guid("2900353B-DFFF-4EB8-A9BF-3CE237EFA96F"); | |
| public static int IdFromGuid(Guid g) | |
| { | |
| var b = BitConverter.ToInt32(g.ToByteArray().Take(4).ToArray(), 0); | |
| return b; | |
| } | |
| public static bool IsGuidOk(Guid g) | |
| { | |
| var b1 = BASEGUID.ToByteArray(); | |
| var b2 = g.ToByteArray(); | |
| for (int i = 4; i < b1.Length; i++) | |
| if (b1[i] != b2[i]) return false; | |
| return true; | |
| } | |
| public static Guid GuidFromId(int Id) | |
| { | |
| var b1 = BASEGUID.ToByteArray(); | |
| var b2 = BitConverter.GetBytes(Id); | |
| for (int i = 0; i < b2.Length; i++) b1[i] = b2[i]; | |
| return new Guid(b1); | |
| } | |
| #endregion | |
| /// <summary> | |
| /// Return a gistblock | |
| /// </summary> | |
| /// <param name="contentLink"></param> | |
| /// <param name="languageSelector"></param> | |
| /// <returns></returns> | |
| protected override IContent LoadContent(ContentReference contentLink, ILanguageSelector languageSelector) | |
| { | |
| var gist=GetGists().Where(gb => (gb as IContent).ContentLink.CompareToIgnoreWorkID(contentLink)).Cast<IContent>().FirstOrDefault(); | |
| return gist; | |
| } | |
| /// <summary> | |
| /// Used to fetch tree structure | |
| /// </summary> | |
| /// <param name="contentLink"></param> | |
| /// <param name="languageID"></param> | |
| /// <param name="languageSpecific"></param> | |
| /// <returns></returns> | |
| protected override IList<GetChildrenReferenceResult> LoadChildrenReferencesAndTypes(ContentReference contentLink, string languageID, out bool languageSpecific) | |
| { | |
| languageSpecific = false; | |
| if (contentLink.CompareToIgnoreWorkID(EntryPoint)) | |
| { | |
| //Root, list items | |
| return GetGists().Select(g => new GetChildrenReferenceResult() { ContentLink = (g as IContent).ContentLink, IsLeafNode = true, ModelType = typeof(GistBlock) }).ToList(); | |
| } | |
| return base.LoadChildrenReferencesAndTypes(contentLink, languageID, out languageSpecific); | |
| } | |
| /// <summary> | |
| /// Used to resolve Guid, IDs and urls. Needs to work for Gists to remain in content areas. | |
| /// </summary> | |
| /// <param name="contentLink"></param> | |
| /// <returns></returns> | |
| protected override ContentResolveResult ResolveContent(ContentReference contentLink) | |
| { | |
| //Tricky bits | |
| if (contentLink.ProviderName != this.ProviderKey) return null; //Not ours | |
| ContentResolveResult crr = new ContentResolveResult(); | |
| crr.ContentLink = contentLink; | |
| var content = LoadContent(contentLink, null); | |
| crr.UniqueID = content.ContentGuid; | |
| crr.ContentUri = ConstructContentUri(content.ContentTypeID, crr.ContentLink, crr.UniqueID); | |
| return crr; | |
| } | |
| protected override ContentResolveResult ResolveContent(Guid contentGuid) | |
| { | |
| if (!IsGuidOk(contentGuid)) return null; //Not ours | |
| ContentResolveResult crr = new ContentResolveResult(); | |
| crr.ContentLink = new ContentReference(IdFromGuid(contentGuid),this.ProviderKey); | |
| var content = LoadContent(crr.ContentLink, null); | |
| crr.UniqueID = contentGuid; | |
| crr.ContentUri = ConstructContentUri(content.ContentTypeID, crr.ContentLink, crr.UniqueID); | |
| return crr; | |
| } | |
| public override void Initialize(string name, NameValueCollection config) | |
| { | |
| base.Initialize(name, config); | |
| if (config["username"] != null) Username = config["username"]; | |
| LoadGists(); | |
| } | |
| /// <summary> | |
| /// Get Gists from Cache | |
| /// </summary> | |
| /// <returns></returns> | |
| protected List<GistBlock> GetGists() | |
| { | |
| var cache = ServiceLocator.Current.GetInstance<ISynchronizedObjectInstanceCache>(); | |
| var rt = cache.Get<List<GistBlock>>(KEY, ReadStrategy.Immediate); | |
| if (rt == null) | |
| { | |
| rt = LoadGists(); | |
| cache.Insert(KEY, rt, new CacheEvictionPolicy(new TimeSpan(0, 30, 0), CacheTimeoutType.Absolute)); | |
| } | |
| return rt; | |
| } | |
| /// <summary> | |
| /// Load Gists from Github and create objects to put in cache | |
| /// </summary> | |
| /// <returns></returns> | |
| private List<GistBlock> LoadGists() | |
| { | |
| //Load Gists | |
| var gists = GistHelper.LoadGists(Username); | |
| var _typeRepo = ServiceLocator.Current.GetInstance<IContentTypeRepository>(); | |
| var _contentFactory = ServiceLocator.Current.GetInstance<IContentFactory>(); | |
| var _contentRepo = ServiceLocator.Current.GetInstance<IContentRepository>(); | |
| ContentType type = _typeRepo.Load(typeof(GistBlock)); | |
| int i = 1000; | |
| var Gists = new List<GistBlock>(gists.Count()); | |
| foreach (var g in gists.OrderBy(g => g.Created)) | |
| { | |
| var fc = _contentFactory.CreateContent(type, new EPiServer.Construction.BuildingContext(type) | |
| { | |
| Parent = _contentRepo.Get<ContentFolder>(EntryPoint) | |
| }) as GistBlock; | |
| fc.Code = g.Id; | |
| (fc as IContent).Name = g.Files.First(); | |
| fc.Description = g.Description; | |
| fc.HtmlUrl = new Url(g.HtmlUrl); | |
| fc.User = Username; | |
| (fc as IVersionable).Status = VersionStatus.Published; | |
| (fc as IVersionable).IsPendingPublish = false; | |
| (fc as IVersionable).StartPublish = DateTime.Now; | |
| (fc as ILocalizable).Language = CultureInfo.GetCultureInfo("en"); | |
| (fc as IContent).ContentLink = new ContentReference(i, this.ProviderKey); | |
| (fc as IContent).ContentGuid = GuidFromId(i); | |
| (fc as IChangeTrackable).Changed = g.Modified; | |
| (fc as IChangeTrackable).CreatedBy = Username; | |
| (fc as IChangeTrackable).Created = g.Created; | |
| (fc as ILocalizable).MasterLanguage = CultureInfo.InvariantCulture; | |
| (fc as ILocalizable).ExistingLanguages = new List<CultureInfo>(); | |
| fc.MakeReadOnly(); | |
| Gists.Add(fc); | |
| i++; | |
| } | |
| return Gists; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Newtonsoft.Json; | |
| using Newtonsoft.Json.Linq; | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Net; | |
| using System.Web; | |
| namespace AllanTech.Web.Business.ContentProviders | |
| { | |
| /// <summary> | |
| /// Helper class to fetch the gists from github | |
| /// </summary> | |
| public class GistHelper | |
| { | |
| public const string APIPath = "https://api.github.com/users/{0}/gists"; | |
| public static IEnumerable<Gist> LoadGists(string Username) | |
| { | |
| //Load url, create gist objects and return them | |
| WebClient wc = new WebClient(); | |
| wc.Headers.Add(HttpRequestHeader.UserAgent, "Custom"); | |
| string s = wc.DownloadString(string.Format(APIPath, Username)); | |
| var array = JArray.Parse(s); | |
| foreach (var gist in array) | |
| { | |
| var g = new Gist(); | |
| g.Description = gist["description"].Value<string>(); | |
| g.Id = gist["id"].Value<string>(); | |
| g.HtmlUrl = gist["html_url"].Value<string>(); | |
| g.Created = gist["created_at"].Value<DateTime>(); | |
| g.Modified = gist["updated_at"].Value<DateTime>(); | |
| var files = gist["files"].Values(); | |
| g.Files = files.Select(j => j["filename"].Value<string>()).ToList(); | |
| yield return g; | |
| } | |
| } | |
| } | |
| /// <summary> | |
| /// The Gist as it is returned from Github | |
| /// </summary> | |
| public class Gist | |
| { | |
| public string Id { get; set; } | |
| public string Description { get; set; } | |
| public string HtmlUrl { get; set; } | |
| public DateTime Created { get; set; } | |
| public DateTime Modified { get; set; } | |
| public List<string> Files { get; set; } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Specialized; | |
| using System.Linq; | |
| using EPiServer; | |
| using EPiServer.Configuration; | |
| using EPiServer.Core; | |
| using EPiServer.DataAccess; | |
| using EPiServer.Framework; | |
| using EPiServer.Framework.Initialization; | |
| using EPiServer.Security; | |
| using EPiServer.ServiceLocation; | |
| namespace AllanTech.Web.Business.ContentProviders | |
| { | |
| [InitializableModule] | |
| [ModuleDependency(typeof(EPiServer.Web.InitializationModule))] | |
| public class GistProviderInitializer : IInitializableModule | |
| { | |
| public static ContentFolder GetEntryPoint(string name) | |
| { | |
| var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>(); | |
| var folder = contentRepository.GetBySegment(ContentReference.GlobalBlockFolder, name, LanguageSelector.AutoDetect()) as ContentFolder; | |
| if (folder == null) | |
| { | |
| folder = contentRepository.GetDefault<ContentFolder>(ContentReference.GlobalBlockFolder); | |
| folder.Name = name; | |
| contentRepository.Save(folder, SaveAction.Publish, AccessLevel.NoAccess); | |
| } | |
| return folder; | |
| } | |
| /// <summary> | |
| /// Alternative to defining in web.config. | |
| /// </summary> | |
| /// <param name="context"></param> | |
| public void Initialize(InitializationEngine context) | |
| { | |
| var gistprovider = new GistsContentProvider(); | |
| var providerValues = new NameValueCollection(); | |
| var entrypoint = GetEntryPoint("Gists").ContentLink; | |
| providerValues.Add(ContentProviderElement.EntryPointString, entrypoint.ToString()); | |
| providerValues.Add(ContentProviderElement.CapabilitiesString, "None"); | |
| providerValues.Add("Username", "AThraen"); | |
| gistprovider.Initialize(GistsContentProvider.KEY, providerValues); | |
| var providerManager = context.Locate.Advanced.GetInstance<IContentProviderManager>(); | |
| providerManager.ProviderMap.AddProvider(gistprovider); | |
| } | |
| public void Uninitialize(InitializationEngine context) | |
| { | |
| //Add uninitialization logic | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using EPiServer.Shell; | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Web; | |
| namespace AllanTech.Web.Business.ContentProviders | |
| { | |
| [UIDescriptorRegistration] | |
| public class GistUIDescriptor : UIDescriptor<GistBlock> | |
| { | |
| public GistUIDescriptor() : base("icon-document") | |
| { | |
| DefaultView = CmsViewNames.AllPropertiesView; | |
| this.DisabledViews = new List<string>(); | |
| this.DisabledViews.Add(CmsViewNames.OnPageEditView); | |
| this.DisabledViews.Add(CmsViewNames.PreviewView); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment