Planet Drupal

Syndicate content
Drupal.org - aggregated feeds in category Planet Drupal
Updated: 1 hour 50 min ago

Drupal.org blog: What’s new on Drupal.org? - July 2017

Thu, 08/03/2017 - 21:41

Read our Roadmap to understand how this work falls into priorities set by the Drupal Association with direction and collaboration from the Board and community.

Drupal.org updates Better Distribution packaging

Distributions are a cornerstone of Drupal, giving site-builders a head start by packaging together proven modules and themes from contrib to build a Drupal site to purpose. In July we spent some time improving the functionality for packaging distributions on Drupal.org, by updating Drupal.org's packaging system to use Drush 8. This resolves several issues:

We hope that these changes will help distribution maintainers

reCAPTCHA

One of the key tools we use to prevent spam on Drupal.org is Mollom, which will reach end of life next year. To replace it, we've implemented reCAPTCHA on Drupal.org, and updated our privacy policy accordingly. We have not yet disabled Mollom, because Mollom is a content analysis tool in addition to a captcha tool. Because reCAPTCHA does not duplicate that content analysis functionality we'll be monitoring spam attack patterns on Drupal.org to see whether reCAPTCHA will be a sufficient as a standalone replacement.

Easier addition of new documentation guides and pages

It's hard to believe that the new documentation system has been in use for almost a year. We've made a number of improvements after the initial release to improve usability for both contributors and maintainers of documentation, and to encourage project maintainers to migrate their docs. One piece of feedback we've heard several times is that the 'add content' links the sidebar of a documentation guide were too difficult to find. To make it easier for documentation contributors to add new sub-guides and pages, we've added a new page link to the 'Edit' menu of documentation guides.

Webmasters and documentation moderators can administer all docs

Finding maintainers for the over 12,000 pages of documentation on Drupal.org continues to be a challenge, and so we've given all users with the Webmaster and Documentation Moderator role the ability to administer any documentation guide. This will expand the pool of users who can help to manage documentation and manage documentation maintainers. Good documentation for a project with Drupal's scale is a community-driven effort and we're incredibly thankful for all the volunteers who contribute.

Any confirmed user may claim unmaintained documentation guides

We also now allow any unmaintained guide to be claimed by any confirmed user—automatically adding them as the maintainer for that guide. This should make it much easier for new contributors to take up the mantle of maintaining sections of documentation on Drupal.org.

Learn more about maintaining documentation by reading our content guidelines.

For evaluators Updated industry page call to action

The Drupal.org industry pages are a new experiment for the Drupal Association this year, with a goal of reaching out to Drupal evaluators in specific markets. The success stories we showcase on these pages demonstrate the power of Drupal in these industries, but we also want these pages to be an opportunity to connect evaluators with experts who can help them achieve their goals with Drupal. To enhance our efforts to connect Drupal evaluators to experts in their industry - we've added an additional call to action at the top of the industry page to encourage evaluators to connect with experts.

Front page case study promotion for supporting partners and top contributors

In July we laid the groundwork for promoting a second row of case studies on the Drupal.org home page. The second row will feature case studies from supporting partners and top Drupal contributors. These will not replace the existing row of case studies that are featured through the community process, but will supplement these case studies with additional stories from organizations that support the Drupal project through monetary and issue contribution. Watch for these new stories in the coming months.

Digital tote for Vienna

For DrupalCon Vienna we're implementing a new digital tote bag to deliver benefits to DrupalCon attendees provided by our event sponsors. This digital totebag will feature content for attendees from our Diamond, Platinum, and Gold sponsors.

Speaking of DrupalCon Vienna - prices are about to go up by €50 + VAT - so make sure to register before early bird ends on Friday.

Infrastructure Audit of monitoring and backups

One of the first steps our new infrastructure partner is undertaking is an audit of our monitoring and backup regime, to ensure that we are well-prepared for disaster recovery and mitigation. While our internal team (with the help of dedicated volunteers) has maintained these existing systems, the current system is something of a patchwork of several tools, and we're hopefully that we can consolidate our tools and process and make them more robust and efficient.

———

As always, we’d like to say thanks to all the volunteers who work with us, and to the Drupal Association Supporters, who made it possible for us to work on these projects. In particular we want to thank:

  • Deeson - Renewing Premium Supporting Partner
  • Bits Creative Agency - *NEW* Classic Supporting Partner
  • Tag1 - *NEW* Signature Supporting Partner
  • Pantheon - Renewing Premium Hosting Supporting Partner

If you would like to support our work as an individual or an organization, consider becoming a member of the Drupal Association.

Follow us on Twitter for regular updates: @drupal_org, @drupal_infra

agoradesign: Drupal quick tip of the day: react differently to CLI calls

Thu, 08/03/2017 - 14:04
Sometimes you want to react differently, when the current script is running in a command-line environment. Here's how you can do this.

Appnovation Technologies: How I Stepped My Way Through a Failing Drush Drupal 8 Migration With PHPStorm’s Xdebug Integration...PART 1 of 2

