Velocity 模板中的对象列表排序 - Liferay

发布于 2024-12-08 10:44:13 字数 2654 浏览 1 评论 0原文

我在 Liferay 中创建了一个结构,如下所示

<root>
      <dynamic-element name='header' type='text' index-type='' repeatable='true'>
        <dynamic-element name='headerlink' type='text' index-type='' repeatable='false'>       </dynamic-element>
        <dynamic-element name='location' type='text' index-type='' repeatable='false'>  </dynamic-element>
        <dynamic-element name='description' type='text_box' index-type='' repeatable='false'>  </dynamic-element>
        <dynamic-element name='date' type='text' index-type='' repeatable='false'></dynamic-element>
      </dynamic-element>
</root>

现在标题可重复块,我有 4-5 个元素块。每一个都有不同的“日期”值。 “日期”是简单的文本类型。日期格式为 (dd/mm/yyyy)

现在我想根据输入的日期按排序顺序显示所有元素。

我的模板如下。

<ul>
                #set($count = 0)
                #foreach( $nm in $header.getSiblings())
                    #set($content="content"+$count)
                    <li id="$content">
                        <div class="event">
                        #set($monthnameid="month"+$count)
                        #set($dayid="day"+$count)
                        <p class="date-section">
                            <span class="month" id="$monthnameid">$nm.date.data</span>
                            <span class="date" id="$dayid"></span>
                        </p>
                        <p class="event-detail-section">
                            #if($nm.headerlink.data !="")
                                <span class="event-title"><a class="event-link" href="$nm.headerlink.data">$nm.data</a></span>
                            #else
                                <span class="event-header">$nm.data</span>
                            #end

                            #if($nm.description.data.toString().length() >100)
                                <span class="event-description">$nm.description.data.toString().substring(0,100)</span>
                            #else
                                <span class="event-description">$nm.description.data.toString()</span>
                            #end
                            <span class="event-location">Location: $nm.location.data</span>
                        </p>
                    </div>
                </li>
                #set($count = $count +1)
            #end
            </ul>

我不知道我们如何对速度内的物体进行排序。

对此的任何帮助将不胜感激。

I've created a structure in Liferay as below

<root>
      <dynamic-element name='header' type='text' index-type='' repeatable='true'>
        <dynamic-element name='headerlink' type='text' index-type='' repeatable='false'>       </dynamic-element>
        <dynamic-element name='location' type='text' index-type='' repeatable='false'>  </dynamic-element>
        <dynamic-element name='description' type='text_box' index-type='' repeatable='false'>  </dynamic-element>
        <dynamic-element name='date' type='text' index-type='' repeatable='false'></dynamic-element>
      </dynamic-element>
</root>

Now header repeatable block, I have 4-5 element blocks as same. Each one of have different "date" value inside it. "date" is simple text type. date format is (dd/mm/yyyy)

Now I want to display all the element in sorting order based on the date entered.

My template is as below.

<ul>
                #set($count = 0)
                #foreach( $nm in $header.getSiblings())
                    #set($content="content"+$count)
                    <li id="$content">
                        <div class="event">
                        #set($monthnameid="month"+$count)
                        #set($dayid="day"+$count)
                        <p class="date-section">
                            <span class="month" id="$monthnameid">$nm.date.data</span>
                            <span class="date" id="$dayid"></span>
                        </p>
                        <p class="event-detail-section">
                            #if($nm.headerlink.data !="")
                                <span class="event-title"><a class="event-link" href="$nm.headerlink.data">$nm.data</a></span>
                            #else
                                <span class="event-header">$nm.data</span>
                            #end

                            #if($nm.description.data.toString().length() >100)
                                <span class="event-description">$nm.description.data.toString().substring(0,100)</span>
                            #else
                                <span class="event-description">$nm.description.data.toString()</span>
                            #end
                            <span class="event-location">Location: $nm.location.data</span>
                        </p>
                    </div>
                </li>
                #set($count = $count +1)
            #end
            </ul>

I am not aware regarding how can we sort object inside velocity.

Any help on this would be much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

