Analysis of BitMango's Word Cookies Mobile Game - by Rob Burns Blogs - 19 January 2017 - 6:47am
Article describes BitMango strategies in the mobile game sphere. In particular, the article will describe the recent success of Word Cookies.
Categories: Game Theory & Design

CMON Releasing Kingz Tomorrow

Tabletop Gaming News - 19 January 2017 - 6:00am
It’s good to be the king. That is, unless you’ve just died. Then, maybe it’s not so great (though it was probably good while it lasted). The King of the Jungle has died. That means it’s time to find a new one. And when you’re the leader of all the animals, you’ve gotta be tough. […]
Categories: Game Theory & Design DIY Drupal hosting

Planet Drupal - 19 January 2017 - 4:42am
The meta stuff

I'll be writing a series of posts exploring DIY drupal hosting options. Many agencies and freelancers need a workflow to manage and maintain their Drupal sites on a budget. Of course, they incur the cost of maintiaining and deploying the system(at least initially) and the additional learning curve involved in using the system, but they get the following advantages:

  • More control over the hosted sites. It is easy to create and deploy new environments to demo sites to clients, triage bugs, run tests etc.

Categories: Drupal

Rest Without Format

New Drupal Modules - 19 January 2017 - 4:23am

Allows access to rest endpoints without specifying the '_format' key. If '_format' key is not available, then uses the 'xml' as default request format.

Related Issues -

Todo -
Make default request format configurable

Categories: Drupal

Invoicing Service

New Drupal Modules - 19 January 2017 - 3:44am

Integrates with Digitale Factuur. To be released soon...

Categories: Drupal

Ginger Payments

New Drupal Modules - 19 January 2017 - 3:40am

Ginger Payments is a payment service provider. This module integrates Ginger Payments with the Payment platform. To be released soon...

Categories: Drupal

Janez Urevc: Entity browser feature freeze will happen in two weeks

Planet Drupal - 19 January 2017 - 12:56am
Entity browser feature freeze will happen in two weeks

Today I released Entity browser 8.x-1.0-beta4. Release includes some nice features; specially Improved MultiStep selection display, which vastly improves editorial experience.

This is also the last release before the feature freeze, which will happen on February 3rd 2017. No new features will be accepted after that day until 8.x-1.0 is released. Feature requests that are not breaking backward compatibility will be accepted after that.

Huge thanks to all contributors. It has been an interesting and very rewarding ride!

slashrsm Thu, 19.01.2017 - 09:56 Tags Drupal Media Enjoyed this post? There is more! Join us at the next Drupal Media sprint at the Mountain camp in Davos! Results of the Drupal 8 media sprint Call for Drupal 8 media ecosystem co-maintainers
Categories: Drupal

Lawful GM: Time

RPGNet - 19 January 2017 - 12:00am
How do you speed up time, to support politic campaigns?
Categories: Game Theory & Design

Lullabot: Building Views Query Plugins for Drupal 8, Part 3

Planet Drupal - 18 January 2017 - 5:39pm

Welcome to the third part of our series on writing Views query plugins. In part 1, we talked about the planning work that should precede coding. In part 2, we covered the basics of actually writing a query plugin. In this final chapter, we will investigate some enhancements to make your plugin more polished and flexible.

Exposing configuration options

Allow Site Admins to set their preferred units: metric or imperial.

Most Fitbit endpoints accept an option to set the units the response is returned in. If you are Canadian like me, you know that metric is preferable, but it’s also in our nature to be be nice, so we should expose a configuration option to allow our American friends to show data in their anachronistic imperial units. (I jest, love you guys!)

Exposing configuration options for a query plugin is done in two parts. First, build the UI and, second, make use of the stored configuration. In our query plugin class, we’ll implement two methods to help us create the UI, defineOptions and buildOptionsForm :