Thu, 08/03/2017 - 13:37
How I Stepped My Way Through a Failing Drush Drupal 8 Migration With PHPStorm’s Xdebug Integration...PART 1 of 2 I was recently going through the d8cards set of exercises to test my knowledge of Drupal 8 APIs, as one does in the dev world... Put simply, or as simply as possible, it consists of a set of 21 exercises, each going over a common Drupal task and how it changes from Drup...

Deeson: Reflections on organising DrupalCamp Bristol 2017

Thu, 08/03/2017 - 11:57

Photo credit: Kris Rzeszut

DrupalCamp Bristol is a non-profit event organised by a team of volunteers from the Bristol Drupal community.

This year, the organising committee chairperson was Mark, a solutions architect at Deeson.

In this post, he considers the challenges and rewards of being involved in organising a community conference. Post-event reflection

After another intense year of planning we’ve just run DupralCamp Bristol for the third time.

It was a really enjoyable few days and we had some great feedback from attendees.

@DrupalCampBris Thanks to all who made #dcbristol17 such a great experience. Inspiring stuff. Looking forward to next year already! :)

— Alison Bancroft (@BancroftAlison) July 2, 2017

Though that’s not to say the experience was entirely stress-free for the organisers!

The challenges

We noticed a shift this year in the way our audience considers the conference. Rather than spending their own time (and money) to attend, people are increasingly opting to make use of company-provided training time and budgets.

It’s great that attendees and their employers see the business value in what DrupalCamp Bristol provides, but it did make organising this year’s camp (on a Saturday) more tricky.

Sponsorship was another area we had to put a lot more of our energy into, compared to previous years. We worked hard to demonstrate the value of spending marketing budget on sponsoring the event, and we were glad to secure the support of some great partners this year, including Deeson.

The positives

Speaker and attendee diversity was a priority for us this year, and we’re proud that our line-up was more representative than in previous years. We know we still have a long way to go and, like Deeson, it’s something we’ll keep actively working on.

A particular highlight for me this year was the lightning talks. It was exciting to witness new talent making, in some cases, their first public speaking appearances in front of the community.

This was also the first year we’ve been able to record all of the sessions, thanks to the hard work of Third Lens Films. Deeson is working on the video post-processing as we speak, and we’ll be publishing the videos in the next few weeks for everyone to enjoy.

How could we improve?

While we’ve received positive feedback year-on-year for the CxO day, I feel like it’s ultimately drawing our attention away from the main conference and would be better suited as an independent event if there is still a demand for it. This would allow us to really focus our energies on organising a fantastic developer conference.

Developers have lives outside of Drupal and companies are increasingly seeing the business value in training events, so I’m confident we would see a surge in attendees if we follow the lead of other technology conferences such as The Lead Developer and move away from running the conference over a weekend.

It’s a lot of work organising the conference, and it couldn’t happen without the hard work and dedication of the committee and volunteers – I’ve particularly appreciated Deeson’s flexible working policy over the last few months! – but something I’m always glad to be part of. Roll on the next one!

Work with Drupal? Deeson is currently hiring for several roles in the development team!

Amazee Labs: Our React learning journey

Thu, 08/03/2017 - 09:39
Our React learning journey

If you push yourself enough with the right amount of motivation, you can achieve more - this notion, along with a lot of curiosity, is what got us through the journey of learning React and helped us to continuously improve the code as we worked on getting the Cape Town Drupal Camp website up and running. 

Maita Kambarami Thu, 08/03/2017 - 09:39 How we started

Like most of our websites at Amazee we first sat down with the design team, to get a clear vision of what their design for this specific project entailed. The design was beautifully crafted and very intuitive to bring out the whole purpose of the Drupal Camp.  

We had an intense briefing meeting, where a lot of sharks and unicorns were mentioned, and at the back of my mind, I had this niggling thought “how is this all going to be done with React” but eventually I hashed my limiting thoughts to focus on the job ahead.

Scrum meeting

During round two of the process, the DBB Scrum Team met for their project planning. These discussions are an agile sort of thing where we go over the estimates and plan how to build the website. We were lucky that Stew had attended the React in Flip Flops training week earlier this year, so he was a good guide and help for most of the things we struggled with.

Before we could plunge into the development of things we had to plan which of the elements qualified to be components, and herein then we encountered our first great learning curve.

The real struggle

There are many bits of advice floating around out there on the best way to learn code, and then more specifically, React. This includes tutorials, in-house knowledge sharing with other team members, reading others’ code with great attention, and blog posts.

Even though tutorials don't always help you the way you expect them to, they do however open your eyes to have an idea of what you hoping to learn. I remember going through Kirupa’s  tutorials and afterwards realising that the way he explained React did indeed open my mind a little more.

Since we were not using React Native I had to rely more on our in-house knowledge share. These regular React knowledge share sessions within the team helped us get some good insight of React and styled components. As a team, we created a Todo App with Facebook’s Create-React-App and went through the code line by line to learn and understand better.