面犯桃花 2024-12-15 10:44:13

您可以创建实用程序 jar 并将其放入服务器 lib 文件夹中,以便所有应用程序都可以使用它。

您需要创建java项目,将下面的代码放入其中(根据您的需要进行修改)。
将其导出为jar并复制到服务器。如果服务器正在运行,请重新启动它。

package com.tejas.liferay.util.cms;

import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.Map;

public final class DateComparator implements Comparator<Object> {

    private String m_node = null;
    private String m_sort = null;
    private String m_format = null;

    public DateComparator(final String p_node, final String p_sort, final String p_format) {
        m_node = p_node;
        m_sort = p_sort;
        m_format = p_format;
    }

    public static DateComparator newInstance(final String p_node, final String p_sort, final String p_format) {
        return new DateComparator(p_node, p_sort, p_format);
    }

    public int compare(Object p_object1, Object p_object2) {
        final Date date1 = getDate((Map) p_object1, m_node);
        final Date date2 = getDate((Map) p_object2, m_node);

        if ("asc".equalsIgnoreCase(m_sort)) {
            return compareAsc(date1, date2);
        } else if ("desc".equalsIgnoreCase(m_sort)) {
            return compareDesc(date1, date2);
        }

        return 0;
    }

    public int compareDesc(Date p_date1, Date p_date2) {

        if (p_date1 == null) {
            return -1;
        }

        if (p_date2 == null) {
            return 1;
        }

        return (p_date1.compareTo(p_date2) * -1);
    }

    public int compareAsc(Date p_date1, Date p_date2) {

        if (p_date1 == null) {
            return -1;
        }

        if (p_date2 == null) {
            return 1;
        }

        return (p_date1.compareTo(p_date2));
    }

    private Date getDate(final Map p_map, final String p_node) {
        final Map map = (Map) p_map.get(p_node);
        if (map == null) {
            return null;
        }
        final String dateStr = (String) map.get("data");

        final Date date1 = parseDate(dateStr, m_format);
        return date1;
    }

    public static Date parseDate(final String p_string, final String p_format) {
        if (p_string == null) {
            return null;
        }

        final SimpleDateFormat sdf = new SimpleDateFormat(p_format);

        try {
            return sdf.parse(p_string);
        } catch (Exception e) {
            // do you error handeling
        }

        return null;
    }
}

然后更新您的速度模板,以便最上面的内容不再是

#set($comparator = $portal.getClass().forName("com.tejas.liferay.util.cms.DateComparator").getMethod("newInstance", $portal.getClass().forName("java.lang.String"), $portal.getClass().forName("java.lang.String"), $portal.getClass().forName("java.lang.String")).invoke(null, "date", "asc", "dd/MM/yyyy"))
#set($void = $portal.getClass().forName("java.util.Collections").getMethod("sort", $portal.getClass().forName("java.util.List"), $portal.getClass().forName("java.util.Comparator")).invoke(null, $header.getSiblings(), $comparator))

您模板中的原始内容。

请注意,第一条速度线的末尾

invoke(null, "date", "asc", "dd/MM/yyyy"))

“date”是保存日期的字段名称,“asc”是排序参数(可以是“desc”),最后一个参数是日期格式。

更新:
上面两条速度线中的第二条显示在渲染的 html 中,因此我已更新为不显示:)

更新:
对于评论中的其他问题,

将其他类添加到您的 jar 中(从上面)

