Feeds

Stack Abuse: Building Custom Email Templates with HTML and CSS in Python

Planet Python - Tue, 2024-08-20 15:04

An HTML email utilizes HTML code for presentation. Its design is heavy and looks like a modern web page, rich with visual elements like images, videos, etc., to emphasize different parts of an email's content.

Building email templates tailored to your brand is useful for various email marketing purposes such as welcoming new customers, order confirmation, and so on. Email template customization allows you to save time by not having to create emails from scratch each time. You can also include an email link in HTML to automatically compose emails in your email client.

In this step-by-step guide, you'll learn how to build an HTML email template, add a CSS email design to it, and send it to your target audience.

Setting Up Your Template Directory and Jinja2

Follow the steps below to set up your HTML email template directory and Jinja2 for Python email automation:

  • Create a Template Directory: To hold your HTML email templates, you will need to set up a template directory inside your project module. Let's name this directory - html_emailtemp.

  • Install Jinja2: Jinja is a popular templating engine for Python that developers use to create configuration files, HTML documents, etc. Jinja2 is its latest version. It lets you create dynamic content via loops, blocks, variables, etc. It's used in various Python projects, like building websites and microservices, automating emails with Python, and more.

    Use this command to install Jinja2 on your computer:

    pip install jinja2
Creating an HTML Email Template

To create an HTML email template, let's understand how to code your email step by step. If you want to modify your templates, you can do it easily by following the steps below:

Step 1: Structure HTML

A basic email will have a proper structure - a header, a body, and a footer.

  • Header: Used for branding purposes (in emails, at least)
  • Body: It will house the main text or content of the email
  • Footer: It's at the end of the email if you want to add more links, information, or call-to-actions (CTA)

Begin by creating your HTML structure, keeping it simple since email clients are less compatible than web browsers. For example, using tables is preferable for custom email layouts.

Here's how you can create a basic HTML mail with a defined structure:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>HTML Email Template</title> <style type="text/css"> /* Add your CSS here */ </style> </head> <body> <table width="100%" cellpadding="0" cellspacing="0"> <tr> <td align="center"> <table width="600" cellpadding="0" cellspacing="0"> <!-- Header --> <tr> <td style="background-color: #1c3f60; color: #ffffff; text-align: center; padding: 20px;"> <h1>Your order is confirmed</h1> </td> </tr> <!-- Body --> <tr> <td style="padding: 20px; font-size: 16px; line-height: 1.6; color:#ffffff;"> <p>The estimated delivery date is 22nd August 2024.</p> </td> </tr> <!-- Footer --> <tr> <td style="background-color: #ff6100; color: #000000; text-align: center; padding: 20px;"> <p>For additional help, contact us at support@domain.com</p> </td> </tr> </table> </td> </tr> </table> </body> </html>

Explanation:

  • <!DOCTYPE html>: This declares HTML as your document type.
  • <html>: This is an HTML page's root element.
  • <head>: This stores the document's metadata, like CSS styles.
  • <style>: CSS styles are defined here.
  • <body>: This stores your email's main content.
  • <table>: This tag defines the email layout, giving it a tabular structure with cells and rows, which makes rendering easier for email clients.
  • <tr>: This tag defines the table's row, allowing vertical content stacking.
  • <td>: This tag is used to define a cell inside a row. It contains content like images, text, buttons, etc.
Step 2: Structure Your Email

Now, let's create the structure of your HTML email. To ensure it's compatible with different email clients, use tables to generate a custom email layout, instead of CSS.

<table width="100%" cellpadding="0" cellspacing="0"> <tr> <td align="center"> <table width="600" cellpadding="0" cellspacing="0" style="border: 1px solid #1c3f60; padding: 20px;"> <tr> <td align="center"> <h1 style="color: #7ed957;">Hi, Jon!</h1> <p style="font-size: 16px; color: #ffde59;">Thank you for being our valuable customer!</p> </td> </tr> </table> </td> </tr> </table> Styling the Email with CSS

Once you've defined your email structure, let's start designing emails with HTML and CSS:

Inline CSS

Use inline CSS to ensure different email clients render CSS accurately and preserve the intended aesthetics of your email style.

<p style="font-size: 16px; color: blue;">Styled paragraph.</p> Adjusting Style

Users might use different devices and screen sizes to view your email. Therefore, it's necessary to adapt the style to suit various screen sizes. In this case, we'll use media queries to achieve this goal and facilitate responsive email design.

<style type="text/css"> @media screen and (max-width: 600px) { .container { width: 100% !important; padding: 10px !important; } } </style> <table class="container" width="600"> <!-- Content --> </table>

Explanation:

  • @media screen and (max-width: 600px) {....}: This is a media query that targets device screens of up to 600 pixels, ensuring the style applies only to these devices, such as tablets and smartphones.
  • width: 100% !important;: This style changes the width of the table - .container. The code instructs that the table width be set to full screen, not 600px.
  • !important: This rule overrides other styles that may conflict with it.
  • padding: 10px !important;: Inside the .container table, a padding of 10px is added to the table.
Adding CTA Button and Links

Here, we are adding a call to action (CTA) link at the button - "Get a 30-day free trial" that points to this page - https://www.mydomain.com.

<table cellpadding="0" cellspacing="0" style="margin: auto;"> <tr> <td align="center" style="background-color: #8c52ff; padding: 10px 20px; border-radius: 5px;"> <a href="https://www.mydomain.com" target="_blank" style="color: #ffffff; text-decoration: none; font-weight: bold;">Get a 30-day free trial</a> </td> </tr> </table>

Let's Now Look at the Complete HTML Email Template:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>HTML Email Template</title> <style type="text/css"> /* Adding the CSS */ body { margin: 0; padding: 0; background-color: #f4f4f4; font-family: Arial, sans-serif; } table { border-collapse: collapse; } .mailcontainer { width: 100%; max-width: 600px; margin: auto; background-color: #ffffff; } .header { background-color: #1c3f60; color: #ffffff; text-align: center; padding: 20px; } .body { padding: 20px; font-size: 16px; line-height: 1.6; background-color: #1c3f60; color: #7ed957; } .footer { background-color: #ff6100; color: #000000; text-align: center; padding: 20px; } .cta { background-color: #8c52ff; padding: 10px 20px; border-radius: 5px; color: #ffffff; text-decoration: none; font-weight: bold; } @media screen and (max-width: 600px) { .container { width: 100% !important; padding: 10px !important; } } </style> </head> <body> <table width="100%" cellpadding="0" cellspacing="0"> <tr> <td align="center"> <table class="container" width="600" cellpadding="0" cellspacing="0"> <!-- Header --> <tr> <td class="header"> <h1>Your order is confirmed</h1> </td> </tr> <!-- Body --> <tr> <td class="body"> <p>The estimated delivery date is 22nd August 2024.</p> <p style="font-size: 16px; color: blue;">Styled paragraph.</p> <table width="100%" cellpadding="0" cellspacing="0" style="border: 1px solid #1c3f60; padding: 20px;"> <tr> <td align="center"> <h1 style="color: #7ed957;">Hi, Jon!</h1> <p style="font-size: 16px; color: #ffde59;">Thank you for being our valuable customer!</p> </td> </tr> </table> <table cellpadding="0" cellspacing="0" style="margin: auto;"> <tr> <td align="center" style="background-color: #8c52ff; padding: 10px 20px; border-radius: 5px;"> <a href="https://www.mydomain.com" target="_blank" rel="noopener noreferrer" style="color: #ffffff; text-decoration: none; font-weight: bold;">Get a 30-day free trial</a> </td> </tr> </table> </td> </tr> <!-- Footer --> <tr> <td style="background-color: #ff6100; color: #000000; text-align: center; padding: 20px;"> <p>For additional help, contact us at support@domain.com</p> </td> </tr> </table> </td> </tr> </table> </body> </html>