A lot of people say to learn and understand code you have to read other people‘s code not just follow tutorials. The aim is to try to understand things from their point of view and so that's what we did, we closely followed a decoupled Drupal site that our Zurich team is working on at the moment.

There is also a good blog post by Dries Buytaert where he explains the future of decoupled Drupal and gives alternatives to the technologies that can be used to achieve this. In his blog, he mentions our very own Sebastian Siemssen and regards his approach to use GraphQL, as one of the best and gives reasons why.

Tools that help out the workflow

We used a variety of tools in our workflow, two of which are lint-staged and Jenkins, working with these tools also helped us to learn a lot of lessons along the way. A linter is a tool that checks your code for potentially dangerous patterns. It also helps with the consistency of your codebase by checking, for example, the use of indentation and other spacing. It helps you catch silly typos or leftover variables as you go.

Jenkins, on the other hand, is an open-source continuous integration software tool, which we use to automate deployments to our dev, staging and prod servers.

We chose to use styled components as our styling method.  There are some other libraries that one can use a good comparison can be found here.

Some examples:

The way we build the Section Title.

Since all the sections had a title we created one Section Title component that could be reused inside the other sections.

This is the section title in yellow --

Then the code

We created a Section Title Component with {title}, {sectionID} and {titleClasses} as props  (property Types) that were passed  down to the SecTitle as className={titleClasses} , id = {sectionID}  and the {title} . The Section Title component displays the title of the section, along with the id and className whenever it is called.

Importing the Section Title

Below is how the Section Title will be imported and used in the other sections.

The Section Title component is called and the title and the ID are defined. So it will be <SectionTitle title= “Call for speakers” sectionID= “callforspeakers”>.

Notice the className is not used here, and only the title and the ID are used.  You can choose not to use all the property types depending on what you want to achieve.

SectionTitle used without the title property type:

Another example

How we used the mapping function to output a list of sponsors.

What we did here is to create a SponsorList component, which manages the type and the sponsors, by mapping each SponsorsListArray to the type of sponsor.

We created the SponsorsItem component to be used by the SponsorsListArray.

Then we created an array of SponsorItems. Below are three arrays: 1. sponsorsListArrayGold, 2. sponsorsListArraySilver and 3. sponsorsListArrayInKind.

So, each array will have a list of sponsors for that particular type.

For the mapping part

A SponsorsList component will receive a { type } as a parameter and use the else if statement to output the code according to the parameter given.  

So if {type}  = gold then...

It will return a list with SponsorListArrayGold. Another point to remember and make a note of is the use of spread operators, which we used to avoid mutating the props objects.  

So, instead of copying the props one by one we just used {...sponsors}. If more props are added to the SponsorItem there will then not be any need to add it inside the SponsorList Component.

The final index.js of the parent component looks like the code snippet below.

The two SponsorsLists have type gold and silver respectively passed to it, so the type property determines which SponsorListArray is going to be returned.

Conclusion

Our next step would be to learn how to connect React front end to Drupal backend. We will most probably take the Graphql route and maybe write another detailed blog about it.

Like I said, during this project we learnt through trial and error as we went through the various stages. After we fully harnessed the power of React components, we had a better picture of what needed to be done and how to do it.  It also meant that we were able to create elements a bit faster. This was all possible, working as a team and reusing and enhancing components that were already built to produce the best website we could.

See the site at https://capetown2017.drupalcamp.co.za/

myDropWizard.com: Drupal 8 has left small non-profits behind... How can we fix that?

Thu, 08/03/2017 - 00:54

My colleague, Elliot, recently wrote a controversial article called "Drupal sucks at non-profits," which led to some really great discussion in the comments. The general consensus is that Drupal 8 is great for big nonprofits (and big organizations in general) but has left the little guy behind.

Drupal used to be AWESOME for small nonprofits... How can we make it awesome again?

This is something we've been discussing internally for a long time, and we'd like to take a stab at a possible solution with the help of the community and some adventurous nonprofits.

In fact, we'd like to offer a FREE migration to Drupal 8 for 10 nonprofit organizations :-)

But, we'll get to that a little later! First, I'd like to dig into why the current situation kinda sucks...

Abhishek Lal | GSoC Blog: Examples for Developer #9 Week of Coding

Wed, 08/02/2017 - 17:09
Examples for Developer #9 Week of Coding Abhishek Lal B Wed, 08/02/2017 - 20:39

Antonio Ospite: drupal-init-tools: quick and easy Drupal 8 setup

Wed, 08/02/2017 - 16:37

Drupal 8 is quite an improvement over previous versions of Drupal with regard to the reproducibility of a site from a minimal source repository.

The recommended way to set up a new Drupal 8 site is to use composer, and the most convenient way to do that is via drupal-composer/drupal-project, which brings in Drush and drupal-console as per-site dependencies; from there the site can be installed and managed.