package com.tejas.liferay.util.cms;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public final class VelocityUtil {

    private VelocityUtil() {
        // utility class
    }

    public static void filterOlderThanTodayFromListAndSort(final List<Map<String, Map<String, ?>>> p_list, final String p_dateFieldName, final String p_dateFormat, final String p_sort) {
        filterOlderThanTodayFromList(p_list, p_dateFieldName, p_dateFormat);
        Collections.sort(p_list, new DateComparator(p_dateFieldName, p_sort, p_dateFormat));
    }

    public static void filterOlderThanTodayFromList(final List<Map<String, Map<String, ?>>> p_list, final String p_dateFieldName, final String p_dateFormat) {
        final Date todayMidnight = getTodayMidnight();

        for (int i = p_list.size() - 1; i >= 0; i--) {
            Map<String, Map<String, ?>> map = p_list.get(i);
            final Date date = getDate(map, p_dateFieldName, p_dateFormat);
            if (todayMidnight.after(date)) {
                p_list.remove(i);
            }
        }
    }

    public static Date getTodayMidnight() {
        final Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);

        final Date todayMidnight = calendar.getTime();
        return todayMidnight;
    }

    public static Date getDate(final Map<String, Map<String, ?>> p_map, final String p_dateFieldName, final String p_dateFormat) {
        final Map<String, ?> map = p_map.get(p_dateFieldName);
        if (map == null) {
            return null;
        }
        final String dateStr = (String) map.get("data");

        final Date date1 = parseDate(dateStr, p_dateFormat);
        return date1;
    }

    public static Date parseDate(final String p_string, final String p_format) {
        if (p_string == null) {
            return null;
        }

        final SimpleDateFormat sdf = new SimpleDateFormat(p_format, Locale.getDefault());

        try {
            return sdf.parse(p_string);
        } catch (Exception e) {
            // do you error handeling
        }

        return null;
    }
}

,并在速度模板中放置

#set($classString = $portal.getClass().forName("java.lang.String"))
#set($classList = $portal.getClass().forName("java.util.List"))
#set($classComparator = $portal.getClass().forName("java.util.Comparator"))

#set($void = $portal.getClass().forName("com.tejas.liferay.util.cms.VelocityUtil").getMethod("filterOlderThanTodayFromList", $classList, $classString, $classString).invoke(null, $header.getSiblings(), "date", "dd/MM/yyyy"))

假设 $header.getSiblings() 是您要过滤的列表。

You can create utility jar and put it in servers lib folder so that it it is available to all applications.

You need to create java project, put code from below in it (modify to your needs).
Export it to jar and copy it to the server. Restart your server if it is running.

package com.tejas.liferay.util.cms;

import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.Map;

public final class DateComparator implements Comparator<Object> {

    private String m_node = null;
    private String m_sort = null;
    private String m_format = null;

    public DateComparator(final String p_node, final String p_sort, final String p_format) {
        m_node = p_node;
        m_sort = p_sort;
        m_format = p_format;
    }

    public static DateComparator newInstance(final String p_node, final String p_sort, final String p_format) {
        return new DateComparator(p_node, p_sort, p_format);
    }

    public int compare(Object p_object1, Object p_object2) {
        final Date date1 = getDate((Map) p_object1, m_node);
        final Date date2 = getDate((Map) p_object2, m_node);

        if ("asc".equalsIgnoreCase(m_sort)) {
            return compareAsc(date1, date2);
        } else if ("desc".equalsIgnoreCase(m_sort)) {
            return compareDesc(date1, date2);
        }

        return 0;
    }

    public int compareDesc(Date p_date1, Date p_date2) {

        if (p_date1 == null) {
            return -1;
        }

        if (p_date2 == null) {
            return 1;
        }

        return (p_date1.compareTo(p_date2) * -1);
    }

    public int compareAsc(Date p_date1, Date p_date2) {

        if (p_date1 == null) {
            return -1;
        }

        if (p_date2 == null) {
            return 1;
        }

        return (p_date1.compareTo(p_date2));
    }

    private Date getDate(final Map p_map, final String p_node) {
        final Map map = (Map) p_map.get(p_node);
        if (map == null) {
            return null;
        }
        final String dateStr = (String) map.get("data");

        final Date date1 = parseDate(dateStr, m_format);
        return date1;
    }

    public static Date parseDate(final String p_string, final String p_format) {
        if (p_string == null) {
            return null;
        }

        final SimpleDateFormat sdf = new SimpleDateFormat(p_format);

        try {
            return sdf.parse(p_string);
        } catch (Exception e) {
            // do you error handeling
        }

        return null;
    }
}

Than update your velocity template so that on top it has

