<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <title>Hierarchical long friendly url</title>
  <link rel="self" href="https://liferay.dev/c/message_boards/find_thread?p_l_id=119785294&amp;threadId=120753999" />
  <subtitle>Hierarchical long friendly url</subtitle>
  <id>https://liferay.dev/c/message_boards/find_thread?p_l_id=119785294&amp;threadId=120753999</id>
  <updated>2026-04-04T09:47:31Z</updated>
  <dc:date>2026-04-04T09:47:31Z</dc:date>
  <entry>
    <title>RE: Hierarchical long friendly url</title>
    <link rel="alternate" href="https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=120785630" />
    <author>
      <name>Sergey Shishov</name>
    </author>
    <id>https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=120785630</id>
    <updated>2021-05-17T09:19:24Z</updated>
    <published>2021-05-17T06:37:43Z</published>
    <summary type="html">&lt;span class="h5 text-default"&gt;
  &lt;div class="alert alert-info"&gt;
    &lt;p&gt;             Dear Sergey Shishov,&lt;br /&gt;
      &lt;br /&gt;              Thank you for participating in the Liferay
      Community.             Your post is currently awaiting moderation
      and will not             be visible to other posters.&lt;br /&gt;
      &lt;br /&gt;              Also please note you are limited to 3 posts
      per hour and 50 posts per day.             Exceeding the post
      limit will temporarily disable posting.&lt;br /&gt;
      &lt;br /&gt;              One of our moderators will review your post shortly.&lt;br /&gt;
      &lt;br /&gt;              Sincerely,&lt;br /&gt;             Webmaster&lt;br /&gt;
      webmaster@community.liferay.com&lt;br /&gt;       http://liferay.dev &lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;/span&gt;
   Original Post: &lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;Finally there are:&lt;/p&gt;
&lt;p&gt;1) service-builder component to store long friendly urls (FriendlyUrlLong)&lt;/p&gt;
&lt;p&gt;2) ModelListener-hook to create long friendly urls (buiseness logic)&lt;/p&gt;
&lt;p&gt;3) Override some LayoutLocalService methods:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;updateLayout (replace urls with cropped one)&lt;/li&gt;
  &lt;li&gt;deleteLayout (syncronious remove our urls)&lt;/li&gt;
  &lt;li&gt;getFriendlyURLLayout&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code class="language-java"&gt;    @Override
    public Layout getFriendlyURLLayout(long groupId, boolean privateLayout, String friendlyURL) throws PortalException {
        Layout layout = null;

        // Try find by our long friendly url.
        String normalizedUrl = FriendlyURLNormalizerUtil.normalizeWithEncoding(friendlyURL);
        FriendlyUrlLong friendlyUrlLong = FriendlyUrlLongLocalServiceUtil.fetchByFriendlyUrl(normalizedUrl);
        if (friendlyUrlLong != null) {
            long plid = friendlyUrlLong.getPlid();
            layout = LayoutLocalServiceUtil.fetchLayout(plid);
        }

        // Try find by liferay.
        if (layout == null) {
            layout = LayoutLocalServiceUtil.getLayoutByFriendlyURL(groupId, privateLayout, friendlyURL);
        }

        return layout;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4) Override some LayoutFriendlyURLLocalService methods:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;updateLayoutFriendlyURLs (replace urls with cropped one)&lt;/li&gt;
  &lt;li&gt;getLayoutFriendlyURL&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;&lt;code class="language-java"&gt;    @Override
    public LayoutFriendlyURL getLayoutFriendlyURL(long plid, String languageId) throws PortalException {
        LayoutFriendlyURL layoutFriendlyURL = getLayoutFriendlyURLInternal(plid);
        if (layoutFriendlyURL != null) {
            return layoutFriendlyURL;
        }
        return super.getLayoutFriendlyURL(plid, languageId);
    }

    @Override
    public LayoutFriendlyURL getLayoutFriendlyURL(long plid, String languageId, boolean useDefault) throws PortalException {
        LayoutFriendlyURL layoutFriendlyURL = getLayoutFriendlyURLInternal(plid);
        if (layoutFriendlyURL != null) {
            return layoutFriendlyURL;
        }
        return super.getLayoutFriendlyURL(plid, languageId, useDefault);
    }

    private LayoutFriendlyURL getLayoutFriendlyURLInternal(long plid) {
        // Try to find our long friendly url.
        FriendlyUrlLong friendlyUrlLong = FriendlyUrlLongLocalServiceUtil.fetchFriendlyUrlLong(plid);
        if (friendlyUrlLong != null) {
            String longFriendlyUrl = friendlyUrlLong.getFriendlyUrl();
            // Compose fake LayoutFriendlyURL.
            LayoutFriendlyURL fakeLayoutFriendlyURL = LayoutFriendlyURLLocalServiceUtil.createLayoutFriendlyURL(0);
            fakeLayoutFriendlyURL.setFriendlyURL(longFriendlyUrl);
            return fakeLayoutFriendlyURL;
        }
        return null;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</summary>
    <dc:creator>Sergey Shishov</dc:creator>
    <dc:date>2021-05-17T06:37:43Z</dc:date>
  </entry>
  <entry>
    <title>Hierarchical long friendly url</title>
    <link rel="alternate" href="https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=120753998" />
    <author>
      <name>Sergey Shishov</name>
    </author>
    <id>https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=120753998</id>
    <updated>2021-05-04T16:36:05Z</updated>
    <published>2021-05-04T12:20:24Z</published>
    <summary type="html">&lt;p&gt;
  &lt;span class="h5 text-default"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;We need to use friendly urls like &lt;b&gt;\xxx\yyy\zzz&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Urls are localized (stores in DB with %-symbols) and may be long enough.&lt;/p&gt;
&lt;p&gt;To make friendlyurl hierarchical I use ModelListener-hook with
  onAfterUpdate() action, and it normally works.&lt;/p&gt;
&lt;p&gt;But default friendlyurl length is only 255 characters.&lt;/p&gt;
&lt;p&gt;With changed length at db-column all works, but fails at&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-java"&gt;FriendlyURLEntryLocalServiceImpl.updateFriendlyURLEntry()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;at validate() method&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;Guess1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;How to correct modify length of friendlyurl column (at 'layout' and
  'layoutfriendlyurl' tables)?&lt;/p&gt;
&lt;p&gt;May be with EXT or model-hints?&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;Guess2&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Not to modify DB, but create a new table with my own long friendly urls?&lt;/p&gt;
&lt;p&gt;I will try to create this with service-builder.&lt;br /&gt;1. Save urls
  works fine&lt;br /&gt;2. To find layout with url I override &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-java"&gt;LayoutLocalServiceWrapper.getFriendlyURLLayout()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;used in&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-java"&gt;PortalImpl.getPortletFriendlyURLMapperLayoutQueryStringComposite()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Page successfully found, but url in address panel change to 'system' at&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-java"&gt;FriendlyUrlServlet with PortalImpl.getLocalizedFriendlyURL()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And I dont want to override whole PortalImpl.&lt;/p&gt;
&lt;p&gt;May be it is real to override FriendlyUrlServlet?&lt;/p&gt;
&lt;p&gt;Or something else to get control about Liferay friendlyurl?&lt;/p&gt;</summary>
    <dc:creator>Sergey Shishov</dc:creator>
    <dc:date>2021-05-04T12:20:24Z</dc:date>
  </entry>
</feed>
