Newsfeeds

Kickstarter — Lessons learned from a 300% funded solo project - by Jonas Manke

Gamasutra.com Blogs - 4 November 2019 - 5:43am
I’m a solo developer from Germany and I ran a Kickstarter campaign for my game as a solo indie dev Omno last year that ended up getting over 300% funded with a pledge total of over $100,000 USD.
Categories: Game Theory & Design

TomThorp.me Blog: Mismatched Entity Error

Planet Drupal - 4 November 2019 - 5:06am
If you are getting a "Mismatched entity and/or field definitions" error in your Drupal status page, then this maybe the solution you are looking for.
Categories: Drupal

Jacob Rockowitz: Webform module supports creating custom elements using HTML and SVG markup

Planet Drupal - 4 November 2019 - 4:24am

Problem

The Webform module for Drupal 8 provides support for basic, advanced, and composite inputs/elements. Developers can also create custom elements and composites via code. Sometimes end-users need an interactive visual mechanism to select a complex option like a map location. The Image select element is limited to allowing users to select horizontally-aligned images.

HTML5 and SVG allow designers and site builders to build visually rich and interactive elements. To convert rich interactive HTML/SVG elements into a form input, there needs to be some PHP and JavaScript glue code that captures a user's selection and sets it as a webform submission value.

Besides capturing the end-users selection, the PHP and JavaScript code must also ensure that the interactive HTML/SVG element is accessible to users with disabilities.

Solution

Concept

The general concept for creating a custom 'options' element' is to allow site builders to provide HTML/SVG markup that is dynamically converted into a select-able and accessible Webform element.

Below is a straightforward example of some HTML markup that can be enhanced.

SVG support requires the same data-id and data-name attributes being added to the HTML markup. Below is an example of a single clickable element in SVG.

Implementation

The HTML/SVG markup must provide an option value or text attribute that can be used to create a list of available options. The default recommended 'value' attribute names are 'data-option-value', 'data-value', 'data-id', or 'id'. The default recommended 'text' attribute names are 'data-option-text', 'data-text', 'data-name', 'name', or 'title'. The Webform module uses these value/text attribute names to parse and detect the custom element's available...Read More

Categories: Drupal

Web Wash: Getting Started with React in Drupal 8

Planet Drupal - 4 November 2019 - 4:00am

If you’ve done any web development in the last couple of years, then I’m sure you noticed that JavaScript libraries and frameworks have become popular. The three that come to mind are React, Vue.js, Angular but there are many, many more.

These libraries and frameworks are great for building complex JavaScript applications. Also, being written in JavaScript means they can easily be embedded into a Drupal site.

In this tutorial, I’ll show you how to embed and compile a React application using two methods: Lavavel Mix and Webpack. If you want to use React then you’ll realize very quickly that you can’t just write JavaScript and have it work out-of-the-box, it needs to be compiled. That’s why I’ll show you two ways you can compile React locally without using a CDN.

This tutorial is targeted towards developers who know how to create a Drupal module, use the npm command and know basic React.

A copy of all the code can be found at https://github.com/WebWash/ww_react_examples.

Categories: Drupal

Fuzzy Thinking: Top Ten Signs Your DM is Making It Up as He Goes

RPGNet - 4 November 2019 - 12:00am
Post-it notes and more.
Categories: Game Theory & Design

Commerce ezPay

New Drupal Modules - 3 November 2019 - 10:42pm
Important 重要

This module isn't an official plugin.
這個模組不是官方提供的模組

Introduce

This module is a payment method using in Taiwan. It can't be used in other countries.

模組介紹

這個模組主要是提供D7 的 Drupal Commerce使用的一種付款方式。ezPay是提供跨境網路交易的一種付款方式,而這個模組主要是提供支付寶的付款方式。

Categories: Drupal

Video Game Deep Cuts: Stranded In Luigi's Death Mansion

Social/Online Games - Gamasutra - 3 November 2019 - 5:12pm

This week's roundup includes impressions of Death Stranding through Luigi's Mansion 3 to Modern Warfare as well as neat pieces on food in games, Junji Ito's influence, & more. ...

Categories: Game Theory & Design

Entity Prepopulate

New Drupal Modules - 3 November 2019 - 12:14pm

Prepopulate any entity field with values containing tokens.

Categories: Drupal

JD Does Development: Using Drupal Blocks in a Decoupled GatsbyJS Application

