geta / tags Goto Github PK
View Code? Open in Web Editor NEWGeta Tags for EPiServer CMS
License: Apache License 2.0
Geta Tags for EPiServer CMS
License: Apache License 2.0
First of all: we would like to say that we really appreciate the GetaTags plugin and all the work you did for it. However, we encountered a situation that the edit function in the admin control does only edit the tags in the internal tagrepository and does not edit the tags in the existing content of Episerver (the ContentRepository). Though this exactly the functionality one of our customers is looking for!
We already worked on a working solution to search for the properties with the Tags attribute, create a writable clone of it and save the editted tag again. We suggest that you problably can implement this in a new update of the plugin. Can we/you maybe create a Fork where we can pull our code change so you can do a code review in it?
Thanks so much in advance!
Hello!
We got a really weird bug showing up in geta-tags.
Some tags/words seems to be causing the modul to delete tags when you publish/save.
There is no special characters in the words that causes the bug to appear.
There is no errors showing up in log4net.
Sometimes I get error-message in chrome, however sometimes there are no errors there either oddly enough.
TypeError: Cannot read property 'tagName' of undefined
at _68.placeAt (widgets.js:2)
at _191b.addChild (widgets.js:2)
at Object.addWidgetToRootFunction (widgets.js:2)
at null. (widgets.js:2)
at dojo.js:15
at _2f2 (dojo.js:15)
at Promise.then._2ff.then (dojo.js:15)
at when (dojo.js:15)
at _5f1._createInternal (widgets.js:2)
at null. (widgets.js:2)(anonymous function) @ widgets.js:2
2widgets.js:2
TypeError: Cannot read property 'appendChild' of null
at Object.place (dojo.js:15)
at _13d.addChild (widgets.js:2)
at _19e (dojo.js:15)
at _6b7.addChild (widgets.js:2)
at _19e (dojo.js:15)
at _1256.addChild (widgets.js:2)
at _19e (dojo.js:15)
at _191b.addChild (widgets.js:2)
at Object.addWidgetToRootFunction (widgets.js:2)
at null. (widgets.js:2)(anonymous function) @ widgets.js:2
widgets.js:2 WidgetFactory: Could not resolve one or more widgets(anonymous function) @ widgets.js:2
widgets.js:2
TypeError: Cannot read property 'tagName' of undefined
at _68.placeAt (widgets.js:2)
at _191b.addChild (widgets.js:2)
at Object.addWidgetToRootFunction (widgets.js:2)
at null. (widgets.js:2)
at dojo.js:15
at _2f2 (dojo.js:15)
at Promise.then._2ff.then (dojo.js:15)
at when (dojo.js:15)
at _5f1._createInternal (widgets.js:2)
at null. (widgets.js:2)(anonymous function) @ widgets.js:2
Any help or tips on how to proceed would be greatly appreciated!
Request.
I would like to see a colorpicker for tags.
It would be great if it was possible to only let editors choose from existing tags.
To manage tags a simple admin plugin page would be nice.
It would also be great to have two tag stores. One with tags where editors can add tags and one that only admins can add tags to from a admin plugin or something like that.
Maximum flexibility :)
Hi,
We are using Geta Tags 2.1.13 from past 2 years in our EPiServer 9.2 application. Recently we applied TagsGroupKey. Below are the code,
` [TagsGroupKey("myTags")]
[UIHint("Tags")]
[Display(Name = "Tags", GroupName = SystemTabNames.Content, Order = 100)]
public virtual string TagData { get; set; }
[TagsGroupKey("myTags2")]
[UIHint("Tags")]
[Display(Name = "Tags2", GroupName = SystemTabNames.Content, Order = 101)]
public virtual string TagsSecond { get; set; }`
Before adding the GroupKey, Mirroring service does not required to have "Geta.Tags.ddl" in bin folder, and it use to work as expected.
After adding the GroupKey, mirroring service failing with error below,
Exception has been thrown by the target of an invocation. [ Error executing task "TestMirror": Initialize action failed for Initialize on class EPiServer.Initialization.ModelSyncInitialization, EPiServer, Version=9.2.0.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7 (Could not load file or assembly 'Geta.Tags, Version=2.1.13.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.) ]
To resolve the above error I have placed Geta.Tags.dll into bin folder, now I an getting new error below.
Mirroring job: 'TestMirror' Mirroring state: Failure during export The following errors occured: Object reference not set to an instance of an object. SourceService: Exported 0 pages TargetService: Imported 0 pages, moved 0 pages, deleted 0 pages including children
EPiServerLog Error,
2019-01-24 03:14:50,504 [13] ERROR EPiServer.MirroringService.Proxy.RuntimeMirroringProxy: StartMirroring Failed System.NullReferenceException: Object reference not set to an instance of an object. at EPiServer.Enterprise.DataExporter.CleanupPackage() at EPiServer.Enterprise.DataExporter.Export() at EPiServer.MirroringService.MirroringSourceService.MirroringExporter.SendPackage(DataExporter exporter, TypeOfPackage typeOfpackage) at EPiServer.MirroringService.MirroringSourceService.MirroringExporter.ExportPackages() at EPiServer.MirroringService.MirroringSourceService.MirroringExporter.Export() at EPiServer.MirroringService.Proxy.RuntimeMirroringProxy.StartMirroring(Guid contextId, ValidationContext validationContext)
Can anyone please help me in this regard to resolve it.
Thanks in Advance,
Hari
I'm using EPiserver Find to find articles that contains any tag or part of tag (free text search).
If an article is tagged "Drive". I want a hit when searching part of the word.
"riv" should get me a search hit.
But I can't make it work. I'm still not sure if this is an issue on the Geta Tag side or on the EPiServer Find side.
EPiServer support told me to put a question in this Forum.
This was I sent to them:
UnifiedSearch - Filtering problem
var hitSpecification = new HitSpecification();
var query = SearchClient.Instance.UnifiedSearch();
query = query.Filter(x => x.MatchTypeHierarchy(typeof(NewsPage)) |
(x.MatchTypeHierarchy(typeof(Blog)) & ((Blog)x).DisplayInNewsFlow.Match(1))
query = query.MatchTags(criterias.Tags);
UnifiedSearchResults searchResult = query.GetResult(hitSpecification);
}
public static ITypeSearch MatchTags(
this ITypeSearch search, string tags)
{
var tagsBuilder = SearchClient.Instance.BuildFilter();
// criterias.Tags is a list of strings ie "TT Jec"
// x.SearchMetaData["Tags"] is also a list of strings ie "TT,AA, Subject,CC"
foreach (string tag in tags.Split(' ').ToList())
{
tagsBuilder =
tagsBuilder.Or(x => x.SearchMetaData["Tags"].StringValue.Contains(tag).Match(true));
}
return search.Filter(tagsBuilder);
}
The goal is to compare those two lists. If one of the strings in criterias.Tags exists or is a part of at
least one of the strings in x.SearchMetaData["Tags"]. I want that item in the result.
This is working - but I don't want a hit on only AnyWordBeginsWith. I want also a hit when
AnyWordWith/Contains in the x.SearchMetaData["Tags"] list
tagsBuilder = tagsBuilder.Or(x => x.SearchMetaData["Tags"].StringValue.AnyWordBeginsWith(tag));
This is not working, Why?
tagsBuilder = tagsBuilder.Or(x =>
x.SearchMetaData["Tags"].StringValue.Contains(tag).Match(true));
or
tagsBuilder = tagsBuilder.Or(x =>
x.SearchMetaData["Tags"].StringValue.indexOf(tag).GreaterThan(-1));
In the exampel above.
Searching on "Jec" should give a hit on "Subject".
When a page gets deleted, does the tag(s) get updated to remove references to the deleted page?
We updated EPiServer to 9.8.0 and suddenly we can't add any new tags in an empty editor. On pages where tags had already been added we can edit and add new, but if we remove them all we can't add any new. Newly created pages can't add tags either.
We are running the latest version 2.1.9
Quite bothersome. Do you have any solution for this?
We have a multi-site/lingual there all languages gets the same suggestions for tags. So for example Norwegian and Danish are really close and easy to pick the wrong tag. Either have a seperate example "feed" for each site or for each country.
Hi Guys,
i just updated the Geta.Tags package to the latest version 2.1.17 just for the nice new admin interface to remove/edit tags.
Update goes well, but when i go to admin --> tools --> Geta tags management i get a 404 error.
The urls points to /GetaTagsAdmin/Index
So what am i missing here? Looks like it can't find the Index view.
I see in my solution under Modules -> Geta.Tags -->2.1.17 --> Views --> Admin --> Index.cshtml
So the files are there...
can someone pls give some insight?
I also update EPi to the current latest version.
Hi guys,
i'm experiencing a strange thing. I hope you can replicate this.
I have this problem with more pages.. All pages that once had the tag and now are removed, are always fetched when asking for a tag it once had...
Hope you can replicate this also, but more importantly fix it soon, as a client found this problem... Using the latest Geta Tags with latest EPiServer 8.8.*
P.S i could reproduce this on a clean MVC Alloy site as well...
When supplying the ITagEngine.GetPageReferencesByTags method with tags it does seem to return the proper amount of PageReference's, however all references seem to be empty.
The cause for this seems to be the TagsHelper.GetPageReference method. This method tries to cast the result of PermanentLinkMapStore.Find to a EPiServer.Web.PermanentPageLinkMap. This fails because the result is actually a EPiServer.Web.PermanentContentLinkMap (seems to be a new type in EPiServer 7).
When the safe cast fails the TagsHelper.GetPageReference method returns PageReference.Empty.
The error is
epi.js:2 TypeError: $.hubConnection is not a function
This is due to Gheta.Tags including its own version of jQuery and overwriting the version that already exists. Removing the reference to jquery breaks the included jquery.ui version.
I would recommend using jquery noconflict, but I'm not sure that is possible given the plugins required for this plugin.
After adding Tags to SitePageData the All Properties view becomes inaccessible.
After installing Geta.Tags with Nuget, there is no CustomProperty for tags in the Admin View. I also cannot edit any page or block with a Tag Property.
Hi
First and all i would like to thank you for this great plugin.
Im wondering if it is possible to make the tags sortable with the use of ex drag & drop, i researched a bit on the net and found this two posts:
https://stackoverflow.com/questions/5222206/how-can-i-make-this-tagging-system-sortable
https://stackoverflow.com/questions/14553917/using-sortable-with-tag-it-jqueryui
From what i can see at the tag-it doc's no sortable feature exists out of the box.
Hi Frederik, can you make this package suitable for EPiServer 7.5
Hi,
Thanks for developing this feature, we have implemented Geta Tags in our EPiServer 9.2 instance and its working good, except for when we do mirroring.
The datastore is not getting mirrored. The string property values are getting mirrored but not the Tag data store.
Please let me know if i have missed anything.
Does not show saved tags when the property is placed in the page header.
[UIHint("Tags")]
[Display(GroupName = SystemTabNames.PageHeader, Order = 50)]
public virtual string Tags { get; set; }
PM> Install-Package Geta.Tags
Install-Package : Unable to find package 'Geta.Tags'
At line:1 char:1
- CategoryInfo : NotSpecified: (:) [Install-Package], Exception
- FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
PM>
This is package source:
https://api.nuget.org/v3/index.json
When saving tags TagsModule.cs will only look for a property named "Tags" when getting the TagGroup:
private void OnPublishedContent(object sender, ContentEventArgs e)
{
var content = e.Content;
var tags = GetContentTags(content);
CleanupOldTags(content.ContentGuid);
var pageType = _contentTypeRepository.Load(content.ContentTypeID);
var tagsProp = pageType.ModelType.GetProperty("Tags");
var groupKeyAttribute = (TagsGroupKeyAttribute)tagsProp.GetCustomAttribute(typeof(TagsGroupKeyAttribute));
var cultureSpecificAttribute = (CultureSpecificAttribute)tagsProp.GetCustomAttribute(typeof(CultureSpecificAttribute));
string groupKey = Helpers.TagsHelper.GetGroupKeyFromAttributes(groupKeyAttribute, cultureSpecificAttribute);
_tagService.Save(content.ContentGuid, tags, groupKey);
}
Scenario:
Page with Tags:
[UIHint("Tags")]
public virtual string Tags { get; set; }
When editing a translated page, the Tags property should not be editable. However, the textbox allows input.
EPiServer rejects the modifications so no changes are persisted.
I have not tested if the Tags property is decorated with [Editable(false)], but this might be another similar use case as well.
In ApplyEditChanges() in PropertyTagsControl.cs , a nullreference exception is thrown when using blocks. This is due to the fact that the guid is based on the CurrentPage object. By editing this method the following way, we were able to correct the error:
public override void ApplyEditChanges()
{
string tags = this.TextBox.Text;
var guid = Guid.Empty;
if (CurrentPage != null)
{
guid = CurrentPage.PageGuid;
}
else if (CurrentContent != null)
{
guid = CurrentContent.ContentGuid;
}
if (!string.IsNullOrEmpty(tags))
{
foreach (string name in tags.Split(','))
{
this.TagService.Save(guid, name);
}
}
this.SetValue(tags);
}
Hello Maris,
My name is Faten and we have worked on GetaTags integration with Episerver CMS on the website
We are facing an issue with saving the tags, we contacted Episerver regarding this issue as we thought it’s a permissions issue, but they advised to check with you
Our issue that when saving or publishing the page from the CMS, this field is not saved only for users that are in the “web editors” group. “Web admins” are able to save normally.
Is there any kind of permissions that should be set in order to work for editors?
Thank you for your assistance
Best Regards
Faten
Hi,
After the Update you get this error from the request http://domain/getatags?term=myterm.
[MissingMethodException: Ingen parameterlös konstruktor har definierats för det här objektet.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +159
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +256
System.Activator.CreateInstance(Type type, Boolean nonPublic) +127
System.Activator.CreateInstance(Type type) +78
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +92
[InvalidOperationException: An error occurred when trying to create a controller of type 'Geta.Tags.Controllers.GetaTagsController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +256
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +169
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +270
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +147
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +12288259
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288
Hey Guys,
we have a client working with geta.tags on epi 8.xx and on production.
We are doing a new release, and on our test env. we upgraded to Epi 9.xx and consequently updated Geta Tags to the latest version as well.
The problem is that existing tags in properties are not visible in the CMS. however, the front-end still shows the tags. So they are there. Also i cannot add new tags. I dont get autocomplete function when typing. I dont get any console errors either..
I can see that when typing in the property, the following api is getting called /getatags?groupKey=en-US&term=agenda
However whatever i type, the array is always empty.
This is a serious problem now, because we cannot put this non-working version live again and we are working against a deadline. So any input would be helpful...
thanks alot.
Using the Geta.Tags plugin 1.0.1 from Nuget on a EPiServer 7.5 site but having some issues where the tags aren't updated on a save/publish of the page. Typically this happens if you edit an existing page and remove existing tags (either but clicking the X on the tag/s or use backspace in the edit field to remove tags) and then add some new tags.
Ocassionally I have also noticed that it also happens that adding new tags don't trigger the Publish command even after moving to another text input, seems to be related to the issue above.
Using Google Chrome Version 37.0.2062.94 m on Windows 8.1.
I have added the tags property to my content type using the following code:
[UIHint("Tags")] [Display( Name = "Tags", Description = "The tags", GroupName = GroupNames.Tabs.MetaData, Order = 11)] [CultureSpecific] public virtual string Tags { get; set; }
When I add a tag to the tags field using the CMS interface I get the following generic error during auto save (and also during publish):
See attachment for the stack trace of the underlying error that occurs on /EPiServer/cms/Stores/contentdata/114_525:
geta_tags_error_stack.txt
I'm using CSM version 9.12.0
The CultureSpecificAttribute sets the GroupKey value depending on CMS language, meaning an editor would have to change his personal language to create language-specific tags on a multi-language setup. Perhaps setting the groupkey value depending on the ContantLanguage would be better. That way an editor with his/her CMS-language set to English could create tags on separate language sites.
The problem occurs when for example a user has selected English as 'CMS language', and a page was created for the Norwegian language, then the entered tags are marked as English.
In a page type; If you have one Tag property without TagGroup attribute specified, and one with TagGroup, the TagGroup is used for GetTags(..) on both properties, even though the first one does not have any TagGroup specified.
I've temporary solved it by hardcoding the property name in the TagSelection.js:
define([
"dojo/_base/declare",
"dijit/form/TextBox",
],
function (
declare,
TextBox) {
return declare([TextBox], {
postCreate: function () {
var $domNode = $(this.domNode),
isReadonly = $domNode.hasClass('dijitReadOnly');
var tagsInput = $domNode.find('input');
if (tagsInput[0].name == 'taggedWith') {
tagsInput.tagit({
autocomplete: { delay: 0, minLength: 2, source: '/getatags' },
readOnly: isReadonly
});
} else {
tagsInput.tagit({
autocomplete: { delay: 0, minLength: 2, source: '/getatags?groupKey=' + this.groupKey },
readOnly: isReadonly
});
}
}
});
});
When using Tags in Epi 9.2 you get error on publishing on blocks/media
Error: Value cannot be null, Parameter name: element", seems like it is a dependency on a old version of Structuremap that makes the problem after debugging around.
Good morning!! Hope you are doing good.
I am doing a POC on Geta.Tags and trying to implement tag feature to a Page Type.
I have added a property to assign tags.
[UIHint("Tags")]
public virtual string Tags { get; set; }
Next I want to filter pages based on tags.But I am facing some challenge.I have implemented ITagEngine and it's dependent interfaces.
Code Snippet of TagEngine class which is implementing ITagEngine:
[ServiceConfiguration(typeof(ITagEngine))]
public class TagEngine : ITagEngine
{
private readonly ITagService _tagService;
private readonly IContentLoader _contentLoader;
public TagEngine(ITagService tagService, IContentLoader contentLoader)
{
this._tagService = tagService;
this._contentLoader = contentLoader;
}
[Obsolete("Use GetContentByTag instead.")]
public PageDataCollection GetPagesByTag(string tagName)
{
if (string.IsNullOrEmpty(tagName))
{
return null;
}
return this.GetPagesByTag(this._tagService.GetTagByName(tagName));
}
I want to call this GetPagesByTag.To create the object of TagEngine class it needs two parameter.So I got confuse on this ,How to pass it?
Please help me get rid of this problem.
When i add more then one tag at the same time it only saves the first newly added tag.
Hi All,
I want to create a tag property with a key like below example
[TagsGroupKey("mykey")]
[UIHint("Tags")]
public virtual string Tags { get; set; }
but TagsGroupKey is not idetifiable.Can anybody help me how to get it.
Hi Guys,
there was an issue previously inserted: #47
I see now that it was partially fixed. The admin section is now visible (no 404 anymore), but when you try to edit or delete an tag in the list you get a 404.
So that part is not working yet..
Hey guys,
wouldn't it be nice if the editors could have an overview (maybe dashboard) of all the tags they have in the tagstore?
I would like to be able to add a comma in a tag ie "Hey, what's up?".
I would like to be able to sort the tags by drag-and-drop. If I want to add a tag in the beginning of the list I have to delete all tags and start all over again.
Trying to use tags in EPiServer 7.5 but I can't create tags containing the space character since it automatically creates a tag when the space key is pressed, i.e. can't add a tag like "Best deal" or similiar. Bug, feature or I'm I missing out on something?
I have a website with two roots, i want to use the same tag for the differnet pages under the two roots.
The problem is that if I used the groupkey i will not be able to differeniate which tags for which page.
Also if I want to delete the tag will be deleted from all the pages under the two roots.
Is there a way to use the same tag as duplicate?
When tagging a page with an existing tag by clicking the tag, EPiServer is not registering the textbox as changed, thus not saving the tag-property on "Save & publish".
This does not seem to be an issue if you are creating a new tag.
However, selecting the existing tag by using the up/down keys + Enter will trigger the textbox changed.
Tried with latest vanilla Alloy site and latest Geta.Tags version.
When installing using Nuget it overwrites the existing web.config. This looks like a bug to me.
Here are the details:
http://world.episerver.com/Modules/Forum/Pages/Thread.aspx?id=81851&epslanguage=en
We have 2 different website in the same solution, I read that we can use (TagsGroupKey("mysite")) for the tags property.
But how can I get the tags for each website alone.
/getatags/?name=test won´t work without default ASP.NET MVC route registered. Should be automatically registered by Geta.Tags for this one controller.
Perhaps I'm missing something but I can't get it to save tags.
I've added a new property to an Page contenttype in EPiServer7
[UIHint("Tags")]
[BackingType(typeof(PropertyTags))]
public virtual string Tags { get; set; }
When I click the button in the Admin to enter a tag, I can enter a tag but when I click save it doesn't get saved.
I really want to use this plugin otherwise I have to fall back to a Categories solution.
Hi,
Can you please provide support for IContent instead of just PageData? Currently the autocomplete are not working within types like blockdata and mediadata.
I believe there is more developers out there including yourselves that wanna be able to have full support and tags for different types of data with this in EPiServer.
Below is just a very quick fix for it to work on these types (PageData, BlockData and MediaData), for saving new tags in the DDS and beeing able to fetch them in autocomplete. Thanks in advance and great job building this Tag engine!
Changes in TagsScheduledJob.cs
using System;
using System.Collections.Generic;
using System.Linq;
using EPiServer;
using EPiServer.BaseLibrary.Scheduling;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.PlugIn;
using EPiServer.ServiceLocation;
using Geta.Tags.Implementations;
using Geta.Tags.Interfaces;
using Geta.Tags.Models;
using Geta.Tags.Helpers;
namespace Geta.Tags
{
[ScheduledPlugIn(DisplayName = "Geta Tags maintenance", DefaultEnabled = true)]
public class TagsScheduledJob : JobBase
{
private bool _stop;
private readonly ITagService _tagService;
private readonly IContentTypeRepository _pageTypeRepository;
public TagsScheduledJob() : this(new TagService())
{
IsStoppable = true;
}
public TagsScheduledJob(ITagService tagService)
{
_tagService = tagService;
_pageTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
}
public override string Execute()
{
var tags = _tagService.GetAllTags().ToList();
var pageGuids = GetTaggedPageGuids(tags);
foreach (var pageGuid in pageGuids)
{
if (_stop)
{
return "Geta Tags maintenance was stopped";
}
IContent page = null;
try
{
var contentReference = TagsHelper.GetPageReference(pageGuid);
if (!ContentReference.IsNullOrEmpty(contentReference))
{
page = DataFactory.Instance.GetPage(contentReference);
}
}
catch (PageNotFoundException) {}
if (page == null || page.IsDeleted)
{
RemoveFromAllTags(pageGuid, tags);
continue;
}
CheckPageProperties(page, tags);
}
return "Geta Tags maintenance completed successfully";
}
private void CheckPageProperties(IContent page, IList<Tag> tags)
{
var pageType = _pageTypeRepository.Load(page.ContentTypeID);
foreach (var propertyDefinition in pageType.PropertyDefinitions)
{
if (!TagsHelper.IsTagProperty(propertyDefinition))
{
continue;
}
string tagNames = null;
if (page is PageData)
{
var pd = page as PageData;
tagNames = pd[propertyDefinition.Name] as string;
}
if (page is BlockData)
{
var bd = page as BlockData;
tagNames = bd[propertyDefinition.Name] as string;
}
if (page is MediaData)
{
var md = page as MediaData;
tagNames = md[propertyDefinition.Name] as string;
}
IList<Tag> allTags = tags;
if (tagNames == null)
{
RemoveFromAllTags(page.ContentGuid, allTags);
continue;
}
var addedTags = ParseTags(tagNames);
// make sure the tags it has added has the pagereference
ValidateTags(allTags, page.ContentGuid, addedTags);
// make sure there's no pagereference to this pagereference in the rest of the tags
RemoveFromAllTags(page.ContentGuid, allTags);
}
}
private static IEnumerable<Guid> GetTaggedPageGuids(IEnumerable<Tag> tags)
{
return tags.Where(x => x != null && x.PermanentLinks != null)
.SelectMany(x => x.PermanentLinks)
.ToList();
}
private IEnumerable<Tag> ParseTags(string tagNames)
{
return tagNames.Split(',')
.Select(_tagService.GetTagByName)
.Where(tag => tag != null)
.ToList();
}
private void ValidateTags(ICollection<Tag> allTags, Guid pageGuid, IEnumerable<Tag> addedTags)
{
foreach (var addedTag in addedTags)
{
allTags.Remove(addedTag);
if (addedTag.PermanentLinks.Contains(pageGuid)) continue;
addedTag.PermanentLinks.Add(pageGuid);
_tagService.Save(addedTag);
}
}
private void RemoveFromAllTags(Guid guid, IEnumerable<Tag> tags)
{
foreach (var tag in tags)
{
if (tag.PermanentLinks == null || !tag.PermanentLinks.Contains(guid)) continue;
tag.PermanentLinks.Remove(guid);
_tagService.Save(tag);
}
}
public override void Stop()
{
_stop = true;
}
}
}
Changes in TagsModule.cs
using System;
using System.Collections.Generic;
using System.Linq;
using EPiServer;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using Geta.Tags.Helpers;
using Geta.Tags.Implementations;
using Geta.Tags.Interfaces;
namespace Geta.Tags
{
[ModuleDependency(typeof (ServiceContainerInitialization))]
public class TagsModule : IInitializableModule
{
private ITagService _tagService;
private IContentTypeRepository _pageTypeRepository;
private void OnPublishedPage(object sender, ContentEventArgs e)
{
var page = e.Content;
var tags = GetPageTags(page);
_tagService.Save(page.ContentGuid, tags);
}
private IEnumerable<string> GetPageTags(IContent page)
{
var pageType = _pageTypeRepository.Load(page.ContentTypeID);
return pageType.PropertyDefinitions
.Where(TagsHelper.IsTagProperty)
.SelectMany(x => GetPropertyTags(page, x));
}
private static IEnumerable<string> GetPropertyTags(IContent page, PropertyDefinition propertyDefinition)
{
string tagNames = null;
if (page is PageData)
{
var pd = page as PageData;
tagNames = pd[propertyDefinition.Name] as string;
}
if(page is BlockData)
{
var bd = page as BlockData;
tagNames = bd[propertyDefinition.Name] as string;
}
if(page is MediaData)
{
var md = page as MediaData;
tagNames = md[propertyDefinition.Name] as string;
}
return tagNames == null
? Enumerable.Empty<string>()
: tagNames.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
}
public void Initialize(InitializationEngine context)
{
_tagService = new TagService();
_pageTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
DataFactory.Instance.PublishedContent += OnPublishedPage;
}
public void Uninitialize(InitializationEngine context)
{
DataFactory.Instance.PublishedPage -= OnPublishedPage;
}
public void Preload(string[] parameters)
{
}
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.