Explanation:

  • .mailcontainer: This is a class that you can use to style your email content's main section. It's given a set width, margin, border, and color.
  • .header, .footer, .body: These are classes used to style your email's header, footer, and body, respectively.
  • .cta: This class allows you to style your buttons, such as CTA buttons, with a specified color, border design, padding, etc.
Bringing Everything Together With Jinja2

Having created our HTML template, it's now time to bring everything together using the Jinja2 templating engine.

Import Project Modules

You've already set up your template directory - html_emailtemp. Now you can find and render templates using code. But before you do that, import the relevant project modules using the code below:

from jinja2 import Environment, PackageLoader, select_autoescape env = Environment(loader=PackageLoader('email_project', 'html_emailtemp'), autoescape=select_autoescape(['html', 'xml']))

Explanation:

  • Environment: Jinja2 utilizes a central object, the template Environment. Its instances store global objects and configurations, and load your email templates from a file.

  • PackageLoader: This configures Jinja2 to load email templates.

  • autoescape: To mitigate security threats such as cross-site scripting (XSS) attacks and protect your code, you can escape values (that are passed to the email template) while rendering HTML using the command autoescape. Or, you can validate user inputs to reject malicious code.

    For security, autoescape is set to True to enable escaping values. If you turn it to False, Jinja2 won't be able to escape values, and XSS attacks may occur. To enable autoescape, set autoescape to True:

    env = Environment(loader=PackageLoader("myapp"), autoescape=True)

Load Your Template

Once done, a template environment will be created with a template loader to find email templates created inside your project module's template folder.

Next, load your HTML email template using the method - get_template(). This function will return your loaded template. It also offers several benefits such as enabling email template inheritance, so you can reuse the template in multiple scenarios.

template1 = env.get_template("myemailtemplate.html")

Render the Template

To render your email template, use the method - render()

html1 = template1.render()

As these HTML email templates are dynamic, you can pass keyworded arguments (kwargs) with Jinja2 to the render function. The kwargs will then be passed to your email template. Here's how you can render your templates using the destined user's name - "Jon Doe" - in your email.

html1 = template1.render(name="Jon Doe")

Let's look at the complete code for this section:

from jinja2 import Environment, PackageLoader, select_autoescape env = Environment(loader=PackageLoader("email_project", "html_emailtemp"), autoescape=select_autoescape(["html", "xml"])) template1 = env.get_template("myemailtemplate.html") html1 = template1.render() Sending the Email

To send an email, you can use the application-level, straightforward protocol - Simple Mail Transfer Protocol (SMTP). This protocol streamlines the email sending process and determines how to format, send, and encrypt your emails between the source and destination mail servers.

In this instance, we'll send emails in Python via SMTP since Python offers a built-in module for email sending. To send emails, Python provides a library, 'smtplib', to facilitate effortless interaction with the SMTP protocol.

To get started:

Install 'smtplib': Ensure you have installed Python on your system. Now, import 'smtplib' to set up connectivity with the mail server.

import smtplib

Define your HTML parameter: Define your HTML parameter for the mail object where you'll keep your HTML template. It will instruct email clients to render the template.

Here's the full code for this section:

import smtplib from email.mime.text import MIMEText # MIMEText is a class from the email package from jinja2 import Template # Let's use Template class for our HTML template sender = "<a href='mailto:sender1@gmail.com' target='_blank' rel='noopener noreferrer'>sender1@gmail.com</a>" recipient = "<a href='mailto:recipient1@gmail.com' target='_blank' rel='noopener noreferrer'>recipient1@gmail.com</a>" subject = "Your order is confirmed!" with open('myemailtemplate.html', 'r') as f: template1 = Template(f.read()) # Enter the HTML template html_emailtemp = """ <!DOCTYPE html> <html lang='en'> <head> <meta charset='UTF-8'> <meta name='viewport' content='width=device-width, initial-scale=1'> <title>HTML Email Template</title> <style type='text/css'> # Adding the CSS body { margin: 0; padding: 0; background-color: #f4f4f4; font-family: Arial, sans-serif; } table { border-collapse: collapse; } .mailcontainer { width: 100%; max-width: 600px; margin: auto; background-color: #ffffff; } .header { background-color: #1c3f60; color: #ffffff; text-align: center; padding: 20px; } .body { padding: 20px; font-size: 16px; line-height: 1.6; background-color: #1c3f60; color: #7ed957; } .footer { background-color: #ff6100; color: #000000; text-align: center; padding: 20px; } .cta { background-color: #8c52ff; padding: 10px 20px; border-radius: 5px; color: #ffffff; text-decoration: none; font-weight: bold; } @media screen and (max-width: 600px) { .container { width: 100% !important; padding: 10px !important; } } </style> </head> <body> <table width='100%' cellpadding='0' cellspacing='0'> <tr> <td align='center'> <table class='container' width='600' cellpadding='0' cellspacing='0'> <!-- Header --> <tr> <td class='header'> <h1>Your order is confirmed</h1> </td> </tr> <!-- Body --> <tr> <td class='body'> <p>The estimated delivery date is 22nd August 2024.</p> <p style='font-size: 16px; color: blue;'>Styled paragraph.</p> <table width='100%' cellpadding='0' cellspacing='0' style='border: 1px solid #1c3f60; padding: 20px;'> <tr> <td align='center'> <h1 style='color: #7ed957;'>Hi, Jane!</h1> <p style='font-size: 16px; color: #ffde59;'> Thank you for being our valuable customer! </p> </td> </tr> </table> <table cellpadding='0' cellspacing='0' style='margin: auto;'> <tr> <td align='center' style='background-color: #8c52ff; padding: 10px 20px; border-radius: 5px;'> <a href='https://www.mydomain.com' target='_blank' rel='noopener noreferrer' style='color: #ffffff; text-decoration: none; font-weight: bold;'>Get a 30-day free trial</a> </td> </tr> </table> </td> </tr> <!-- Footer --> <tr> <td style='background-color: #ff6100; color: #000000; text-align: center; padding: 20px;'> <p>For additional help, contact us at support@domain.com</p> </td> </tr> </table> </td> </tr> </table> </body> </html> """ template1 = Template(html_emailtemp) html1 = template1.render(name="Jon Doe") # Attach your MIMEText objects for HTML message = MIMEText(html1, 'html') message['Subject'] = subject message['From'] = sender message['To'] = recipient # Send the HTML email with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server: server.login(username, password) server.sendmail(sender, recipient, message.as_string())

Explanation:

  • sender: The sender's email address
  • recipient: The recipient's email address
  • from email.mime.text import MIMEText: This is used to import the class MIMEText, enabling you to attach your HTML template in the email.
  • smtplib.SMTP_SSL('smtp.gmail.com', 465) as server:: This establishes a connection with your email provider's (Gmail's) SMTP server using port 465. If you are using another SMTP provider, use their domain name, such as smtp.domain.com, with an appropriate port number. The connection is secured with SSL.
  • server.login(username, password): This function allows you to log in to the email server using your username and password.
  • server.sendemail(sender, recipient, message.as_string()): This command sends the HTML email.
Testing

Before sending your HTML email, test it to understand how different email clients render CSS and HTML. Testing tools like Email on Acid, Litmus, etc. can assist you.

Conclusion

To build custom email templates with HTML and CSS in Python, follow the above instructions. First, begin structuring your HTML email template, style emails with CSS, and then send them to your recipients. Always check your email template's compatibility with different email clients and ensure to keep your HTML simple using tables. Adding an email link in HTML will also allow you to compose an email automatically in your email client and send it to a specific email address.

Categories: FLOSS Project Planets

Matt Glaman: Next stages for the Drupal Starshot trial experience

Planet Drupal - Tue, 2024-08-20 12:57

Drupal CMS is the official name for Drupal Starshot. We officially have the Drupal CMS project on Drupal.org, where the previous prototype has been converted into the official codebase. This monolithic repository will contain the Composer project and packages (recipes) that makeup Drupal CMS. 

