TEIA.RU
Зеленый хостинг ТЭИА

Uptolike

LTCBTC - Bitfinex

Криптоновости

feedspot

Syndicate content My RSS Feed
My RSS Feed
Updated: 14 weeks 6 days ago

Tesla Shows Off ‘Giga Lab’ Concept Store That Swiftly Builds Cars In 45 Seconds

Tue, 06/13/2023 - 06:02

Image via Tesla Asia

 


While car enthusiasts eagerly await Tesla’s Cybertruck to finally hit the streets, over in Chengdu, China, the automaker recently lifted the curtains on its latest concept store to offer a sneak peek at its manufacturing process, robot helpers, and more.



Dubbed the ‘Giga Lab’, the site was described as “the most beautiful store in Chengdu” by the brand itself. The highlight of the impressive space, no doubt, is the claim that visitors can enjoy the “immersive experience of the magic of building a car in 45 seconds.”


 



Image via Tesla Asia

 


Yup, it takes less than a minute to construct an entire vehicle. Unlike typical retail stores or showrooms, the interior of the site imitates the interior of the company’s Shanghai Gigafactory, providing a more relaxed atmosphere in which customers can appreciate the “beauty of Tesla.”



Within the all-white interior, fans can marvel at the all-white electric automobiles on display, along with manufacturing-related displays, including assembly robots and spare parts. An incomplete Model 3 car hangs off the ceiling on some cables to add to the “workshop” aesthetic.



Could brands begin investing more in non-traditional retail spaces that showcase their unique identity and offerings instead of just functioning as a place for customers to purchase items? It certainly seems to be moving in that direction.


 



Image via Tesla Asia

 



Image via Tesla Asia

 



Image via Tesla Asia

 



Image via Tesla Asia

 



Image via Tesla Asia

 



Image via Tesla Asia

 


 


 


[via autoevolution and Inside EVs, images via Tesla Asia]

Categories: World News

KitchenAid Creates Gadget Cakes So You Can Have Your Kitchen & Eat It Too

Tue, 06/13/2023 - 06:02
[Click here to view the video in this article]


Video screenshot via KitchenAid Canada

 


Ever felt like chomping down on a KitchenAid stand mixer or blenders? Well, to tap into the popular internet meme that spurred an actual Netflix series, the appliance brand recently created a series of sponge cakes in the image of its most famed products.



The project, a partnership with the creative agency Zulu Alpha Kilo, involved the expertise of cake artist April Julian—a recognizable face from the hit show Is It Cake?—to craft simulacrums of the brand’s iconic mixer, a stove, and a refrigerator.


 





 

 
 


 
 

View this post on Instagram

 


 
 
 


 
 


 
 
 



 
 

A post shared by KitchenAid Canada (@kitchenaid_ca)








According to AdForum, Janice Ryder, Country Manager at KitchenAid Small Appliances, described the idea as championing the kitchen’s importance as a place of “joy, discovery, and creativity,” spurring customers on to go as far as their imagination will take them.



Michael Siegers, Zulu Alpha Kilo’s Creative Director, explained that creating a “tasty facsimile” out of appliances by using the said gadget was the “perfect expression” of the KitchenAid brand. Perhaps, it goes to show that you can have your favorite kitchen tools and eat them, too.


 


Head here to watch the entire process of putting the cakes together. 


 





 

 
 


 
 

View this post on Instagram

 


 
 
 


 
 


 
 
 



 
 

A post shared by KitchenAid Canada (@kitchenaid_ca)







 





 

 
 


 
 

View this post on Instagram

 


 
 
 


 
 


 
 
 



 
 

A post shared by KitchenAid Canada (@kitchenaid_ca)







 


 


 


[via The Message and AdForum, cover image via KitchenAid Canada]

Categories: World News

Museum Gives Staff The Freedom To Come Up With Artworks For Latest Exhibition

Tue, 06/13/2023 - 04:06

Snowfall by Larry Giacoletti. Image via The Noguchi Museum (for press use)

 


Instead of displaying pieces by renowned artists, The Noguchi Museum in Queens, New York, is heading in a different direction. For its summer exhibition, the institution handed over the reins to its very own gallery attendants, curators, project managers, and more to contribute the artworks.



The unique project, which has culminated in a show titled A Living Mechanism, will see the museum showcase over two dozen art pieces to the public. These creations range from paintings to sculptures and installations across diverse aesthetics and subjects.



According to Artnet News, the showcase came to be after the museum’s Anti-Oppression Committee, spearheded by gallery attendant Trasonia Abbott, petitioned the higher-ups. Co-curator Orlando Lacro emphasized that this wasn’t a “performative gesture” but a real gallery project for gallery attendants.



In fact, Noguchi offered the artists a budget with “no strings attached,” allowing them free reign in terms of creativity and logistics to do as they deemed fit. Such a spirit, in its essence, portrays the way in which the museum’s namesake—Isamu Noguchi—worked.


 


“This was a museum-wide collaboration. We all played a part in it. I want it to be known that Trasonia fought for it, and we worked to make it a true collaboration in the spirit of Isamu Noguchi,” said Lacro. 


 



Queensboro Bridge by Barbara Leven. Image via The Noguchi Museum (for press use)

 