/** * {@inheritdoc} */ protected function defineOptions() { $options = parent::defineOptions(); $options['accept_lang'] = array( 'default' => NULL, ); return $options; } /** * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $form['accept_lang'] = [ '#type' => 'select', '#options' => [ '' => $this->t('Metric'), 'en_US' => $this->t('US'), 'en_GB' => $this->t('UK'), ], '#title' => $this->t('Unit system'), '#default_value' => $this->options['accept_lang'], '#description' => $this->t('Set the unit system to use for Fitbit API requests.'), ]; }

With this done, we should see our configuration options in the Views UI under Advanced > Query settings.


However, it won’t work because we’re not actually using the stored configuration yet. To do that, we’ll add to our execute method in our query plugin:

/** * {@inheritdoc} */ public function execute(ViewExecutable $view) { // Set the units according to the setting on the view. if (!empty($this->options['accept_lang'])) { $this->fitbitClient->setAcceptLang($this->options['accept_lang']); } // Clip... }

Query plugin options are available via $this->options, which Drupal provides as part of the QueryPluginBase class that our Views plugin is extending. We use the stored value, together with a method on the Fitbit client service to set the preferred units for all subsequent API requests: $this->fitbitClient->setAcceptLang($this->options['accept_lang']); . With that, site admininstrators can set their preferred units, and the result set will reflect that choice. Since this is Views and we’ve exposed height as a numeric field, Views core gives us a nice way to format the data and suffix it with units so we end up with a polished result. Just edit the field options.

undefined Field plugin options

Adding options to customize the appearance of the avatar field.

Views also allows us to have custom options for our field plugins. In the last article, we set up a field plugin for avatar which uses the avatar URI from the API response and renders it as an <img> tag. Fitbit’s API actually provides two avatar size options and it would be great to leave it to the site administrator to decide which size to render. We’ll use field plugin options to do that.

As with query plugins, exposing configuration options for a field plugin follows the same two parts, with one small addition. In our query plugin class, we’ll implement two methods, defineOptions and buildOptionsForm , to build the UI:

/** * {@inheritdoc} */ protected function defineOptions() { $options = parent::defineOptions(); $options['avatar_size'] = ['default' => 'avatar']; return $options; } /** * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $form['avatar_size'] = [ '#type' => 'select', '#title' => $this->t('Image size'), '#options' => [ 'avatar' => $this->t('Default (100px)'), 'avatar150' => $this->t('Medium (150px)'), ], '#default_value' => $this->options['avatar_size'], '#description' => $this->t('Choose the size avatar you would like to use.'), ]; parent::buildOptionsForm($form, $form_state); }

This should be fairly self explanatory; we’re defining a form element for the UI and, once saved, the configuration option will be stored in $this->options['avatar_size'] . The small addition I referred to earlier lies within the query plugin. Before, we were only passing along the single value for avatar. Now that the site administrator has the option, we’ll want to make sure both values for avatar are passed along in the Views result. We do that, in the query plugins execute method like so:

$row['avatar'] = [ 'avatar' => $data['avatar'], 'avatar150' => $data['avatar150'], ];

Instead of a flat value, we’re setting ‘avatar’ to an array with both values for avatar from the API response. Then, back in the field plugin, in the render method, we take care to use the appropriate size avatar according to the option selected:

/** * {@inheritdoc} */ public function render(ResultRow $values) { $avatar = $this->getValue($values); if ($avatar) { return [ '#theme' => 'image', '#uri' => $avatar[$this->options['avatar_size']], '#alt' => $this->t('Avatar'), ]; } }

We simply call $this->getValue($values), which is able to pull out the value we want from the ResultRow object. The render method receives a ResultRow object that has all of the data for the row. FieldPluginBase has a getValue method which we can access since we are extending FieldPluginBase . With that done, we can now click on the avatar field in the Views UI and set the desired image size:

undefined Filter plugins

Filtering the leaderboard by user id.

What if we wanted to limit the result to only a particular user? Say we wanted to show a user's Fitbit details on their Drupal user profile page. For that, we’d need to filter the result set by a user id. To make that happen, we need a Views filter plugin. The first step is to define the field to filter on in hook_views_data():

/** * Implements hook_views_data(). */ function fitbit_views_example_views_data() { // Base data and other field definitions... $data['fitbit_profile']['uid'] = [ 'title' => t('User id'), 'help' => t('Drupal user id, not to be confused with Fitbit profile id.'), 'field' => [ 'id' => 'standard', ], 'filter' => [ 'id' => 'fitbit_uid', ], ]; return $data; }

The part we are most concerned with here is the ‘filter’ key. Its value is an associative array with one key ‘id’, which we set to the name of the filter plugin we’re going to create. Also, note the ‘field’ key, which makes the Drupal user id available as a field in the Views UI. It doesn’t hurt to add it, and it also illustrates how plugins related to a certain field (e.g. field, filter, and others like relationship and argument) are all defined in the same array in hook_views_data(). So, for the next step, we’ll create this file: fitbit_views_example/src/Plugin/views/filter/Uid.php 

<?php namespace Drupal\fitbit_views_example\Plugin\views\filter; /** * Simple filter to handle filtering Fitbit results by uid. * @ViewsFilter("fitbit_uid") */ class Uid extends FilterPluginBase { }

So far, this is typical Drupal 8 plugin scaffolding code. The file is placed in the right folder for the plugin type. The namespace follows PSR-4 naming. The annotation for the plugin type assigns an id to our plugin. Finally, we extend the base class provided by Views for the plugin type. Now let’s look at the specifics required for our filter plugin implementation:

class Uid extends FilterPluginBase { public $no_operator = TRUE; /** * {@inheritdoc} */ protected function valueForm(&$form, FormStateInterface $form_state) { $form['value'] = [ '#type' => 'textfield', '#title' => $this->t('Value'), '#size' => 30, '#default_value' => $this->value, ]; } }

$no_operator = TRUE tells Views that we are not interested in the site administrators having an option to select an operator. In our case, we’ll keep things simple and always assume '='. You could, of course, allow for choice of operators if your remote service supports it. The key component here is the valueForm method. In it, we need to set an appropriate Form API element for the ‘value’ key of the $form array passed as the first argument. The name ‘value’ is important as the base class expects this key to work. The form element that you return is used in a couple of places. It’s used in the Views UI for when the site administrator is setting up a filter. It’s also used if the filter is exposed, rendered in the exposed filters form with the view itself. That’s it for the plugin implementation.  At this point we can add the filter in the Views UI:


The last step adjusts our query plugin to be able to handle and make use of the filter. The first thing we’ll need to do is implement an addWhere method on the query plugin class:

public function addWhere($group, $field, $value = NULL, $operator = NULL) { // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all // the default group. if (empty($group)) { $group = 0; } // Check for a group. if (!isset($this->where[$group])) { $this->setWhereGroup('AND', $group); } $this->where[$group]['conditions'][] = [ 'field' => $field, 'value' => $value, 'operator' => $operator, ]; }

Here, especially, we can see Views’ biases to SQL rear its head. The method name, addWhere, is odd from our perspective of querying a remote service. There is no notion of a WHERE clause present in the Fitbit API. Further, Views supports grouping filters, and logical operators within each group. Here again, the remote service we are using has no notion of this. It’s possible the remote service your implementing does in which case the flexibility Views affords is amazing. In our case it’s overkill, but I’ve copied core Views implementation for the SQL query plugin, so we’ll be able to handle everything that the Views UI allows for setting up filters. The final step is adjusting the execute method on our query plugin to incorporate the filter into the call to the Fitbit API:

/** * {@inheritdoc} */ public function execute(ViewExecutable $view) { // Clip ... if (isset($this->where)) { foreach ($this->where as $where_group => $where) { foreach ($where['conditions'] as $condition) { // Remove dot from beginning of the string. $field_name = ltrim($condition['field'], '.'); $filters[$field_name] = $condition['value']; } } } // We currently only support uid, ignore any other filters that may be // configured. $uid = isset($filters['uid']) ? $filters['uid'] : NULL; if ($access_tokens = $this->fitbitAccessTokenManager->loadMultipleAccessToken([$uid])) { // Query remote API and return results ... } }

Here, we’re looping through any filters that have been configured on the view and grabbing their values. We then ignore any other filter that may have been configured on the view, since we’re only supporting uid for now and pass it along to $this->fitbitAccessTokenManager->loadMultipleAccessToken([$uid]), which will limit the access tokens we get back to just the uid set and only show us results for the corresponding user.

Often, as was the case on a recent client project, the filters that you set up will actually get passed along in the remote API request. The Fitbit API is a bit odd in this regard in that most endpoints only return data for a single user anyway, so there is no filtering that makes sense.

That’s it! After all that work, we can set up a filter by uid to limit the results to a single user.

Wrap up

We did it, at long last, we’ve produced a custom Fitbit leaderboard, which might look something like this:


Of course this is just stock Drupal 8 with the Fitbit module installed and configured, but it’s Views and we all know how to customize the look and feel of Views, so make it pretty to your heart's content.

While we've looked at a lot of code, I don't think that any of it has been horribly complicated. It's mostly a matter of knowing what to put where, with a healthy dose of planning to make sure our data fits into the Views paradigm properly. In summary, the steps are:

  1. Make a plan of attack, taking into account the data you're retrieving and the way Views expects to use it.

  2. Create field handlers for your data as necessary.

  3. Write remote queries to retrieve your data and store it in rows in the view object.

  4. Write filter plugins as necessary to narrow the result set.

There's a lot of work in those steps, but after running through it a couple times the architecture makes a lot of sense.

Get the code!

The code from this article can be found in the Fitbit module on It consists of a base module to handle application setup, authentication and access token storage and two sub-modules for Views integration. The first is fitbit_views_example, which I created specifically for this article series. You’ll find all the code we went through in there. The other one, fitbit_views is a more fully featured and slightly more complex version, including spanning multiple API endpoints with relationship plugins. You should use fitbit_views if your intending on using this functionality on your Drupal site. Feel free to file issues and patches!

Phew, that was a lot. Thanks for sticking with me through it all. Special thanks to Greg Dunlap for trusting me with the reboot of his original series, which has guided me through my own Views query plugin implementations. Thanks also to the Fitbit module maintainer, Matt Klein, who was kind enough to grant me co-maintainer rights on the project.

Categories: Drupal

Report: Internet-breaking DDoS worm traced to chief of Minecraft-focused DDoS guard firm

Social/Online Games - Gamasutra - 18 January 2017 - 4:48pm

Security expert Brian Krebs reports the author of the "Internet-breaking" Mirai DDoS botnet malware -- and indeed, the business of conducting DDoS attacks in general -- is intertwined with Minecraft. ...

Categories: Game Theory & Design

Delve Card Game Up On Kickstarter

Tabletop Gaming News - 18 January 2017 - 3:00pm
What is it about dungeons that brings out so many adventurers? … The loot! Duh! What a silly question I asked. Anyway, the dungeon at Skull Cavern surely has lots of loot. Of course it does. And don’t call me Shirley (… though Pete Shirley did work on the game). Grab your band and head […]
Categories: Game Theory & Design

Simple entity merge D8

New Drupal Modules - 18 January 2017 - 2:26pm

Simple module that adds a tab for entities that lets you chose a another entity of the same type and merge all the references to this entity to that other entity.

Only takes care of entity_reference fields and it doesn't process entities in batch so is not advised for large number of references.

Categories: Drupal

Gale Force Nine Previews Recruiting Companions in Time of the Daleks

Tabletop Gaming News - 18 January 2017 - 2:00pm
When one goes gallivanting all across time and space, it’s a good idea to have someone go along with you. You know, someone to watch your back, talk to, and make sure your scarf is clean. That kind of stuff. In Doctor Who: Time of the Daleks, you can have companions as well. But how […]
Categories: Game Theory & Design

Appnovation Technologies: Great UX design with Drupal

Planet Drupal - 18 January 2017 - 1:37pm

Drupal is the #1 platform for web content management systems. It powers millions of websites in more than 180 languages, with a massive online community with more than 26,000 constantly building and sharing themes and resources.

Categories: Drupal

Argle Bargle Card Game Up On Kickstarter

Tabletop Gaming News - 18 January 2017 - 1:00pm
Your mother was a hamster and your father smelled of elderberries! That, right there, is Argle Bargle in a nutshell. It’s a new card game that’s up on Kickstarter now where you create inventive insults using your hand of cards and use them to lay low your opponents. From the campaign: Argle Bargle is the […]
Categories: Game Theory & Design

A layer-by-layer breakdown of League of Legends' rendering process

Social/Online Games - Gamasutra - 18 January 2017 - 12:49pm

Riot Games' engineering blog is frequently a goldmine for interesting technical breakdowns of League of Legends systems, and a recent post explaining the game's rendering process is no exception. ...

Categories: Game Theory & Design

River Horse Posts Tails of Equestria RPG Update

Tabletop Gaming News - 18 January 2017 - 12:00pm
We’ve been having a small discussion about My Little Pony in the comments section. Mostly about whether or not the show is ubiquitous enough that people can just use the acronym “MLP” and have it be known what they are talking about. Whether you feel the show has gotten to that point or not, MLP […]
Categories: Game Theory & Design

Midweek Snippets

Tabletop Gaming News - 18 January 2017 - 11:00am
And we’re already to Wednesday. It helps the week go along when you’re off on Monday. It’s also my friend Gilbert’s birthday! Yo. Gilbert. You old, dude. Anyway, along with cake and ice cream, we should fill up on some bite-sized gaming stories. Today on the platter we have: Mindwork Games New Online Store Now […]
Categories: Game Theory & Design

Details Filter

New Drupal Modules - 18 January 2017 - 10:05am

Adds a filter that eats input like this and renders a details element:

[details]foo bar baz[/details] [details open]foo bar baz[/details] [details: Summary]foo bar baz[/details] [details open: Summary]foo bar baz[/details]
Categories: Drupal

January Releases for Eden Now Available

Tabletop Gaming News - 18 January 2017 - 10:00am
The first month of the year is a bit more than half over, seems like a good time to get out your first releases of 2017. That’s what Happy Games Factory has done. They’ve got new Eden releases available now over in their webshop. From the release: The January news releases are here!!! This month […]
Categories: Game Theory & Design


Subscribe to As If Productions aggregator