Categories: FLOSS Project Planets

Plasma Crash Course - KCrash

Planet KDE - Tue, 2024-08-20 12:42

A while ago a colleague of mine asked about our crash infrastructure in Plasma and whether I could give some overview on it. This seems very useful to others as well, I thought. Here I am, telling you all about it!

Our crash infrastructure is comprised of a number of different components.

  • KCrash: a KDE Framework performing crash interception and prepartion for handover to…
  • coredumpd: a systemd component performing process core collection and handover to…
  • DrKonqi: a GUI for crashes sending data to…
  • Sentry: a web service and UI for tracing and presenting crashes for developers

We will look at them in turn. This post introduces KCrash.

KCrash

KCrash, as the name suggests, is our KDE framework for crash handling. While it is a mid-tier framework and could be used by outside projects, it mostly doesn’t make sense to, because some behavior is very KDE-specific.

It installs POSIX signal handlers to intercept crash signals and then prepares the crashed process for handover to coredumpd and DrKonqi. More on these two in another post. Once prepared it sends the crash signal into the next higher level crash handler until the signal eventually reaches the default handler and cause the kernel to invoke the core pattern.

Before that can happen, a bunch of work needs doing inside KCrash. Most of it quite boring, but also somewhat challenging.

You see, when handling a signal you need to only use signal-safe functions. The manpage explains very well why. This proves quite challenging at the level we usually are at (i.e. Qt) because it is entirely unclear what is and isn’t ultimately signal-safe under the hood. Additionally, since we are dealing with crash scenarios, we must not trigger new memory allocation, because the heap management may have had an accident.

To that end, KCrash has to use fairy low-level API. To make that easier to work with, there are actually two parts to KCrash:

  • The Initialization Stage
  • The Crash Stage
The Initialization Stage

Initialization is generally triggered by calling KCrash::initialize. You may already wonder what kind of initialization KCrash could possibly need. Well, the obvious one is setting up the signal handling. But beyond that the init stage is also used to prepare us for the crash stage. I’ve already mentioned the serious constraints we will encounter once the signal hits, so we had best be prepared for that. In particular we’ll do as much of the work as possible during initialization. This most important includes copying QString content into pre-allocated char * instances such that we later only need to read existing memory. The second most important aspect is the metadata file preparation for use in…

The Crash Stage

Once initialization has happened, we are ready for crashes. Ideally the application doesn’t crash, of course. 😉

But if it does the biggest task is rescuing our data!

Metadata

Inside KCrash we have the concept of Metadata: everything we know about the crashed application: the signal, process ID, executable, used graphics device… and so on and so forth. All this data is collected into a metadata file on-disk in ~/.cache/kcrash-metadata at the time of crash.

Here’s an example file:

[KCrash] exe=/usr/bin/kwin_wayland glrenderer= platform=wayland appname=kwin_wayland apppath=/usr/bin signal=11 pid=1353 appversion=6.1.80 programname=KWin bugaddress=submit@bugs.kde.org

The actual fields vary depending on what is available for any given application, but it’s generally more or less what is shown in the example.

This metadata file will later be consumed by DrKonqi in an effort to obtain information that only existed at runtime inside the application - such as the version that was running, or whether it was running in legacy X11 mode.

Handoff

Once the metadata is safely saved to disk, KCrash simply calls raise(). This re-raises the signal into the default handler, and through that causes a core dump.

What happens next is up to the system configuration as per the core manpage.

The recommended setup for distributions is that a crash handler be configured as core_pattern and that this handler consumes the crash. We recommend an implementation of the coredumpd and journald interfaces as that will then allow our crash handler to come in and log the crash with KDE.

So that was KCrash, the first in our four-step crash-handling pipeline. In the next blog post I’ll tell you all about the next one: coredumpd.

Categories: FLOSS Project Planets

Real Python: Exploring Astrophysics in Python With pandas and Matplotlib

Planet Python - Tue, 2024-08-20 10:00

This course uses three problems often covered in introductory astro-physics courses to play in Python. Along the way you’ll learn some astronomy, and how to use a variety of datascience libraries like NumPy, Matplotlib, pandas, and pint.

In this video course you’ll learn about:

  • Introductory astrophysics topics
  • Working with dataframes in pandas
  • Writing code that uses scientific units
  • Visualizing information with Matplotlib

