Help center Customer portals Liquid loops: display request and article collections correctly Updated Wednesday, October 28, 2026 · Marc Staine Loops turn a supplied collection into a readable list of requests, articles or discussions. They also let you provide an honest empty state when there are no rows. Understanding the boundary between a display loop and server paging prevents a common mistake: assuming the template can retrieve records that were never supplied to the page. At a glanceFor: portal administrators and designers, including people new to Liquid. Applies to: Supportbench Core.Start here: Settings → Customer Portal → select the portal → Page templates Start with the practical purpose · Syntax and supported behavior · Example: show a small request preview and an empty state · Use break and continue deliberately · Understand existing advanced loop templates · Apply the example in a working portal page · Troubleshoot the common mistakes · Keep the customization understandable Start with the practical purpose {% for item in collection %} repeats the enclosed markup for each available row. Inside the loop, item represents one row and its members become available. The loop’s else block handles an empty collection.Core’s current renderer does not support the Shopify paginate tag. The older claim that every Liquid loop is limited to 50 results and should be expanded with paginate does not apply. The portal’s data-loading and paging behavior determines which rows the template receives. Syntax and supported behavior ConstructPurposefor / endforRepeat markup for rows in a collection.else inside forDisplay a useful message when the collection has no rows.limit:10Render at most ten of the supplied rows. It does not fetch more records or create a server page.offset:2Skip the first two supplied rows before iterating. It is not an account-wide result offset.reversedIterate the supplied collection in reverse order. This does not change the underlying saved ordering.breakStop the current loop.continueSkip the rest of the current row and move to the next iteration.cycleAlternate supplied presentation values, such as row classes. Named groups keep separate cycles independent. Example: show a small request preview and an empty state <ul> {% for request in sb.cases limit:10 %} <li> <a href="/case/{{ request.id | escape }}">{{ request.subject | escape_once }}</a> <span>{{ request.status | escape }}</span> </li> {% else %} <li>No requests are available in this list.</li> {% endfor %} </ul>This displays up to ten rows from the current case-list context. Keep the existing request-list navigation so the customer can inspect the full supported list. Do not label this fragment as every open request for the whole company. Use break and continue deliberately {% for number in (1..5) %} {% if number == 2 %}{% continue %}{% endif %} {% if number == 5 %}{% break %}{% endif %} {{ number }} {% endfor %}This small syntax example prints 1, 3 and 4. In a real portal, skipping rows can make visible counts disagree with the displayed list. Prefer a clear server-provided filter or an accurately labeled subsection when the customer needs a complete result set. Understand existing advanced loop templates The installed DotLiquid package also recognizes tablerow, which generates table rows/cells inside a surrounding table. It is not part of the current designer’s advertised starter tags. Preserve a working existing use unless you have tested the replacement; for new examples, ordinary semantic HTML with for is easier to inspect and adapt.The include tag is not a usable route to external snippets in this render context. Do not copy an example that depends on Shopify product templates or include files. Apply the example in a working portal page Open the intended portal’s Page templates with permission to administer communities or the applicable edit override. Choose the page that supplies the object used by your example.Preserve a copy of the existing template in your change record. Keep the working forms, routes, input names and script hooks; these examples change presentation.Make the smallest useful edit, then choose Save Changes → Design. Inspect populated, empty and signed-out preview states as relevant.Check punctuation, long text, optional values and narrow-screen layout. Confirm the result says what you intend, not merely that it renders.Use Review changes → Publish for the approved design. Then verify the actual portal as the intended customer and check the full task.Designer preview data is synthetic. A successful preview confirms neither real customer access nor the effect of a server-side workflow. Liquid cannot grant permission, edit a case or fetch arbitrary database records. Troubleshoot the common mistakes ProblemCorrectionpaginate is unknownUse the page’s supported paging controls and supplied URLs.The loop shows no rowsConfirm the collection’s page context, access and active filters.A count is larger than the rendered listCheck server paging and any loop limit, offset, continue or break.Alternating styles continue unexpectedly in a second listUse separate named cycle groups or existing CSS row styling. Keep the customization understandable Choose limits for a deliberate preview section, not to conceal missing paging. Tell the reader what subset they are seeing and preserve the route to the full authorized task.Use descriptive local variable names and keep conditions close to the content they control. Record the customer scenario tested when publishing a change. Recheck the template when its source fields, portal role rules or supported language behavior changes. Continue learning Customize and publish portal pages with LiquidTransform supplied lists with array filtersUse search paging URLsDisplay customer requests Was this article helpful? Yes No Thank you for your feedback.