Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Xml Feed Widget Extension Laravel Package

anomaly/xml_feed_widget-extension

A companion extension for the Anomaly XML Feed Widget, adding supporting functionality for XML feed generation in PyroCMS/Anomaly applications. It helps integrate and extend XML feed widgets within Laravel-based CMS projects.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install into a PyroCMS/Streams project. This is an Anomaly Labs addon, not a generic Laravel package. It only works inside a PyroCMS 3.x / Streams Platform application:

    composer require anomaly/xml_feed_widget-extension
    php artisan addon:install anomaly.extension.xml_feed_widget
    

    If addon:install isn't present, confirm the project is actually a PyroCMS 3 app (anomaly/streams-platform in composer.json).

  2. Read these files first, in order:

    • src/XmlFeedWidgetExtension.php — the extension registration. Look at the $provides string; it tells you which dashboard "widget" slot the addon advertises.
    • The widget class under src/Widget/ (file names vary between Anomaly addons; grep for extends WidgetExtension). This is where $view, $options/$form, and getData() live.
    • resources/views/ — the Blade template that renders the feed.
    • resources/lang/en/addon.php — the widget's dashboard name/description.
  3. Register it on the dashboard. Go to Admin → Dashboard → Widgets, or edit the dashboard config in config/dashboard.php. The widget should appear under its translated name.

  4. First real use case: point the widget at an RSS/Atom feed (release notes, a status blog, a partner's changelog) and let it render on the admin dashboard without a custom controller or route. If you're building anything more than a read-only display, stop and write your own widget — it's one class plus one view.

Implementation Patterns

Per-instance configuration via widget options. Anomaly widgets typically expose a form/options builder in the widget class. Use it for the feed URL and a cache TTL rather than hardcoding in the view, so the same addon can serve several dashboards:

protected function options(WidgetFormBuilder $builder)
{
    return $builder->setFields([
        'url'     => ['type' => 'anomaly.field_type.url', 'required' => true],
        'ttl'     => ['type' => 'anomaly.field_type.integer', 'config' => ['default_value' => 15]],
        'limit'   => ['type' => 'anomaly.field_type.integer', 'config' => ['default_value' => 5]],
    ]);
}

Always wrap the fetch in a cache. The dashboard polls on every admin page load, so an uncached widget turns your admin UI into a dependency on a third-party host:

public function getData()
{
    $url = $this->getOption('url');
    $ttl = (int) $this->getOption('ttl', 15);

    return [
        'items' => Cache::remember('xml_feed:'.md5($url), $ttl * 60, function () use ($url) {
            return $this->parse($url);
        }),
    ];
}

Normalize RSS vs Atom in the parser, not the view. Feeds differ materially (item/entry, pubDate/updated, link as text vs. attribute). Parse once into a flat array of ['title','url','date'] and keep the Blade template dumb:

$xml = simplexml_load_string($body, 'SimpleXMLElement', LIBXML_NONET | LIBXML_NOCDATA);
foreach ($xml->channel->item ?? $xml->entry as $item) { ... }

Fail soft. Return ['items' => []] and log the exception. A dead feed should render an empty card, not a 500 on the dashboard.

Override the view instead of forking. Publish the addon resources and edit the copy in your project's views; that survives composer update and keeps the upgrade path open.

Integration tip: if the feed drives anything actionable (deploy status, incident banner), don't scrape it in a widget. Consume it in a scheduled command, cache to the database, and let the widget read your own table.

Gotchas and Tips

  • Age and version drift are the real risk. With zero stars and zero dependents, expect Laravel 5.x-era constraints and an unmaintained composer.json. Check require against your Laravel version before installing; if it conflicts, fork it into a vcs repository and widen the constraints — the code is small enough that this is usually faster than hoping for a patch.
  • allow_url_fopen and SSL. If the addon uses file_get_contents/simplexml_load_file, it inherits whatever your PHP openssl.cafile situation is. Replace the fetch with Http::get($url)->body() for consistent timeouts and error handling.
  • XXE. Do not pass LIBXML_NOENT or LIBXML_DTDLOAD when parsing remote XML, and keep LIBXML_NONET. Remote feeds are untrusted input.
  • Namespaced Atom feeds need children(). $entry->link returns nothing for Atom because link is in the Atom namespace and carries href. Use $entry->children('http://www.w3.org/2005/Atom')->link['href']. Same trap for media: and dc: extensions.
  • CDATA and entities. LIBXML_NOCDATA saves you from titles full of raw <![CDATA[...]]>. Strip tags and decode entities again in the view ({{ }} escapes, so this is display hygiene, not security).
  • Widget data contract. getData() must return an array of view variables; returning a Collection or a model silently breaks the widget. If you see a blank card with no error, this is the first thing to check.
  • Debugging a blank widget: storage/logs/laravel.log first, then php artisan addon:list to confirm it's installed and enabled, then re-publish views (php artisan addon:publish anomaly.extension.xml_feed_widget) — a stale published view shadows the vendor one and will confuse you for an hour.
  • Timeout starvation. Dashboard renders several widgets in parallel; a slow feed hangs the whole panel even with caching, because the cache miss still blocks. Set an explicit HTTP timeout (5s) and pre-warm the cache from a scheduler task if the feed is important.
  • Extension points are thin. Effectively you get the view and the options form. Anything richer (auth headers, JSON feeds, multi-feed aggregation) means copying the widget class into your own addon rather than extending this one.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route