[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

Categories: FLOSS Project Planets

Drupal Association blog: Extending the Life of Drupal 7 with Commercial Support

Planet Drupal - Tue, 2024-08-20 09:44

As a Drupal 7 user, you might feel the pressure of the impending end-of-life (EOL) announcement. While Drupal 7 has served us well over the years, preparing for the future is essential. However, The Drupal Association has partners who offer D7 Extended Security Support.  you can confidently extend the life of your Drupal 7 site while strategically planning your migration to newer versions of Drupal. Find a partner here.

The Importance of Planning Your Migration

Migrating from Drupal 7 is crucial for staying current with new features, security updates, and performance improvements. There are significant advantages to moving to newer versions of Drupal:

  • Enhanced Security: Newer versions of Drupal come with advanced security measures that protect your site from emerging threats.

  • Modern Features: Newer Drupal versions introduce features that streamline content management, enhance user experience, and improve site performance.

  • Better Performance: Newer versions are optimized for speed and efficiency, providing a better experience for your users.

  • Community Support: With most of the Drupal community moving forward, staying on an outdated version might limit your access to community resources and modules.

To find a Drupal 7 Migration Partner to lead your migration, reach out to our Certified Migrations Partners that offer services in these categories.

Categories: FLOSS Project Planets

Debian Brasil: Debian Day 2024 in Santa Maria - Brazil

Planet Debian - Tue, 2024-08-20 09:00

by por Andrew Gonçalves

Debian Day in Santa Maria - RS 2024 was held after a 5-year hiatus from the previous version of the event. It took place on the morning of August 16, in the Blue Hall of the Franciscan University (UFN) with support from the Debian community and the Computing Practices Laboratory of UFN.

The event was attended by students from all semesters of the Computer Science, Digital Games and Informational Systems, where we had the opportunity to talk to the participants.

Around 60 students attended a lecture introducing them to Free and Open Source Software, Linux and were introduced to the Debian project, both about the philosophy of the project and how it works in practice and the opportunities that have opened up for participants by being part of Debian.

After the talk, a packaging demonstration was given by local DD Francisco Vilmar, who demonstrated in practice how software packaging works in Debian.

I would like to thank all the people who helped us:

  • Debian Project
  • Professor Ana Paula Canal (UFN)
  • Professor Sylvio André Garcia (UFN)
  • Laboratory of Computing Practices
  • Francisco Vilmar (local DD)

And thanks to all the participants who attended this event asking intriguing questions and taking an interest in the world of Free Software.

Photos:

Categories: FLOSS Project Planets

Debian Brasil: Debian Day 2024 em Santa Maria/RS - Brasil

Planet Debian - Tue, 2024-08-20 09:00

por Andrew Gonçalves

O Debian Day em Santa Maria - RS 2024 foi realizado após 5 anos de hiato, foi feito durante a manhã do dia 16/08/2024 no Salão Azul da Universidade Franciscana (UFN) com apoio da comunidade Debian e do Laboratório de Práticas da Computação da UFN.

O evento contou com alunos de todos os semestres dos cursos de Ciência da Computação, Jogos Digitais e Sistemas de Informação, fizemos um coffee break onde tivemos a oportunidade de conversar com os participantes.

Cerca de 60 alunos prestigiaram uma palestra de introdução ao Software Livre e de Código Aberto, Linux e foram introduzidos ao projeto Debian, tanto sobre a filosofia do projeto, até como ele acontece na prática e oportunidades que se abriram para participantes do projeto por fazerem parte do Debian.

Após a palestra foi feita uma demonstração de empacotamento pelo DD local Francisco Vilmar, que demonstrou na prática como funciona o empacotamento de software no Debian.

Gostaria de agradecer a todas as pessoas que nos ajudaram:

  • Projeto Debian
  • Professora Ana Paula Canal (UFN)
  • Professor Sylvio André Garcia
  • Laboratório de Práticas da Computação
  • Francisco Vilmar (DD local)

E um muito obrigado a todos os participantes que nos prestigiaram neste evento fazendo perguntas intrigantes e se interessando pelo mundo do Software Livre.

Algumas fotos:

Categories: FLOSS Project Planets

Specbee: How to configure Faceted Search in Drupal - An easy step-by-step guide

Planet Drupal - Tue, 2024-08-20 08:00
Faceted search offers users with a superior search experience by displaying filters against their search results. It is particularly useful for websites having large catalogues and listings. Once the user types in their search query, they will be presented with a list of relevant filter options to further narrow down their search. These filtering elements are facets.Previously Facet API in Drupal 9, the Facet module in Drupal 10 enables your website with faceted searching abilities. Let’s look at configuring and implementing Faceted search with Drupal’s own search server, Search API. What is Faceted Search? If your users are finding it hard to see what they are searching for even after keying in their search query, they are bound to get frustrated. Faceted search provides users with multiple filters at the same time for the various attributes of the content. The facets provided are based on the search query the user has executed. Facets will also display the number of matched results (usually within brackets) next to it. Let’s take a look at this below screenshot to understand Facets better. In one of our recent Drupal projects, a quick search for Homes in Columbia on this website presents to you with facets like Communities, Hot Deals, Quick Move-ins and more. You will also see the count of the results next to each facet. So, a query with “Columbia” keyword is sent to the search server to retrieve the already configured and indexed categories (Communities, Hot Deals, etc.) Installing the Facets Module for Drupal 10 As previously discussed, we will be implementing Faceted search using Drupal’s Search API module.  Step 1: Enabling the modules Install and enable these modules •    The Facet Module •    Search API module Step 2: Creating Content Types Create the content you would like to include in the faceted search by adding Content types as shown below. You can also use the default content types provided by Drupal. Step 3: Configuring the Search server Navigate to Configuration -> Search and metadata -> Search-API from the admin interface to configure your search server. Give a name to your search server (here - data server).  Step 4: Configuring the Search Index Next, configure the search index to improve the search performance. Navigate to Configuration -> Search and metadata -> Search-API -> Index -> data_index. Give a name to your index and then select Content as your Datasources since we will be indexing the Content entities here. You can then move on to the next section - Configuring the Datasource (here – Content). Here you can choose to select all the bundles or only select a few from the below list to index. Next, select your server that you had already created (here - data server). Select the “Index items immediately” option to begin the indexing process. Click on Save. Step 5: Adding Fields for Indexing Next, we need to add Fields to be indexed. Navigate to Configuration -> Search and metadata ->Search API -> data index and select the Fields tab. Click on the Add fields button to create fields according to your requirement. Step 6: Indexing the Content Under the same location, click on the View tab to start the process of indexing your content. In the Start Indexing Now section, click on the Index Now button. It will then show you a progress bar with the status of the number of items that have been indexed. Step 7: Creating a View Now we will be creating a view for the data that needs to be indexed and displayed to your users. Navigate to Structure -> Views -> Add View. Give a name for the View.Under View Settings dropdown list, select the index that you have created in Step 4.Create a page for your search results by clicking on the Create a page checkbox under the Page Settings tab. Give a name and a path for the same. Under Items to Display, select 0 if you want to display all the results in one page. Else, select a number of results to be displayed. Under Page Display settings, you can select the format in which you want to display your results – Table, Grid, HTML list or Unformatted list. We have selected Unformatted list here. Click on Save. Step 8: Adding Fields to the View Here we will be adding fields that we have indexed earlier to the View.Go to Views, click on Add button next to the Fields section. Select the Fields, click on Add and Configure. Under Render Settings, select the Link to Content checkbox so that the results displayed are clickable.Click Save. Step 9: Configuring the Facets Now let’s begin configuring and enabling the facets. Navigate to Configuration -> Search and meta data -> FacetsClick on the Add Facet button. Select the Facet Source – This will be your View that you created previously.Select the Field – This will display the fields you had added for indexing in Step 5.Give a name to the Facet.Click on Save. Next, you will then see more configuration options for displaying the facets (as shown in the below image). Widgets will list out a number of options like List of links, array, dropdown, etc. You can choose what suits your website the best.Select the “Transform entity ID to label” to avoid displaying the machine name of the content type.Click on Save. Step 10: Placing the Facet blocks in the chosen page regions  Next, place the Facets you created as blocks in a page region of your choice. Navigate to Structure -> Block Layout. Select the region of the page where you would like to place the block containing the Facets.Here, we are selecting Sidebar. Click on the Place Block button next to the Sidebar.In the next dialog box, search for the Facet name and click on Place Block. In the Configure Block section, mention the Search page path that you had previously created. Here -“site-search” is our page we had created. Give a display name for your Block and select the Display title checkbox if you want the block name to be displayed (here – Type).Click on Save Block. The Result And just like that, your faceted search page and functionality is ready! Notice the Facet called Type (display name) that has Basic page and Article listed as content types to filter against.(Note: Since there is no content available under ‘Basic Page’, it will not show up in the filter).   Select Type as ‘Person’   Select Type as ‘Article’ Final Thoughts Implementing faceted search provides users with an easy and fast search experience. In this tutorial, we have used Search API as the search engine. You could also use search servers like Apache Solr, Search API Solr search or Elasticsearch with Drupal 8, whatever suits your requirements. As a leading Drupal development company, Specbee’s Drupal experts can help you build exemplary search experiences. Contact us to know more.
Categories: FLOSS Project Planets

The Drop Times: “It’s Time to Give Back Beyond Code”: Kevin Quillen

Planet Drupal - Tue, 2024-08-20 05:12
As part of The DropTimes&#039; &quot;Meet the Candidate&quot; campaign for the ongoing Drupal Association Board Elections, Kevin Quillen, Practice Lead at Velir, shares his vision for making Drupal more accessible and appealing worldwide. With over 16 years of experience in the community, Kevin discusses his plans to modernize Drupal.org, attract new developers, and enhance the platform&#039;s global impact. Voting runs until 5 September.
Categories: FLOSS Project Planets

Python Bytes: #397 So many PyCon videos

Planet Python - Tue, 2024-08-20 04:00
<strong>Topics covered in this episode:</strong><br> <ul> <li><strong><a href="https://github.com/ZeroIntensity/pyawaitable?featured_on=pythonbytes">pyawaitable</a></strong></li> <li><strong><a href="https://nrennie.rbind.io/blog/plotnine-annotated-area-chart/?featured_on=pythonbytes">Annotated area charts with plotnine</a></strong></li> <li><strong><a href="https://github.com/uname-n/deltabase?featured_on=pythonbytes">DeltaDB</a></strong></li> <li><strong><a href="https://pycon.blogspot.com/2024/08/pycon-us-2024-recap-and-recording.html?featured_on=pythonbytes">PyCon US 2024 Recap + Videos are up</a></strong></li> <li><strong>Extras</strong></li> <li><strong>Joke</strong></li> </ul><a href='https://www.youtube.com/watch?v=67F3kv6jCEU' style='font-weight: bold;'data-umami-event="Livestream-Past" data-umami-event-episode="397">Watch on YouTube</a><br> <p><strong>About the show</strong></p> <p>Sponsored by us! Support our work through:</p> <ul> <li>Our <a href="https://training.talkpython.fm/?featured_on=pythonbytes"><strong>courses at Talk Python Training</strong></a></li> <li><a href="https://courses.pythontest.com/p/the-complete-pytest-course?featured_on=pythonbytes"><strong>The Complete pytest Course</strong></a></li> <li><a href="https://www.patreon.com/pythonbytes"><strong>Patreon Supporters</strong></a></li> </ul> <p><strong>Connect with the hosts</strong></p> <ul> <li>Michael: <a href="https://fosstodon.org/@mkennedy"><strong>@mkennedy@fosstodon.org</strong></a></li> <li>Brian: <a href="https://fosstodon.org/@brianokken"><strong>@brianokken@fosstodon.org</strong></a></li> <li>Show: <a href="https://fosstodon.org/@pythonbytes"><strong>@pythonbytes@fosstodon.org</strong></a></li> </ul> <p>Join us on YouTube at <a href="https://pythonbytes.fm/stream/live"><strong>pythonbytes.fm/live</strong></a> to be part of the audience. Usually Tuesdays at 10am PT. Older video versions available there too.</p> <p>Finally, if you want an artisanal, hand-crafted digest of every week of the show notes in email form? Add your name and email to <a href="https://pythonbytes.fm/friends-of-the-show">our friends of the show list</a>, we'll never share it.</p> <p><strong>Michael #1:</strong> <a href="https://github.com/ZeroIntensity/pyawaitable?featured_on=pythonbytes">pyawaitable</a></p> <ul> <li>CPython API for asynchronous functions.</li> <li>by Peter Bierma</li> <li>It was originally designed to be directly part of CPython - you can read the <a href="https://gist.github.com/ZeroIntensity/8d32e94b243529c7e1c27349e972d926?featured_on=pythonbytes">scrapped PEP</a> about it. </li> <li>Since this library only uses the public ABI, it's better fit outside of CPython, as a library.</li> </ul> <p><strong>Brian #2:</strong> <a href="https://nrennie.rbind.io/blog/plotnine-annotated-area-chart/?featured_on=pythonbytes">Annotated area charts with plotnine</a></p> <ul> <li>Nicola Rennie</li> <li>This is a marvelous, very professional looking plot, and a tutorial for how to achieve it.</li> <li>Uses <a href="https://plotnine.org?featured_on=pythonbytes">plotline</a>, which is “.. an implementation of a <em>grammar of graphics</em> in Python based on ggplot2” <ul> <li>I actually didn’t know the gg in ggplot came from “grammar of graphics”. TIL</li> </ul></li> </ul> <p><strong>Michael #3:</strong> <a href="https://github.com/uname-n/deltabase?featured_on=pythonbytes">DeltaDB</a></p> <ul> <li>A lightweight, comprehensive solution for managing delta tables built on polars and deltalake.</li> <li><a href="https://github.com/delta-io/delta-rs?featured_on=pythonbytes">Deltalake</a>: Delta Lake is an open-source storage format that runs on top of existing data lakes. </li> <li><a href="https://github.com/pola-rs/polars?featured_on=pythonbytes">Polars</a>: Dataframes powered by a multithreaded, vectorized query engine, written in Rust (aka fluent, rust-based pandas)</li> <li>See <a href="https://uname-n.github.io/deltabase/?featured_on=pythonbytes">the docs</a>.</li> </ul> <p><strong>Brian #4:</strong> <a href="https://pycon.blogspot.com/2024/08/pycon-us-2024-recap-and-recording.html?featured_on=pythonbytes">PyCon US 2024 Recap + Videos are up</a></p> <ul> <li>95 countries attended</li> <li>total attendance of 2,991 <ul> <li>2,551 in person</li> <li>440 remote</li> </ul></li> <li>Videos available <a href="https://www.youtube.com/@PyConUS">PyConUS</a> <ul> <li>I recommend <a href="https://www.youtube.com/playlist?list=PL2Uw4_HvXqvYhjub9bw4uDAmNtprgAvlJ">Playlist → 2024 → view full playlist</a>, as it’s easier to see the talk titles.</li> <li>I’ve got Paul Gannsle’s pytest for unittesters and Amitosh Swain’s Testing Data Pipelines queued up</li> </ul></li> </ul> <p><strong>Extras</strong> </p> <p>Brian:</p> <ul> <li><a href="https://courses.pythontest.com/hello-pytest?featured_on=pythonbytes">Hello, pytest!</a> course available as of last Friday. <ul> <li>Now the fastest way to get started using pytest. </li> <li>16 lessons (really 12 + intro, outro, code download, pytest flag cheat sheet)</li> <li>The whole shebang is about 90 min. (faster if you bump up the video speed. :)</li> </ul></li> </ul> <p>Michael:</p> <ul> <li>Cutting back on digital distractions, trying <a href="https://apps.apple.com/us/app/dumb-phone/id6504743503?featured_on=pythonbytes">Dumb Phone</a> for iPhone. <ul> <li>See <a href="https://python-bytes-static.nyc3.digitaloceanspaces.com/dumb-phone-experiment.jpeg?featured_on=pythonbytes">screenshot</a></li> </ul></li> <li><a href="https://www.codeinacastle.com/python-zero-to-hero-2024?featured_on=pythonbytes">Code in a Castle Event</a></li> </ul> <p><strong>Joke:</strong> <a href="https://www.talisman.org/tao/?featured_on=pythonbytes">The Tao of Programming: 4.3</a></p> <p>A master was explaining the nature of Tao of to one of his novices, "The Tao is embodied in all software -- regardless of how insignificant," said the master.</p> <p>"Is the Tao in a hand-held calculator?" asked the novice.</p> <p>"It is," came the reply.</p> <p>"Is the Tao in a video game?" continued the novice.</p> <p>"It is even in a video game," said the master.</p> <p>"And is the Tao in the DOS for a personal computer?"</p> <p>The master coughed and shifted his position slightly. "The lesson is over for today," he said.</p>
Categories: FLOSS Project Planets

CKEditor: DrupalCon 2024 - A chat with Simon Morvan

Planet Drupal - Tue, 2024-08-20 02:55
Simon Morvan discusses EvolvingWeb, Drupal development, and CKEditor 5 migration at DrupalCon Portland 2024.
Categories: FLOSS Project Planets

Dirk Eddelbuettel: digest 0.6.37 on CRAN: Maintenance

Planet Debian - Mon, 2024-08-19 22:18

Release 0.6.37 of the digest package arrived at CRAN today and has also been uploaded to Debian.

digest creates hash digests of arbitrary R objects. It can use a number different hashing algorithms (md5, sha-1, sha-256, sha-512, crc32, xxhash32, xxhash64, murmur32, spookyhash, blake3,crc32c, xxh3_64 and xxh3_128), and enables easy comparison of (potentially large and nested) R language objects as it relies on the native serialization in R. It is a mature and widely-used package (with 70.8 million downloads just on the partial cloud mirrors of CRAN which keep logs) as many tasks may involve caching of objects for which it provides convenient general-purpose hash key generation to quickly identify the various objects.

This release updates one of the different hashing source functions which, to remain close to their upstream, used Free() and Calloc() (uppercased to use the R allocator) but not the prefixed stricter versions R_Free() and R_Calloc(). R will switch to enforcing these in the next release next year. Kevin had noticed (while doing some other testing) that this now fails under R-devel (with a switch set), and prepares a very nice and clean PR to take care of it. As of today, CRAN is now sending ‘please fix, or else …’ notes so it was a good time to send this to CRAN. We also updated some remaining http URLs in the README.md to https, and switched to Author/Maintainer field to the now also mandatory Authors@R.

My CRANberries provides a summary of changes to the previous version. For questions or comments use the issue tracker off the GitHub repo. For documentation (including the changelog) see the documentation site.

If you like this or other open-source work I do, you can now sponsor me at GitHub.

This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. Please report excessive re-aggregation in third-party for-profit settings.

Categories: FLOSS Project Planets

TestDriven.io: Limiting Content Types in a Django Model

Planet Python - Mon, 2024-08-19 18:28
This article looks at how to limit the content types in a Django model.
Categories: FLOSS Project Planets

Message-passing APIs (SIMPL)

Planet KDE - Mon, 2024-08-19 18:00

In the KDE world, famously there was that weekend where DCOP (Desktop Communicating Objects Protocol) was created, setting the stage for things like KParts. GNOME picked the CORBA object model, and much later the Free Desktop world settled on DBus as a message-passing API. But even at the time, there were other message-passing APIs. At work-work I use one, called SIMPL, which is kind of shout-out to the late ’90s of DCOP.

Please note that my presentation of “history” is just what I remember now of events that were already “tales told ‘round the campfire” 15 years ago. Corrections welcome (by email).

At work-work SIMPL is just a given, and it’s got wrappers and abstractions so that there’s a decent C++ style API around it. At its heart it is a point-to-point message-passing API with no policy at all about the payload of messages. That is both a blessing – no policy means it can be used for whatever kind of messages you think is necessary – and a curse – no policy means that you end up writing a bunch of abstractions to represent the messages that you actually use.

Code at the wrapped-in-C++ level looks something like this (effectively obscuring the underlying transport):

auto reply = CoordinatorTask().Send(requests::GetCurrentUser()); if(reply.has_value()) { do_something(reply.value().username); ...

There does not seem to be much online about SIMPL anymore. There is a LinuxDevices article from 2000 when SIMPL was under some active development as an Open Source project, there’s a LWN comment from 2015 that mentions it still, and there’s a Wikipedia article on it, as a historical note. Note that the Website link on wikipedia goes to something that is now a spam domain. I can’t quickly find sources anymore.

I do wonder at the chances of history that made desktop developers at the time entirely miss out on this existing message-passing mechanism – perhaps the SIMPL authors were too focused on industrial automation and not visible in the X11 desktop space, and not visible on SunOS and other platforms where a fair bit of KDE development happened at the time.

One thing that the SIMPL library developers emphasize repeatedly in documentation (there’s a book) is a philosophy of doing one thing and doing it well. So serialization and message payloads are not part of this – no policy. So security and access control are not part of his – no policy. Those concerns are things that can go into a different API layer on top of SIMPL.

Something else that the SIMPL authors emphasize is doing one thing and doing it well. That applies to the applications that use SIMPL, in particular. And that translates, in the depths of the library, to being able to register only one name for an application (for purposes of discovering what other applications there are, each application has a unique name in the system). It translates into a lack of thread safety, due to the use of global state. It translates into a contextless API, so all an application can do is call “give me the next incoming message”. There’s no concept of an event-loop, and no obvious mechanisms for integrating SIMPL message-handling into another event loop (like an X11 loop).

For me personally this means that I need to re-tool my brain during the trip between home and work, switching of Qt wrappers around DBus to work-work wrappers around SIMPL and the subtleties of each. In practice, that means mostly cursing QtDBus (because of the relative amount of time I put into both).

Categories: FLOSS Project Planets

Matthew Garrett: Client-side filtering of private data is a bad idea

Planet Debian - Mon, 2024-08-19 15:03
(The issues described in this post have been fixed, I have not exhaustively researched whether any other issues exist)

Feeld is a dating app aimed largely at alternative relationship communities (think "classier Fetlife" for the most part), so unsurprisingly it's fairly popular in San Francisco. Their website makes the claim:

Can people see what or who I'm looking for?
No. You're the only person who can see which genders or sexualities you're looking for. Your curiosity and privacy are always protected.

which is based on you being able to restrict searches to people of specific genders, sexualities, or relationship situations. This sort of claim is one of those things that just sits in the back of my head worrying me, so I checked it out.

First step was to grab a copy of the Android APK (there are multiple sites that scrape them from the Play Store) and run it through apk-mitm - Android apps by default don't trust any additional certificates in the device certificate store, and also frequently implement certificate pinning. apk-mitm pulls apart the apk, looks for known http libraries, disables pinning, and sets the appropriate manifest options for the app to trust additional certificates. Then I set up mitmproxy, installed the cert on a test phone, and installed the app. Now I was ready to start.

What became immediately clear was that the app was using graphql to query. What was a little more surprising is that it appears to have been implemented such that there's no server state - when browsing profiles, the client requests a batch of profiles along with a list of profiles that the client has already seen. This has the advantage that the server doesn't need to keep track of a session, but also means that queries just keep getting larger and larger the more you swipe. I'm not a web developer, I have absolutely no idea what the tradeoffs are here, so I point this out as a point of interest rather than anything else.

Anyway. For people unfamiliar with graphql, it's basically a way to query a database and define the set of fields you want returned. Let's take the example of requesting a user's profile. You'd provide the profile ID in question, and request their bio, age, rough distance, status, photos, and other bits of data that the client should show. So far so good. But what happens if we request other data?

graphql supports introspection to request a copy of the database schema, but this feature is optional and was disabled in this case. Could I find this data anywhere else? Pulling apart the apk revealed that it's a React Native app, so effectively a framework for allowing writing of native apps in Javascript. Sometimes you'll be lucky and find the actual Javascript source there, but these days it's more common to find Hermes blobs. Fortunately hermes-dec exists and does a decent job of recovering something that approximates the original input, and from this I was able to find various lists of database fields.

So, remember that original FAQ statement, that your desires would never be shown to anyone else? One of the fields mentioned in the app was "lookingFor", a field that wasn't present in the default profile query. What happens if we perform the incredibly complicated hack of exporting a profile query as a curl statement, add "lookingFor" into the set of requested fields, and run it?

Oops.

So, point 1 is that you can't simply protect data by having your client not ask for it - private data must never be released. But there was a whole separate class of issue that was an even more obvious issue.

Looking more closely at the profile data returned, I noticed that there were fields there that weren't being displayed in the UI. Those included things like "ageRange", the range of ages that the profile owner was interested in, and also whether the profile owner had already "liked" or "disliked" your profile (which means a bunch of the profiles you see may already have turned you down, but the app simply didn't show that). This isn't ideal, but what was more concerning was that profiles that were flagged as hidden were still being sent to the app and then just not displayed to the user. Another example of this is that the app supports associating your profile with profiles belonging to partners - if one of those profiles was then hidden, the app would stop showing the partnership, but was still providing the profile ID in the query response and querying that ID would still show the hidden profile contents.

Reporting this was inconvenient. There was no security contact listed on the website or in the app. I ended up finding Feeld's head of trust and safety on Linkedin, paying for a month of Linkedin Pro, and messaging them that way. I was then directed towards a HackerOne program with a link to terms and conditions that 404ed, and it took a while to convince them I was uninterested in signing up to a program without explicit terms and conditions. Finally I was just asked to email security@, and successfully got in touch. I heard nothing back, but after prompting was told that the issues were fixed - I then looked some more, found another example of the same sort of issue, and eventually that was fixed as well. I've now been informed that work has been done to ensure that this entire class of issue has been dealt with, but I haven't done any significant amount of work to ensure that that's the case.

You can't trust clients. You can't give them information and assume they'll never show it to anyone. You can't put private data in a database with no additional acls and just rely on nobody ever asking for it. You also can't find a single instance of this sort of issue and fix it without verifying that there aren't other examples of the same class. I'm glad that Feeld engaged with me earnestly and fixed these issues, and I really do hope that this has altered their development model such that it's not something that comes up again in future.

(Edit to add: as far as I can tell, pictures tagged as "private" which are only supposed to be visible if there's a match were appropriately protected, and while there is a "location" field that contains latitude and longitude this appears to only return 0 rather than leaking precise location. I also saw no evidence that email addresses, real names, or any billing data was leaked in any way)

comments
Categories: FLOSS Project Planets

FSF Events: Free Software Directory meeting on IRC: Friday, August 23, starting at 12:00 EDT (16:00 UTC)

GNU Planet! - Mon, 2024-08-19 12:39
Join the FSF and friends on Friday, August 23 from 12:00 to 15:00 EDT (16:00 to 19:00 UTC) to help improve the Free Software Directory.
Categories: FLOSS Project Planets

The Drop Times: A Name of Purpose and Clarity

Planet Drupal - Mon, 2024-08-19 11:15
<p>Dear Readers,<br><br><a href="https://www.thedroptimes.com/42282/drupal-starshot-initiative-now-officially-drupal-cms">The official naming of "Drupal CMS" marks a significant step in the evolution of the product initially developed under the Drupal Starshot Initiative</a>. The name was chosen for its clarity and simplicity, with "CMS" explicitly conveying the product's core function as a content management system. This approach addresses a common issue where users, particularly those unfamiliar with Drupal, often need clarification on what Drupal represents. Incorporating "CMS" into the name immediately defines the product’s purpose, aligning it more closely with industry norms and expectations.</p><p>The selection of "Drupal CMS" also reflects a broader strategy to make Drupal more accessible and understandable to various user groups. Participants in the testing process, especially marketers and designers, appreciated the inclusion of "CMS" in the name. For marketers unfamiliar with Drupal, the new name offered immediate recognition of the product's capabilities. Designers and other industry professionals echoed this sentiment, noting that "CMS" is a widely recognized term that accurately describes the product's function.</p><p>In contrast to Drupal CMS, Drupal Core continues to serve as the foundational framework for Drupal, offering a minimalist approach that is highly customizable but requires more technical expertise to implement fully. While Drupal Core provides the essential building blocks for creating custom web applications, Drupal CMS is designed to be more user-friendly and ready to use out-of-the-box. This distinction is crucial for users choosing between the two, as Drupal CMS comes with pre-configured modules, themes, and settings that streamline the development process, making it an ideal choice for less technical users or those needing rapid deployment.</p><p>The reception of the new name has been positive, particularly because it brings a level of clarity and accessibility that was previously lacking. By deciding to retire the internal code name "Drupal Starshot" after the first official release of Drupal CMS, the community is signaling a shift toward a more transparent and user-centered approach. This renaming simplifies the branding and helps position Drupal more effectively in a competitive market, ensuring that users immediately understand what the product offers and how it can meet their needs.</p><p>With that, let's move on to the important stories from the past week.</p><p><a href="https://www.thedroptimes.com/42278/drupal-association-board-election-2024-voting-now-open">Voting for the 2024 Drupal Association At-Large Board Member election has officially begun</a> as of August 15, 00:00 UTC. Eligible members of the Drupal community can cast their votes until the polls close on September 5 at 23:59 UTC. In relation to the election and thoroughly acquainting the candidates to the Drupal Community, <em>The DropTimes </em>began the <em><strong>"Meet the Candidate" </strong></em>campaign. This initiative features a series of interviews with each candidate, delving into their motives, expertise, and reasons for running in this election.&nbsp;</p><p>So far, The DropTimes has featured three candidates vying for the Drupal Association Board position. <a href="https://www.thedroptimes.com/interview/42166/elevating-drupal-beyond-cms-dominique-de-cooman">Dominique De Cooman</a> believes his advice can help the DA make better decisions on how to market Drupal to the midmarket and bring Drupal to market as a part of the DXP.&nbsp;</p><p><a href="https://www.thedroptimes.com/interview/42239/steering-drupals-potential-in-academia-janna-malikova">Janna Malikova</a>, a Senior Software Engineer at <a href="/organization/23133/tomato-elephant-studio" data-entity-type="node" data-entity-uuid="e140de54-1e29-4cf3-9d22-cc0c4909e30c" data-entity-substitution="canonical">Tomato Elephant Studio,</a> feels passionate about Drupal's potential in academia (schools, colleges, and universities). By teaching Drupal early on par with better advertised and competing technologies, the community has a chance to foster Drupal's recognition and improve awareness among graduates, teachers, and novice users. <a href="https://www.thedroptimes.com/interview/42122/bold-changes-propel-drupal-forward-will-huggins">Will Huggins</a>, the CEO and co-founder of <a href="/organization/8854/zoocha" data-entity-type="node" data-entity-uuid="286bb19b-bd4d-4979-90ba-be7617ae2bef" data-entity-substitution="canonical">Zoocha</a>, running in this election because he wants to contribute to the strategic direction of Drupal and the governance of the Drupal Association. Stay tuned for more.</p><p><a href="https://www.thedroptimes.com/42195/drupal-govcon-2024-heartbeat-dc-drupal-community">The premiere event of the DC Drupal Community, Drupal GovCon 2024</a><a href="https://www.thedroptimes.com/42195/drupal-govcon-2024-heartbeat-dc-drupal-community" target="_blank"><span style="box-sizing:border-box;margin:0;padding:0;text-align:left;">,</span></a><span style="box-sizing:border-box;margin:0;padding:0;text-align:left;">&nbsp;concluded successfully. As the official media partner of the event,&nbsp;</span><em><span style="box-sizing:border-box;margin:0;padding:0;text-align:left;">The DropTimes</span></em><span style="box-sizing:border-box;margin:0;padding:0;text-align:left;">&nbsp;had the privilege of speaking with the organizers to gather their insights and expectations for this year's conference. The event gathered more than 800 participants, who primarily discussed</span> government applications.&nbsp;</p><p><a href="https://www.thedroptimes.com/42243/key-rebuilding-drupal-communities-what-will-be-revealed-at-govcon-2024">A session of the Drupal GovCon 2024 featured prominent voices from the Drupal ecosystem</a>, including <a href="/people/26956/anoopjohn" data-entity-type="node" data-entity-uuid="740348ee-847a-4ca4-9357-46ce19ec9d71" data-entity-substitution="canonical">Anoop John</a>, <a href="/people/42242/amy-swackhamer" data-entity-type="node" data-entity-uuid="32b34c8a-79d6-44df-b303-972c74a0974f" data-entity-substitution="canonical">Amy Swackhamer</a>, <a href="/people/34722/ninaogor" data-entity-type="node" data-entity-uuid="4b378f54-29fe-4102-8e0b-5b541ecb42e8" data-entity-substitution="canonical">Nina Ogor</a>, and <a href="/people/9466/doyle" data-entity-type="node" data-entity-uuid="56419b1d-51a1-44d8-a407-495ac24b0efe" data-entity-substitution="canonical">John Doyle</a>. The panelists brought a wealth of experience in community building and revitalization, offering a roadmap for reconnecting Drupal enthusiasts and newcomers alike.</p><p><a href="https://www.thedroptimes.com/42277/pacific-northwest-drupal-summit-2024-sponsorship-opportunities-now-open">The Pacific Northwest Drupal Summit (PNWDS) 2024 invites companies and individuals to sponsor</a> the region’s leading event for Drupal professionals. <a href="/organization/10395/droptica" data-entity-type="node" data-entity-uuid="1a3dfede-eafe-421d-8c2a-841bbdaf44c3" data-entity-substitution="canonical">Droptica </a>is hosting a free webinar titled <a href="https://www.thedroptimes.com/42220/droptica-webinar-navigating-end-drupal-7-support"><em>"The Future After Drupal 7"</em></a> on August 27, 2024, at 3:00 PM CEST. This online event, organized by <a href="/people/32079/maciej-lukianski" data-entity-type="node" data-entity-uuid="5a16eb75-368b-4095-ad32-86d6e4f64e74" data-entity-substitution="canonical">Maciej Łukiański</a> and <a href="/people/32080/grzegorzbartman" data-entity-type="node" data-entity-uuid="6aa41a60-4108-4c9f-bed6-479ed05745dc" data-entity-substitution="canonical">Grzegorz Bartman</a>, will explore the options available for managing Drupal 7 websites after the official support ends. <a href="https://www.thedroptimes.com/42225/civicrm-hosts-session-drupal-7-end-life-and-civicrm-impact">CiviCRM will hold an online session on September 10, 2024</a>, at 4:00 PM BST to discuss the upcoming End of Life for Drupal 7, scheduled for January 5, 2025.<br><br>This week, <a href="/events/drupalcamps/drupalcamp-wolfsburg" data-entity-type="node" data-entity-uuid="022869b3-0085-404c-89db-0815d2a23f61" data-entity-substitution="canonical">DrupalCamping returns to Wolfsburg from August 22nd to 25th, 2024</a>, offering four days of camping, swimming, barbecuing, and Drupal discussions at the Allersee campsite. This event combines a relaxed, barcamp-style atmosphere with opportunities to learn, network, and enjoy outdoor activities with Drupal enthusiasts from across Germany and beyond. Tickets are now available.</p><p><a href="https://www.thedroptimes.com/42229/drupal-gutenberg-303-and-210-released">Drupal Gutenberg has released versions 3.0.3 and 2.10</a>, both of which are now fully compatible with Drupal 11. <a href="https://www.thedroptimes.com/42246/adci-solutions-launches-bibcite-demo-drupal-based-bibliographic-management">ADCI Solutions has newly launched BibCite demo</a>, an innovative module designed to streamline bibliographic data management for institutions using Drupal-based websites. Originally created years ago, BibCite has been a trusted tool for universities, research centers, and libraries. Now it offers a new demo version that allows users to experience its full functionality before installation.</p><p>Finally, <a href="https://www.thedroptimes.com/42222/dries-buytaert-present-40th-driesnote-at-drupalcon-barcelona-2024">Dries Buytaert, the founder of Drupal, will deliver his 40th Driesnote on September 24, 2024 during DrupalCon Barcelona</a>. The presentation will take place in the Auditorium at the CCIB, where Buytaert will provide an update on the current state of Drupal.</p><p>We acknowledge that there are more stories to share. However, due to selection constraints, we must pause further exploration for now.</p><p>To get timely updates, follow us on <a href="https://www.linkedin.com/company/the-drop-times/">LinkedIn</a>, <a href="https://twitter.com/thedroptimes">Twitter</a> and <a href="https://www.facebook.com/thedroptimes">Facebook</a>. You can also, join us on Drupal Slack at <a href="https://drupal.slack.com/archives/C04A6AZGYF6">#thedroptimes</a>.</p><p>Thank you,<br>Sincerely<br><strong>Alka Elizabeth</strong><br><strong>Sub-editor, </strong><em><strong>The DropTimes</strong></em><strong>.</strong></p>
Categories: FLOSS Project Planets

Real Python: Python Classes: The Power of Object-Oriented Programming

Planet Python - Mon, 2024-08-19 10:00

Python supports the object-oriented programming paradigm through classes. They provide an elegant way to define reusable pieces of code that encapsulate data and behavior in a single entity. With classes, you can quickly and intuitively model real-world objects and solve complex problems.

If you’re new to classes, need to refresh your knowledge, or want to dive deeper into them, then this tutorial is for you!

In this tutorial, you’ll learn how to:

  • Define Python classes with the class keyword
  • Add state to your classes with class and instance attributes
  • Provide behavior to your classes with methods
  • Use inheritance to build hierarchies of classes
  • Provide interfaces with abstract classes

To get the most out of this tutorial, you should know about Python variables, data types, and functions. Some experience with object-oriented programming (OOP) is also a plus. Don’t worry if you’re not an OOP expert yet. In this tutorial, you’ll learn the key concepts that you need to get started and more. You’ll also write several practical examples to help reinforce your knowledge of Python classes.

Get Your Code: Click here to download your free sample code that shows you how to build powerful object blueprints with classes in Python.

Take the Quiz: Test your knowledge with our interactive “Python Classes - The Power of Object-Oriented Programming” quiz. You’ll receive a score upon completion to help you track your learning progress:

Interactive Quiz

Python Classes - The Power of Object-Oriented Programming

In this quiz, you'll test your understanding of Python classes. With this knowledge, you'll be able to define reusable pieces of code that encapsulate data and behavior in a single entity, model real-world objects, and solve complex problems.

Getting Started With Python Classes

Python is a multiparadigm programming language that supports object-oriented programming (OOP) through classes that you can define with the class keyword. You can think of a class as a piece of code that specifies the data and behavior that represent and model a particular type of object.

What is a class in Python? A common analogy is that a class is like the blueprint for a house. You can use the blueprint to create several houses and even a complete neighborhood. Each concrete house is an object or instance that’s derived from the blueprint.

Each instance can have its own properties, such as color, owner, and interior design. These properties carry what’s commonly known as the object’s state. Instances can also have different behaviors, such as locking the doors and windows, opening the garage door, turning the lights on and off, watering the garden, and more.

In OOP, you commonly use the term attributes to refer to the properties or data associated with a specific object of a given class. In Python, attributes are variables defined inside a class with the purpose of storing all the required data for the class to work.

Similarly, you’ll use the term methods to refer to the different behaviors that objects will show. Methods are functions that you define within a class. These functions typically operate on or with the attributes of the underlying instance or class. Attributes and methods are collectively referred to as members of a class or object.

You can write classes to model the real world. These classes will help you better organize your code and solve complex programming problems.

For example, you can use classes to create objects that emulate people, animals, vehicles, books, buildings, cars, or other objects. You can also model virtual objects, such as a web server, directory tree, chatbot, file manager, and more.

Finally, you can use classes to build class hierarchies. This way, you’ll promote code reuse and remove repetition throughout your codebase.

In this tutorial, you’ll learn a lot about classes and all the cool things that you can do with them. To kick things off, you’ll start by defining your first class in Python. Then you’ll dive into other topics related to instances, attributes, and methods.

Defining a Class in Python

To define a class, you need to use the class keyword followed by the class name and a colon, just like you’d do for other compound statements in Python. Then you must define the class body, which will start at the next indentation level:

Python Syntax class ClassName: <body> Copied!

In a class’s body, you can define attributes and methods as needed. As you already learned, attributes are variables that hold the class data, while methods are functions that provide behavior and typically act on the class data.

Note: In Python, the body of a given class works as a namespace where attributes and methods live. You can only access those attributes and methods through the class or its objects.

As an example of how to define attributes and methods, say that you need a Circle class to model different circles in a drawing application. Initially, your class will have a single attribute to hold the radius. It’ll also have a method to calculate the circle’s area:

Python circle.py import math class Circle: def __init__(self, radius): self.radius = radius def calculate_area(self): return math.pi * self.radius ** 2 Copied!

In this code snippet, you define Circle using the class keyword. Inside the class, you write two methods. The .__init__() method has a special meaning in Python classes. This method is known as the object initializer because it defines and sets the initial values for the object’s attributes. You’ll learn more about this method in the Instance Attributes section.

Read the full article at https://realpython.com/python-classes/ »

[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

Categories: FLOSS Project Planets

Consensus Enterprises: Starshot: Moving Drupal Towards a Product Platform

Planet Drupal - Mon, 2024-08-19 09:11
Drupal is shifting from a developer-centric framework to a product-oriented platform with the Starshot initiative, aimed at simplifying the site building experience for smaller organizations through Low Code/No Code tools and automatic updates.
Categories: FLOSS Project Planets

mandclu: What’s Cooking with the Events Recipe for Drupal CMS

Planet Drupal - Mon, 2024-08-19 08:48
What’s Cooking with the Events Recipe for Drupal CMS

When I first heard the vision for Starshot (now Drupal CMS), I knew exactly how I wanted to contribute. For years I have been working on trying to make it easier to quickly build Drupal sites following established best practices. I had been working on a set of modules I called Configuration Kits, but they were conceptually very similar to Recipes, albeit in a simpler (and less flexible) form.

mandclu Aug 19, 2024 - 8:48am Tags
Categories: FLOSS Project Planets

Pages