Drupal Planet

Théodore 'nod_' Biadala: Replacing jQuery parents() with CSS :has()

1 month 3 weeks ago

CSS has been on a roll for a few years and we keep getting great things to use. In the process of removing jQuery from Drupal core, we’re running into the problem of replacing jQuery .parents() method by something else. In certain conditions it is very easy to use CSS selectors to replace this method. Given the following HTML:

<html> <body> <main> <article id="article-19"></article> </main> </body> </html>

To select all the parents of the article tag with jQuery you could do:

// This returns: main, body, html $('#article-19').parents(); // This returns: body $('#article-19').parents('body');

The typical way of doing this is with a while loop looking at the parentElement and building the array manually. Now with :has() it becomes much easier:

// This returns: html, body, main document.querySelectorAll(':has(#article-19)'); // To return the same order as jQuery: Array.from( document.querySelectorAll(':has(#article-19)') ).reverse(); // This returns: body document.querySelectorAll('body:has(#article-19)');

The only limitation is that a unique identifier needs to exist to build the CSS selector, that’s easy enough to generate if necessary.

Use the platform. When it’s good, it’s really good.

Four Kitchens: AstroJS and Drupal

1 month 3 weeks ago

Mike Goulding

Senior Drupal Engineer

Mike has been part of the Four Kitchens crew since 2018, where he works as a senior engineer and tech lead for a variety of Drupal and WordPress projects.

January 1, 1970

There are many different options available for the organization or team that decides it is time to decouple their Drupal site. There are frameworks that are designed for static site generation (SSG) and there are others that use server-side rendering (SSR), with many that claim to do both well.

React and NextJS have been popular options for a while now, and they are well-loved here at Four Kitchens as well. Another framework that is a little different from the above is Astro, and it may be worth considering.

What is Astro?

Astro is an interesting framework to work with, and it only becomes more so with time. Astro’s website makes claims of performance advantages over many other frameworks in the space. The full report can be found here.

More interesting than performance claims are some of the unique features this framework brings with it. Astro has many official integrations for other popular JS frameworks. This means, for example, that part of a page could use React, while another part could use Svelte. An even more ambitious page could use Vue, React, and AlpineJS for different components. While these examples are not a typical or recommended use case, they do illustrate that flexibility is one of the real strengths of Astro.

This flexibility doesn’t come with a steep learning curve, as Astro makes use of enough familiar pieces so that newcomers aren’t immediately overwhelmed. It is possible to write Astro components in a straightforward manner, similar to HTML, and still incorporate JavaScript XML (JSX) expressions to include data in the component’s output. There are a couple of tutorials for getting started with Astro, and they do a good job of giving the general structure of a project along with some scenarios that are unique to the framework.

(Also, Houston is an adorable mascot and I am here for it!)

Using Astro with Drupal

Despite all of the integrations that can be found in the Astro toolset, there is notably one key thing that is missing: There isn’t an existing integration for Drupal! The list of content management systems (CMSs) that Astro recommends are specifically headless CMSs, which make for a more natural starting point for this setup than converting a Drupal site.

Never fear, though! Drupal may not specifically be on that list, but that doesn’t mean it isn’t something that should be considered. Astro has that incredible flexibility, after all, and that means there are more options than it seems on the surface. All that is needed is an endpoint (or several) to fetch data from Drupal, and things are looking up once again.

Using the Drupal GraphQL and GraphQL Compose modules, it is possible to quickly get data ready to expose from Drupal and into the hands of a decoupled framework like Astro. With that, it becomes possible to fetch that data within Astro and build our frontend while taking advantage of many of the features that Astro offers. This can also be done with REST API or JSON:API, but for our purposes, the consistency and structure of GraphQL can’t be beat when crafting a decoupled integration with Drupal.

Using the fetch function that is available to Astro, (and JavaScript in general), we can get data from just about anywhere into our Astro components. This blends well with the head start from the compose module, as you can take an existing Drupal site and be ready to connect to a frontend framework very quickly. This means quicker prototyping and quicker assembling of components.

Astro also supports dynamic routing out of the box, which is an essential feature when connecting to a Drupal site where routes aren’t always structured like directories. Using this wildcard type of functionality, we can more easily take an existing site — regardless of the structure of the content — and get output into Astro. With the data from the routes in hand, we can get to the fun part: building the components and taking advantage of more of the Astro’s flexibility.

Flexibility is key

For me, Astro’s strength doesn’t solely come from the speed that it builds and renders content or the ease of building pages in a familiar JSX or Markdown pattern. Its real strength comes from the flexibility and variety of build options. While it does a great job handling some functionality on a given component or creating simple pages for a blog listing, it does even more with the ability to bring in other frameworks inside of components. Want to add a search page, but there isn’t an existing integration for Astro? If there is one for React, that works here, too! Do you have an internal team member really excited about building personalized content with Vue? Bring that in, and that component will work as well.

While the reality of the implementations may be a bit more involved than described on the tin, it is surprisingly easy and encouraged to bring in live updating components inside of Astro. This changes what would otherwise be a run-of-the-mill frontend tool into something much more interesting. Astro does shine in its own right, especially with statically generated pages and content. It just wouldn’t be doing anything especially new without bringing in other frameworks.

