Foren

Auto-Tag Web Content based on entered text (Liferay 7/DXP)

thumbnail
Zsombor Nagy, geändert vor 6 Jahren.

Auto-Tag Web Content based on entered text (Liferay 7/DXP)

New Member Beiträge: 22 Beitrittsdatum: 22.03.17 Neueste Beiträge
As a Web Content creator and portal developer, I'd like my Web Content to be automatically tagged based on attributes.

E.g. I'm writing an article about the new GTX 1070 GPU and I'd like Liferay to set the tags nvidia, computing, graphics, geforce, etc., based on certain keywords that may occur in the article, like Direct X, Vulkan, GTX, Nvidia, Geforce, Pascal.

How is it possible to achieve the above mentioned, so one shouldn't manually enter separate tags for Web Content on creation/edit, but tags get assigned to web content automatically based on keywords?
thumbnail
Andrew Jardine, geändert vor 6 Jahren.

RE: Auto-Tag Web Content based on entered text (Liferay 7/DXP) (Antwort)

Liferay Legend Beiträge: 2416 Beitrittsdatum: 22.12.10 Neueste Beiträge
Hi Zsombor,

There are a couple of ways you can get this done. I'm going to assume that you are on Liferay 7. If you are not, the recommendations don't change, but the plugin structures might.

There are a few ways to loop yourself into the entity process. In this case, because it is data related and the data is directly related to the item that is being saved, I would probably go with a service wrapper. Check out this article.

https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/customizing-liferay-services-service-wrappers

In your case, you are going to perform the super call first so that the entity is added as usual, and then on the return, process the article using your logic to determine the tags you want to add and then use the AssetTagLocalService to add them to the article.

One thing to note though is that the article that is INDEXED will be different at this stage than the one that you "alter" so you will probably want o make sure that you re-index the article once you are done with it to make sure that the assetTags* index fields are kept up to date with the database.
thumbnail
Zsombor Nagy, geändert vor 6 Jahren.

RE: Auto-Tag Web Content based on entered text (Liferay 7/DXP)

New Member Beiträge: 22 Beitrittsdatum: 22.03.17 Neueste Beiträge
Hi Andrew!

First off, I'd like to thank you for your quick reply!

I took some time searching through Liferay's APIs, found a bunch of addArticle methods in the Journal Services classes, yet I couldn't find a publish method.
If I understand correctly, all I need to do, is create a service wrapper, wrap the service which contains a supposed publish method, implement my changes, and leave the rest to Liferay (at least this sounds great and easy, like a possible best approach).

Is this approach valid? Where should I find the publish method, or some other method, which gets called by the New Web Content / Edit Web Content application when the publish button is pressed?

Thank you for your help!
thumbnail
Andrew Jardine, geändert vor 6 Jahren.

RE: Auto-Tag Web Content based on entered text (Liferay 7/DXP)

Liferay Legend Beiträge: 2416 Beitrittsdatum: 22.12.10 Neueste Beiträge
Hi Zsombor,

Yep, that sounds like the right approach to me. You are right that there are often several methods in the services that can be used for adding a new entity, but a closer inspection and you will find that there is only one that does it, and the others are all overloaded versions that eventually end up in the ONE method that does the actual work. This one that does the work is the one that I usually override. That way my logic is applied regardless of which API method any external classes invoke. In your case, I think it is the method with this signature --

public JournalArticle addArticle(
			long userId, long groupId, long folderId, long classNameId,
			long classPK, String articleId, boolean autoArticleId,
			double version, Map<locale, string> titleMap,
			Map<locale, string> descriptionMap, String content,
			String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
			int displayDateMonth, int displayDateDay, int displayDateYear,
			int displayDateHour, int displayDateMinute, int expirationDateMonth,
			int expirationDateDay, int expirationDateYear,
			int expirationDateHour, int expirationDateMinute,
			boolean neverExpire, int reviewDateMonth, int reviewDateDay,
			int reviewDateYear, int reviewDateHour, int reviewDateMinute,
			boolean neverReview, boolean indexable, boolean smallImage,
			String smallImageURL, File smallImageFile,
			Map<string, byte[]> images, String articleURL,
			ServiceContext serviceContext)
		throws PortalException {</string,></locale,></locale,>


If you look into this method, at the bottom of the logic you will see where it decides whether or not to set the item to "published" --

// Workflow

		if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
			startWorkflowInstance(userId, article, serviceContext);
		}
		else {
			updateStatus(
				userId, article, WorkflowConstants.STATUS_APPROVED, null,
				serviceContext, new HashMap<string, serializable>());
		}
</string,>


.. but for your use case, I don't think the status of the article should matter to be honest. Draft, expired, published... I would just tag the content accordingly so that when it changes state, everything I need is already prepped and there.
thumbnail
Zsombor Nagy, geändert vor 6 Jahren.

RE: Auto-Tag Web Content based on entered text (Liferay 7/DXP)

New Member Beiträge: 22 Beitrittsdatum: 22.03.17 Neueste Beiträge
Hi again!

I managed to achieve what I desired, yet there's still a problem to which I couldn't find any solution anywhere until now.
@Component(
		immediate = true,
		property = {
		},
		service = ServiceWrapper.class
		)
public class CustomArticleServiceWrapper extends JournalArticleServiceWrapper {

	public CustomArticleServiceWrapper() {
		super(null);
	}

	@Override
	public JournalArticle addArticle(long groupId, long folderId, long classNameId, long classPK, String articleId,
			boolean autoArticleId, Map<locale, string> titleMap, Map<locale, string> descriptionMap, String content,
			String ddmStructureKey, String ddmTemplateKey, String layoutUuid, int displayDateMonth, int displayDateDay,
			int displayDateYear, int displayDateHour, int displayDateMinute, int expirationDateMonth,
			int expirationDateDay, int expirationDateYear, int expirationDateHour, int expirationDateMinute,
			boolean neverExpire, int reviewDateMonth, int reviewDateDay, int reviewDateYear, int reviewDateHour,
			int reviewDateMinute, boolean neverReview, boolean indexable, boolean smallImage, String smallImageURL,
			File smallFile, Map<string, byte[]> images, String articleURL, ServiceContext serviceContext)
					throws PortalException {
		// TODO Auto-generated method stub
		System.out.println("Added a new Web Content");
		return super.addArticle(groupId, folderId, classNameId, classPK, articleId, autoArticleId, titleMap, descriptionMap,
				content, ddmStructureKey, ddmTemplateKey, layoutUuid, displayDateMonth, displayDateDay, displayDateYear,
				displayDateHour, displayDateMinute, expirationDateMonth, expirationDateDay, expirationDateYear,
				expirationDateHour, expirationDateMinute, neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
				reviewDateHour, reviewDateMinute, neverReview, indexable, smallImage, smallImageURL, smallFile, images,
				articleURL, serviceContext);
	}
	
	@Override
	public JournalArticle updateArticle(long groupId, long folderId, String articleId, double version,
			Map<locale, string> titleMap, Map<locale, string> descriptionMap, String content, String ddmStructureKey,
			String ddmTemplateKey, String layoutUuid, int displayDateMonth, int displayDateDay, int displayDateYear,
			int displayDateHour, int displayDateMinute, int expirationDateMonth, int expirationDateDay,
			int expirationDateYear, int expirationDateHour, int expirationDateMinute, boolean neverExpire,
			int reviewDateMonth, int reviewDateDay, int reviewDateYear, int reviewDateHour, int reviewDateMinute,
			boolean neverReview, boolean indexable, boolean smallImage, String smallImageURL, File smallFile,
			Map<string, byte[]> images, String articleURL, ServiceContext serviceContext) throws PortalException {
		// TODO Auto-generated method stub
		System.out.println("Update Called");
		return super.updateArticle(groupId, folderId, articleId, version, titleMap, descriptionMap, content, ddmStructureKey,
				ddmTemplateKey, layoutUuid, displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
				displayDateMinute, expirationDateMonth, expirationDateDay, expirationDateYear, expirationDateHour,
				expirationDateMinute, neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
				reviewDateMinute, neverReview, indexable, smallImage, smallImageURL, smallFile, images, articleURL,
				serviceContext);
	}
}</string,></locale,></locale,></string,></locale,></locale,>

On deploy it works just fine, yet when I restart the server, it gives the following error:
Unable to get service bag for class CustomArticleServiceWrapper.CustomArticleServiceWrapper
java.lang.NullPointerException


I found this post with the same problem I encounter, but I cannot really understand Erick's solution. I should somehow resolve the dependencies, so the base classes are loaded before my wrapper module.
How can I solve this problem?

Update:

I finally realized I just needed to paste the "methodThatNoOneCalls" with it's tags to the end of my custom class, that solved my problem emoticon
thumbnail
Jan Verweij, geändert vor 5 Jahren.

RE: Auto-Tag Web Content based on entered text (Liferay 7/DXP)

New Member Beitrag: 1 Beitrittsdatum: 17.03.17 Neueste Beiträge

I just noticed this post so for what it is worth have a look at https://community.liferay.com/blogs/-/blogs/auto-tagging-your-assets

 

thumbnail
Andrew Jardine, geändert vor 5 Jahren.

RE: Auto-Tag Web Content based on entered text (Liferay 7/DXP)

Liferay Legend Beiträge: 2416 Beitrittsdatum: 22.12.10 Neueste Beiträge

Awesome! Thanks so much for sharing this Jan, I'll be looking at ways to work this into my projects for sure.