itech-world/sulu-article-twig-extension-filter-bundle

SuluArticleTwigExtensionFilterBundle extends the Sulu CMS to enable article retrieval in TWIG without ElasticSearch

Installs: 28

Dependents: 0

Suggesters: 0

Security: 0

Stars: 2

Watchers: 1

Forks: 0

Open Issues: 0

Type:sulu-bundle

pkg:composer/itech-world/sulu-article-twig-extension-filter-bundle

v1.0.3 2026-02-12 08:05 UTC

This package is auto-updated.

Last update: 2026-02-12 08:06:11 UTC


README

Itech World logo

Article Twig Extension Filter Bundle for Sulu

Developed by Steeven THOMAS

GitHub license Sulu compatibility

ArticleTwigExtensionFilterBundle extends the Sulu CMS to enable article retrieval in TWIG without ElasticSearch

📂 Requirements

  • PHP ^8.2
  • Sulu ^3.0@dev

🛠️ Features

  • TWIG extension sulu_article_load_by_uuid allowing an article to be retrieved by its identifier
  • TWIG extension sulu_article_count_published for counting the number of published articles
  • TWIG extension sulu_article_load_recent allowing you to retrieve the latest recent articles
  • TWIG extension sulu_article_load_recent_paginated allowing you to retrieve the latest recent articles with pagination

📝 Installation

Composer

composer require itech-world/sulu-article-twig-extension-filter-bundle

Symfony Flex

If you don't use Symfony Flex, you can add the bundle to your config/bundles.php file:

return [
    // ...
    ItechWorld\SuluArticleTwigExtensionFilterBundle\ItechWorldSuluArticleTwigExtensionFilterBundle::class => true,
];

Instructions

Retrieve an item using its UUID

Use sulu_article_load_by_uuid. Possible parameters:

  • uuid : The UUID of the article
  • locale : The locale of the article

Count the number of published articles

Use sulu_article_count_published. Possible parameters:

  • locale : The locale of the article
  • filters : An array of filters to apply to the query

Retrieve the latest recent articles

Use sulu_article_load_recent. Possible parameters:

  • limit : The number of articles to retrieve
  • templateKeys : An array of template keys to filter the articles
  • locale : The locale of the article
  • ignoreWebspace : Ignore webspace and return all articles
  • categoryKeys : An array of category keys to filter the articles
  • tagNames : An array of tag names to filter the articles
  • webspaceKeys : An array of webspace keys to filter the articles (only if ignoreWebspace is false)

Retrieve the latest recent articles with pagination

Use sulu_article_load_recent_paginated. Possible parameters:

  • limit : The number of articles to retrieve
  • offset : The offset of the articles to retrieve
  • templateKeys : An array of template keys to filter the articles
  • locale : The locale of the article
  • ignoreWebspace : Ignore webspace and return all articles
  • categoryKeys : An array of category keys to filter the articles
  • tagNames : An array of tag names to filter the articles
  • webspaceKeys : An array of webspace keys to filter the articles (only if ignoreWebspace is false)

Returned Data Structure

All functions return articles as arrays with the following properties:

Property Type Description
uuid string Unique identifier of the article
id int Database ID
title string Article title
description string Excerpt description (from "Excerpt & Taxonomies" tab)
excerptTitle string Excerpt title (from "Excerpt & Taxonomies" tab)
excerptMore string "Read more" text (from "Excerpt & Taxonomies" tab)
url string|null Article URL
template string|null Template key used
stage string Publication stage (live, draft)
locale string Article locale
published DateTime|null Publication date
workflowPlace string Workflow status
categories Collection Categories (from "Excerpt & Taxonomies" tab)
tags Collection Tags (from "Excerpt & Taxonomies" tab)
created DateTime Creation date
changed DateTime Last modification date
content array All template data (custom fields from your XML template)

Examples of usage

Create a templates/articles.html.twig file with the following content:

{% extends 'base.html.twig' %}

{% block content %}

    {% set paginatedResult = sulu_article_load_recent_paginated(12, 0, ['article-template-key'], app.request.locale) %}
    {% set recentArticles = paginatedResult.articles %}
    {% set pagination = paginatedResult.pagination %}
    
    {% if recentArticles %}
        {% for article in articles %}
            {{ article.title }}
        {% endfor %}
    {% endif %}

{% endblock %}

Note : Replace article-template-key with the key of your XML template.

For pagination, you can create an AJAX route in a Controller and use ItechWorld\SuluArticleTwigExtensionFilterBundle\Service\ArticleService.

Example:

<?php

declare(strict_types = 1);

namespace App\Controller\Front;

use ItechWorld\SuluArticleTwigExtensionFilterBundle\Service\ArticleService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;

class ArticleController extends AbstractController
{
    public function __construct(
        private ArticleService $articleService
    ) {
    }

    /**
     * API AJAX to load more articles with pagination.
     *
     * @param Request $request
     * @return JsonResponse
     */
    #[Route('/api/articles/load-more', name: 'api_articles_load_more', methods: ['GET'])]
    public function loadMore(Request $request): JsonResponse
    {
        $offset = (int)$request->query->get('offset', 0);
        $limit = (int)$request->query->get('limit', 12);
        $templateType = $request->query->get('type', 'project');
        $locale = $request->query->get('locale', $request->getLocale());

        try {
            $result = $this->articleService->loadRecentPaginated(
                $limit,
                $offset,
                [$templateType],
                $locale
            );

            // Render the HTML of articles
            $articlesHtml = '';
            if (!empty($result['articles'])) {
                $articlesHtml = $this->renderView('articles_cards.html.twig', [
                    'articles' => $result['articles']
                ]);
            }

            return new JsonResponse([
                'success' => true,
                'html' => $articlesHtml,
                'pagination' => $result['pagination'],
                'articlesCount' => count($result['articles'])
            ]);
        } catch (\Exception $e) {
            return new JsonResponse([
                'success' => false,
                'error' => $e->getMessage()
            ], 500);
        }
    }
}

🐛 Bug and Idea

See the open issues for a list of proposed features (and known issues).

💰 Support me

You can buy me a coffee to support me this plugin is 100% free.

Buy me a coffee

👨‍💻 Contact

📘  License

This bundle is under the MIT License.