This is also where bringing a CMS like Drupal into a decoupled setup with Astro is intriguing. There is an opportunity for highly dynamic pages that wouldn’t work with a traditional static framework while still getting the speed and benefits of that approach. Drupal sites are typically very quick to update when content changes, which can be a sticking point for working with a decoupled architecture. How often should the frontend be rebuilt and how much can caching make up the difference? With having some parts of the site use components that can update more easily on the page, there benefits of both approaches can come through.

The post AstroJS and Drupal appeared first on Four Kitchens.

Drupal StackExchange

How can I disable Webform submit button after being clicked

1 month 3 weeks ago

I've been trying to resolve an issue with no luck. For some reason there are no submission indicators out of the box with D7 Webforms and from what i've found it doesn't look like they have any plans to implement this as they have already added this 'feature' in D8.

I wrote a handler in javascript that will just replace the input with another, but it doesn't appear that the script is firing because the actual submit is taking priority

var form = document.getElementsByClassName("webform-client-form")[0]; var isValidForm = form.checkValidity(); var submitBtn = document.getElementsByClassName('webform-submit')[0]; function preventExtraSubmits() { if (isValidForm) { var fakeBtn = document.createElement("input"); fakeBtn.value = "Submitting..."; fakeBtn.classList.add('webform-submit button-primary form-submit') insertAfter(submitBtn, fakeBtn); submitBtn.style.display = 'none'; } } function insertAfter(referenceNode, newNode) { referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } submitBtn.onsubmit = function(){preventExtraSubmits()}

From what i've seen is that this might need to be handled server side, but I can't seem figure out how to override webforms submit function.

Fairly new to Drupal and this has been a very frustrating battle to get this working

Drupal v 7.77 Webform v 7.x-4.23

Hunter Trammell

Theme UberCart catalog page to use custom html

1 month 3 weeks ago

Working with Ubercart 3.x on Drupal 7.

I want to theme the /catalog/1 page, where it shows my products. I want to use completely custom html that has divs nested with tables nested with divs.

I know that I can override with my own view, but I have no idea how to get the data that the existing view is using? I want to make my own tpl.php file that will loop the products for that catalog, but I don't know which variables to access, or what functions to call.

Thank you

bladefist

Computed field that displays the full username of the author

1 month 3 weeks ago

I am using a computed field and I want to display the field_first_name and field_last_name, which are properties of the user that created that node.

I have been trying things, but it seems like $entity does not have a uid?

I have no idea how to get load the user. These are the variables I have:

The variables available to your code include: &$entity_field, $entity_type, $entity, $field, $instance, $langcode, and $items. To set the value of the field, set $entity_field[0]['value']. For multi-value computed fields continue with $entity_field[1]['value']. Here's a simple example which sets the computed field's value to the value of the sum of the number fields (field_a and field_b) in a node entity: $entity_field[0]['value'] = array_pop(array_pop(field_get_items($entity_type, $entity, 'field_a'))) + array_pop(array_pop(field_get_items($entity_type, $entity, 'field_b'))); The first pop fetches the last (or only) item from the field while the second pop fetches its ['value'] contents (assuming it's the only key that's set).

dorien

How to comment on image in colorbox (modal form)?

1 month 3 weeks ago

I have created view to display images and also user to display it in popup using Colorbox trigger in view.

I want to allow users to comment on each individual image in modal form only. Just like Facebook. I have printed the comment form on popup but it is coming with preview button which redirects user to the photo's node page. And allow there to POST comment which I don't want.

What I want is user should be able to comment in popup with post button and the comment should be posted in modal form only (Should be visible in modal and node page as well). Is there any module to workout this?

D-pak

Custom Flag not appearing in "Configure Relationship: Flags"

1 month 3 weeks ago

I am building a community site to link former co-workers. I have used the Flags module to allow users to tag locations/teams. I am trying to use views to now list all the users who have flagged a location/team. When I try to add my flag to "Configure Relationship: Flags" it is not an option. Can anyone explain this?

EDIT I started with a list of users, those users have flagged the node with a custom flag marking it as a work location. My intention is to connect people who tagged the location in the same way. I wish to add a block to each page with a list of those people who worked together.

After the Mouse

How do I limit the allowed taxonomy terms basing on the content type?

1 month 3 weeks ago

I have two different content types, Computer and Chemistry, and taxonomy terms for all articles (content types) which store the methodology of the article. The taxonomy hierarchy is the following.

  • Articles
    • Computer
      • Arithmetic (Term ID: 1)
      • DMA (Term ID: 2) // abbreviation for "Direct Memory Access"
    • Chemistry
      • NGE (Term ID: 3) // abbreviation for "Noble Gas Elements"
      • DMA (Term ID: 4) // abbreviation for "Dynamic Mechanical Analysis"

When users are creating or editing a node of type Chemistry, just NGE and DMA (whose ID is 4) should be allowed to select.

I only need one taxonomy vocabulary, since there are too many content types, and if I want to add a vocabulary for each of them, then it leads too many vocabularies; more importantly it removes the ability of freely navigating in different types using taxonomy hierarchy.

How do I limit the allowed taxonomy terms basing on the content type?

Alireza Tabatabaeian