-
Notifications
You must be signed in to change notification settings - Fork 0
5: Services
In a complex website, you may want to have a central place where you can define general functions and attributes that can be used by multiple components.
Twack has a concept for this: Services! Every service class is a singleton that is globally managed by Twack. If multiple components ask for a service, they will all get the same instance. Services aren't meant to render anything, so they have no view.
You can define your own service-classes in site/templates/services/
. This path is configurable in the module's configuration.
Here is, for example, a news service that can retrieve, sort and filter our news-item pages.
<?php
namespace ProcessWire;
class NewsService extends TwackComponent {
public function __construct($args) {
parent::__construct($args);
}
public function getNewsPage() {
return wire('pages')->get('template.name="newsroom"');
}
public function getArticles($args = array()) {
$output = new \StdClass();
$articles = $this->getNewsPage()->find('template=newsitem');
if (isset($args['sort'])) {
$articles->filter('sort=' . $args['sort']);
} else {
$articles->filter('sort=-date');
}
// Filter by Tags:
if (isset($args['tags'])) {
if (is_string($args['tags'])) {
$args['tags'] = explode(',', $args['tags']);
}
if (is_array($args['tags'])) {
$articles->filter('tags='.implode('|', $args['tags']));
}
}
// Filter by search query:
if (isset($args['query'])) {
if (is_string($args['query'])) {
$query = wire('sanitizer')->text($args['query']);
$articles->filter("title|name|einleitung|inhalte.text%={$query}");
}
}
// Save the original count of all items before applying limit and offset:
$output->count = $articles->count;
// Index of last element of the output:
$output->lastElementIndex = 0;
// Apply Limit and Offset:
$limitSelector = array();
if (isset($args['start'])) {
$limitSelector[] = 'start=' . $args['start'];
$output->lastElementIndex = intval($args['start']);
} elseif (isset($args['offset'])) {
$limitSelector[] = 'start=' . $args['offset'];
$output->lastElementIndex = intval($args['offset']);
} else {
$limitSelector[] = 'start=0';
}
if (isset($args['limit']) && $args['limit'] >= 0) {
$limitSelector[] = 'limit=' . $args['limit'];
$output->lastElementIndex = $output->lastElementIndex + intval($args['limit']);
} elseif (!isset($args['limit'])) {
$limitSelector[] = 'limit=12';
$output->lastElementIndex = $output->lastElementIndex + 12;
}
if (!empty($limitSelector)) {
$articles->filter(implode(', ', $limitSelector));
}
// Are there any more posts that can be downloaded?
$output->hasMore = $output->lastElementIndex + 1 < $output->count;
$output->articles = $articles;
return $output;
}
}
site/templates/services/news_service.class.php
We can call $this->getService('NewsService');
in many components and then use the service's functions. Twack will look for the class in our services-directory and make a singleton-instance out of it. I think, to avoid name-conflicts with the "normal" components its a good convention to add "Service" as a suffix to every service-class.
➡️ Continue with 6: Named components
⬅️ Back to 4: Asset handling
Twack
Reusable components for your ProcessWire-templates!
ProcessWire-Module: | https://modules.processwire.com/modules/twack/ |
Support-Forum: | https://processwire.com/talk/topic/23549-twack/ |
Repository: | https://github.com/Sebiworld/Twack |
Wiki: | https://github.com/Sebiworld/Twack/wiki/ |