• Drupal 8/9 Social Auth Buttons

    Finally an easy way to render Social Auth links/buttons. Simply download and enable Social Auth Buttons and the buttons will be rendered in Drupal's default login form. You can even embed and render it to your custom forms like this:   $form['social_auto_buttons'] = [ '#type' => 'social_auth_buttons', '#title' => t('Social Auth Buttons'), ];   Theming The form elements that came with this module are fully themeable. Below is a sample to add icons to the buttons using Font Awesome icons Make sure you have Font Awesome libraries loaded in to your theme. [theme].libraries.yml ... fontawesome: version: VERSION js: node_modules/@fortawesome/fontawesome-free/js/all.min.js: {} css: component: node_modules/@fortawesome/fontawesome-free/css/all.min.css: {} ... Theme the buttons using hook_preprocess_social_auth_buttons_link() [theme].theme   ... /** * Implements hook_preprocess_HOOK(). */ function [theme]_preprocess_social_auth_buttons_link(&$variables) { /* Your code here */ $icons = [ 'facebook' => 'fab fa-facebook-f', 'google' => 'fab fa-google', 'instagram' => 'fab fa-instagram', ]; $id = $variables['name']; if (isset($icons[$id])) { $variables['icon'] = [ '#markup' => '<i class="' . $icons[$id] . '"></i>', ]; } $variables['attributes']['class'][] = 'btn-' . $id; } ...  
  • Get active theme in Drupal 8

    if you want to get actual active theme name (administration theme included), use:  $activeTheme = \Drupal::service('theme.manager')->getActiveTheme(); if you want your default front end theme, use: $defaultThemeName = \Drupal::config('system.theme')->get('default');  
  • Drupal 8 site with Docker + Solr search (docker4drupal by wodby)

    This tutorial applies to docker4drupal by wodby. PART 1: Install and configure Drupal 8 Search API Solr module Install Search API Solr module. After installing the module, configure Solr server. Go to Home > Administration > Configuration > Search and metadata > Search API Create a new server or edit an existing one and update the fields under CONFIGURE SOLR BACKEND field group HTTP protocol: http Solr host: solr Solr port: 8983 Solr path: [empty] Solr core: [NAME OF YOUR CORE THAT WE WILL USE ON PART 2]   PART 2: Creating Solr core SSH to a runnig Solr container: make shell solr or docker-compose exec solr sh Create Solr core make create core=[core name that we want to use on PART 1] -f /usr/local/bin/actions.mk  
  • drupal + docker

    Drupal 8 Docker with multisite setup

    1. Setup Docker Download latest release of Docker4Drupal and install as Vanilla Drupal or to an existing codebase. Follow the comprehensive tutorial from https://wodby.com/docs/1.0/stacks/drupal/local/#usage   2. Update Docker configurations Set the default site domain name in .env  ... PROJECT_BASE_URL=mycoolsite.localhost ...   Create multiple instances of database servers in docker-compose.yml ... default: image: wodby/mariadb:$MARIADB_TAG container_name: "${PROJECT_NAME}_default" stop_grace_period: 30s environment: MYSQL_ROOT_PASSWORD: $DB_ROOT_PASSWORD MYSQL_DATABASE: $DB_NAME MYSQL_USER: $DB_USER MYSQL_PASSWORD: $DB_PASSWORD ports: - 42330:3306 # Port that we can access outside of the container volumes: - ./assets/default.sql:/docker-entrypoint-initdb.d/dump.sql # Place init .sql file(s) here. subsite: image: wodby/mariadb:$MARIADB_TAG container_name: "${PROJECT_NAME}_subsite" stop_grace_period: 30s environment: MYSQL_ROOT_PASSWORD: $DB_ROOT_PASSWORD MYSQL_DATABASE: $DB_NAME MYSQL_USER: $DB_USER MYSQL_PASSWORD: $DB_PASSWORD ports: - 42331:3306 # Port that we can access outside of the container volumes: - ./assets/subsite.sql:/docker-entrypoint-initdb.d/dump.sql # Place init .sql file(s) here. ...   Set web server (nginx) configurations ... nginx: image: wodby/nginx:$NGINX_TAG container_name: "${PROJECT_NAME}_nginx" depends_on: - php environment: NGINX_STATIC_OPEN_FILE_CACHE: "off" NGINX_ERROR_LOG_LEVEL: debug NGINX_BACKEND_HOST: php NGINX_SERVER_ROOT: /var/www/html/web NGINX_VHOST_PRESET: $NGINX_VHOST_PRESET # NGINX_DRUPAL_FILE_PROXY_URL: http://example.com volumes: - ./:/var/www/html:cached ports: - "8001:80" # port to use for proxy labels: - 'traefik.backend=${PROJECT_NAME}_nginx' - 'traefik.frontend.rule=HostRegexp:{subdomain:[a-z]+}.${PROJECT_BASE_URL}' # subdomain ...   3. Drupal site configurations In this tutorial we will have these 2 sites: Default Name: default Domain: mycoolsite.localhost Port: 80001 Subsite Name: subsite Domain: subsite.mycoolsite.localhost Port: 80001     First thing is we need to make changes on sites.php file base on the site informations above.  ... $sites['8001.mycoolsite.localhost'] = 'default'; // Docker default site $sites['8001.subsite.mycoolsite.localhost'] = 'subsite'; // Docker subsite site ...   Next is we need to make sure we have these 2 folders under the sites folder: default subsite   Add the database configurations for both sites using the hostname that we configured from docker-compose.yml.   sites/default/settings.php (default) ... $databases['default']['default'] = [ 'database' => 'drupal', 'username' => 'drupal', 'password' => 'drupal', 'prefix' => '', 'host' => 'default', 'port' => '3306', 'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql', 'driver' => 'mysql', ]; ...   sites/subsite/settings.php (default) ... $databases['default']['default'] = [ 'database' => 'drupal', 'username' => 'drupal', 'password' => 'drupal', 'prefix' => '', 'host' => 'subsite', 'port' => '3306', 'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql', 'driver' => 'mysql', ]; ...    
  • Drupal 8: Show Drupal throbber on button that manually calls Views AJAX RefreshView

    In this tutorial, I will guide you how to show Drupal's progress/throbber icon on your button that call the Views AJAX RefreshView.   Views Configuration Make sure your view is using AJAX. To do that, set the "Advanced > Use Ajax" on your view.   HTML Button <a href="#" class="btn btn-default reload-view-button">Refresh View</a>   Javascript Drupal.behaviors.refreshLink = { attach: function(context, settings) { if ($('.reload-view-button', context).length > 0) { $('.reload-view-button', context).once().on('click', function(e) { e.preventDefault(); var self = this; // Change [YOUR VIEW ID] to your actual view id // This loop will get the view instance from the view class var viewInstance = Object.values(Drupal.views.instances).find(function(item) { if (item.$view.length > 0 && $('.view-id-[YOUR VIEW ID]').length > 0) { return item.$view[0] === $('.view-id-[YOUR VIEW ID]')[0]; } }); if (viewInstance) { // Get the ajax throbber from theme var progressElement = $(Drupal.theme('ajaxProgressThrobber')); // Append the throbber to the button $(self).append(progressElement); // Refresh the view by ajax $('.view-id-[YOUR VIEW ID]').trigger('RefreshView'); // Override the success callback method viewInstance.refreshViewAjax.success = function(response, status) { // Call the original callback Drupal.Ajax.prototype.success.call(this, response, status); // ADD ALL THE THINGS WE WANT TO DO AFTER REFRESH VIEW AJAX SUCCESS! // Remove the throbber element that we added above $(progressElement).remove(); }; } }); } } }  
  • drupal 8

    Drupal 8: Redirect to page from Event Subscriber with destination query

    Create your Event Subscriber Create your module's services yml file and declare the event subscriber services: mymodule.autologin: class: Drupal\mymodule\EventSubscriber\AutoLogin tags: - {name: event_subscriber} Save this as mymodule.services.yml inside mymodule folder Create the actual class used from above code <?php namespace Drupal\mymodule\EventSubscriber; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class AutoLogin implements EventSubscriberInterface { public function redirectToLogin() { // PUT YOUR LOGIC HERE } /** * {@inheritdoc} */ public static function getSubscribedEvents() { $events[KernelEvents::REQUEST][] = ['redirectToLogin']; return $events; } } Save this as AutoLogin.php inside mymodule/src/EventSubscriber folder   Redirect using URL::fromRoute with destination query $current_path = \Drupal::service('path.current')->getPath(); $url = \Drupal\Core\Url::fromRoute('simplesamlphp_auth.saml_login', [], ['query' => ['destination' => $current_path, 'absolute' => TRUE]]); $response = new RedirectResponse($url->toString(), 302); $event->setResponse($response); Put the above code in the AutoLogin::redirectLogin(). This code will get the current path and redirect to saml login page to auto login, then if the login is successful, it will redirect to the original path that we are trying to access.  
  • drupal + bootstrap

    Drupal 8 module: Bootstrap 4 Modal

    Are you using Drupal 8 Bootstrap 4 Theme (Barrio) and you want to use Drupal Ajax Dialog? Chances are you might have to do some extra coding just to make that Drupal core modal dialog make it look and feel like a bootstrap modal. Bootstrap 4 Modal module adds new type of dialog that you can use. Example of Drupal core ajax modal dialog: <a class="use-ajax" data-dialog-options="{&quot;width&quot;:400}" data-dialog-type="modal" href="/node/1"> First node displayed in core modal dialog. </a> This link will load drupal node id 1 by ajax on drupal core modal dialog with 400px width   Example of Bootstrap 4 Modal dialog: <a class="use-ajax" data-dialog-options="{&quot;dialogClasses&quot;:&quot;modal-dialog-centered&quot;,&quot;dialogShowHeader&quot;:false}" data-dialog-type="bootstrap4_modal" href="/node/1"> First node displayed in bootstrap 4 modal dialog. </a> This link will load drupal node id 1 by ajax on drupal core modal dialog with modal dialog vertically centered and no modal header.  
  • Drupal 8 Layout Builder + Display Suite Drag & Drop Fix - Display suite

    Layout Builder + Display Suite - Drag & Drop Issue By default, Display Suite layouts are using it's own region attributes like below: {{ title_suffix.contextual_links }} <{{ outer_wrapper }}{{ attributes.addClass('row', 'clearfix') }}> <{{ top_wrapper }}{{ top_attributes.addClass('col-12', 'region-top') }}> {{ top }} </{{ top_wrapper }}> </div> This takes out classes that the layout builder used for the drag & drop feature. The fix is to simply use the region attributes from layout builder like: {{ title_suffix.contextual_links }} <{{ outer_wrapper }}{{ attributes.addClass('row', 'clearfix') }}> <{{ top_wrapper }}{{ region_attributes.top.addClass('col-12', 'region-top') }}> {{ top }} </{{ top_wrapper }}> </div>   Layout Builder + Display Suite - Custom Classes Missing After Layout Region Attribute Fix Although the drag & drop issues was fixed with the above code, it introduces another issue when you want to use the custom classes. I noticed that the regions that used the default layout builder region attributes are not loading the custom classes. To fix it, we should combine the classes from both layout builder region attributes and display suite region attributes. Simply add the rendered class to the region attributes like: {{ title_suffix.contextual_links }} <{{ outer_wrapper }}{{ attributes.addClass('row', 'clearfix') }}> <{{ top_wrapper }}{{ region_attributes.top.addClass('col-12', 'region-top', top_attributes.class|render) }}> {{ top }} </{{ top_wrapper }}> </div>  
  • Using Drupal 8 Structure Sync Module

    Structure Sync module is a great tool that helps you import/export your site's contents like Taxonomy, Menu and Blocks. Installation Download the latest version from https://www.drupal.org/project/structure_sync or by using composer: composer require drupal/structure_sync Then go to Extend and install Structure Sync module or by drush: vendor/bin/drush en structure_sync --uri=default   Exporting Go to Structure > Structure sync. You will see Taxonomies, Custom blocks and Menu links tabs. Choose one that you want to export. Select the item/items you want to export and click the Export button. You should see a success message that tells that you have successfully exported the items. Go to Configuration > Configuration synchronization > Export to get the configuration sync file. This file will include the structure sync export files.   Importing Go to Configuration > Configuration synchronization > Import and upload the configuration sync file. (You can skip this step if your configuration sync file is committed on your repo and you have your sync folder fully configured) Go to Configuration > Configuration synchronization > Synchronize and click the Import all button to import everything from the config sync file. After the sync is finished, go to Structure > Structure sync. You will see Taxonomies, Custom blocks and Menu links tabs. Choose one that you want to import. Click Import button accordingly.  
  • playstation network

    Display Playstation Network (PSN) Public Trophies on your Drupal 8 site

    I've been recently searching for a Drupal 8 module that can integrate and display my Playstation profile but I can't find one. So, I created one. Feel free to use it on your own Drupal 8 sites. Here's how: Manual Download Download the Drupal 8 module https://www.drupal.org/project/psn_public_trophies and put inside your project's module folder. Run  composer require vhin0210/php-psnpublictrophies from your project's root folder. Download using Composer Run  composer require drupal/psn_public_trophies from your project's root folder. Install the module by either: Using the admin page Drush command  drush en psn_public_trophies   Connect to PSN NOTE: Make sure your PSN account 2-Step Verification is enabled. Go to Configuration > PSN Public Trophies Settings Enter your PSN ID and Password and hit "Save Configuration" Get Ticket UUID and Verification Code Click the Get Ticket UUID link - This will open the PSN login form in a new tab. Login on the form. When successful login, it will redirect you to enter the verification code sent by SMS. Do not enter the verification code in this PSN form. Copy the whole URL of the verify form/page and paste it in the "Ticket UUID URL" field. Enter the verification code that you get in the "Verification Code" field. Click the "Connect" button Add the Block Look for "PSN Public Trophies Profile Block".