However the fact that Drush and drupal-console are per-site dependencies poses a problem: they are not available until the site dependencies have been downloaded, this means that it's not really possible to add “bootstrapping” commands to them to make it easier to set up new projects. This is what motivated me to put together drupal-init-tools: a minimalistic set of wrapper scripts which can be used when Drush and drupal-console are not available yet, or when they have to be combined together to perform a task in a better way.

drupal-init-tools has been developed mainly to speed up prototyping, and it is particularly useful to set up sites under ~/public_html when the web server is using something like the Apache userdir module; however I feel it could be useful in production too after some cleanups.

drupal-init-tools standardizes the setup and installation of new Drupal projects: for example the drin new command makes sure that the original drupal-composer/drupal-project repository is still accessible from an upstream git remote so that the developer can easily track changes in drupal-composer/drupal-project and keep up if appropriate for their particular project.

Some drin commands also provide a nicer interface for frequent and important tasks, like the actual site-install step, or the creation of an installation profile that could replicate the installed site.

Here are some examples of use taken from the drin manual.

Create and install a new Drupal project:

cd ~/public_html drin new drupal_test_site cd drupal_test_site $EDITOR bootstrap.conf drin bootstrap --devel

Create an installation profile from the currently installed project:

drin create-profile "Test Profile" test_profile

Clean and rebuild the whole project to verify that installing from scratch works:

drin clean drin bootstrap

A quick way to test drupal-init-tools is this:

git clone git://git.ao2.it/drupal-init-tools.git cd drupal-init-tools/ make local ./drin --help

Give it a go and let me know what you think.

If it proves useful to others I could have it packaged and uploaded to Debian to make it more “official”, IMHO it makes sense to have such a small meta-tool like drin as a system global command.

MD Systems blog: MD Systems is now a Certified Thunder Integrator

Wed, 08/02/2017 - 15:31
Since we released the thunderdemo.com earlier this year a lot of interesting things happened in the Thunder ecosystem. We thought that it is a good time to provide an update.

Sooper Drupal Themes: Are you excited for Drupal 8? Join us to test Glazed Theme 8, Glazed Builder 8 and all our Drupal 8 Products

Wed, 08/02/2017 - 14:14

Have you been waiting for this update? Yes it's that time, I can finally show you the Drupal 8 products we've been working on! In the last 4 months we were 100% focused on upgrading all products to Drupal 8. I tagged today's updates as alpha releasea but the products have come a long way and are practically on par with their matured Drupal 7 counterparts.

Considering the size and scope of this enormous update, we are excited to get people involved in testing the products and to begin testing as soon as possible. To facilitate this I put a link and feedback thread in the support forum, it's only visible to registered users: Glazed Drupal 8 Alpha1 Download & Feedback thread.

For people who are not yet subscribers of our Drupal themes shop, now is the time to get in and get early access to our awesome Drupal 8 product line. Join here to start downloading Drupal 8 themes!

Sneak Preview Oops, YouTube iFrame won't load here. Read this blog here to view the video.

Drupal 8 Related Questions

Will Drupal 8 products cost existing subscribers more money? (No)

At SooperThemes all our subscriptions, including the entry level subscription give you access to all themes and modules. No exception. Drupal 8 products are immediately available to all subscribers regardless of subscription level or sign-up date.

When can we expect a stable release of all products?

We will integrate drupal 8.4 Media fields across all our products so that we don't miss out on critical media-reusability features. This means we are bound by the Drupal 8.4 release schedule with our Drupal 8 products and installation profile. Drupal 8.4 is supposed to have a beta release on September 14th, a release candidate on September 20th and a stable release on October 4th. We will try to provide backwards-compatible beta releases as soon as Drupal 8.4 has a beta release. Before then we recommend you only use our Drupal 8 products for testing, unless you are prepared to migrate or manually fix file fields on your content.

What can we test today?

The alpha release contains the full Main Demo with all features and demo content. It includes upgraded versions of Glazed Builder, Glazed Theme, Glazed GridStack and contrib modules. The Glazed Portfolio module built on top of the MD Portfolio module has been phased out. We built an all-new SooperThemes Portfolio module from the ground up. This module has surpassed feature parity with the Glazed Portfolio module and now provides even more features and design options.

Amazee Labs: Drupal and GraphQL with React and Apollo

Wed, 08/02/2017 - 11:03
Drupal and GraphQL with React and Apollo

Building an app that displays a list of articles in Drupal in the traditional way is a straightforward task - meaning that we use Drupal for everything: backend configuration and data storage as well as frontend (usually twig in Drupal 8).

However, doing the same thing in a decoupled configuration, where we use for example Drupal for backend and data storage, and React as frontend, is not that easy.

To help you with this, this blog post aims to show how you can successfully build that.

Vasi Chindris Wed, 08/02/2017 - 11:03

There are 3 things you'll need to build this: Drupal, React and something that can bind those two together, meaning that it can fetch the data from Drupal and make it available in React. For this third thing, we will use GraphQL and Apollo.

Drupal Setup