Planet Drupal - 3 November 2019 - 10:40am
Using Drupal Blocks in a Decoupled GatsbyJS Application jflynn Sun, 11/03/2019 - 12:40

One of the most useful components of Drupal is the Block system. This system allows for pieces of content to be created and reused throughout a site in various regions of the page structure. You can also select which bundles or content types this piece of content should appear on, making it so that a blog post gets a certain Call to Action section while an article gets something similar, but different.

When we use GatsbyJS for a decoupled front-end solution with a Drupal back-end, we lose out on quite a bit, if not everything, that the theme layer of Drupal provides. This means that Drupal regions mean nothing to Gatsby, nor does block placement. In fact, any functionality that would go into a .theme file is no longer available on the Drupal side.

Before I get into the "how" of using Drupal blocks in Gatsby, I want to cover a little bit of the "why".

Why Use Drupal Blocks for Content in a Gatsby Front End?

The main advantage of blocks in Drupal is that the content is created in one place, but can be placed in several spots. I have worked with solutions that use Paragraphs (from the Paragraphs contrib module) for similar functionality, but the problem remains where the content needs to be recreated on every new parent entity. For example, I can create a Call to Action (CTA) Paragraph and place fields that reference them on every content type, but the Paragraphs themselves remain separate. A Paragraph is more like a collection of fields to be filled out than a reusable entity, and that's okay.

In contrast, a Block can be created in one place, usually using the Block UI, and the content of the Block remains the same no matter where it is placed. A CTA block on a blog post will have identical content to the CTA block on an article. This makes content changes extremely fast compared to having to update every article and blog post if the wording or link need to change.

It is entirely possible to create these types of entities in Gatsby by defining a reusable component, however the editing experience doesn't really pan out. It may require a developer to go in and edit a React component, adding a middle-person to the process. Using reusable Drupal blocks can save time and budget when set up appropriately.

How to Use Drupal Blocks for Content in a Gatsby Front End

This section is going to make a few assumptions.

  1. You have a basic understanding of Gatsby and React components.
  2. You understand the Drupal theme layer.
  3. You have a basic understanding of the Drupal block system.
  4. Your decoupled application is already setup and pulling content from Drupal (not necessary, but it helps if you can try it out)
  5. You have the JSON:API module enabled on Drupal
  6. You're sourcing content from Drupal.

If you're having problems with any of these, feel free to reach out to me on Drupal Slack, I go by Dorf there.

Now the "how".  We're going to start by creating a Custom Block Type. Let's keep going with the CTA theme and call it "CTA Block". We do this by logging into our site as someone with permissions to access the Block UI and going to admin/structure/block/block-content/types. Once there, select "Add custom block type".

Let's label this CTA Block and begin creation. After we create it, we need to add some fields, so let's add the following fields:

  • CTA Heading
    • A plain text field, max 255 chars
  • CTA Link
    • A Link field using URL and label, internal and external links, Label required.
  • CTA Content Types
    • This is the field that will make all the difference. Create this field as Reference: Other... to begin with.
    • Label it CTA Content Type.
    • Under "Type of entity to reference" choose "Content type" from the select list, under Configuration.
    • Set unlimited cardinality.
    • Go through the remaining screens to create this field. Once you're back on the field list, select "Manage form display"
    • From here, we're going to change the widget from Autocomplete to Check boxes/radio buttons.
    • Save your changes

Now we're going to create a new block using this Custom Block Type. When we create the block under block/add/cta_block the form should look something like this:

Now, add whatever text you want to the fields, but only select a single content type in the CTA Content Type field.  Save the block and spin up your Gatsby dev environment. We're going to switch over there for a bit.

Let's fire up our develop environment and take a look at GraphiQL to see what we have going on.

As you can see, we now have access to allBlockContentCtaBlock in GraphiQL, but what are we going to do with it? Well, we are first going to create the CTA Block React component. We'll do that by creating the file src/components/blocks/CtaBlock.js and adding the following:

import React from 'react' import { graphql } from 'gatsby' const CtaBlock = ({ data }) => { return CTA Heading

CTA Text goes here and here and here.

Link Text } export default CtaBlock

This is pretty simple and doesn't include anything having to do with our GraphQL query yet, but we have the structure in place. Now, let's look at the data we can pull from GraphQL. We want to get the heading, body, link, and content type, so our query is going to look something like this:

query MyQuery { allBlockContentCtaBlock { nodes { field_cta_heading field_cta_link { title uri } body { value } relationships { field_cta_content_type { name } } } } }

Which will give us back:

{ "data": { "allBlockContentCtaBlock": { "nodes": [ { "field_cta_heading": "Heading for the CTA Block", "field_cta_link": { "title": "Learn more!", "uri": "http://google.com" }, "body": { "value": "

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Aenean massa.

\r\n\r\n

Praesent nec nisl a purus blandit viverra. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Phasellus dolor.

\r\n" }, "relationships": { "field_cta_content_type": [ { "name": "Blog Post" } ] } } ] } } }

Perfect! Now I want you to notice a couple of things here. First, we're querying ALL of the CTA blocks here. Second, we're using the content type in the query. Let's get this into our component. Add in the query to our CtaBlock.

import React from 'react' import { graphql } from 'gatsby' const CtaBlock = ({ data }) => { return CTA Heading

CTA Text goes here and here and here.

Link Text } export default CtaBlock export const CtaBlockQuery = graphql` allBlockContentCtaBlock { nodes { field_cta_heading field_cta_link { title uri } body { value } relationships { field_cta_content_type { name } } } }`

But wait, this isn't a page template, and it shouldn't be. What's the problem then? We have a query in a non-page template, and that's not good. What we need to do is figure out which of our templates are going to use this block and add it in there. Since we chose to have the block show on the blog post content type, we're going to use the blog post template. This will probably differ for your setup.

Let's open up our page template and take a look:

import React from 'react' import { graphql } from 'gatsby' import Layout from '../layouts' const BlogPostTemplate = ({ data }) => { const blogBody = data.nodeBlogPost.body.value return {data.nodeBlogPost.title} {data.nodeBlogPost.body.value} } export default BlogPostTemplate export const query = graphql` query($BlogPostID: String!){ nodeBlogPost(id: { eq: $BlogPostID }) { id title body { processed } } } `

Now let's update this to have the block appear.

import React from 'react' import { graphql } from 'gatsby' import Layout from '../layouts' import CtaBlock from '../blocks/CtaBlock' const BlogPostTemplate = ({ data }) => { const blogBody = data.nodeBlogPost.body.value return {data.nodeBlogPost.title} {data.nodeBlogPost.body.value} } export default BlogPostTemplate export const query = graphql` query($BlogPostID: String!){ nodeBlogPost(id: { eq: $BlogPostID }) { id title body { processed } } } `

But we still need to include the query for the block itself. To do this, we're going to make a few edits to both of our components. We'll start with the CtaBlock component and convert the query into a fragment that we can reuse in multiple places if need be.

import React from 'react' import { graphql } from 'gatsby' const CtaBlock = ({ data }) => { return CTA Heading

CTA Text goes here and here and here.

Link Text } export default CtaBlock export const CtaBlockQuery = graphql` fragment CtaBlockQuery on block_content__cta_block { field_cta_heading field_cta_link { title uri } body { value } relationships { field_cta_content_type { name } } }`

If you have a keen eye, you'll notice that we've removed the nodes section of the query. This is because we're now going to query for a single block. However, there is some risk to this. In the event that a content creator creates a new CTA block on Drupal for this content type instead of editing the existing one, the old one will remain in place because a single item query will only return a single item.

Now, let's move back over to our page template and use this fragment to query for our block.

import React from 'react' import { graphql } from 'gatsby' import Layout from '../layouts' import CtaBlock from '../blocks/CtaBlock' const BlogPostTemplate = ({ data }) => { const blogBody = data.nodeBlogPost.body.value return {data.nodeBlogPost.title} {data.nodeBlogPost.body.value} } export default BlogPostTemplate export const query = graphql` query($BlogPostID: String!){ nodeBlogPost(id: { eq: $BlogPostID }) { id title body { processed } } blockContentCtaBlock (relationships: {field_cta_content_types: {elemMatch: {name: {eq: "Blog Post"} } } } ){ ...CtaBlockQuery } } `

Take a look at what we've done here.  We've added in a query for the CtaBlock and we're filtering it by the content type it's attached to. After that, we're pulling in everything from the query on our component. This is exactly what we were wanting to do, but there's another step that we need to take to actually use the data on our component.

If you look at the JSX element for


you'll notice we aren't passing anything to it, so we've got to make sure it has data to work with or we're going to end up rendering nothing.  Edit that line to be 

In case you're not familiar, this is a React concept known as passing props, or properties, to a child component. We're passing the data object that was returned from our GraphQL query to the CtaBlock component so that it can use the included data. Since this is just a demo, we're passing the entire thing along, but it's easy enough to only pass the relevant parts of the object.

Now back in our CtaBlock component we can use the data to render out our block's content.

import React from 'react' import { graphql } from 'gatsby' const CtaBlock = ({ data }) => { return {data.blockContentCtaBlock.field_cta_heading}

{data.blockContentCtaBlock.field_cta_link.title} } export default CtaBlock export const CtaBlockQuery = graphql` fragment CtaBlockQuery on block_content__cta_block { field_cta_heading field_cta_link { title uri } body { value } relationships { field_cta_content_type { name } } }`

Now we have our block based on content type rendering within our content type's Gatsby template. Note that I've left out a few things that should be noted for decoupled sites. 

  1. An internal link should us the Gatsby component.
  2. Drupal needs some love to pass the correct alias over for an internal link so that it renders correctly.
  3. This is a very basic example. YMMV.

Anyway, I hope that this helps someone out there who ran into the same problems that I did. Please feel free to reach out to me on Twitter @jddoesdev, on Slack where I'm usually Dorf, or just leave a comment here if you have questions, concerns, comments, or just something nice to say.

Also, please feel free to support my efforts in speaking on mental health in tech or creating blog posts and tutorials like these by checking out my gofundme and patreon campaigns in the sidebar.

Thanks for reading!

Category Development Tags Drupal Planet Drupal GatsbyJS decoupled JSON:API Comments
Categories: Drupal

Entity Information Table

New Drupal Modules - 3 November 2019 - 7:51am

Display drupal entity info in one table.
It's useful for PM.

Categories: Drupal

Video Game Deep Cuts: Stranded In Luigi's Death Mansion - by Simon Carless

Gamasutra.com Blogs - 3 November 2019 - 5:05am
This week's roundup includes impressions and reviews of a whole bunch of big holiday titles, from Death Stranding through Luigi's Mansion 3 to Modern Warfare and beyond, as well as neat pieces on food in games, Junji Ito's influence on our medium, & lots
Categories: Game Theory & Design

Address Suggestions

New Drupal Modules - 2 November 2019 - 9:46am
Categories: Drupal

Commerce CMI MA

New Drupal Modules - 2 November 2019 - 4:08am
Categories: Drupal

Commerce Fatourati

New Drupal Modules - 2 November 2019 - 4:03am
Categories: Drupal

Virtuous CRM Integration

New Drupal Modules - 1 November 2019 - 6:43pm

This module provides integration of your Drupal 8 website with Virtuous CRM, but is in no way affiliated with or supported by Virtuous Software. This module is not yet ready for production environments.

Categories: Drupal

SingStar servers slated for January 2020 shutdown

Social/Online Games - Gamasutra - 1 November 2019 - 4:05pm

The fat lady sings for SingStar servers at the end of January, when the curtain closes on the SingStore after 15 years of SingService. ...

Categories: Game Theory & Design

Workflow buttons (not dropdown)

New Drupal Modules - 1 November 2019 - 3:52pm

Provide workflow buttons for content moderation instead of a select dropdown of states.

Categories: Drupal

Tithe.ly

New Drupal Modules - 1 November 2019 - 2:10pm

This module provides integration of your Drupal 8 website with Tithe.ly, but is in no way affiliated with or supported by Tithe.ly. This module is not yet ready for production environments.

Categories: Drupal

ZeniMax to grant Fallout 76 refunds under pressure from Australian commission

Social/Online Games - Gamasutra - 1 November 2019 - 12:52pm

Bethesda parent company ZeniMax has admitted it was "likely to have misled" Australian Fallout 76 purchasers about their consumer rights after initially denying several refund requests. ...

Categories: Game Theory & Design

Svg Pan Zoom

New Drupal Modules - 1 November 2019 - 12:30pm

The Svg Pan Zoom module provides an integration of the Svg Pan Zoom library. It provides you a field formatter for your Image fields that supports SVGs.

Svg Pan Zoom is a library that allows you to pan or zoom inside an SVG image.

Requirements

Categories: Drupal

Pages

Subscribe to As If Productions aggregator