Pre-1.0. Not intended for public use yet. The API is subject to undocumented change, and these pages may already be wrong about it.

Skip to content

Quickstart ​

Introduction ​

To record an activity, prepare the models, define a headline, and publish the activity from your application. This example records a customer placing an order with a shop.

Preparing the Models ​

Install Storyfeed before defining your models and headline.

To include the Order model in an activity, implement the Feedable interface and use the InteractsWithFeed trait. Define its label in the toFeed method:

app/Models/Order.php
php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Storyfeed\Concerns\InteractsWithFeed;
use Storyfeed\Contracts\Feedable;
use Storyfeed\FeedEntity;

class Order extends Model implements Feedable
{
    use InteractsWithFeed;

    public function toFeed(): FeedEntity
    {
        return FeedEntity::make()->label("Order #{$this->reference}");
    }
}
php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Storyfeed\Concerns\InteractsWithFeed;
use Storyfeed\Contracts\Feedable;
use Storyfeed\FeedEntity;

class Order extends Model implements Feedable
{
    use InteractsWithFeed;

    public function toFeed(): FeedEntity
    {
        return FeedEntity::make(
            label: "Order #{$this->reference}",
        );
    }
}

For the Shop and User models, implement Feedable and use InteractsWithFeed as well. If you omit the toFeed method, Storyfeed generates a default label from the model's attributes, such as name.

Defining a Headline ​

Define a headline for the place verb in routes/feed.php:

routes/feed.php
php
use App\Models\Order;
use Storyfeed\Facades\Story;

Story::for(Order::class)->verb('place')
    ->headline(':actor placed :object with :target');

Publishing an Activity ​

Publish the activity where your application places the order:

Where the order is placed: a controller, an action, a listener
php
use Storyfeed\Facades\Storyfeed;

Storyfeed::activity()
    ->by($customer)
    ->action('place', $order)
    ->to($shop)
    ->publish();
php
use Storyfeed\Facades\Storyfeed;

Storyfeed::record(
    verb: 'place',
    object: $order,
    actor: $customer,
    target: $shop,
);
ES
Erica Sinclair placed Order #1035 with Scoops Ahoy

Retrieving the Feed ​

To retrieve a page of activities, call the feed method on the Storyfeed facade, followed by the get method. You may return the result from a route:

routes/web.php
php
use Illuminate\Support\Facades\Route;
use Storyfeed\Facades\Storyfeed;

Route::get('/', function () {
    return Storyfeed::feed()->get();
});

The route returns a JSON payload:

{
  "payload_version": 1,
  "items": [
    {
      "kind": "activity",
      "id": "j84",
      "verb": "place",
      "published_at": "1985-07-02T12:00:00.000000Z",
      "headline_template": ":actor placed :object with :target",
      "headline": null,
      "glyph": null,
      "glyph_intent": null,
      "actor": {
        "type": "user",
        "id": "113",
        "label": "Erica Sinclair",
        "url": null,
        "attributes": {},
        "modal": false,
        "data": {},
        "media": null,
        "body": null,
        "tombstone": null
      },
      "object": {
        "type": "order",
        "id": "1035",
        "label": "Order #1035",
        "url": null,
        "attributes": {},
        "modal": false,
        "data": {},
        "media": null,
        "body": null,
        "tombstone": null
      },
      "target": {
        "type": "venue",
        "id": "101",
        "label": "Scoops Ahoy",
        "url": null,
        "attributes": {},
        "modal": false,
        "data": {},
        "media": null,
        "body": [
          {
            "$body": "Storyfeed/Body/Image",
            "$v": 1,
            "caption": "Scoops Ahoy",
            "alt": "Scoops Ahoy",
            "width": null,
            "height": null,
            "image": "preview"
          }
        ],
        "tombstone": null
      },
      "context": null,
      "origin": null,
      "result": null,
      "instrument": null,
      "data": {},
      "tombstoned": [],
      "redundant": false,
      "missing_headline_template": null,
      "missing_headline": null
    }
  ],
  "next_cursor": "eyJwIjoiMjAyNi0wOC0xNFQxNDowNTowMFoifQ",
  "sync_token": "01J8Z3K4Q2V9WMX7R5T0B6N1CD"
}

Storyfeed is headless: it has no views

Storyfeed serializes the feed as a structured payload, and your frontend chooses how to render it. For Blade, Storyfeed UI renders it with one component.

See Rendering to display the feed with Blade or Vue.

Released under the MIT License.