#set($comparator = $portal.getClass().forName("com.tejas.liferay.util.cms.DateComparator").getMethod("newInstance", $portal.getClass().forName("java.lang.String"), $portal.getClass().forName("java.lang.String"), $portal.getClass().forName("java.lang.String")).invoke(null, "date", "asc", "dd/MM/yyyy"))
#set($void = $portal.getClass().forName("java.util.Collections").getMethod("sort", $portal.getClass().forName("java.util.List"), $portal.getClass().forName("java.util.Comparator")).invoke(null, $header.getSiblings(), $comparator))

than goes original content from you template.

Notice end of first velocity line

invoke(null, "date", "asc", "dd/MM/yyyy"))

"date" is the name of the field that holds your date, "asc" is sort parameter (it can be "desc") and last parameter is date format.

UPDATE:
Second of two velocity lines from above was showing in rendered html, so I've updated to not be shown :)

UPDATE:
For additional question in comment

Add additional class to your jar (from above)

package com.tejas.liferay.util.cms;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public final class VelocityUtil {

    private VelocityUtil() {
        // utility class
    }

    public static void filterOlderThanTodayFromListAndSort(final List<Map<String, Map<String, ?>>> p_list, final String p_dateFieldName, final String p_dateFormat, final String p_sort) {
        filterOlderThanTodayFromList(p_list, p_dateFieldName, p_dateFormat);
        Collections.sort(p_list, new DateComparator(p_dateFieldName, p_sort, p_dateFormat));
    }

    public static void filterOlderThanTodayFromList(final List<Map<String, Map<String, ?>>> p_list, final String p_dateFieldName, final String p_dateFormat) {
        final Date todayMidnight = getTodayMidnight();

        for (int i = p_list.size() - 1; i >= 0; i--) {
            Map<String, Map<String, ?>> map = p_list.get(i);
            final Date date = getDate(map, p_dateFieldName, p_dateFormat);
            if (todayMidnight.after(date)) {
                p_list.remove(i);
            }
        }
    }

    public static Date getTodayMidnight() {
        final Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);

        final Date todayMidnight = calendar.getTime();
        return todayMidnight;
    }

    public static Date getDate(final Map<String, Map<String, ?>> p_map, final String p_dateFieldName, final String p_dateFormat) {
        final Map<String, ?> map = p_map.get(p_dateFieldName);
        if (map == null) {
            return null;
        }
        final String dateStr = (String) map.get("data");

        final Date date1 = parseDate(dateStr, p_dateFormat);
        return date1;
    }

    public static Date parseDate(final String p_string, final String p_format) {
        if (p_string == null) {
            return null;
        }

        final SimpleDateFormat sdf = new SimpleDateFormat(p_format, Locale.getDefault());

        try {
            return sdf.parse(p_string);
        } catch (Exception e) {
            // do you error handeling
        }

        return null;
    }
}

and in velocity template put

#set($classString = $portal.getClass().forName("java.lang.String"))
#set($classList = $portal.getClass().forName("java.util.List"))
#set($classComparator = $portal.getClass().forName("java.util.Comparator"))

#set($void = $portal.getClass().forName("com.tejas.liferay.util.cms.VelocityUtil").getMethod("filterOlderThanTodayFromList", $classList, $classString, $classString).invoke(null, $header.getSiblings(), "date", "dd/MM/yyyy"))

Assuming $header.getSiblings() is list that you want to filter.

吻风 2024-12-15 10:44:13

我使用 Velocity $sortTool 得到了很好的结果
可以在页面底部找到示例
http://www.liferay.com/community/forums/-/message_boards /消息/11146823
helparray 是无法避免的。

由于您的日期没有 yyyyMMdd 格式,因此您还需要 $dateTool.toDate 将日期作为可比较的日期放入数组中。

I had good results with the Velocity $sortTool.
An example can be found here at the bottom of the page
http://www.liferay.com/community/forums/-/message_boards/message/11146823
The helparray can not be avoided.

Since your dates don't have the format yyyyMMdd you also need $dateTool.toDate to put the date in the array as a Comparable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文