As mentioned, the first thing you'll need to do is to install Drupal. Nothing special to mention here, just do a plain Drupal 8 installation. Additionally, you should also download the GraphQL module or clone it from https://github.com/fubhy/graphql-drupal. For now, we will just install the GraphQL Content and the GraphQL Views modules (they will automatically install the GraphQL and GraphQL Core dependencies).

We want to list some articles, so just go ahead and create a few (or use the Devel generate module if you want). Be sure to also create a simple view that lists articles (don't worry about displays right now, just list the title of them).

So now you have the Article content type (which was already there) and the Articles view which you just created, and you want to expose them via GraphQL. For this, you need a schema. You don't have to write it yourself, you just have to expose your configuration.

To expose content, just go to /admin/config/graphql/content and there you should see a list with all your entity types and bundles that you can expose. We want to expose the Article content type, so just click on Content and then Article.

Then you have the possibility to choose which fields to expose. And you do that by selecting a View mode. So before actually exposing the Article bundle, we need to configure a view mode. I recommend creating a new one, let's call it graphql, so that you can easily see it is used to expose data to GraphQL.

Go to admin/structure/display-modes/view and create the new view mode. Now you can go back to admin/config/graphql/content, click again on Content and Article and you should be able to select GraphQL from the view modes list. Don't forget to click on the Save configuration button.

Next you can go to the Manage display tab of the Article content type (/admin/structure/types/manage/article/display), and configure the GraphQL display.

Let's say we want to expose the body field(the title is automatically exposed).


 

The second thing we want to expose is the Articles view. To do that, just go to edit your view and add a GraphQL display. Let's change the machine name to graphql_articles. Rebuild the cache and that's it. You just exposed your view to the GrapqQL schema.

Now, how can you be sure that what you did has really changed the schema. There is a very easy way to check this. There is a tool called GraphiQL which you can use to run GraphQL queries and also check the schema. For this, just install the GraphQL Explorer module, and then navigate to /graphql/explorer on your site. On the top right you should have a link called Docs which will expand the Documentation Explorer on click.

In the search box, just input Article and you should see two entries: NodeArticle (this is the article content type you exposed) and articlesGraphqlArticlesView which is your view. If you see those, then you properly configured the schema.


As mentioned, with GraphiQL you can run GraphQL queries. It's time to see if we get any data.

So for the article view, just use this query:

{   articlesGraphqlArticlesView {     ...on NodeArticle {       entityId       title       body     }   } }

Put this in the left panel, click the run button and you should see the results in the right panel. The above query can be translated like this: give me the results from the articlesGraphqlArticlesView view, and when the type of the object is NodeArticle, give me the title, the body and the entityId fields.

With the query above we just tested both things we exposed: the Articles view and NodeArticle content type.


React

The second thing to do is to prepare your frontend. In this example, we'll use React. Probably the easiest is to use create-react-app. So just go ahead and create a new app and make sure you can start it and have the home screen displaying properly.

Let's build now an ArticlesView component which can display a list of ArticleTeaser components.

Here is the ArticlesView component:

import React from 'react'; import ArticleTeaser from '../ArticleTeaser'; const ArticlesView = ({articles}) => (   <ul>     {articles.map(article => <li key={article.id}><ArticleTeaser article={article} /></li>)}   </ul> ); export default ArticlesView;


And here is the ArticleTeaser component:
 

import React from 'react'; const ArticleTeaser = ({ article }) => (   <div>     <h3>{article.title}</h3>     <div>{article.body}</div>   </div> ); export default ArticleTeaser;

 

Finally, the App.js can look something like this for now (with a dummy list of articles):

import React, { Component } from 'react'; import ArticlesView from './ArticlesView'; const articles = [   {     id: 1,     title: 'First article',     body: 'This is the first article',   },   {     id: 2,     title: 'Second article',     body: 'This is the second article',   } ] const App = () => (   <div className="App">     <ArticlesView articles={articles} />   </div> ); export default App;

If you run this you should see a list of two articles with their title and body. This is pretty much the pure frontend you have to do. The rest is just supplying the real data to the frontend. This needs some additional packages to be installed. So here we go!
 

GraphQL and React Apollo

To connect to our GraphQL server from React, we will use the React Apollo library. To install it just run:

yarn add react-apollo

The first thing we will do is to update our ArticlesView component. We want to get the list of the articles injected into the component. So we will use the graphql Higher Order Component provided by the react-apollo library and run a basic query to get the results. 

Here is the updated code for the ArticlesView component:

import React from 'react'; import { gql, graphql } from 'react-apollo'; import ArticleTeaser from '../ArticleTeaser'; const query = gql`   query articlesQuery {      articlesGraphqlArticlesView {       ...on NodeArticle {         id:entityId         title body       }     }   } `; const withQuery = graphql(query, {   props: ({ data: { loading, articlesGraphqlArticlesView } }) => ({     loading,     articles: articlesGraphqlArticlesView   }), }); const ArticlesView = ({ loading, articles }) => {   if (loading) {     return null;   }   return (     <ul>       {articles.map(article => <li key={article.id}><ArticleTeaser article={article} /></li>)}     </ul>   ) }; export default withQuery(ArticlesView);

The first thing to do is to build the GraphQL query that we'll use to fetch our data. We can do this using the gql function. Then we wrap our initial ArticlesView component with the Higher Order Component returned by grapqhl. The GraphQL HOC will get our query as a parameter, as well as a config object where we can specify among other things the props that our ArticlesView component will get.

In our case, the ArticlesView component will receive a loading flag which can be used to check if the data is still loading from the server and the articles which are basically the articlesGraphqlArticlesView result from the GraphQL request.

We also need to update a bit the App component, because we need to wrap everything into an ApolloProvider component.

Here is the code:

import React, { Component } from 'react'; import ArticlesView from './ArticlesView'; import { ApolloClient, createNetworkInterface } from 'apollo-client'; import { ApolloProvider } from 'react-apollo'; const client = new ApolloClient({   networkInterface: createNetworkInterface({     uri: 'http://url_to_drupal_site/graphql'   }), }); const App = () => ( <ApolloProvider client={client}>   <ArticlesView />   </ApolloProvider> ); export default App;

As you can see, the App component wraps the ArticlesView component inside ApolloProvider (which is initialized with an ApolloClient) and this means that any component bellow ApolloProvider can use the HOC returned by graphql to make requests to the GraphQL server using the ApolloClient which we instantiate in the client parameter.

This is a very important thing to keep in mind. If you move the ArticlesView component outside of the ApolloProvider, your app will not work anymore.

At this point, you can try to run your app, but you may receive a few js errors.

The first may be this one:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

This means that your backend server does not allow sending content to a different domain than its own. So we'd need to enable the cors.config in your services.yml file (in sites/default). More about that here: https://www.drupal.org/node/2715637

Here's a possible configuration:

cors.config:     enabled: true     # Specify allowed headers, like 'x-allowed-header'.     allowedHeaders: ['x-csrf-token','authorization','content-type','accept','origin','x-requested-with', 'access-control-allow-origin']     # Specify allowed request methods, specify ['*'] to allow all possible ones.     allowedMethods: ['*']     # Configure requests allowed from specific origins.     allowedOrigins: ['*']     # Sets the Access-Control-Expose-Headers header.     exposedHeaders: false     # Sets the Access-Control-Max-Age header.     maxAge: false     # Sets the Access-Control-Allow-Credentials header.     supportsCredentials: false

Rebuild the drupal cache and this error should dissapear.

A second error you could get is a 403 for the request to /graphql. The problem is that the anonymous user does not have access to run GraphQL queries. Just go to the administer permissions page and give the Execute arbitrary GraphQL requests permission to the anonymous role. Reload the page and you should see a list of articles (which of course you have to create first in Drupal).

This is the most simple listing app that you can do with Drupal, GraphQL, React and Apollo. However, there are many other features you may need. In the next section, we'll discuss pagination and filtering (including contextual arguments).

Filtering

For this example, we need to add a new field on our Article content type. Let's say we add a Year field on our articles, which is of type List (integer) and can have for now 3 possible values: 2017, 2016 and 2015.

It may look something like this:

Then add the Year field as an exposed filter.

And you can also expose the year field in the GraphQL display mode of the Article content type so that you can also fetch it for displaying in the frontend.

And now all you have to do in the frontend is to adjust the query and use the filter, like this:

const query = gql`   query articlesQuery {      articlesGraphqlArticlesView(filter: {field_year_value: "2015"}) {       ...on NodeArticle {         id:entityId         title         body       }     }   } `;

One important thing to keep in mind for now: if you have a filter on a view, you must provide a value for it in the query, otherwise the empty string will be used and most probably you will not get any results. And in this case, if you just want to print all the articles, use 'All' for the field_year_value filter.

Now, of course, having that year value hardcoded in the query is good enough for a demo, but in real apps you will probably want to have that variable. For this, we have to update our query to contain variables and our config object which is used by the graphql HOC to inject that variable into our query.

First, let's see the new query:

const query = gql`   query articlesQuery($year: String!) {      articlesGraphqlArticlesView(filter: {field_year_value: $year}) {       ...on NodeArticle {         id:entityId         title         body         fieldYear       }     }   } `;

And second, let's see the new GraphQL call:

const withQuery = graphql(query, {   options: () => ({     variables: {       year: 2016,     },   }),   props: ({ data: { loading, articlesGraphqlArticlesView } }) => ({     loading,     articles: articlesGraphqlArticlesView   }), });

What we did so far was to just move the hard-coded value from the query into the config object. It's a step forward, but it is still kind of hard-coded. Ideally, we'd have the year specified as a prop on the ArticlesView component.

And in fact we can do that, because the options function can get the component props as a parameter, like this:

options: (props) => ({   variables: {     year: props.year,   }, })


Which means you will use the ArticlesView component in App.js like this:

<ArticlesView year={2016} />


If you try now the app and replace the year with different values you should get different results.

Contextual filters are pretty much the same as filters. So, for example, if we want to add the author of the articles as a contextual filter to the view, to query that in fronted just add the contextual_filterI argument to the articlesGraphqlArticlesView field, like this:

articlesGraphqlArticlesView(filter: {field_year_value: $year}, contextual_filter: {uid:"2"}) {   ... }

And just like for the year filter, you can use a variable for the uid filter.


Pagination

To use pagination, first, you have to update the view itself. It is not important how many items per page you set, it is just important that the view has a page. The number of items per page will be specified in the query.

If you do that the articlesGraphqlArticlesView field will get two additional arguments: page and pageSize.

You will have something like this:

articlesGraphqlArticlesView(page: 0, pageSize: 2, filter: {field_year_value: $year}, contextual_filter: {uid:"2"}) {   ... }

And if you run now your app you will actually see that there are no results returned. The reason is that the articlesGraphqlArticlesView will now return a different structure. It will be an object with two attributes: count that represents the total number of results and results which are the results of the current page.

The new query therefore is (for simplicity, the filters and contextual filters are removed):

const query = gql`   query articlesQuery {      articlesGraphqlArticlesView(page: 0, pageSize: 2) {       count       results {         ...on NodeArticle {           id:entityId           title           body           fieldYear         }       }     }   } `;

Of course, now we have to update the props of the graphql config object.

props: ({ data: { loading, articlesGraphqlArticlesView } }) => ({   loading,   articles: articlesGraphqlArticlesView && articlesGraphqlArticlesView.results, }),

If you reload the page, you should see now 2 articles. The last thing to do is to have a link or a button that when clicked it will load more entries.

Here is the LoadMore component:

import React from 'react'; const LoadMore = ({ loadMoreHandler }) => (   <a onClick={(e) => loadMoreHandler(); e.preventDefault()} href="https://www.amazeelabs.com/en">Load more</a> ); export default LoadMore;

And add the LoadMore component in the ArticlesView component:

<div>   <ul>     {articles.map(article => <li key={article.id}><ArticleTeaser article={article} /></li>)}   </ul>   <LoadMore /> </div>

 

Now we have to supply a loadMoreHandler to the LoadMore component. Luckily, when using the config object of the grapqhl we have access to a function called fetchMore() which we can use to rerun the query and fetch more (or other) results. Using that function, we will add a new prop which will be injected into our ArticlesView component, which will be the loadMoreHandler.

Here is the updated query (which now contains the page and pageSize as variables) and the updated graphql call:

const query = gql`   query articlesQuery($page: Int!, $pageSize: Int!, $year: String!) {      articlesGraphqlArticlesView(page: $page, pageSize: $pageSize, filter: {field_year_value: $year}) {       count       results {         ...on NodeArticle {           id:entityId           title           body           fieldYear         }       }     }   } `; const withQuery = graphql(query, {   options: (props) => ({     variables: {       year: props.year,       page: 0,       pageSize: 2,     },   }),   props: ({ data: { loading, articlesGraphqlArticlesView, fetchMore } }) => ({     loading,     articles: articlesGraphqlArticlesView && articlesGraphqlArticlesView.results,     total: articlesGraphqlArticlesView && articlesGraphqlArticlesView.count,     loadMoreEntries() {       return fetchMore({         variables: {           // The page number will start with 0, so the next page is basically           // the number of current results divided by the page size.           page:             articlesGraphqlArticlesView.results &&             Math.ceil(               articlesGraphqlArticlesView.results.length / 2,             ),         },         updateQuery: (previousResult, { fetchMoreResult }) => {           // If there are no new results, then just return the previous result.           if (!fetchMoreResult.articlesGraphqlArticlesView.results) {             return previousResult;           }           return {             articlesGraphqlArticlesView: {               ...previousResult.articlesGraphqlArticlesView,               count: fetchMoreResult.articlesGraphqlArticlesView.count,               results: [                 ...previousResult.articlesGraphqlArticlesView.results,                 ...fetchMoreResult.articlesGraphqlArticlesView.results,               ],             },           };         },       });     },   }), });

So fetchMore will rerun the query. The config object it gets as a parameter has two main properties: the variables which will be used to merge new variables into the existing ones (in our case we just want to get the next page) and updateQuery, which is actually a function that can access the previous result as well as the new result and has to return the new articlesGraphqlArticlesView field.  

As seen above, we use that to merge the new results into the existing ones. And it's now time to use the new props that we inject into our ArticlesView component.

Here is the updated component:

const ArticlesView = ({ loading, articles, total, loadMoreEntries }) => {   if (loading) {     return null;   }   return (     <div>       <ul>         {articles.map(article => <li key={article.id}><ArticleTeaser article={article} /></li>)}       </ul>       { total > articles.length ? <LoadMore loadMoreHandler={loadMoreEntries}/> : null}     </div>   ) }; export default withQuery(ArticlesView);

And that's all I wrote, folks! You now have a view built in Drupal that you expose in GraphQL and use Apollo and React to display it in frontend, with pagination and filters.

Vardot: Introducing Vardot's New Drupal 8 Website

Wed, 08/02/2017 - 07:44
Introducing Vardot's New Drupal 8 Website Mohammed J. Razem Wed, 08/02/2017 - 08:44

The cobbler's children always go barefoot! Is a saying we no longer want to be associated with. As a Drupal-specialized development house, it's no longer an excuse to keep a Drupal 7 website.

You're currently reading this post from our new Drupal 8 website, built using the ultimate Bootstrap distribution available for Drupal 8; Varbase (see project page on drupal.org). We've built Varbase with the basic concept of DRY (Don’t Repeat Yourself), so that we relieve ourselves from repeating all the modules, features, configurations, best-practices that are included in every Drupal website we built.

Did you know that Varbase is available for free to install and build websites on it yourself? You can test-drive it now on Simplytest.me. Or contact us to build one for you.

 

New Website Sections

Our new website features our Products in a new section where you can learn more about each product we build.

We also highlight how we deliver business solutions for various industries and verticals, including Higher-ed and SchoolsCorporates and Enterprises, Non-profits and NGOs, and News, Media and Entertainment.

 

Paragraphs to Build Nice Pages

The new website (and Varbase) uses the famous Paragraphs module, and suite of other modules that we have specifically built for Varbase, such as Varbase Bootstrap Paragraphs.

You can now leverage this functionality with an intuitive page building experience when you use Varbase.

 

It's worth noting that it took us 2 weeks to build the new website! Amazing, right? Let us know what you think.

And contact us to discuss your next project.

ADCI Solutions: Top-10 responsive Drupal e-commerce themes

Wed, 08/02/2017 - 06:00

Who cares about shopping offline if one can do it online? Thanks to attractive ready-to-use commerce templates, the process of selling and buying things in the Interner is becoming more smooth and pleasant day by day. For this article we chose ten Drupal e-commerce themes which can be used for different kind of stores. 

Retail, fashion, food store - Drupal can do it all.

 

Read the full article and choose your theme.

 

ActiveLAMP: Migrating Drupal 7 redirects to Drupal 8

Wed, 08/02/2017 - 04:00

When migrating from Drupal 7 to Drupal 8, it is important to remember to migrate over the redirects as well.

Read more...

PreviousNext: Testing sort order with BrowserTestBase

Wed, 08/02/2017 - 00:39

Just a quick post to share a simple way to assert some markup is ordered correctly using BrowserTestBase

Himanshu Dixit | Blog: Week 9: Finishing Base Social Auth Implementer And Work on Social Post Implementer

Tue, 08/01/2017 - 20:10
Week 9: Finishing Base Social Auth Implementer And Work on Social Post Implementer himanshu-dixit Tue, 08/01/2017 - 23:40

Mediacurrent: Designer to Developer: How to Go from Paper to Style Guide

Tue, 08/01/2017 - 19:42

Ever wonder how websites go from initial design to code? What steps and tools are involved? What are the common pitfalls and how can you avoid them? In this blog post, I will recap the process our designers and front-end developers take to when creating a new website design for our clients. Hopefully, this will give you a little more insight into Mediacurrent’s methodology and in turn help you develop a more robust workflow of your own.
 

Build the Foundation

Before design even begins, there are a few key items to set the project up for success:

Web Wash: Getting Started with Webform in Drupal 8

Tue, 08/01/2017 - 19:00
The Webform module in Drupal 8 makes it easy to create complex forms in no time. The basics are easy to learn but when you start digging below the surface, the huge power of the Webform module starts to reveal itself. While the Contact module in Drupal 8 core does allow you to create simple personal and site-wide contact forms, functionality is limited. This is where Webform module steps in. In the first part of this tutorial, we’ll use some Webform elements to create a simple but fully functioning form. We’ll show what you can do with the results of submissions and then add some additional elements. We’ll also demonstrate how one of the built-in JavaScript libraries can improve the look of form elements. In part two, we’ll add additional pages to our Webform, apply conditional logic, show how to create great layouts and much more!

InternetDevels: Dockerize it, or why use Docker in Drupal development

Tue, 08/01/2017 - 18:26

The smart drop and the clever whale — there is no doubt that Drupal and Docker are highly compatible! It seems like their element is water, however, their true “element” is efficiency. Flexibility, security, and open-source standards are also worth mentioning. So after sharing a collection of useful links for working with Docker, we would like to take a closer look at this great “couple” and see why it’s worth using Docker to boost your Drupal development.

Read more

Mediacurrent: Building Components: Breaking it down

Tue, 08/01/2017 - 18:25

By now it’s no secret that the recommended approach for building websites is using components.  Component-driven development is breaking entire web pages into smaller pieces and working with those pieces individually.  As Stephen Hay puts it in his talk on Responsive Design Workflow, “We’re not designing pages, we’re designing systems of components."