The famed Japanese-American creator was always in search of collaborators, be it in Greenwich Village in the heart of New York City or in Mure in Shikoku, Japan. As such, the show plays on the artist’s life-long ethos of relying on all components of space to “create a harmonious environment.”



“The exhibition celebrates The Noguchi Museum as a total work of art and the diverse artistic perspectives of its staff that continuously energize and sustain it,” the organization explained in a press statement.



“With a memory towards Isamu Noguchi’s own eagerness in collaborating with an astonishing range of other artists, architects, manufacturers, gardeners, photographers, craftspeople, and others in realizing his visions, A Living Mechanism nods to how this spirit of collective effort continues today,” it added.



Take a look at some of the staff works on display below and head here for more details on the exhibition.


 



Instructions (Five and Six) by Danielle Draik. Image via The Noguchi Museum (for press use)

 



I am Here@Greene St & Spring St, New York, NY, November 9, 2021, 3:33 pm by Harumi Ori. Image via The Noguchi Museum (for press use)

 



The Zero Hour, 2023 by Joe Tokumasu Field. Image via The Noguchi Museum (for press use)

 



Snowfall by Larry Giacoletti. Image via The Noguchi Museum (for press use)

 



Flowerbed by Lindy Chiu. Image via The Noguchi Museum (for press use)

 


 


 


[via Artnet News and Astoria Post, images via The Noguchi Museum (for press use)]

Categories: World News

Heinz Celebrates The Taste Of Each State With Special ‘Saucemerica’ Packets

Tue, 06/13/2023 - 02:51

Image via Heinz / Business Wire

 


This month, Heinz is launching The United States of Saucemerica Collection, a limited-edition capsule of 50 different condiment packet designs, one for each state in the country. All packets will feature a unique design of the corresponding state’s most popular dish.



For example, Idaho’s design features its famed French Fries, while Wisconsin showcases its Fried Cheese Curds. The packets will house seven of Heinz range of condiments, including Ketchup, Yellow Mustard, Real Mayonnaise, Ranch, BBQ Sauce, Tartar Sauce, and Simply Ketchup.



Fans can collect all 50 designs from now till August from restaurants, drive-thrus, theme parks, movie theaters, and stadiums across the country. Don’t miss out on Maryland’s Crab Cake design or Texas’ Brisket!


 



Image via Kraft Heinz Away From Home

 


Submit and track the state packets collected on the official website and stand a chance to win US$500,000 worth of prizes, including a grand prize of a whopping US$100,000.



“From art to coins, stamps, and more, collecting culture has become a popular practice with devoted fanbases. But perhaps the most unexpected collectible is the Heinz packet,” said Devaang Sibal, Brand Manager at Heinz Away From Home.



“An iconic on-the-go staple, Heinz fans everywhere collect packets in their homes, bags, and cars, to ensure they are always on hand in case of a condiment conundrum. With the Saucemerica collection, we are excited to pay homage to this fan behavior with the unique, hometown pride-evoking designs.”


 


 


 


[via Food Network and The Dieline, images via various sources]

Categories: World News

How to disable a CKEditor5 package loaded by core?

Tue, 06/13/2023 - 01:36

Is there a way to disable a CKEditor5 package loaded by core? I would like to disable paste-from-office, but I can see the question here applying to different packages.

In the file web/core/core.libraries.yml we see this code:

ckeditor5.pasteFromOffice: remote: https://github.com/ckeditor/ckeditor5 version: "35.4.0" license: name: GNU-GPL-2.0-or-later url: https://raw.githubusercontent.com/ckeditor/ckeditor5/v35.4.0/LICENSE.md gpl-compatible: true js: assets/vendor/ckeditor5/paste-from-office/paste-from-office.js: { minified: true } dependencies: - core/ckeditor5

I tried removing it but now when CKEditor loads on an edit page it complains about the missing library.

We also have in web/core/modules/ckeditor5/ckeditor5.ckeditor5.yml

ckeditor5_pasteFromOffice: ckeditor5: plugins: [pasteFromOffice.PasteFromOffice] drupal: label: Paste From Office library: core/ckeditor5.pasteFromOffice elements: false conditions: []
Categories: World News

How to write a custom action in Views VBO to print a batch of selected invoices

Tue, 06/13/2023 - 01:36

I need a custom action in Views VBO with Drupal Commerce to print a selected group of invoices to a browser print dialog. I have configured this as a src plugin and a custom twig template. Here is an example of the code in the action .php:

<?php namespace Drupal\my_action_module\Plugin\Action; use Drupal\Core\Action\ActionBase; use Drupal\Core\Session\AccountInterface; use Drupal\commerce_order\Entity\OrderInterface; /** * Prints an invoice for the selected order(s). * * @Action( * id = "print_invoice_action", * label = @Translation("Print Invoice"), * type = "commerce_order" * ) */ class PrintInvoiceAction extends ActionBase { /** * {@inheritdoc} */ public function execute($entities = []) { if (!empty($entities)) { foreach ($entities as $entity) { if ($entity instanceof OrderInterface) { $this->printInvoice($entity); } } } } /** * Print the invoice for an order. * * @param \Drupal\commerce_order\Entity\OrderInterface $order * The order entity. */ protected function printInvoice(OrderInterface $order) { // Get the array of orders from the context. $orders = $this->getContextValue('entity'); // Initialize the output variable. $output = ''; // Loop through each order and generate the invoice output. foreach ($orders as $order) { // Render the Twig template with the order entity. $build = [ '#theme' => 'mymodule_theme_template', '#order' => $order, ]; // Render the Twig template. $output .= \Drupal::service('renderer')->renderPlain($build); } // Set the content type to HTML. $headers = ['Content-Type' => 'text/html; charset=utf-8']; // Print the invoice output with JavaScript to trigger the print dialog. print '<html><head><title>Invoice</title></head>'; print '<body onload="print();">'; print '<div id="invoice-container">' . $output . '</div>'; print '</body></html>'; exit; } /** * {@inheritdoc} */ public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { return $object instanceof OrderInterface; } }

So far I cannot get the print dialog of the browser to open my selected group of invoices

Categories: World News

Email does not contain a link to the file attached to the contact form

Tue, 06/13/2023 - 01:36

I am using the following code that programmatically creates a file and attaches it to a file field when a contact form is submitted.

function mymodule_form_alter(&$form, &$form_state, $form_id) { $form['actions']['submit']['#submit'][] = 'custom_submit_handler'; } function custom_submit_handler(&$form, &$form_state) { $file_contents = '777'; $filename = 'my_file.txt'; $file = File::create([ 'uri' => 'public://' . $filename, 'filename' => $filename, ]); $file->save(); file_put_contents($file->getFileUri(), $file_contents); $entity = $form_state->getFormObject()->getEntity(); $entity->get('my_field_file')->appendItem($file); $entity->save(); }

The code works as expected, but there is no link to the new file in the sent email.

What should I do to change the email message?

Categories: World News

Talking Drupal: Talking Drupal #403 - Live @ Drupalcon

Tue, 06/13/2023 - 01:25

Today we are Live from DrupalCon Pittsburgh with Jim Birch and Cathy Theys.

For show notes visit: www.talkingDrupal.com/403

Topics
  • What is new
  • Driesnote
  • Pitchburg
  • What was great on the first day
  • EoL announcement
  • Looking forward to
  • Next Drupalcon
  • Pittsburgh
Resources Guests

Jim Birch - @jimbirch Cathy Theys- @YesCT

Hosts

Nic Laflin - www.nLighteneddevelopment.com @nicxvan John Picozzi - www.epam.com @johnpicozzi Martin Anderson-Clutz - @mandclu

MOTW Correspondent

Martin Anderson-Clutz - @mandclu Retrofit Provides compatibility layers for Drupal 7 code to allow run on Drupal 10.

Categories: World News

The Drop Times: The Final Topics of Discussion

Tue, 06/13/2023 - 01:25

My father and I left for a two-day trip to another state. It wasn’t a vacation, so we hadn’t planned anything. We still had a few hours to spend before we set to head back home.

My dad then realised he knew a friend from college who lived there, so he dropped in a message. It wasn’t till the last moment that we decided to meet.

Meeting a friend from college almost 30 years later, the first thing you can think of is to connect over ‘the major you studied together in college’ and how almost none of you work in that field anymore. That final topic of discussion was probably what they discussed last on graduation day too.

As rightly said by TV character Cornell Graduate and runaway manager Andy Bernard from the hit show ‘The Office’, ‘I wish there was a way to know you’re in “the good old days” before you’ve left them,’ we sometimes do wish, don’t we?

Now not to get all teary-eyed, but can we all take a moment to think about the friendships made over the years? It is a tale as old as time, the nature of passing moments and the yearning to make them stop for a few seconds.

DrupalCon has been a place to reconnect. Meeting up with your mentors, people that started their careers with you, an internet friend. DrupalCon has proven a space for much more than simply ‘work’. It shows community.

Over the past few days, TheDropTimes (TDT) has thoroughly covered DrupalCon. With our Team TDT physically present at the event, we received the action taking place at DrupalCon Pittsburgh 23 with photos, voice and video clips provided by Aiden Dean Dunn, Varun Baker and Anoop John; coordinating with sub-editors miles away, we published a few writeups so far; some exclusive content was on our official LinkedIn page. Also, find the stories on the website: Day 1 ‘DrupalCon Ignites With a Spectacular Start’ and A Glimpse into Day 3 at DrupalCon 23.

At DrupalCon Pittsburgh: Dries’s Inspiring Keynote Address was the First Day’s Major Takeaway, and Randy Fay was awarded the 2023 Aaron Winborn Award for Outstanding Contributions to the Drupal Community. 5 Winners were also awarded the Pitch-burgh funding Totaling $78,000 at DrupalCon.

Aidan Dean Dunn interviewed Dries Buytaert, founder and creator of Drupal: ‘Good Sleep, Superpowers, Open Source: An Interview with Dries Buytaert’. Aiden also spoke to Fei Lauren, scrum master at Renesas Electronics, on Neuroinclusivity and People-First Leadership.  He also covered a session by Kevin Quillen, 'Could OpenAI and Drupal 10 Play the Master and the Muse?' and wrote a detailed feature on Lullabot’s Road to Becoming 100% Employee-Owned.

Meanwhile, I had the privilege to write about The Cycling Drupalers: a 330-mile cycling trip, by Aaron Winborn award winner Randy Fay and his spouse to attend DrupalCon NA. Kazima Abbas, sub-editor at TDT, recently interviewed Suchi Garg, technical manager at Salsa Digital and organising committee member at DrupalCon Pittsburgh 2023.

TDT also interviewed Bert Boerland, co-initiator of the DrupalJam movement, a handbook writer and a Drupal evangelist, to ask all about his Drupal Journey and the recently conducted DrupalJam; A Drupal Multipotentialite Bert Boerland. In the past week, Dries also announced that Lauri Eskola is to Become Drupal Core Product Manager

We posted a video from a session in DrupalSouth, Drupal in New Zealand Gov Ecosystem and DUG Berlin had a Summer Festival on July 6. 

That’s some of it, Folks, You can always turn to The Drop Times to read more. 

Alethia Rose Braganza
Sub Editor, TheDropTimes

Categories: World News

20 Best New Websites, June 2023

Tue, 06/13/2023 - 00:27

Every month we take the opportunity to look at some of the most creative and innovative website designs to be launched in the previous four weeks.

Categories: World News

Gatsby Headaches And How To Cure Them: i18n (Part 1)

Mon, 06/12/2023 - 21:14

Internationalization, or i18n, is making your content understandable in other languages, regions, and cultures to reach a wider array of people. However, a more interesting question would be, “Why is i18n important?”. The answer is that we live in an era where hundreds of cultures interact with each other every day, i.e., we live in a globalized world. However, our current internet doesn’t satisfy its globalized needs.

Did you know that 60.4% of the internet is in English, but only 16.2% percent of the world speaks English?

Source: Visual Capitalist

Yes, it’s an enormous gap, and until perfect AI translators are created, the internet community must close it.

As developers, we must adapt our sites’ to support translations and formats for other countries, languages, and dialects, i.e., localize our pages. There are two main problems when implementing i18n on our sites.

  1. Storing and retrieving content.
    We will need files to store all our translations while not bloating our page’s bundle size and a way to retrieve and display the correct translation on each page.
  2. Routing content.
    Users must be redirected to a localized route with their desired language, like my-site.com/es or en.my-site.com. How are we going to create pages for each locale?

Fortunately, in the case of Gatsby and other static site generators, translations don’t bloat up the page bundle size since they are delivered as part of the static page. The rest of the problems are widely known, and there are a lot of plugins and libraries available to address them, but it can be difficult to choose one if you don’t know their purpose, what they can do, and if they are compatible with your existing codebase. That’s why in the following hands-on guide, we will see how to use several i18n plugins for Gatsby and review some others.

The Starter

Before showing what each plugin can do and how to use them, we first have to start with a base example. (You can skip this and download the starter here). For this tutorial, we will work with a site with multiple pages created from an array of data, like a blog or wiki. In my case, I choose a cooking blog that will initially have support only for English.

Start A New Project

To get started, let’s start a plain JavaScript Gatsby project without any plugins at first.

npm init gatsby cd my-new-site

For this project, we will create pages dynamically from markdown files. To be able to read and parse them to Gatsby’s data layer, we will need to use the gatsby-source-filesystem and gatsby-transformer-remark plugins. Here you can see a more in-depth tutorial.

npm i gatsby-source-filesystem gatsby-transformer-remark

Inside our gatsby-config.js file, we will add and configure our plugins to read all the files in a specified directory.

// ./gatsby-config.js module.exports = { //... plugins: [ { resolve: `gatsby-source-filesystem`, options: { name: `content`, path: `${__dirname}/src/content`, }, }, `gatsby-transformer-remark`, ], }; Add Your Content

As you can see, we will use a new ./src/content/ directory where we will save our posts. We will create a couple of folders with each recipe’s content in markdown files, like the following:

├── src │ ├── content | | ├── mac-and-cheese | | | ├── cover.jpg | | | ├── index.en.md | | ├── burritos | | | ├── cover.jpg | | | ├── index.en.md | | ├── pizza | | | ├── cover.jpg | | | ├── index.en.md │ ├── pages │ ├── images

Each markdown file will have the following structure:

--- slug: "mac-and-cheese" date: "2023-01-20" title: "How to make mac and cheese" cover_image: image: "./cover.jpg" alt: "Macaroni and cheese" locale: "en" --- Step 1 Lorem ipsum...

You can see that the first part of the markdown file has a distinct structure and is surrounded by --- on both ends. This is called the frontmatter and is used to save the file’s metadata. In this case, the post’s title, date, locale, etc.

As you can see, we will be using a cover.jpg file for each post, so to parse and use the images, we will need to install the gatsby-plugin-image gatsby-plugin-sharp and gatsby-transformer-sharp plugins (I know there are a lot ?).

npm i gatsby-plugin-image gatsby-plugin-sharp gatsby-transformer-sharp

We will also need to add them to the gatsby-config.js file.

// ./gatsby-config.js module.exports = { //... plugins: [ { resolve: `gatsby-source-filesystem`, options: { name: `content`, path: `${__dirname}/src/content`, }, }, `gatsby-plugin-sharp`, `gatsby-transformer-sharp`, `gatsby-transformer-remark`, `gatsby-plugin-image`, ], }; Querying Your Content

We can finally start our development server:

npm run develop

And go to http://localhost:8000/___graphql, where we can make the following query:

query Query { allMarkdownRemark { nodes { frontmatter { slug title date cover_image { image { childImageSharp { gatsbyImageData } } alt } } } } }

And get the following result:

{ "data": { "allMarkdownRemark": { "nodes": [ { "frontmatter": { "slug": "/mac-and-cheese", "title": "How to make mac and cheese", "date": "2023-01-20", "cover_image": { /* ... */ } } }, { "frontmatter": { "slug": "/burritos", "title": "How to make burritos", "date": "2023-01-20", "cover_image": { /* ... */ } } }, { "frontmatter": { "slug": "/pizza", "title": "How to make Pizza", "date": "2023-01-20", "cover_image": { /* ... */ } } } ] } } }

Now the data is accessible through Gatsby’s data layer, but to access it, we will need to run a query from the ./src/pages/index.js page.

Go ahead and delete all the boilerplate on the index page. Let’s add a short header for our blog and create the page query:

// src/pages/index.js import * as React from "react"; import {graphql} from "gatsby"; const IndexPage = () => { return ( <main> <h1>Welcome to my English cooking blog!</h1> <h2>Written by Juan Diego Rodríguez</h2> </main> ); }; export const indexQuery = graphql` query IndexQuery { allMarkdownRemark { nodes { frontmatter { slug title date cover_image { image { childImageSharp { gatsbyImageData } } alt } } } } } `; export default IndexPage; Displaying Your Content

The result from the query is injected into the IndexPage component as a props property called data. From there, we can render all the recipes’ information.

// src/pages/index.js // ... import {RecipePreview} from "../components/RecipePreview"; const IndexPage = ({data}) => { const recipes = data.allMarkdownRemark.nodes; return ( <main> <h1>Welcome to my English cooking blog!</h1> <h2>Written by Juan Diego Rodríguez</h2> {recipes.map(({frontmatter}) => { return <RecipePreview key={frontmatter.slug} data={frontmatter} />; })} </main> ); }; // ...

The RecipePreview component will be the following in a new directory: ./src/components/:

// ./src/components/RecipePreview.js import * as React from "react"; import {Link} from "gatsby"; import {GatsbyImage, getImage} from "gatsby-plugin-image"; export const RecipePreview = ({data}) => { const {cover_image, title, slug} = data; const cover_image_data = getImage(cover_image.image.childImageSharp.gatsbyImageData); return ( <Link to={/recipes/${slug}}> <h1>{title}</h1> <GatsbyImage image={cover_image_data} alt={cover_image.alt} /> </Link> ); }; Creating Pages From Your Content

If we go to http://localhost:8000/, we will see all our recipes listed, but now we have to create a custom page for each recipe. We can do it using Gatsby’s File System Route API. It works by writing a GraphQL query inside the page’s filename, generating a page for each query result. In this case, we will make a new directory ./src/pages/recipes/ and create a file called {markdownRemark.frontmatter__slug}.js. This filename translates to the following query:

query MyQuery { allMarkdownRemark { nodes { frontmatter { slug } } } }

And it will create a page for each recipe using its slug as the route.

Now we just have to create the post’s component to render all its data. First, we will use the following query:

query RecipeQuery { markdownRemark { frontmatter { slug title date cover_image { image { childImageSharp { gatsbyImageData } } alt } } html } }

This will query the first markdown file available in our data layer, but to specify the markdown file needed for each page, we will need to use variables in our query. The File System Route API injects the slug in the page’s context in a property called frontmatter__slug. When a property is in the page’s context, it can be used as a query variable under a $ followed by the property name, so the slug will be available as $frontmatter__slug.

query RecipeQuery { query RecipeQuery($frontmatter__slug: String) { markdownRemark(frontmatter: {slug: {eq: $frontmatter__slug}}) { frontmatter { slug title date cover_image { image { childImageSharp { gatsbyImageData } } alt } } html } } }

The page’s component is pretty simple. We just get the query data from the component’s props. Displaying the title and date is straightforward, and the html can be injected into a p tag. For the image, we just have to use the GatsbyImage component exposed by the gatsby-plugin-image.

// src/pages/recipes/{markdownRemark.frontmatter__slug}.js const RecipePage = ({data}) => { const {html, frontmatter} = data.markdownRemark; const {title, cover_image, date} = frontmatter; const cover_image_data = getImage(cover_image.image.childImageSharp.gatsbyImageData); return ( <main> <h1>{title}</h1> <p>{date}</p> <GatsbyImage image={cover_image_data} alt={cover_image.alt} /> <p dangerouslySetInnerHTML={{__html: html}}></p> </main> ); }; //...

The last thing is to use the Gatsby Head API to change the page’s title to the recipe’s title. This can be easily done since the query’s data is also available in the Head component.

// src/pages/recipes/{markdownRemark.frontmatter__slug}.js //... export const Head = ({data}) => <title>{data.markdownRemark.frontmatter.title}</title>;

Summing all up results in the following code:

// src/pages/recipes/{markdownRemark.frontmatter__slug}.js import * as React from "react"; import {GatsbyImage, getImage} from "gatsby-plugin-image"; import {graphql} from "gatsby"; const RecipePage = ({data}) => { const {html, frontmatter} = data.markdownRemark; const {title, cover_image, date} = frontmatter; const cover_image_data = getImage(cover_image.image.childImageSharp.gatsbyImageData); return ( <main> <h1>{title}</h1> <p>{date}</p> <GatsbyImage image={cover_image_data} alt={cover_image.alt} /> <p dangerouslySetInnerHTML={{__html: html}}></p> </main> ); }; export const recipeQuery = graphqlquery RecipeQuery($frontmatter&#95;&#95;slug: String) { markdownRemark(frontmatter: {slug: {eq: $frontmatter&#95;&#95;slug}}) { frontmatter { slug title date cover&#95;image { image { childImageSharp { gatsbyImageData } } alt } } html } }; export default RecipePage; export const Head = ({data}) => <title>{data.markdownRemark.frontmatter.title}</title>; Creating Localized Content

With all this finished, we have a functioning recipe blog in English. Now we will use each plugin to add i18n features and localize the site (for this tutorial) for Spanish speakers. But first, we will make a Spanish version for each markdown file in ./src/content/. Leaving a structure like the following:

├── src │ ├── content | | ├── mac-and-cheese | | | ├── cover.jpg | | | ├── index.en.md | | | ├── index.es.md | | ├── burritos | | | ├── cover.jpg | | | ├── index.en.md | | | ├── index.es.md | | ├── pizza | | | ├── cover.jpg | | | ├── index.en.md | | | ├── index.es.md │ ├── pages │ ├── images

Inside our new Spanish markdown files, we will have the same structure in our frontmatter but translated to our new language and change the locale property in the frontmatter to es. However, it’s important to note that the slug field must be the same in each locale.

gatsby-plugin-i18n

This plugin is displayed in Gatsby’s Internationalization Guide as its first option when implementing i18n routes. The purpose of this plugin is to create localized routes by adding a language code in each page filename, so, for example, a ./src/pages/index.en.js file would result in a my-site.com/en/ route.

I strongly recommend not using this plugin. It is outdated and hasn’t been updated since 2019, so it is kind of a disappointment to see it promoted as one of the main solutions for i18n in Gatsby’s official documentation. It also breaks the File System API, so you must use another method for creating pages, like the createPages function in the Gatsby Node API. Its only real use would be to create localized routes for certain pages, but considering that you must create a file for each page and each locale, it would be impossible to manage them on even medium sites. A 20 pages site with support for five languages would need 100 files!

gatsby-theme-i18n

Another plugin for implementing localized routes is gatsby-theme-i18n, which will be pretty easy to use in our prior example.

We will first need to install the gatsby-theme-i18n plugin and the gatsby-plugin-react-helmet and react-helmet plugins to help add useful language metadata in our <head> tag.

npm install gatsby-theme-i18n gatsby-plugin-react-helmet react-helmet

Next, we can add it to the gatsby-config.js:

// ./gatsby-config.js module.exports = { //... plugins: [ //other plugins ... { resolve: `gatsby-theme-i18n`, options: { defaultLang: `en`, prefixDefault: true, configPath: require.resolve(`./i18n/config.json`), }, }, ], };

As you can see, the plugin configPath points to a JSON file. This file will have all the information necessary to add each locale. We will create it in a new ./i18n/ directory at the root of our project:

[ { "code": "en", "hrefLang": "en-US", "name": "English", "localName": "English", "langDir": "ltr", "dateFormat": "MM/DD/YYYY" }, { "code": "es", "hrefLang": "es-ES", "name": "Spanish", "localName": "Español", "langDir": "ltr", "dateFormat": "DD.MM.YYYY" } ]

Note: To see changes in the gatsby-config.js file, we will need to restart the development server.

And just as simple as that, we added i18n routes to all our pages. Let’s head to http://localhost:8000/es/ or http://localhost:8000/en/ to see the result.

Querying Localized Content

At first glance, you will see a big problem: the Spanish and English pages have all the posts from both locales because we aren’t filtering the recipes for a specific locale, so we get all the available recipes. We can solve this by once again adding variables to our GraphQL queries. The gatsby-theme-i18n injects the current locale into the page’s context, making it available to use as a query variable under the $locale name.

index page query:

query IndexQuery($locale: String) { allMarkdownRemark(filter: {frontmatter: {locale: {eq: $locale}}}) { nodes { frontmatter { slug title date cover_image { image { childImageSharp { gatsbyImageData } } alt } } } } }

{markdownRemark.frontmatter__slug}.js page query:

query RecipeQuery($frontmatter__slug: String, $locale: String) { markdownRemark(frontmatter: {slug: {eq: $frontmatter__slug}, locale: {eq: $locale}}) { frontmatter { slug title date cover_image { image { childImageSharp { gatsbyImageData } } alt } } html } } Localizing Links

You will also notice that all Gatsby links are broken since they point to the non-localized routes instead of the new routes, so they will direct the user to a 404 page. To solve this, gatsby-theme-i18n exposes a LocalizedLink component that works exactly like Gatsby’s Link but points to the current locale. We just have to switch each Link component for a LocalizedLink.

// ./src/components/RecipePreview.js + import {LocalizedLink as Link} from "gatsby-theme-i18n"; - import {Link} from "gatsby"; //... Changing Locales

Another vital feature to add will be a component to change from one locale to another. However, making a language selector isn’t completely straightforward. First, we will need to know the current page’s path, like /en/recipes/pizza, to extract the recipes/pizza part and add the desired locale, getting /es/recipes/pizza.

To access the page’s location information (URL, HREF, path, and so on) in all our components, we will need to use the wrapPageElement function available in the gatsby-browser.js and gatsby-ssr.js files. In short, this function lets you access the props used on each page, including a location object. We can set up a context provider with the location information and pass it down to all components.

First, we will create the location context in a new directory: ./src/context/.

// ./src/context/LocationContext.js import * as React from "react"; import {createContext} from "react"; export const LocationContext = createContext(); export const LocationProvider = ({location, children}) => { return <LocationContext.Provider value={location}>{children}</LocationContext.Provider>; };

As you can imagine, we will pass the page’s location object to the provider’s location attribute on each Gatsby file:

// ./gatsby-ssr.js & ./gatsby-browser.js import * as React from "react"; import {LocationProvider} from "./src/context/LocationContext"; export const wrapPageElement = ({element, props}) => { const {location} = props; return <LocationProvider location={location}>{element}</LocationProvider>; };

Note: Since we just created the gatsby-ssr.js and gatsby-browser.js files, we will need to restart the development server.

Now the page’s location is available in all components through context, and we can use it in our language selector. We have also to pass down the current locale to all components, and the gatsby-theme-i18n exposes a useful useLocalization hook that let you access the current locale and the i18n config. However, a caveat is that it can’t get the current locale on Gatsby files like gatsby-browser.js and gatsby-ssr.js, only the i18n config.

Ideally, we would want to render our language selector using wrapPageElement so it is available on all pages, but we can’t use the useLocazication hook. Fortunately, the wrapPageElement props argument also exposes the page’s context and, inside, its current locale.

Let’s create another context to pass down the locale:

// ./src/context/LocaleContext.js import * as React from "react"; import {createContext} from "react"; export const LocaleContext = createContext(); export const LocaleProvider = ({locale, children}) => { return <LocaleContext.Provider value={locale}>{children}</LocaleContext.Provider>; };

And use it in our wrapPageElement function:

// ./gatsby-ssr.js & ./gatsby-browser.js import * as React from "react"; import {LocationProvider} from "./src/context/LocationContext"; import {LocaleProvider} from "./src/context/LocaleContext"; export const wrapPageElement = ({element, props}) => { const {location} = props; const {locale} = element.props.pageContext; return ( <LocationProvider location={location}> <LocaleProvider locale={locale}>{element}</LocaleProvider> </LocationProvider> ); };

The last thing is how to remove the locale (es or en) from the path (/es/recipes/pizza). Using the following simple but ugly regex, we can remove all the /en/ and /es/ at the beginning of the path:

/(\/e(s|n)|)(\/*|)/

It’s important to note that the regex pattern only works for the en and es combination of locales.

Now we have to create our LanguageSelector.js:

// ./src/components/LanguageSelector import * as React from "react"; import {useContext} from "react"; import {useLocalization} from "gatsby-theme-i18n"; import {Link} from "gatsby"; import {LocationContext} from "../context/LocationContext"; import {LocaleContext} from "../context/LocaleContext"; export const LanguageSelector = () => { const {config} = useLocalization(); const locale = useContext(LocaleContext); const {pathname} = useContext(LocationContext); const removeLocalePath = /(\/e(s|n)|)(\/*|)/; const pathnameWithoutLocale = pathname.replace(removeLocalePath, ""); return ( <div> {config.map(({code, localName}) => { return ( code !== locale && ( <Link key={code} to={`/${code}/${pathnameWithoutLocale}`}> {localName} </Link> ) ); })} </div> ); };

Let’s break down what is happening:

  1. Get our i18n config through the useLocalization hook.
  2. Get the current locale through context.
  3. Get the page’s current pathname through context, which is the part that comes after the domain..
Categories: World News

Chromatic: Drupal 7 End-of-Life Ep 09: New End-of-Life Date Announcement!

Mon, 06/12/2023 - 20:29
Live from DrupalCon, Mark and Dave discuss Drupal 7's new end-of-life date and its implications. While the official end-of-life date has been extended, changes in overall support come into effect as early as August 2023.
Categories: World News

LN Webworks: Why Choose LN Webworks as Your Web Development Partner?

Mon, 06/12/2023 - 20:29

Hiring a web development company is perhaps the best decision when it comes to building or resigning a business website. An eminent agency can bestow your site with a professional design and captivating ambiance. It can also equip your website with cutting-edge features such as an intuitive user interface, voice search, and so on. Not only this, but an adept web development partner can help you rank high on search engines with invincible Search Engine Optimization (SEO) practices.

If such enormous benefits of hiring a splendid web development company have driven you to seek one, LN Webworks may be your search’s point of culmination. Here, we’ll take you on an enchanting journey to unravel why you should consider choosing LN Webworks for website development.

Categories: World News

The Drop Times: Lullabot’s Road to Becoming 100% Employee-Owned

Mon, 06/12/2023 - 20:29
At this year’s DrupalCon, Lullabot gave a presentation on their shift to a fascinating business model that allows every employee to become a partial company owner. It’s called an ESOP, or an Employee Stock Ownership Plan, and Lullabot transitioned to this organizational structure in 2021. 
Categories: World News

The Drop Times: The Cycling Drupalers

Mon, 06/12/2023 - 20:29
Two Determined and veteran cyclist travel 330 Miles to Pittsburgh! Randy and Nancy live in Palisade, Colorado, USA on the western edge of Colorado, between the mountains and the desert. Read more about their journey and cycling trails.
Categories: World News

History revisited: US DOJ unseals Mt. Gox cybercrime charges

Mon, 06/12/2023 - 20:25
Though the mills of the Law grind slowly/Yet they grind exceeding small/Though with patience they stand waiting/With exactness grind they all...
Categories: World News

Ubuntu Blog: Canonical at HPE Discover 2023

Mon, 06/12/2023 - 19:53

Canonical, the company behind Ubuntu, is proud to sponsor HPE Discover this year again and have a presence at the Expo. Join us in Las Vegas on June, 20–22 to learn how Canonical and Hewlett Packard Enterprise (HPE) can help you securely advance your business with comprehensive open source solutions that span from infrastructure to MLOps platforms.

Register to HPE Discover 2023

What to expect from Canonical at HPE Discover 2023

Canonical and HPE partner to deliver to enterprise and service providers the best open source solutions and support. Beyond Ubuntu support, we have created reference designs and centers of expertise for the deployment of OpenStack, Kubernetes, Ceph, AI/ML and open source applications.

MicroCloud – a composable and flexible solution to future-proof any edge computing deployment

Canonical MicroCloud provides an edge over IoT by performing computing tasks, thereby facilitating unattended, autonomous, and clustering features that resolve typical edge computing challenges. It trades the exponential scalability of public clouds for the security, privacy, governance, and low latency of decentralized environments.

Discover how MicroCloud and HPE ProLiant Servers deliver next-generation compute solutions to power hybrid environments wherever it lives — from the edge to the cloud.

Generate and monetise new offerings for stream mobile apps with HPE and Canonical Anbox.

Anbox Cloud is a Canonical offering which lets you stream mobile apps securely, at any scale, to any device letting you focus on your apps. It is tailor made for delivering mobile app content independent of the end user’s device capabilities by offloading the compute, storage, and energy intensive applications from end device to HPE Infrastructure.

HPE Telco validated Designs with Canonical Openstack and Kubernetes

There is a need for communications service providers (CSPs) to look beyond mere connectivity to become digital service providers by optimizing their current legacy hardware to improve service and costs and create value from newer, innovative operating models and service offers. To achieve this, the CSPs require programmable infrastructure, operations automation, and the capacity to deliver on-demand services.

These validated designs with Canonical Kubernetes and OpenStack are developed in close technical collaboration with Canonical and include container technology to allow multiple and isolated applications to run on a single OS and shared kernel. It also provides an integrated cloud-native platform that deploys an OpenStack cluster on dedicated physical servers.

This approach allows the service provider to help optimize its resources (memory and CPU), build and scale virtualized applications for telco companies.

Have some fun and win great prizes!

We are running a Trivia Game about Canonical, Ubuntu, and HPE during the Expo showtime. The highest scores will receive amazing rewards, such as Ubuntu powered Robots, branded backpacks, power banks, and other surprises!

Visit the Canonical Ubuntu booth to participate, have some fun, and take a chance to win big!

<noscript> <img alt="" src="https://res.cloudinary.com/canonical/image/fetch/f_auto,q_auto,fl_sanitize,c_fill,w_720/https://ubuntu.com/wp-content/uploads/942a/dtw23-prizes.jpg" width="720" /> </noscript> Canonical | Ubuntu and HPE

Hewlett Packard Enterprise (HPE) and Canonical have joined forces to offer comprehensive open source solutions that span from infrastructure to cutting-edge, secure, cloud-native MLOps platforms. 

Canonical provides HPE the capacity to support everything open source.

Together, we help customers cut costs, streamline operations, and boost performance, all while ensuring top-notch security for both physical and virtual environments.

HPE and Canonical have created reference designs and established centers of excellence to build and deploy OpenStack, Kubernetes, Ceph, and AI/ML solutions.

Learn more >

Getting to the Event

Join the Canonical team at HPE Discover 2023 to discuss how to provide customers with solutions that capitalize on the benefits of Open Source with security and compliance.

Location
The Venetian Convention and Expo Center
201 Sands Ave, Las Vegas, NV 89169

Canonical Booth # 226

Dates
June 20 – 22

Hours
Tuesday, 8 AM – 7:30 PM PT
Wednesday, 8 AM – 6 PM PT
Thursday, 8 AM – 3 PM PT

You can meet with the Canonical team on-site in Las Vegas and pick our technical experts’ brains about your particular open source scenario.

Register to HPE Discover 2023

Want to learn more?
Please stop by booth 226 to speak to our experts and check out our Demos.

Are you interested in setting up a meeting with our team?
Reach out to our Alliances team at partners@canonical.com

Categories: World News

Digital Gardens

Mon, 06/12/2023 - 18:46

“…as I wander the internet, I wonder where the digital gardens are that will connect me to fellow gardeners more deeply. More often than not, the digital gardens of today are botanic—privately owned online spaces made for visitors to fawn over while a “do not touch” sign looms in view. These private gardens are generative for our personal learning, but they are far from the communal gardens I grew up in that valued collective work and knowledge. Where are the digital gardens that lead us towards collective learning, play, and dreaming?”

On Digital Gardens: Tending to Our Collective Multiplicity by Annika Hansteen-Izora

(Thank you Annie)

Categories: World News

Просто хороший хостинг