All RPGs and Storygames by Tod Foley are now available at DrivethruRPG. Bring these games to your table!
The Drupal 8 Shield module allows you to protect your site using a simple htaccess authentication. It’s great for sites that you are working on that you don’t want the world (or Google) to see yet. This way you can send the site to a client or anyone really to test and just provide them the username/password to view the site. Once it’s ready to go, you can launch the site and remove this module.
If you have ever wanted to password protect your Drupal site, the Shield module will help with that!Tags: DrupalDrupal 8Site BuildingDrupal Planet
This week's roundup includes Remnant: From The Ashes and Telling Lies, as well as a new Westworld VR title, 20 years of Sid Meier's Alpha Centauri, Steam China, & more. ...
Adds options to fully remove theming from fields and Layout Builder blocks.
This can be especially useful when using layout definitions and Layout Builder in component-based theming.
Currently requires a core patch from #3015152: Support third party settings for components within a section to work with Layout Builder blocks.
This module makes it easy to add crossword puzzles that are playable in the browser to your Drupal site. It is not for authoring puzzles; rather, it allows you to upload crossword puzzle files that have been created elsewhere.
Greg Anderson, Open Source Contributions Engineer at Pantheon joins Mike Anello to talk about the Drupal Community's [Composer Support in Core Initiative][(https://www.drupal.org/about/strategic-initiatives/composer).Discussion
- Composer contributor community on GitHub
- Drupal Composer/Drupal Project
- Ryan Aslett - Mixologic
- Paul Mitchum - Mile23
- Adam G-H - phénaproxima
- Matthew Grasmick - grasmash
- Wikimedia Composer Merge Plugin
- Composer Installers
- Where do the scaffolding files live?
- Slides from Greg's recent presentation on the Composer Support in Core initiative at SFDUG
- Drupal Career Online - the 12-week (3 half-days/week) best-practice focused training program begins August 26, 2019. Learn more at one of our free Taste of Drupal webinars in July and August.
- Professional local development with DDEV - 2-hour, hands-on, online workshop held monthly (Tuesday, September 10).
- Mike's book: Local Web Development with DDEV Explained,
- Composer Basics at DrupalCamp Atlanta - Friday, September 13, 2019.
- Intro to Git and Composer at Cornell DrupalCamp - Thursday, September 26, 2019.
- Composer Basics at BADCamp - Wednesday October 2, 2019.
- Drupal Aid - Drupal support and maintenance services. Get unlimited support, monthly maintenance, and unlimited small jobs starting at $99/mo.
- WebEnabled.com - devPanel.
If you'd like to leave us a voicemail, call 321-396-2340. Please keep in mind that we might play your voicemail during one of our future podcasts. Feel free to call in with suggestions, rants, questions, or corrections. If you'd rather just send us an email, please use our contact page.
In the last blog post we were introduced to managing migration as configuration entities using Migrate Plus. Today, we will present some benefits and potential drawbacks of this approach. We will also show a recommended workflow for working with migration as configuration. Let’s get started.What is the benefit of managing migration as configurations?
At first sight, there does not seem to be a big difference between defining migrations as code or configuration. You can certainly do a lot without using Migrate Plus’ configuration entities. The series so far contains many examples of managing migrations as code. So, what are the benefits of adopting s configuration entities?
The configuration management system is one of the major features that was introduced in Drupal 8. It provides the ability to export all your site’s configuration to files. These files can be added to version control and deployed to different environments. The system has evolved a lot in the last few years, and many workflows and best practices have been established to manage configuration. On top of Drupal core’s incremental improvements, a big ecosystem has sprung in terms of contributed modules. When you manage migrations via configuration, you can leverage those tools and workflows.
Here are a few use cases of what is possible:
- When migrations are managed in code, you need file system access to make any changes. Using configuration entities allows site administrators to customize or change the migration via the user interface. This is not about rewriting all the migrations. That should happen during development and never on production environments. But it is possible to tweak certain options. For example, administrators could change the location to the file that is going to be migrated, be it a local file or on a remote server.
- When writing migrations, it is very likely that you will work on a subset of the data that will eventually be used to get content into the production environment. Having migrations as configuration allow you to override part of the migration definition per environment. You could use the Configuration Split module to configure different source files or paths per environment. For example, you could link to a small sample of the data in development, a larger sample in staging, and the complete dataset in production.
- It would be possible to provide extra configuration options via the user interface. In the article about adding HTTP authentication to fetch remote JSON and XML files, the credentials were hardcoded in the migration definition file. That is less than ideal and exposes sensitive information. An alternative would be to provide a configuration form in the administration interface for the credentials to be added. Then, the submitted values could be injected into the configuration for the migration. Again, you could make use of contrib modules like Configuration Split to make sure those credentials are never exported with the rest of your site’s configuration.
- You could provide a user interface to upload migration source files. In fact, the Migrate source UI module does exactly this. It exposes an administration interface where you have a file field to upload a CSV file. In the same interface, you get a list of supported migrations in the system. This allows a site administrator to manually upload a file to run the migration against. Note: The module is supposed to work with JSON and XML migrations. It did not work during my tests. I opened this issue to follow up on this.
These are some examples, but many more possibilities are available. The point is that you have the whole configuration management ecosystem at your disposal. Do you have another example? Please share it in the comments.Are there any drawbacks?
Managing configuration as configuration adds an extra layer of abstraction in the migration process. This adds a bit of complexity. For example:
- Now you have to keep the uuid and id keys in sync. This might not seem like a big issue, but it is something to pay attention to.
- When you work with migrations groups (explained in the next article), your migration definition could live in more file.
- The configuration management system has its own restrictions and workflows that you need to follow, particularly for updates.
- You need to be extra careful with your YAML syntax, especially if syncing configuration via the user interface. It is possible to import invalid configuration without getting an error. It is until the migration fails that you realize something is wrong.
Using configuration entities to define migrations certainly offers lots of benefits. But it requires being extra careful managing them.Workflow for managing migrations as configuration entities
The configuration synchronization system has specific workflows to make changes to configuration entities. This imposes some restrictions in the way you make updates to the migration definitions. Explaining how to manage configuration could use another 31 days blog post series. ;-) For now, only a general overview will be presented. The general approach is similar to managing configuration as code. The main difference is what needs to be done for changes to the migration files to take effect.
You could use the “Configuration synchronization” administration interface at /admin/config/development/configuration. In it you have the option to export or import a “full archive” containing all your site’s settings or a “single item” like a specific migration. This is one way to manage migrations as configuration entities which lets you find their UUIDs if not set initially. This approach can be followed by site administrators without requiring file system access. Nevertheless, it is less than ideal and error-prone. This is not the recommended way to manage migration configuration entities.
Another option is to use Drush or Drupal Console to synchronize your site’s configuration via the command line. Similarly to the user interface approach, you can export and import your full site configuration or only single elements. The recommendation is to do partial configuration imports so that only the migrations you are actively working on are updated.
Ideally, your site’s architecture is completed before the migration starts. In practice, you often work on the migration while other parts of the sites are being built. If you were to export and import the entire site’s configuration as you work on the migrations, you might inadvertently override unrelated pieces of configurations. For instance, this can lead to missing content types, changed field settings, and lots of frustration. That is why doing partial or single configuration imports is recommended. The following code snippet shows a basic Drupal workflow for managing migrations as configuration:# 1) Run the migration. $ drush migrate:import udm_config_json_source_node_local # 2) Rollback migration because the expected results were not obtained. $ drush migrate:rollback udm_config_json_source_node_local # 3) Change the migration definition file in the "config/install" directory. # 4a) Sync configuration by folder using Drush. $ drush config:import --partial --source="modules/custom/ud_migrations/ud_migrations_config_json_source/config/install" # 4b) Sync configuration by file using Drupal Console. $ drupal config:import:single --file="modules/custom/ud_migrations/ud_migrations_config_json_source/config/install/migrate_plus.migration.udm_config_json_source_node_local.yml" # 5) Run the migration again. $ drush migrate:import udm_config_json_source_node_local
Note the use of the --partial and --source flags in the migration import command. Also, note that the path is relative to the current working directory from where the command is being issued. In this snippet, the value of the source flag is the directory holding your migrations. Be mindful if there are other non-migration related configurations in the same folder. If you need to be more granular, Drupal Console offers a command to import individual configuration files as shown in the previous snippet.
Note: Uninstalling and installing the module again will also apply any changes to your configuration. This might produce errors if the migration configuration entities are not removed automatically when the module is uninstalled. Read this article for details on how to do that.
What did you learn in today’s blog post? Did you know the know the benefits and trade-offs of managing migrations as configuration? Did you know what to do for changes in migration configuration entities to take effect? Share your answers in the comments. Also, I would be grateful if you share this blog post with others.
This blog post series, cross-posted at UnderstandDrupal.com as well as here on Agaric.coop, is made possible thanks to these generous sponsors. Contact Understand Drupal if your organization would like to support this documentation project, whether it is the migration series or other topics.
Agaric Collective: Defining Drupal migrations as configuration entities with the Migrate Plus module
Today, we are going to talk about how to manage migrations as configuration entities. This functionality is provided by the Migrate Plus module. First, we will explain the difference between managing migrations as code or configuration. Then, we will show how to convert existing migrations. Finally, we will talk about some important options to include in migration configuration entities. Let’s get started.Drupal migrations: code or configuration?
So far, we have been managing migrations as code. This is functionality provided out of the box. You write the migration definition file in YAML format. Then, you place it in the migrations directory of your module. If you need to update the migration, you make the modifications to the files and then rebuild caches. More details on the workflow for migrations managed in code can be found in this article.
Migrate Plus offers an alternative to this approach. It allows you to manage migrations as configuration entities. You still use YAML files to write the migration definition files, but their location and workflow is different. They need to be placed in a config/install directory. If you need to update the migration, you make the modifications to the files and then sync the configuration again. More details on this workflow can be found in this article.
There is one thing worth emphasizing. When managing migrations as code you need access to the file system to update and deploy the changes to the file. This is usually done by developers. When managing migrations as configuration, you can make updates via the user interface as long as you have permissions to sync the site’s configuration. This is usually done by site administrators. You might still have to modify files depending on how you manage your configuration. But the point is that file system access to update migrations is optional. Although not recommended, you can write, modify, and execute the migrations entirely via the user interface.Transitioning to configuration entities
To demonstrate how to transition from code to configuration entities, we are going to convert the JSON migration example. You can get the full code example at https://github.com/dinarcon/ud_migrations The module to enable is UD config JSON source migration whose machine name is udm_config_json_source. It comes with four migrations: udm_config_json_source_paragraph, udm_config_json_source_image, udm_config_json_source_node_local, and udm_config_json_source_node_remote.
The transition to configuration entities is a two step process. First, move the migration definition files from the migrations folder to a config/install folder. Second, rename the files so that they follow this pattern: migrate_plus.migration.[migration_id].yml. For example: migrate_plus.migration.udm_config_json_source_node_local.yml. And that’s it! Files placed in that directory following that pattern will be synced into Drupal’s active configuration when the module is installed for the first time (only). Note that changes to the files require a new synchronization operation for changes to take effect. Changing the files and rebuilding caches does not update the configuration as it was the case with migrations managed in code.
If you have the Migrate Plus module enabled, it will detect the migrations and you will be able to execute them. You can continue using the Drush commands provided the Migrate Run module. Alternatively, you can install the Migrate Tools module which provides Drush commands for running both types of migrations: code and configuration. Migrate Tools also offers a user interface for executing migrations. This user interface is only for migrations defined as configuration though. It is available at /admin/structure/migrate. For now, you can run the migrations using the following Drush command: drush migrate:import udm_config_json_source_node_local --execute-dependencies.
Note: For executing migrations in the command line, choose between Migrate Run or Migrate Tools. You pick one or the other, but not both as the commands provided by the two modules have the same name. Another thing to note is that the example uses Drush 9. There were major refactorings between versions 8 and 9 which included changes to the name of the commands.UUIDs for migration configuration entities
When managing migrations as configuration, you can set extra options. Some are exposed by Migrate Plus while others come from Drupal’s configuration management system. Let’s see some examples.
The most important new option is defining a UUID for the migration definition file. This is optional, but adding one will greatly simplify the workflow to update migrations. The UUID is used to keep track of every piece of configuration in the system. When you add new configuration, Drupal will read the UUID value if provided and update that particular piece of configuration. Otherwise, it will create a UUID on the fly, attach it to the configuration definition, and then import it. That is why you want to set a UUID value manually. If changes need to be made, you want to update the same configuration, not create a new one. If no UUID was originally set, you can get the automatically created value by exporting the migration definition. The workflow for this is a bit complicated and error prone so always include a UUID with your migrations. This following snippet shows an example UUID:uuid: b744190e-3a48-45c7-97a4-093099ba0547 id: udm_config_json_source_node_local label: 'UD migrations configuration example'
The UUID a string of 32 hexadecimal digits displayed in 5 groups. Each is separated by hyphens following this pattern: 8-4-4-4-12. In Drupal, two or more pieces of configuration cannot share the same value. Drupal will check the UUID and the type of configuration in sync operations. In this case the type is signaled by the migrate_plus.migration. prefix in the name of the migration definition file.
When using configuration entities, a single migration is identified by two different options. The uuid is used by the Drupal’s configuration system and the id is used by the Migrate API. Always make sure that this combination is kept the same when updating the files and syncing the configuration. Otherwise you might get hard to debug errors. Also, make sure you are importing the proper configuration type. The latter should not be something to worry about unless you utilize the user interface to export or import single configuration items.
Tip: If you do not have a UUID in advance for your migration, you can copy one from another piece of configuration and change some of the hexadecimal digits. Keep in mind that this could lead to a duplicated UUID if you happen to make the exact changes to the UUID in two separate files. Another option is to use a tool to generate the values. Searching online for UUID generators will yield many tools for this.Automatically deleting migration configuration entities
By default, configuration remains in the system even if the module that added it gets uninstalled. This can cause problems if your migration depends on custom migration plugins provided by your module. It is possible to enforce that migration entities get removed when your custom module is uninstalled. To do this, you leverage the dependencies option provided by Drupal’s configuration management system. The following snippet shows how to do it:uuid: b744190e-3a48-45c7-97a4-093099ba0547 id: udm_config_json_source_node_local label: 'UD migrations configuration example' dependencies: enforced: module: - ud_migrations_config_json_source
You add the machine name of your module to dependencies > enforced > module array. This adds an enforced dependency on your own module. The effect is that the migration will be removed from Drupal’s active configuration when your custom module is uninstalled. Note that the top level dependencies array can have others keys in addition to enforced. For example: config and module. Learning more about them is left as an exercise for the curious reader.
It is important not to confuse the dependencies and migration_dependencies options. The former is provided by Drupal’s configuration management system and was just explained. The latter is provided by the Migrate API and is used to declare migrations that need be imported in advance. Read this article to know more about this feature. The following snippet shows an example:uuid: b744190e-3a48-45c7-97a4-093099ba0547 id: udm_config_json_source_node_local label: 'UD migrations configuration example' dependencies: enforced: module: - ud_migrations_config_json_source migration_dependencies: required: - udm_config_json_source_image - udm_config_json_source_paragraph optional: 
What did you learn in today’s blog post? Did you know that you can manage migrations in two ways: code or configuration? Did you know that file name and location as well as workflows need to be adjusted depending on which approach you follow? Share your answers in the comments. Also, I would be grateful if you shared this blog post with others.
This blog post series, cross-posted at UnderstandDrupal.com as well as here on Agaric.coop, is made possible thanks to these generous sponsors. Contact Understand Drupal if your organization would like to support this documentation project, whether it is the migration series or other topics.
This project integrate BulkGate SMS gateway to Drupal. For now it add new Telephone field display widget which require user to verify the phone number via SMS. So you can use SMS phone verifiaction on any entity, even as a required for registration.
In the near future we are planning to extend support for Drupal commerce and sending Mass SMS.
Welcome to The Indie Game Shelf! Each article in this series will highlight a different small press roleplaying game to showcase the wide variety of games available. Whether you’re new to the hobby and looking to see what’s out there or you’re a veteran gamer looking for something new, I hope The Indie Game Shelf always holds something fun and new for you to enjoy!Psi*Run
Psi*Run from Night Sky Games is a low-prep, GMed roleplaying story game designed for 4-6 players (including a Game Master) to explore the stories of amnesiac psychics fleeing relentless pursuers. The Night Sky Games edition is Meguey Baker’s 2011 remake of a 2007 ashcan by Chris Moore and Michael Lingner. The game uses a handful of six-sided dice, some playsheets available in the book or by download, a few tokens, and a stack of index cards. It is one of my all-time favorite games, not only overall, but also particularly for introducing people to story games.The Story
Psi*Run is built to tell a particular kind of story with specific themes, and while the setting is in large part decided at the table, the fiction is best placed in a modern or near-future time frame. The desired narrative themes lean on a cat-and-mouse chase, and the game benefits from the fiction occurring in a time, place, and culture with mass communication and mass media but with technology advanced only to the point that psychic powers are extraordinary and dangerous.
While all Psi*Run stories are improvised, they also all start the same way: with a crash. The party of player characters (the Runners) are being transported somewhere in a vehicle, and the transportation has gone awry. They also each have psychic powers, and none of them remember who they are or anything about their past. All they know is that they are being chased and they have to run to avoid capture. From there, the rest of the story is up to the players and the dice.
The Runners move from place to place in an attempt to outpace the ever-following Chasers. As the Runners move, they build the map of the world they inhabit which, in a sense, consists only of the space between them and the Chasers. Along the way, they can take actions, use powers, and investigate the handful of clues they have about themselves to try to uncover their pasts. The game continues, the Runners run, and the Chasers chase until one player has answered all their character’s questions about themselves, at which point they have learned enough to stop running. This signals the end phase of the game, and one by one, all the characters find themselves no longer on the run, one way or another.The Game
This game, like many low- and no-prep story games, includes a dedicated setup phase before starting the story proper, but it is also interesting for establishing questions instead of answers. To put it another way, due to the conceit of the Runners knowing very little about their past, the ideas gathered during setup and character creation are more for looking forward in the fiction than looking back. The character sheet (Runner Sheet) for the game is very simple; besides including some reminders about the base mechanics of the game, a player only records what the Runner looks like, what power the Runner has, and a list of questions the Runner wants to answer. Even knowing a character’s name is optional.
The Runner questions comprise the core of how the game mechanizes narrative progress. Each Runner will start with 4-6 questions about certain prescribed topics: their powers, their strengths and weaknesses, and their situations. These questions may collaterally establish facts in the narrative (“What does this key in my pocket unlock?”), but none of the answers are known at the beginning of the story. Over the course of play, Runners discover answers to these questions. Once one Runner has answered all of their questions, it signals the imminent approach of epilogues and the end of the game soon after.
Once the Runners are created by the players, a few details about the Chasers are decided on by the GM and recorded on the Chaser Sheet. These are just a few notes on the Look, Method, and Technology of the Chasers, and all of it is public knowledge so that the players know what they’re running from. In addition, though, the GM also makes a few private notes on a Chaser Card to focus and guide their descriptions of the Chasers over the course of the game.
There are no character-specific stats or attributes. Significant actions call for the roll of a pool of dice which is assembled by perusing a list of questions on the Runner Sheet. Each question which might be answered by the action being undertaken adds a die to the pool. The pool will always be 4-6 dice in size; some questions will always be asked by an action, while others are optional. (For example, all significant actions trigger the question “Do I achieve my goal?” However, only actions involving powers will ask the question “Do my psi powers cause trouble?”) The questions and their possible outcomes are listed on a playmat-style sheet called the Risk Sheet. Once the pool is rolled, the player assigns the result of each die to answer each question that was triggered, and each result indicates two things: (1) how successful or beneficial the answer and (2) who has narrative control of the result.
For example, the question “Does anyone get caught?” may be triggered by an action. If the die result is 1, the Risk Sheet says “Everyone gets caught. Other players have first say.” For results 2-3, “Somebody gets caught – it may or may not be you. GM has first say.” For 4-6, “Nobody gets caught. Player has first say.” Note that in each case, each range not only dictates a different narrative result but also indicates a different person taking narrative control of the outcome. Because every roll involves a die pool, every roll involves a player decision about how to assign outcomes. In a simplified example, a player might be left with a 1 and a 6 and have to decide which question gets a good outcome and which gets a bad one: “Do I achieve my goal?” or “Do my psi powers cause trouble?”
Eventually, everyone stops running, but not every ending will be a happy one. Share1Tweet1Reddit1EmailThe final key components of the gameplay are locations, as the story of the game focuses on the pursuit of the Runners by the Chasers from place to place. The scale of locations is variable and important only so far as they impact the fiction. If the Runners flee immediately to the next room, that could be a new location. If they escape to a different city days later, that could also just be a new location. Each new location is denoted by a separate index card, and as the game progresses, a path of index cards (the Trail) is built which shows the course of the Runners’ flight. The Runners’ locations are indicated on the trail by tokens, and likewise the Chasers are also represented by tokens, so the Runners always know just how far away they are (or how close they are!) to getting caught.
At the end of the game (when one Runner has all their questions answered), all Runners get the chance to end their story. They choose from a list of possible reasons they are no longer running which guides the tone of their epilogue. However, the list contains a variety of endings, some good (like “Home”) and some not as good (like “Trapped”), and a given ending can only be chosen once. Eventually, everyone stops running, but not every ending will be a happy one.The Love
I’m including an extra section in this installment of The Indie Game Shelf, because this game is one of my absolute favorites, particularly as an introduction to story games. The characters not knowing anything about their past means that no character backstory is needed in order to play. The game itself is all about learning things about the characters and their world, and the mechanics are character-driven narrative prompts, so everything the characters learn about themselves are things the players wanted to learn. The action resolution mechanic is a straightforward directing of every action to impact both the immediate result and the overall game story in a significant way; every action answers questions that are important to the game. The decision-making the players must engage in when determining the results of their actions teach quickly that character “failure” is not the same thing as storytelling failure. If a player chooses that a character doesn’t achieve their immediate goal with a roll, it is often because the player chooses to succeed in some other way: to protect other Runners from the Chasers, for example, or to remember something about their past. Even if all results of a roll are low and a “success” isn’t possible, the results still cause the fiction to progress; it is an elegant mechanical implementation of the “fail forward” philosophy. In addition, the shifting responsibilities of narrative control over roll results mean that everyone at the table can get a chance to contribute to every character’s story. Lastly, the separation of character failure from story failure is also promoted by the ending of the game, in which not every character may get the ending they were hoping for, but all players get to construct some kind of ending for their character.
Also as a recurring theme in The Indie Game Shelf thus far is my love for collaborative map-building. Although map-building in this game is not of the same type as, say, Legacy or Companions’ Tale or The Quiet Year, I find it just as enjoyable and for different reasons. The collaborative map in Psi*Run (the Trail of index cards) is far more abstract, and even more temporary, than maps in other games, but it is built with narrative importance at the forefront and is more of a “logical” map than a geographical one. It is also built over the course of play instead of during setup, so each new location adds a dose of the thrill of discovery to every scene change.
I cannot recommend this game strongly enough to gamers of all levels of experience and all styles of play. No matter your personal approach to playing RPGs, I believe this game holds both enjoyment and learning opportunities for roleplayers of all kinds.The Shelf
Psi*Run is available for purchase in print and PDF from Night Sky Games. The game has a compelling theme and has inspired a variety of hacks and reskins. A couple popular (and free!) fan-made hacks based on existing worlds are Psi*Run: Days of Future Past (based on the X-Men title of the same name) and Terminator: Runners (based on the Terminator movie franchise). For those familiar with those properties, the parallels with Psi*Run are unmistakable. I also recommend a more recent entry to this family of games, No Crime But Living by Silent Ferrets Games, a GMless game about outcast mages hunted by wizard fascists. Finally, there was an excellent discussion about this game on an episode of The Farrier’s Bellows, a podcast which explores deep examinations of many indie RPGs. If you’re interested in indie RPG design history and haven’t already subscribed, I recommend checking the podcast out.
If you’ve got something on your shelf you want to recommend as well, let us know in the comments section below. Let’s fill our shelves together!