Adding lazy-load version of feed component to load data using AJAX after page content has been rendered.

This commit is contained in:
Jason Williams
2020-10-23 22:54:30 +00:00
parent 2a8454d197
commit af4f1366a0
71 changed files with 1753 additions and 88 deletions

View File

@@ -0,0 +1,41 @@
<?php namespace JasonWilliams\Feed\Components;
use Cms\Classes\ComponentBase;
use JasonWilliams\Feed\Models\Channels;
class ChannelList extends ComponentBase
{
public function componentDetails()
{
return [
'name' => 'Channel List',
'description' => 'Displays a list of feed channels.'
];
}
public function defineProperties()
{
return [
'includeEmpty' => [
'title' => 'Include Empty?',
'description' => 'Include channels with no posts?',
'type' => 'checkbox',
'default' => true
]
];
}
public function onRun()
{
$this->page['channels'] = Channels::orderBy('id')->withCount('feeditems')->get();
// If applicable, remove empty channels
if (!$this->property('includeEmpty'))
{
foreach($this->page['channels'] as $key => $value)
{
if (!$value->feeditems_count) unset($this->page['channels'][$key]);
}
}
}
}

View File

@@ -0,0 +1,47 @@
<?php namespace JasonWilliams\Feed\Components;
use Cms\Classes\ComponentBase;
use JasonWilliams\Feed\Models\FeedItem;
class LazyLoadShortFeed extends ComponentBase
{
public function componentDetails()
{
return [
'name' => 'Short Feed (Lazy Load)',
'description' => 'Displays a mini-feed of the most recent feed items, retrieved after other page content has been loaded'
];
}
public function defineProperties()
{
return [
'maxItems' => [
'title' => 'Max items',
'description' => 'How many feed items should be displayed?',
'default' => 10,
'type' => 'string',
'validationPattern' => '^[0-9]+$',
'validationMessage' => 'The Max items property must be numeric'
],
'renderPartial' => [
'title' => 'Render partial',
'description' => 'The path to the partial that will be used as a template to render feed items. @feed is provided by the plugin itself.',
'default' => '@feed',
'type' => 'string'
]
];
}
public function onRun()
{
$this->page['renderPartial'] = $this->property('renderPartial');
$this->addJs('/plugins/jasonwilliams/feed/assets/javascript/lazyloadshortfeed.js');
}
public function onUpdateRequested()
{
date_default_timezone_set('America/Edmonton');
$this->page['posts'] = FeedItem::orderBy('timestamp', 'desc')->take($this->property('maxItems'))->get();
}
}

View File

@@ -0,0 +1,79 @@
<?php namespace JasonWilliams\Feed\Components;
use Cms\Classes\ComponentBase;
use JasonWilliams\Feed\Models\FeedItem;
use JasonWilliams\Feed\Models\Tags;
class ShortFeed extends ComponentBase
{
private $channelfilter;
public function componentDetails()
{
return [
'name' => 'Short Feed',
'description' => 'Displays a mini-feed of the most recent feed items, loaded with other page content'
];
}
public function defineProperties()
{
return [
'channelFilter' => [
'title' => 'Channels',
'description' => 'A comma-separated list of channels to include in feed.',
'type' => 'string',
'default' => ''
],
'tagFilter' => [
'title' => 'Tag',
'description' => 'The tag to display in the feed.',
'type' => 'string',
'default' => ''
],
'maxItems' => [
'title' => 'Max items',
'description' => 'How many feed items should be displayed?',
'default' => 10,
'type' => 'string',
'validationPattern' => '^[0-9]+$',
'validationMessage' => 'The Max items property must be numeric'
]
];
}
public function onRun()
{
date_default_timezone_set('America/Edmonton');
// Set up the results query
$results = FeedItem::orderBy('timestamp', 'desc')->take($this->property('maxItems'));
// Do we need to filter based on a tag?
if ($this->property('tagFilter') != null)
{
$results->join('jasonwilliams_feed_tags', 'jasonwilliams_feed_.id', '=', 'jasonwilliams_feed_tags.feed_item_id');
$results->where('tag', $this->property('tagFilter'));
}
// Do we need to filter based on the channel?
if ($this->property('channelFilter') != null && $this->property('channelFilter') != 'all')
{
$this->channelfilter = explode(',', $this->property('channelFilter'));
$results->whereHas('channel', function($q) {
$firstchannel = true;
foreach ($this->channelfilter as $channel)
{
if ($firstchannel) $q->where('slug', $channel);
else $q->orWhere('slug', $channel);
$firstchannel = false;
}
});
}
$this->page['posts'] = $results->get();
}
}

View File

@@ -0,0 +1,26 @@
<?php namespace JasonWilliams\Feed\Components;
use Db;
use Cms\Classes\ComponentBase;
use JasonWilliams\Feed\Models\Tags;
class TagList extends ComponentBase
{
public function componentDetails()
{
return [
'name' => 'Tag List',
'description' => 'Displays a list of feed tags.'
];
}
public function defineProperties()
{
return [];
}
public function onRun()
{
$this->page['tags'] = Tags::groupBy('tag')->select(Db::raw('tag, count(*) as count'))->orderBy('count', 'desc')->get();
}
}

View File

@@ -0,0 +1,5 @@
<ul>
{% for channel in channels %}
<li><a href="/feed/{{ channel.slug }}">{{ channel.title }}</a></li>
{% endfor %}
</ul>

View File

@@ -0,0 +1,4 @@
<div id="feedarea">Loading...</div>
{% put scripts %}
<script type="text/javascript">const renderPartial = '{{ renderPartial }}'</script>
{% endput %}

View File

@@ -0,0 +1,9 @@
<ul>
{% for post in posts %}
{% if post.title %}
<li>{{ post.title | raw }}</li>
{% else %}
<li>Post</li>
{% endif %}
{% endfor %}
</ul>

View File

@@ -0,0 +1,9 @@
<ul>
{% for post in posts %}
{% if post.title %}
<li>{{ post.title | raw }}</li>
{% else %}
<li>Post</li>
{% endif %}
{% endfor %}
</ul>

View File

@@ -0,0 +1,5 @@
<ul>
{% for tag in tags %}
<li><a href="{{ tag.tag }}">{{ tag.tag }}</a></li>
{% endfor %}
</ul>