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

Xeed Laravel Package

cable8mm/xeed

Xeed generates Laravel database seeders from Excel spreadsheets. Map worksheets to tables, define columns and relationships, then produce ready-to-run seeder classes so bulk data stays version-controlled and reloads consistently across environments.

View on GitHub
Deep Wiki
Context7

Getting Started

cable8mm/xeed generates RSS/Atom feeds straight from Eloquent models — the appeal is that you describe a feed as a class instead of hand-assembling XML.

  1. Install and publish

    composer require cable8mm/xeed
    php artisan vendor:publish --tag=xeed-config   # config/xeed.php
    

    Check composer.json constraints first — v2.0.2 is a patch on the 2.x line, so if you are still on 1.x the breaking surface lives in the 2.0.0 major, not here.

  2. Where to look first

    • README.md (the only thing that changed in 2.0.2 besides internal refactoring) for the current generator signature.
    • config/xeed.php for default format, cache TTL, and route prefix.
    • src/Feed.php (or equivalent base class) after the "refactoring: all codes" commit — the public surface should be unchanged, but confirm the base class methods your feeds override (items(), toFeedItem(), format/view properties) still exist with the same signatures.
  3. First feed, end to end

    php artisan make:feed PostFeed
    
    // app/Feeds/PostFeed.php
    class PostFeed extends Feed
    {
        protected $model = Post::class;
        protected $format = 'atom';       // or 'rss'
        protected $limit = 50;
    
        public function toFeedItem(Post $post): FeedItem
        {
            return FeedItem::create()
                ->id($post->id)
                ->title($post->title)
                ->summary($post->excerpt)
                ->updated($post->updated_at)
                ->link(route('posts.show', $post))
                ->authorName($post->author->name);
        }
    }
    
    // routes/web.php
    Route::feeds();   // registers the published feeds
    
  4. Verify before trusting it — hit /feed/post (or whatever prefix your config uses), check the Content-Type header is application/rss+xml / application/atom+xml, and paste the URL into the W3C Feed Validator. Do this once at setup; it catches the 90% of feed bugs that are date-format or escaping problems.

First real use case: a blog or changelog feed for a Post model with a published_at scope — small, verifiable, and exercises ordering, limits, and date handling in one go.

Implementation Patterns

One feed class per collection, not per route. Feeds are cheap to declare; a PostFeed, NewsFeed, PodcastFeed each get their own class and their own URL. This keeps ordering/filtering logic in one place and lets you tune $limit per feed.

Filter at the query, not in the mapping. Override the items query so the feed reflects only published content:

protected function items(): Collection
{
    return Post::query()
        ->whereNotNull('published_at')
        ->where('published_at', '<=', now())
        ->latest('published_at')
        ->limit($this->limit)
        ->with('author')   // eager-load anything toFeedItem touches
        ->get();
}

The with() matters: a feed of 50 items without eager loading is 50+ extra queries per request.

Treat feeds as cached HTTP responses. Feeds are read by crawlers far more often than by humans. Wrap them in your normal cache layer (Cache::remember around the query, or the package's TTL config) and set a sane Cache-Control. A 60-second TTL plus a updated_at-keyed invalidation covers most sites.

Scheduling pattern for expensive feeds. If a feed aggregates across models, generate the XML on a schedule into a static file or cache key rather than rebuilding on every request:

Schedule::call(fn () => Cache::put('feed.posts', PostFeed::render(), now()->addHour()))->hourly();

Integration tips

  • Point <link rel="alternate" type="application/rss+xml" href="..."> in your layout <head> — this is what makes browsers and readers discover the feed.
  • Add the feed URLs to sitemap.xml generation and to your robots.txt/Search Console if discovery matters.
  • Keep the FeedItem id() stable and globally unique (a permalink or tag: URI is ideal); changing it re-surfaces every item as new in readers.
  • Test feeds like any other endpoint: $this->get('/feed/posts')->assertHeader('Content-Type', 'application/atom+xml; charset=UTF-8') plus an assertSee on a known title. Snapshot the XML if you want regressions to be visible in diffs.

Upgrading within 2.x. v2.0.2 is "refactoring: all codes" plus a README icon fix — no stated feature or deprecation. Pin ^2.0.2 deliberately, then diff the generated feed XML against what 2.0.1 produced for the same data. Byte-identical (or semantically identical) output means the refactor is safe for you; anything else is worth a bug report.

Gotchas and Tips

  • The refactor is the only risk in 2.0.2. A whole-codebase refactor in a patch release is normally safe for public API but can shift edge-case behaviour (null handling, empty collections, date formatting, trailing slashes in links). Run your feed tests and eyeball one real feed before deploying. If you have no feed tests yet, this release is a good excuse to write them.
  • Dates are the #1 breakage. RSS 2.0 wants RFC 2822 (D, d M Y H:i:s O), Atom wants RFC 3339/ISO 8601. Timezones must be explicit — a Carbon instance without ->tz() serialized in UTC is fine, but published_at stored as a naive local datetime will render wrong offsets. Set APP_TIMEZONE correctly and convert on output.
  • Empty feeds are valid but suspicious. An empty channel usually means a scope, a status enum string, or a soft-delete global scope silently excluded everything. Log the count when debugging rather than assuming the mapping is broken.
  • Escaping and CDATA. Titles/summaries with &, <, or emoji will break hand-rolled XML but should be escaped by the package's builder. If you inject raw HTML into a content field, do it via the package's content method, not string concatenation — and remember readers sanitize aggressively, so inline styles and scripts are wasted bytes.
  • Route collisions. Route::feeds() registers wildcard-ish routes; if you have a catch-all /{slug} route defined earlier, feeds can 404 or render your page instead. Register feed routes before catch-alls and check php artisan route:list | grep feed.
  • Cache invalidation is manual. Nothing in the package knows when a model changes. Hook Post::saved/deleted to forget the feed cache key, or you will ship stale feeds for the full TTL and get complaints from aggregators.
  • Validation, not vibes. Feed readers are stricter than browsers. Run the W3C validator after any change to item structure; a single missing updated on one item can invalidate an entire Atom document.
  • Extension points to prefer. Subclass the base Feed and override the item query or the view rather than editing vendor code; publish the feed view if you need custom XML elements (<enclosure> for podcasts, <media:content> for images). Vendor-published overrides survive patch releases — direct edits do not.
  • Watch the repo, not just the changelog. With a two-line changelog and one maintainer, the PR diff (/#109) is the real release note for anything touching serialization.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource