This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Development

Welcome to the development corner of the YMCA Website Services distribution. This section contains resources and guidelines for developers, QA engineers, and YMCA associations involved in the development and maintenance of YMCA Website Services.

For YMCA Associations

For Developers

For QA Engineers


Community Guidelines

Best Practices

Getting Started with YMCA Website Services Development

Whether you are just getting started with YMCA Website Services or need to test a feature in a stable environment, the YMCA Website Services Core Team maintains a number of Sandboxes that you can use.

Processes & Components

Environment Setup

Contributing to YMCA Website Services

Working with Existing Functionality

Adding and Removing Functionality

Dependency Management

Decoupling YMCA Website Services

Ongoing Maintenance

Releases

Update Processes & Notices

These documents are for old versions of YMCA Website Services but may contain useful information for troubleshooting future update issues.

1 - Onboarding

Welcome to YMCA Website Services

List of migrated repositories/projects

In 2022, maintenance of the distribution moved from Open Y LLC to Y-USA. With this, repository locations have changed:

How to start developing YMCA Website Services

To get a copy of the latest development version of the distribution, follow the steps in the YUSA OpenY README.

YMCA Website Services has a modular structure. If you plan changes to a specific component, create a Pull Request/Merge Request in the respective project or repository, based on the component’s composer.json data.

To test a specific component, create a PR to yusaopeny and add a reference in composer.json of YMCA Website Services so the build system starts using the updated component.

QA sandboxes for YMCA Website Services

The YMCA Website Services core team manages sandboxes for various configurations of the distribution. These sandboxes facilitate evaluation, QA, and issue investigation.

How to start developing Virtual Y

Get started with the README

QA sandboxes for Virtual Y

How to start developing Membership Framework

Get started with the README

QA sandboxes for Membership Framework

How to start developing Activity Finder

Activity Finder is installed with the distribution by default.

Get started with the README

QA Sandboxes for Activity Finder

2 - 3rd-party dependencies

YMCA Website Services’s system requirements generally track those of Drupal with some occasional more opinionated recommendations. YMCA Website Services leverages many other open source frameworks including, but not limited to, the ones listed below. These dependencies are reviewed periodically for new features and deprecations.

General Requirements

Supported versions may differ based on your Drupal version. Refer to Drupal’s documentation for specific version compatibility.

Recommended for advanced functionality, but not required:

  • Apache SOLR search server
    • Version 4.9.1 and version 8 have been tested for Activity Finder. Other versions are works in progress.

For high load/performance sites

See also Drupal’s recommendations for managing site performance and scalability.

For development

See our installation instructions for a full walkthrough of these tools.

Software libraries and frameworks

3 - Acceptance Testing

YMCA Website Services is a large distribution with a significant number of modules, components, subsystems, and business processes. Therefore, we must take appropriate steps to ensure the stability of major functionality during development.

For automated tests, we have created a General Checks template on GitHub. Every developer should follow this template to get review approval from the YMCA Website Services core team. However, General Checks are for testing functionality related to the current proposed change only and are not intended for Regression Testing.

For regression testing, Behat tests are provided automatically on each build by the YMCA Website Services community.

Every pull request should include a testing plan before being released into YMCA Website Services. This plan should cover the testing of all workflows and functionality to ensure they continue to work with any new code or changes implemented. Conflicts can occur between elements of YMCA Website Services, Drupal modules, and Drupal core. Pull request testing plans increase productivity and decrease the effort required for manual Acceptance Testing of upcoming releases. The testing plan should cover specific features and functionality that are likely to cause regression issues post-release or post-upgrade to the latest version of YMCA Website Services after the new code is implemented.

Example of a testing plan: If the Drupal core is updated, gather all Drupal core Release Notes since the last core upgrade for YMCA Website Services and analyze the important issues fixed.

For example, if you are upgrading from version 8.4.0 to 8.4.4:

This means that the following systems should be tested:

  • Multilingual
  • PostgreSQL support
  • Migration
  • Taxonomy
  • CKEditor
  • Composer

This list can be extended by analyzing the YMCA Website Services distributions’ important parts that depend on the subsystems listed above. Spending time on every module with a taxonomy dependency is not required, but testing at least one impacted module to ensure it is still working post-implementation is essential. If a Behat test is already created for the subsystem in a list, a manual test can be skipped if the build is not failing due to the module or element covered in the associated Behat test.

How to choose which modules to test: Modules can be randomly selected from the list of impacted systems, or one of the oldest modules in an impacted system. Older modules that have not received recent or regular updates are more likely to have regression issues caused by a minor change.

The oldest modules (contrib modules) with dependencies from the above list should also be updated. However, to improve productivity, initiate these updates only if there is a security issue or a module has stopped working because the subsystems are being updated within an upcoming release. If a module update creates more issues than the older version of said module, it is better to keep the old module and fix the associated regression bug.

Tip: A new module version usually contains a bug fix, so adding a patch from Drupal.org to the YMCA Website Services distribution’s composer.json is preferred to releasing the distribution. Remember to create a follow-up task for updating the module after the release.

After creating a list of modules that could introduce regression issues, following the Quick-start section of the modules’ README files (usually shipped with modules) is highly recommended.

Example for the location_finder.

If a module has no Quick-start or Acceptance testing section in its README, testing at least one place where the module’s functionality should be working is essential. Adding these manual test steps as a follow-up task ( new issue) or creating a Pull Request with changes to the README in the YMCA Website Services repository is highly recommended. For performance, adding step-by-step how-to instructions to the respective modules’ README.md file is highly recommended. Writing a couple of lines of documentation takes only a few minutes and will greatly help others with future contributions and changes.

Optionally, adding a Drupal tour for the how-to instructions created in the README will benefit future YMCA Website Services users and developers. Having a tour for the business functionality is highly recommended to ship with the component, creating in-site visual guided documentation and helping to decrease the time for Acceptance testing.

Lastly, adding Behat tests to the system will ensure functionality is tested on every pull request and every CI build in the future.

Rule

Every release of YMCA Website Services since 8.1.9 should include a list of subsystems changed in the release for the community to be aware of possible regressions on their end.

4 - Anti-spam Protection

To protect YMCA Website Services customers, anti-spam protection based on CAPTCHA and Google reCAPTCHA is included in the YMCA Website Services core. This solution leverages the CAPTCHA and reCAPTCHA Drupal modules.

Understanding CAPTCHA and reCAPTCHA

  • CAPTCHA: A challenge-response test used to determine whether the user is human. It blocks form submissions by spambots, which are automated scripts that post spam content. The CAPTCHA module provides this feature to virtually any user-facing web form.
  • reCAPTCHA: A free service from Google that protects your website from spam and abuse while letting real people pass through with ease. It uses an advanced risk analysis engine and adaptive CAPTCHAs to keep automated software from engaging in abusive activities on your site.

Configuration

  1. Install and Enable Modules: Install both the CAPTCHA module and the reCAPTCHA module. Enable them in the Extend administration page (/admin/modules).
  2. reCAPTCHA Settings: Configure reCAPTCHA settings at /admin/config/people/captcha/recaptcha. You’ll need a Site key and a Secret key.
  3. Get API Keys: Register your website at the reCAPTCHA Admin console to obtain your Site key and Secret key.
  4. Enter API Keys: Input the Site key and Secret key into the reCAPTCHA settings form.
  5. CAPTCHA Settings: Configure where you want the CAPTCHA/reCAPTCHA to appear on your site at /admin/config/people/captcha.

Additional Spam Protection

In most cases, the above configuration protects you from most spam. However, human-entered spam may require additional protection.

  • Blacklist Logic: Implement blacklist logic to block email domains frequently used in spam messages.
  • Protected Submissions Module: Consider using the Protected Submissions module to harden all submissions on a site with a list of stop words and per-language settings.

Virtual Y Use Case

For Virtual Y, the simple_recaptcha module is used to address caching issues and may be suitable in similar cases. The standard CAPTCHA + reCAPTCHA module combination has sometimes presented reliability issues. Replacing those modules with “Simple reCAPTCHA” may resolve those issues.

5 - Code of Conduct and Best Practices

The YMCA Website Services community aims to build from the methods and best practices of other open-source projects, such as the Drupal community and the Drupal Ukrainian community.

Bylaws

For the OpenY distribution, we have a Terms of Use and Participant Agreement.

Development

To understand how we use and develop technologies, refer to the documents below:

JavaScript Code Standards

6 - Code Review Quality Best Practices

This document supplements our Code of Conduct and Best Practices. It provides technical and in-depth guidelines for specific cases discussed during code quality reviews by the YMCA Website Services team. All code should be reviewed by 1-2 developers before being merged into the YMCA Website Services codebase.

General Rules

Components in YMCA Website Services (modules, themes, or other code structures) should be reusable and atomic whenever possible. Bundle all features, content types, settings, and styles to create cohesive components.

  1. General naming conventions
    1. Features module naming
      1. openy_${entity_type|abbr}_${entity_bundle|abbr}_${feature|optional}
        1. Example: openy_node_blog_feature
        2. openy_prgf_sc_feature -> OpenY Paragraph Simple Content (name within yml)
    2. Fields naming (<=20 chars)
      1. field_${entity_type|abbr}_${entity_bundle|abbr}_{name|abbr}
        1. Example: field_prgf_sc_body
    3. All descriptions are mandatory!
  2. Module naming conventions - Choose the name from this list, depending on the context:
    1. ${project_name|abbr}_${business_name|abbr} - when the code looks like legacy and has specifics that are not ready to be open-sourced.
    2. openy_${business_name|abbr} - when the code is ready to be extracted to an OpenY package.
    3. ${business_name} - when the code is so abstract that it has no connection to OpenY and is ready to be hosted on Drupal.org as an independent project.

Code Sharing

To support community reuse, the MODULE-NAME should relate to the module’s business logic. Avoid creating modules by abstracting them out of the business context. Modules shared to Drupal.org from past projects were shareable because they represented a feature tied to a business need. For example:

  • personify - module for SOAP related methods for working with Personify API
  • acrypt - Asymmetric crypt algorithm

and so on.

PHP

Return Early Pattern

To improve readability in functions and methods, return early if simple conditions can be checked at the beginning of a method:

<?php

function foo($bar, $baz)
{
    if ($foo) {
        // logic goes here
        return $calculated_value;
    } else {
        return null;
    }
}
?>

Returning early reduces indentation and cognitive load.

<?php

function foo($bar, $baz)
{
    if (!$foo) {
        return null;
    }

    // logic goes here
    return $calculated_value;
}
?>

Define Early Pattern

When a condition aims to change a variable’s value without additional logic, define the variable early and change it based on conditions, avoiding if else elseif structures.

Before:

<?php
if ($a == 'hello') {
 $text = 'Welcome to site';
}
else {
 $text = 'Register please';
}
?>

After:

<?php
$text = 'Register please';
if ($a == 'hello') {
 $text = 'Welcome to site';
}
?>

Null Checks with isset()

isset() verifies if a variable is set and not null. Additional verification against NULL is unnecessary.

Before:

<?php
...
'video' => (isset($feed['profile_media_videos']) || $feed['profile_media_videos'] != NULL) ? $feed['profile_media_videos'] : '',
...
?>

After:

<?php
...
'video' => (isset($feed['profile_media_videos'])) ? $feed['profile_media_videos'] : '',
...
?>

Dependency Injection

Use dependency injection instead of calling methods from services statically for decoupled and easier-to-upgrade code in Drupal 8+.

See the Drupal API Overview of the Dependency Injection Container and Services.

Before:

<?php
...
$node = Drupal::entityTypeManager()->getStorage('node')->load($result->getField('nid')->getValues()[0]);
...
?>

After:

<?php
...

$node = $this->entityTypeManager->getStorage('node')->load($result->getField('nid')->getValues()[0]);
...
?>

Creating Meaningful Log Messages

Write meaningful log messages with proper context to provide useful logging for site managers.

Before:

<?php
...
        if($type == 'program') {

          if ($feed['profile_media_videos'] != NULL || $feed['profile_media_images'] != NULL) {
          \Drupal::logger('272')->notice($type);
...
?>

After:

<?php
...
        if($type == 'program') {

          if ($feed['profile_media_videos'] != NULL || $feed['profile_media_images'] != NULL) {
          \Drupal::logger('form_import')->notice("FORM IMPORT: type is $type");
...
?>

Maintaining an Upgrade Path

Add all configuration changes to appropriate hook_update_N functions to update existing environments. We suggest using the Config Importer and Tools package for working with hook_update_N.

Install Files

openy.install in Profile

Place updates related to the distribution in general and not specific to any feature in this file.

  • Enable/Disable module
  • General configs

openy_*.install in Modules

If you update a configuration for a specific feature, put the updates in the appropriate module’s install file.

Config Management

Revert Only Specific Property from Config

This is the preferred method for updating configurations, resulting in fewer conflicts when upgrading customized YMCA Website Services instances.

You can update only part of the full config with the Config Importer module.

Use the openy_upgrade_tool.param_updater service to update a specific property in config:

  1. Find the module where your config lives.
  2. Create a new hook_update_N in the openy_*.install file.
  3. Add the update code to that hook (for example):
<?php
$config = drupal_get_path('module', 'openy_media_image') . '/config/install/views.view.images_library.yml';
$config_importer = \Drupal::service('openy_upgrade_tool.param_updater');
$config_importer->update($config, 'views.view.images_library', 'display.default.display_options.pager');
?>

Where:

  • $config variable contains the path to the config file.
  • views.view.images_library - config name
  • display.default.display_options.pager - config specific property (you can set value from a nested array with variable depth)

Revert Full Configs

This method involves extensive config file manipulation and increases upgrade time.

Use the openy_upgrade_tool.importer service to update a full config or several configs from a directory:

<?php
$config_dir = drupal_get_path('module', 'openy_media_image') . '/config/install';
$config_importer = \Drupal::service('openy_upgrade_tool.importer');
$config_importer->setDirectory($config_dir);
$config_importer->importConfigs(['views.view.images_library']);
?>

Where:

  • $config_dir - path to directory with config files
  • views.view.images_library - config name

You can also update several configs from a directory:

<?php
$config_importer->importConfigs([
  'views.view.images_library',
  'views.view.example_view',
]);
?>

JavaScript Includes

JavaScript Includes Example

7 - Colorways

What goes into making the selectable colorways in Layout Builder.

CSS Variables

Base Variables

We start by defining a base set of colors based on the “Y Color Wheel and Neighbored Color Zones” from the “Websites & Platforms Style Guide”, available in the YMCA Brand Resource Center. These colors are used to create the color palettes available in the Layout Builder.

A color wheel with labels corresponding to the official YMCA colors.

Note: RGB variable values are not complete color definitions and must be wrapped in rgb{a}(), like background-color: rgb(var(--ylb-color-rgb-red-dark), 0.5);. This allows you to control the opacity of the color.

:root {
    --ylb-color-red-dark: #a92b31;
    --ylb-color-rgb-red-dark: 169, 43, 49;
    --ylb-color-red: #ed1c24;
    --ylb-color-rgb-red: 237, 28, 36;
    --ylb-color-red-light: #f15922;
    --ylb-color-rgb-red-light: 241, 89, 34;
    --ylb-color-orange-dark: #dd5828;
    --ylb-color-rgb-orange-dark: 221, 88, 40;
    --ylb-color-orange: #f47920;
    --ylb-color-rgb-orange: 244, 121, 32;
    --ylb-color-orange-light: #fcaf17;
    --ylb-color-rgb-orange-light: 252, 175, 23;
    --ylb-color-green-dark: #006b6b;
    --ylb-color-rgb-green-dark: 0, 107, 107;
    --ylb-color-green: #01a490;
    --ylb-color-rgb-green: 1, 164, 144;
    --ylb-color-green-light: #20bdbe;
    --ylb-color-rgb-green-light: 32, 189, 190;
    --ylb-color-blue-dark: #0060af;
    --ylb-color-rgb-blue-dark: 0, 96, 175;
    --ylb-color-blue: #0089d0;
    --ylb-color-rgb-blue: 0, 137, 208;
    --ylb-color-blue-light: #00aeef;
    --ylb-color-rgb-blue-light: 0, 174, 239;
    --ylb-color-purple-dark: #5c2e91;
    --ylb-color-rgb-purple-dark: 92, 46, 145;
    --ylb-color-purple: #92278f;
    --ylb-color-rgb-purple: 146, 39, 143;
    --ylb-color-purple-light: #c6168d;
    --ylb-color-rgb-purple-light: 198, 22, 141;
    --ylb-color-white: #FFFFFF;
    --ylb-color-rgb-white: 255, 255, 255;
    --ylb-color-light-grey-1: #f2f2f2;
    --ylb-color-rgb-light-grey-1: 242, 242, 242;
    --ylb-color-light-grey-2: #e7e7e7;
    --ylb-color-rgb-light-grey-2: 231, 231, 231;
    --ylb-color-light-grey-3: #cccccc;
    --ylb-color-rgb-light-grey-3: 204, 204, 204;
    --ylb-color-grey-1: #636466;
    --ylb-color-rgb-grey-1: 99, 100, 102;
    --ylb-color-grey-2: #4F4F4F;
    --ylb-color-rgb-grey-2: 79, 79, 79;
    --ylb-color-grey-3: #3F4042;
    --ylb-color-rgb-grey-3: 63, 64, 66;
    --ylb-color-dark-grey-1: #2F2F2F;
    --ylb-color-rgb-dark-grey-1: 47, 47, 47;
    --ylb-color-dark-grey-2: #231F20;
    --ylb-color-rgb-dark-grey-2: 35, 31, 32;
    --ylb-color-black: #000000;
    --ylb-color-rgb-black: 0, 0, 0;
}

Colorway Variables

Each colorway is built upon four core colors derived from the base color palette:

  • PrimaryColor: The main color for the colorway.
  • SecondaryColor: A complementary color to the primary.
  • TertiaryColor: Another complementary color, providing additional visual interest.
  • PartnerColor: A contrasting color, often used for buttons and calls to action.

These four colors are used to style the majority of page elements. Each variable is prefixed with ws to denote “Website Services”. RGB versions of these colors are also provided for use with rgba() styles.

In addition to the main colors, five more variables are used to define the YMCA logo gradients:

  • LogoChevronDark
  • LogoChevronMid
  • LogoChevronLight
  • LogoTriangleDark
  • LogoTriangleLight

Important: These Logo variables should only be used for styling the YMCA logo. They are not intended for use in other page components. The Canadian Y logo does not change colors, and therefore these extra colors are not needed for Canadian colorways.

Here’s a complete list of the colorway variables:

--wsPrimaryColor
--wsPrimaryColorRGB
--wsSecondaryColor
--wsSecondaryColorRGB
--wsTertiaryColor
--wsTertiaryColorRGB
--wsPartnerColor
--wsPartnerColorRGB
--wsLogoChevronDark
--wsLogoChevronMid
--wsLogoChevronLight
--wsLogoTriangleDark
--wsLogoTriangleLight

These variables are typically defined by referencing the base color variables. Here’s an example of a complete colorway definition:

:root {
  --wsPrimaryColor: var(--ylb-color-blue-dark);
  --wsPrimaryColorRGB: var(--ylb-color-rgb-blue-dark);
  --wsSecondaryColor: var(--ylb-color-blue);
  --wsSecondaryColorRGB: var(--ylb-color-rgb-blue);
  --wsTertiaryColor: var(--ylb-color-blue-light);
  --wsTertiaryColorRGB: var(--ylb-color-rgb-blue-light);
  --wsPartnerColor: var(--ylb-color-purple-dark);
  --wsPartnerColorRGB: var(--ylb-color-rgb-purple-dark);
  --wsLogoChevronDark: var(--ylb-color-blue-dark);
  --wsLogoChevronMid: var(--ylb-color-blue);
  --wsLogoChevronLight: var(--ylb-color-blue-light);
  --wsLogoTriangleDark: var(--ylb-color-purple-dark);
  --wsLogoTriangleLight: var(--ylb-color-purple-light);
}

Logo Colors

To ensure consistency and minimize code duplication, the YMCA logo is divided into six distinct sections, each styled individually:

  • the
  • chevron
  • ymca
  • triangle
  • registeredtm
  • areas-of-impact

The chevron and triangle sections use radialGradient elements, taking advantage of the wsLogo variables mentioned above. The other sections are styled using the standard colorway variables. Each section is a path element with a unique id and a color defined using the fill property.

The YMCA logo with labels corresponding to the colors used in each component as described in text below.

  • #logo-the uses --wsSecondaryColor
  • #logo-chevron uses a gradient composed of (from top to bottom) --wsLogoChevronLight, --wsLogoChevronMid, and --wsLogoChevronDark
  • #logo-ymca uses --wsPartnerColor
  • #logo-triangle uses a gradient composed of (from left to right) --wsLogoTriangleLight and --wsLogoTriangleDark
  • #logo-registeredtm uses --wsPartnerColor
  • #logo-areas-of-interest uses --wsSecondaryColor

Y Styles

Each “Y Styles” option activates a specific CSS library, as defined in y_lb.ws_style_option.yml. These libraries can be overridden by a custom theme, allowing for further customization (see the Drupal documentation on Overriding Theme Functions for details).

8 - Composer

It’s crucial to keep your composer.lock file synchronized with your composer.json file. Here’s how:

  • After any changes to composer.json: Ensure you update the composer.lock file.

  • Update a specific package: Use the composer update command, which automatically updates the composer.lock file.

    composer update drupal/metatag
    
  • Force update the composer.lock file: Use composer update --lock to regenerate the composer.lock file based on the dependencies defined in composer.json. This is useful if you suspect the lock file is out of sync.

    composer update --lock
    

For comprehensive information, refer to the official Composer documentation:

https://getcomposer.org/doc/01-basic-usage.md

9 - Composer Version Constraints for YMCA Website Services

In 2020, due to changes in Drupal core release management and demand from YMCA Website Services customers to improve upgrade path flexibility and stability, the YMCA Website Services team added extended composer version constraints to our composer.json. This allows for greater flexibility and stability when upgrading the YMCA Website Services platform.

Examples from composer.json:

  • "drupal/ckeditor_bootstrap_buttons": "^1.2 || ^2.0.0", - This line means the project is compatible with version 1.2 and any subsequent 1.x versions starting from 1.2. It also indicates that version 2.0.0 has been tested and that any stable 2.x versions starting from 2.0.0 are allowed.
  • "drupal/custom_formatters": "^3.0 || ^3.0@beta", - This indicates testing with the 3.0 beta of custom_formatters and allows any 3.x version starting from 3.0 once it is released as stable.

By having multiple OR (||) conditions, we provide developers with information on which versions can be used for upgrades. In some cases, the latest stable version of a dependency might be incompatible with other functionalities. Using older versions is a valid strategy while other functionalities are being upgraded to be compatible.

For example, if custom_formatters version 3.0 is incompatible with any YMCA Website Services dependencies at the time of its release, a developer can select an older beta version to proceed with the upgrade.

To select a specific version of a dependency during an upgrade of YMCA Website Services, add the dependency and its version alongside YMCA Website Services in the composer require step.

For example, from the upgrade documentation:

composer require YCloudYUSA/yusaopeny:NEW_VERSION_HERE --no-update
composer update --prefer-dist --with-dependencies --prefer-stable --no-suggest

To change a dependency version:

composer require YCloudYUSA/yusaopeny:NEW_VERSION_HERE --no-update
composer require drupal/custom_formatters:3.0@beta1

You can change any dependency version without upgrading YMCA Website Services by running the composer require command for specific dependencies and then running the Drupal Update DB routines.

Check the official Composer documentation about version constraints and updating Drupal modules with Composer.

It’s important to note that many YMCA Website Services modules and themes specify core version requirements in their .info.yml files. These constraints define the compatible Drupal core versions for each component.

For Example:

core_version_requirement: ^10 || ^11

This example indicates that the module is compatible with Drupal 10 and 11. When managing dependencies with composer, you must ensure that the version constraints defined in the .info.yml files are respected.

10 - Contributing

The YMCA Website Services distribution is open source, and we welcome contributions from the YMCA Movement, the Drupal community, and beyond. Be sure to check our Community Resources for how to get in touch and our Roadmap to see if your request is already in progress.

Issues

If you have a support request, you’ve found a bug, or you have a feature request, you can start in our primary repository, YCloudYUSA/yusaopeny:

If you are able to pinpoint the issue to a specific piece of functionality, you can open an issue on the appropriate module.

When submitting issues, please refer to the CONTRIBUTION.md file in the Blazy module for guidelines on submitting issues and bug reports.

Pull Requests

We use the GitHub “Fork and pull model” for community contributions. If you have some time to make a contribution to the project, here are the steps that will help you:

  • Create a fork of YCloudYUSA/yusaopeny.
  • Commit & push changes into your fork.
  • Create new Pull Request.
  • Write steps for review. In this way maintainers can go through steps on build to verify your fix/feature.
    • Ensure steps for review added to README.md file in a module’s/project’s directory if it makes sense to check them on regular basis. Often this is needed for crucial parts of the system which is main business functionality of the component. Example of super simple steps for review see in Quickstart section of location_finder module, please.
  • Wait for a CI build and ask maintainers for review.

Important: make sure your git email is associated with account on drupal.org, otherwise you won’t get commits there.

When submitting patches, please refer to the CONTRIBUTION.md file in the Blazy module for guidelines on submitting patches.

Merge Requests

Modules on Drupal.org follow their Merge Request process. The Drupal Wiki has in-depth documentation on these processes:

Drupal.org credits

If you would like to get drupal.org credits for your contribution:

  • Create issue on drupal.org
  • Link drupal.org issue to GitHub Pull Request
  • Specify in GitHub Pull Request link to drupal.org issue
  • Once PR has been merged, reviewer will close drupal.org issue with appropriate credits.

11 - Create & Use New View Modes

As with any other entity in Drupal, when rendering it in different contexts, you might want to have specific view modes.

Here you can find instructions on how to add new view modes into the embedded entity form on the YMCA Website Services distribution.

Create a New View Mode

  1. Go to the ‘View modes’ page: Structure > Display modes > View modes (or visit the URL: /admin/structure/display-modes/view).

    View Modes in Menu

    View Mode Types

  2. Create a new view mode: click the ‘Add view mode’ button and select an entity type (or visit the URL: /admin/structure/display-modes/view/add).

    Add View Mode - First Way

    Alternatively, after each entity type, you can see ‘Add new {Name} view mode’ and click on it.

    Add View Mode - Second Way

  3. Select “Media” and then give a name to your new view mode (or visit the URL: /admin/structure/display-modes/view/add/media).

    Creating View Mode

Use the View Mode

  1. Go to Configuration > Text editor embed buttons (or visit the URL: /admin/config/content/embed).

    Using View Mode

    View Mode Using List

  2. Ensure you enable the new view mode in “Allowed Entity Embed Display plugins” and click “Save” at the bottom of the page.

    Enable View Mode

12 - Daxko

Relates to: Program Registration (Daxko)

Configuration setting at /admin/config/development/daxko

Account configuration must be set up before the Program Registration paragraph will work.

GroupEx Pro

There are three methods of integrating GroupEx Pro with your YMCA Website Services site, ordered from most to least complex/customizable:

  • API integration
  • Embedded schedules
  • Responsive schedule link

GroupEx PRO APIs

YMCA Digital Services, with the help of YMCA of the North, has developed and adopted a Syncer for Repeat Application, which helps migrate from the GroupEx PRO Public API to the Daxko Group API v1 and pulls data from GroupEx PRO to the Program Event Framework.

See open-y-subprojects/openy_daxko_gxp_syncer for how to configure the Syncer.

Embedded schedules

This replaces the deprecated Embedded GroupEx Pro Schedule Paragraph.

Embed code for GroupEx Pro schedules can be found in your GroupEx Pro admin interface.

  1. Look for the “New embed” toggle.

    Screenshot showing “New Schedule” and other options in the GroupEx Pro admin.

  2. Expand the options and choose any filters or colors that you prefer.

  3. Disable the “Fixed Header” option.

    Screenshot showing “Schedule Hosting LInk / Embedded Code for New Schdule” from Daxko

  4. Copy the resulting code. It will look similar to the following, substituting 000 for your own account number and adding any location or category filters as needed:

```
  1. Navigate to your YMCA website.

  2. Follow the directions to add a Code Paragraph or a Code Block.

  3. Paste the embed code into your block.

  4. Save the paragraph/block and the page.

If the pasted code does not appear on the page, ensure your site is updated with this change to enable direct copy/pasting of embed codes.

While the incoming code is controlled by Daxko/GroupEx Pro, many changes can be made with CSS. Try the CSS Editor module (≥2.0.1), which is bundled with the distribution, or work with your development partner to make customizations.

GroupEx Pro also provides direct links to the schedule page. These can be found in the “New Embed” section. Simply copy the link and add it to any link field or button on your site.

13 - Decoupled (external) projects

Inventory of external modules available via Composer

Check all GitHub for the tag openy-decoupled to discover more decoupled projects.

GitHub Hosted

  1. YCloudYUSA/yusaopeny_block_modal - Implements a simple block with a body and title that will be used to display modal windows.
  2. YCloudYUSA/yusaopeny_memberships - Membership Framework for OpenY and Drupal.
  3. YCloudYUSA/yusaopeny_prgf_sidebar_menu - SideBar menu for referencing menu blocks and using in SideBars across different pages.
  4. YCloudYUSA/yusaopeny_activity_finder - Activity Finder app
  5. YCloudYUSA/yusaopeny_loc_finder - Extended Location Finder. Note: The repository name (yusaopeny_loc_filter) does not match the link text (yusaopeny_loc_finder). Please verify that this is the correct repository.
  6. Open-Y-subprojects/reqclique_gxp_sync - Reqclique Group Exercise Sync
  7. open-y-subprojects/virtual_y_signaling_server - Signalling server for Virtual Y
  8. open-y-subprojects/openy_daxko_gxp_syncer - Daxko GroupEx PRO v1 API Syncer into Program Event Framework
  9. open-y-subprojects/ynorth_gxp_spots_proxy - Availability Spots Cache Proxy for Groupex PRO embed API Syncer into PEF
  10. open-y-subprojects/openy_node_alert - Alerts APP for YMCA Website Services
  11. open-y-subprojects/openy_focal_point - YMCA Website Services Focal Point routines
  12. open-y-subprojects/shared_content_server - Shared Content Server
  13. ynorth-projects/openy_node_session - YMCA Website Services Node Session
  14. ynorth-projects/openy_repeat - Repeat API for PEF. Schedules APP built in Vue.js
  15. ynorth-projects/openy_pef_gxp_sync - Groupex Pro Embed/OpenY Syncer into PEF
  16. ymcatwincities/ymca_sync - Syncer backend core
  17. ymcatwincities/media_entity_document - Media Entity Document
  18. ynorth-projects/openy_prgf_session_table - if you need to present couple of Sessions in a table view without using any complex app like Schedules or Activity Finder

Drupal.org Hosted

  1. drupal/upgrade_tool - YMCA Website Services Upgrade Tool
  2. drupal/paragraph_skins - Skins component from OpenY. Decoupled from ymcatwincities/paragraph_skins.
  3. drupal/openy_autocomplete_path - YMCA Website Services Autocomplete Path. Works in Drupal 8 only. Removed from 9.* YMCA Website Services releases.

Decoupling Mind-Map

YMCA Website Services decoupling

14 - Decoupling components as independent modules

History

In 2019, the YMCA Website Services team started decoupling major components to streamline distribution and simplify support. This involved separating components into independent modules, making them easier to manage and update.

Communication started in the Community Board - Ejecting modules from OpenY distro as independent projects.

The decoupling process is ongoing. See the index of decoupled projects.

In 2021, the YMCA Website Services core team faced coupling blockers in the distribution during the upgrade from Drupal 8 to Drupal 9.

To formalize the ongoing development and maintenance strategy, the YMCA Website Services core team shared its decoupling plan with the wider community in mid-2021.

This document elaborates on those processes and provides guidelines for decoupling components.

Policy

  • Every new component or sub-project of YMCA Website Services should be developed in its own repository - either on GitHub or Drupal.org.
  • The decoupled project could be:
  • GitHub should be used when there is no strategy to make a component or project available for the wider Drupal community; that is, when it is tied to YMCA business and unlikely to be leveraged by somebody else.
  • Drupal.org should be used when the component could be useful to projects outside of YMCA Website Services. This allows for broader community contribution and usage.

Process

Creating a new decoupled component

  1. Create a new GitHub/Drupal.org repository.
  2. Work on getting an initial release with at least beta version stability. This ensures the component is reasonably tested and ready for use.
  3. Create a composer.json file for the component to be able to start using it via composer. See Virtual Y for an example. The composer.json file defines the dependencies and other metadata for the component.
  4. Make it available for the public via packagist.org or Drupal.org as a release. Ensure podarok is added as a co-maintainer to the respective system. This allows others to easily find and use the component.
  5. Suggest adding to YMCA Website Services by opening an issue. This initiates the process of including the component in the main distribution.
  6. If approved, create a Pull Request adding it as a dependency in composer.json.
  7. Ensure this component is enabled in any of the packages maintained in the YMCA Website Services profile installation. This makes the component active by default in new installations.
  8. Ask for review and release, according to the release plan. This ensures the component is properly integrated and released to the community.

Decoupling an existing component of YMCA Website Services

Follow the steps above, but with these additional considerations:

  • After creating the repo, filter the selected component by running git filter-branch --subdirectory-filter ... from the latest development branch of the YMCA Website Services profile. This keeps credits of work done for this component as a part of the Code of Conduct.
  • After separating the code, ensure the ejected code is not duplicated in the YMCA Website Services profile. Remove duplicated code in the same Pull Request in which you add the new dependency. This avoids redundancy and potential conflicts.

Examples

Updating a module on Drupal.org

  • Use git filter-branch to get a history of changes.
  • Change the git origin to the Drupal.org project.
  • Create a new branch and push the code to Drupal.org.
  • Create and push a tag to Drupal.org. Create a release on Drupal.org.
  • Update composer.json in this distribution with a new tag.

Decoupling a module from YN to Drupal.org

Example: paragraph_skins

git clone git@github.com:YCloudYUSA/yusaopeny.git decouple
rm -rf decouple_copy && cp -a decouple decouple_copy
cd decouple_copy
git filter-branch --subdirectory-filter docroot/modules/contrib/paragraph_skins
git clean -dfx
git remote remove origin && git remote add origin git@git.drupal.org:project/paragraph_skins.git
git pull origin 8.x-1.x --allow-unrelated-histories
# Resolve conflicts if applicable.
git push origin production:8.x-1.x
# Create tags and release on Drupal.org

Decoupling a module from YMCA Website Services to YMCA Website Services Subprojects

Request a repository for the module. Example: shared_content_server

git clone git@github.com:YCloudYUSA/yusaopeny.git decouple
rm -rf decouple_copy && cp -a decouple decouple_copy
cd decouple_copy
git filter-branch --subdirectory-filter docroot/profiles/contrib/openy/modules/custom/SOME_MODULE_HERE
git clean -dfx
git remote remove origin && git remote add origin git@github.com:Open-Y-subprojects/SOME_MODULE_HERE.git
git push origin production
# Create composer.json on the decoupled repository. Example: https://github.com/YCloudYUSA/yusaopeny_activity_finder/blob/4.x/composer.json
git clone git@github.com:ynorth-projects/distribution.git yn-distribution
# Update composer json for distrubution. See below

Example for Activity Finder

References

15 - Dependencies in Drupal info.yml

In order to generate composer.json files for Drupal projects, Drupal.org uses specific rules defined in a module’s info.yml file. These dependencies are used to manage the module’s external libraries and Drupal core module requirements.

Declaring Dependencies

If your module depends on another Drupal module, you should declare it in your module’s info.yml file using the following format:

dependencies:
  - drupal:webform

This tells the packager to include drupal/webform as a Composer dependency for your module. The Drupal.org packaging system resolves drupal:webform to the correct package name and version.

You can find the correct Drupal.org project shortname to use for dependency declarations on the project page near the bottom. For example, the Webform project is webform. The corresponding composer package name is drupal/webform.

Incorrect Dependency Declaration

If you were to specify a dependency like this:

dependencies:
  - whatevernameyouwish:webform

The Drupal.org packaging routine will automatically correct it to drupal:webform during the packaging process.

Soft Dependencies (Drupal Core Only)

There may be situations where you want to express a dependency for Drupal core to manage during module installation and enabling, but not require Composer to manage it. This is sometimes referred to as a “soft dependency”. In such cases, you can use the simplified format:

dependencies:
  - webform

In this scenario:

  • Composer will not include any dependency.
  • Drupal core will require that the webform module be present in the codebase before your module can be enabled. Drupal will check for the existence of the module when resolving dependencies during module installation.

This approach is useful when a module’s functionality degrades gracefully if another module is not present, but is enhanced if it is.

16 - Deprecating and removing components

Occasionally, old code is deprecated from the YMCA Website Services codebase. To minimize disruption to existing sites, we use the following process:

  1. Decide: Before removing components from the distribution, we gather feedback from the community to protect active projects from having components accidentally removed. We accomplish this via messaging in the YMCA Website Services Slack channel and discussion on monthly calls.
  2. Deprecate: Once a decision is made, we notify users that the feature will be removed soon. The deprecated component is moved from the YMCA Website Services package group to the YMCA Website Services (Deprecated) package group. For example, see Deprecate Daxko Program Registration Paragraph. Deprecation notices are posted in point and quarterly releases of YMCA Website Services.
  3. Uninstall: Before removing code, components should be uninstalled via an update hook in the distribution, and any hard dependencies should be removed. Uninstalls must occur at least one point (fix) release after the deprecation notice.
  4. Remove: Complete removal of the component from the codebase or composer.json should happen at least one quarterly (feature) release after the deprecation notice.

Additionally, the following housekeeping steps should be taken when deprecating a component:

  1. Add the release where the deprecated component has been uninstalled to the important versions document in the Wiki.
  2. Decouple the code to external GitHub repositories with all history of commits, marked as openy-decoupled, and archive the repository.

UX/CX for deprecated components

To deliver a high-quality upgrade path and keep the distribution on the leading edge of technologies, we occasionally replace old and aged components with new ones for a better User Experience (UX) and Content Experience (CX).

To achieve deprecations, we have a policy that aims to provide a comfortable migration path for all components of the distribution.

  1. When we create a component that will replace an old one, we must introduce a period of overlap when both components are available in the system for some time (typically 6-18 months). This allows users time and resources to migrate from the old component to the new one before it is removed from the distribution. See the Activity Finder v3 to v4 migration.

  2. Deprecated components are moved to the deprecated modules group in the list of modules at Admin > Extend. Also, we add lifecycle and lifecycle_link to the documentation in every deprecated module to provide enough information for the community. See Deprecate openy_gxp.info.yml.

  3. All titles of deprecated components in the Content Editing interface should be renamed to add the suffix (deprecated) to help Content Managers daily avoid choosing an old component and using a new one.

    Naming Example

  4. For most content components, an automated migration path is expensive and sometimes impossible. Therefore, we have a “lazy migration” practice in our community, which puts the responsibility of migration on Content Managers and Strategists. Once new components are available in the distribution, all editors should start using them and rebuild old pages by replacing old components with new ones. After the communicated timeframe (6-18 months), old components are removed from the distribution. However, if an association needs it, the component will be available as an independent—but unsupported—project. A 3rd-party agency or developer can support it as long as needed.

  5. After the communicated timeframe (6-18 months), the Core team will remove the component from the distribution and keep it in an independent project for archival reasons. Usually, the project is marked as archived/obsolete to clarify that it is not supported and is possibly insecure.

  6. If the normal timeframe (6-18 months) is not achievable due to unforeseeable circumstances, the Core team will add proper notifications and tutorials for the community to help migrate comfortably in a shorter time. See the GroupEx Pro API deprecation notice.

17 - Development FAQ

YMCA Website Services Developer FAQ

Local Development

Getting started with a local environment

To start developing, you need to obtain the latest YMCA Website Services codebase. See the openy-project repository for the full process. This includes instructions for setting up your local environment and configuring your development tools.

This video tutorial will walk you through how to initiate a local development environment.

The YMCA Website Services team has pre-built environments and walkthroughs using either Vagrant and VirtualBox or Docker and Docksal. Choose the method that you’re most comfortable with and get started!

Gathering information about your local environment

To best troubleshoot issues, it’s helpful for the YMCA Website Services team to have as much information about your environment as possible. Before you ask for help, watch this tutorial on how to gather that information. This video explains how to collect relevant details about your setup, such as operating system, software versions, and configuration settings.

Debugging with Xdebug in your local

The Docksal project maintains detailed information for using Xdebug with VSCode, PHPStorm, and more. This documentation covers installation, configuration, and usage of Xdebug with popular IDEs for efficient debugging of your code.

Contributing

Who should I specify for review?

We have a best practice to get at least 2 independent reviews before merging code. Please request a review from the YMCA Website Services Lead Technical Architect (Andrii Podanenko, @podarok) and somebody else (from your team or another YMCA Website Services partner).

Who is responsible for merging?

The YMCA Website Services Lead Technical Architect (Andrii Podanenko, @podarok) is responsible for final approval, merging, and release management on the YMCA Website Services project.

What labels in PRs should I use?

[Link to Labels documentation]

What milestone should I specify?

[Link to Milestones documentation]

Why I can’t add labels or specify milestones?

All of these require you to be granted Contributor access to the YMCA Website Services GitHub repository. Contact the YMCA Website Services Lead Technical Architect (Andrii Podanenko, @podarok) to get access. Labels are usually set by the YMCA Website Services Core Team.

Why are the steps for review in Pull Requests so important?

When you send your code for review our team must know both how to review the code and what to test to verify the functionality. You are the only source of truth for how to check functionality. Adding steps for review will help the reviewer and QA team to verify that the issue is resolved.

Why should I add a reference to the GitHub issue in my PR description?

As we are a community-led project, there may be a long time between creating an issue and resolving it in a Pull Request. The reviewer should be able to understand the context and possible discussion around the issue to be resolved with your PR. The more context we have, the better and faster we can review the request.

In what format should I add commits, should I add internal Jira task ID or GitHub issue?

It is important to make commit messages with some sort of sense for the human to read them when digging back in history. Adding any task identifications from the project management system is allowed.

What is the “DeepCode” bot?

The DeepCode bot is an automated, machine learning code review system that analyzes a large number of GitHub repositories. It can be useful for finding common issues before human reviews. It is helpful, but not always necessary to fix issues found by the DeepCode bot because sometimes it flags false positives. If you see a comment, be sure to read the report. If the report makes sense, then fix the issue suggested by the bot.

Build Automation & CI

What CI processes does YMCA Website Services have in place?

To get a fully working YMCA Website Services site for the code change you are about to push for review there is a build generating system installed for the YMCA Website Services GitHub repository that automatically generates a dedicated temporary website with your changes applied.

Why are some builds created automatically and some not?

By default, builds are configured for trusted users, so if you are getting a message from the bot like

“Can one of the admins verify this patch? Use “o+k to test” or ‘’t+est this please” for manual build execution."

then your username is not in the allowlist and somebody from the YMCA Website Services Core Team can comment to initiate a build for you. Contact @podarok to get your build generated or your name added to the allowlist.

How do I create a build for my PR?

If you are on the allowlist then simply create a Pull Request from your fork to the YMCA Website Services repository. After up to 30 minutes you’ll receive comments with links to the generated site builds.

When are builds deleted from the server?

Usually, you have a day for the build to be wiped out from the server. If there is an upcoming deadline and many PRs are coming in, the lifetime could be significantly shorter, down to a couple of hours.

Who should I contact to get logs from the build server?

Andrii Podanenko @podarok or Dima Danylevskyi @danylevskyi

What should I do if tests fail?

If you have any concerns with reports generated by the code checkers that are used in YMCA Website Services ask YMCA Website Services Lead Technical Architect Andrii Podanenko to get them resolved. The majority of these systems are works-in-progress and it is helpful to have feedback on them.

How do I install YMCA Website Services on Pantheon hosting

See request from a community. The solution is described in Pantheon’s documentation on nested docroots. We suggest that you maintain your own composer.json with the specified web-root directory, as described in the Pantheon examples.

Upgrade Troubleshooting

See Upgrading to a new version of the distribution for full instructions.

Config is missing

Occasionally, configuration will get removed or otherwise go missing in the upgrade process. For instance, the list of colors could go missing in the Layout Builder styles pane.

A screenshot with missing colors.

Usually, these changes are resolved by update hooks that import new config, but on occasion, these too can fail or break. In that case, we have a few options for resolving the issue:

  1. Re-run the most recent related update hook.
  2. Import the config with drush.
  3. Import the config with the Drupal UI.

The first step in any of this troubleshooting is to try to find the offending config. In this case, searching your codebase for “text-color” might lead you to this config file in y_lb. Now, we can try a few things…

NOTE: These methods could damage your site if not tested. Please take a backup before proceeding.

Re-run an update hook

Often, searching an adjacent .install file can get you an existing update hook to import the missing configuration. In our example case, y_lb_update_9001 imports the one settings file that we’re looking for. It doesn’t matter that the hook is old, if we re-run it, it will import the file in its current state in our file system.

To re-run the update hook (via gist):

drush php-eval "\Drupal::moduleHandler()->loadInclude('y_lb', 'install'); y_lb_update_9001();"

Understanding this command:

Import config with drush

Suppose the target config exists mostly on its own, or you wish to import the entire config of a module (due to a failed install, for instance). In that case, you can use drush config:import with --partial and --source pointing to a module directory, relative to the Drupal root. In this case:

drush config-import --partial --source=modules/contrib/y_lb/config/optional/

Be aware that all configs in that directory will be imported. Targeting a single config file with drush is impossible, although you could also temporarily move the config to its own directory.

Import config with the UI

Another way to import a single configuration file is with the Drupal “Config Synchronization” admin pages. To import a single item:

  • Go to Admin > Configuration > Development > Config Synchronization > Import > Single item (admin/config/development/configuration/single/import).
  • Choose the Configuration type (if you are unsure, choose “Simple Configuration”)
  • Paste in the configuration from the file and click Import.

18 - Drupal 10 update

The update from Drupal 9 to 10 is easier than some, but still comes with some challenges.

The distribution core team has gone through these steps to ensure as smooth of a transition as possible. If your site is up-to-date and using no additional dependencies you may be able to skip right to the update, but otherwise you’ll want to review these steps.

Resources

Review Important Versions

Step through the distribution’s important versions until you reach 9.2.13.0. You should be running the latest Drupal 9.5.x before you begin the upgrade to 10.

Pre-checks

  1. CKEditor
    1. If any custom/contrib modules are used, CKE5 should likely be done AFTER your D10 upgrade
    2. Contrib checks will NOT be found in the next step, be sure to check these manually
  2. Dependency cleanup
    1. Modules not installed, but in composer.json should be cleaned up to prevent unwanted dependency issues in trying to update.
  3. Admin theme
    1. If your website uses a deprecated admin theme, you should migrate to the Claro theme and test the admin experience. If necessary you can keep the deprecated theme as a contrib package but that is not recommended and won’t be supported by the distribution.

Upgrade Report

  • Install Upgrade Status
    • fin composer show drupal/core | grep versions
    • fin composer require --dev drupal/core-dev:[copy version above] --update-with-all-dependencies
    • fin composer require drupal/upgrade_status
    • fin drush en upgrade_status
  • Run the report
    • /admin/reports/upgrade-status
  • Check if the website is using custom CKEditor plugins with CKEditor Plugin Report

Keep / Kill

  • Based from the report above, determine which modules (if any) could be removed without impacting the site
  • From the remaining, review if the module
    • Has a D10 ready version
    • Has a D10 ready Fork/Patch
    • Has been abandoned
  • Itemize based on the above with notes of efforts to continue using the modules

Custom Modules and Themes

Patches

  • Review patches in composer.json. Review any that are no longer applying or may be duplicated by the distribution.
  • Carefully review and re-roll custom patches.

Update

At this point you should be ready to update to the latest version of the distribution:

  • Edit the ycloudyusa version in your project root composer.json: "ycloudyusa/yusaopeny":"^10.3",
  • Run composer update
  • If errors occur, review the conflicts, check out the known issues, and attempt to resolve them.
  • Re-run the previous steps until they complete successfully
  • Run drush updb, review the updates, and run them.

Smoke Tests

We recommend reviewing critical functionality after the update to ensure any custom functionality still works.

Troubleshooting

Composer Issues

Composer can be … tricky. To resolve composer conflicts:

  • If specific modules conflict, try requiring them directly to get more information about the conflict.
  • Make good use of composer why and composer why-not

Update Hook Conflicts

If you run into an error like this:

> [notice] Update started: y_lb_update_9011

> [error] Configuration core.entity_view_display.node.lb_event.featured depends on the core.entity_view_mode.node.featured configuration that will not exist after import.

you may be able to resolve it yourself.

Breaking down the error message:

  • core.entity_view_mode.node.featured is missing, which is blocking y_lb_update_9011 from installing core.entity_view_display.node.lb_event.featured

  • We need to figure out where core.entity_view_mode.node.featured should be coming from, so we can search our code for that.

    • Use the “Find in files” command in your IDE to search docroot/modules, or
    • from the command line:
    ╰─ grep -rI "core.entity_view_mode.node.featured"
    ./contrib/ws_event/config/optional/core.entity_view_display.node.lb_event.featured.yml:    - core.entity_view_mode.node.featured
    ./contrib/y_lb_article/config/optional/core.entity_view_display.node.article_lb.featured.yml:    - core.entity_view_mode.node.featured
    
    • Looking at those files in the codebase, they are identical, so we could manually import them from either module. Let’s do it.
  1. Add an update hook to your own custom module like this example.

    // This goes in mymodule.install as the next update hook.
    // Increment the number accordingly.
    function mymodule_update_9000() {
        $path = \Drupal::service('extension.list.module')->getPath('ws_event') . '/config/optional';
        /** @var \Drupal\config_import\ConfigImporterService $config_importer */
        $config_importer = \Drupal::service('config_import.importer');
        $config_importer->setDirectory($path);
        $config_importer->importConfigs([
            'core.entity_view_mode.node.featured',
        ]);
    }
    
  2. Use hook_update_dependencies to ensure this new update runs before the failing one.

    // This also goes in mymodule.install.
    function mymodule_update_dependencies() {
      $dependencies['y_lb'][9011] = [
        'mymodule' => 9000,
      ];
    }
    
  3. Re-run drush updb.

  4. If you run into other missing configs, add them to the list to be imported in update hook and re-run updb.

  5. Consider backporting your customization which led to the challenge of doing this upgrade in order for it to be covered and tested by distribution developers.

19 - Drupal Core Dependencies Version Flexibility

:::caution This document is no longer actively maintained. The information it contains may be outdated. :::

To update the version of Drupal being used on your site independently of YMCA Website Services, see the official Drupal documentation: Updating Drupal Core via Composer.

Important: The openy/composer.json file may set Drupal core version constraints. Always review these constraints before updating Drupal core. These constraints define the compatible Drupal core versions for the YMCA Website Services distribution.

Working with Drupal Core Versions (Example: Drupal 9)

In the February 2021 release, YMCA Website Services tagged Drupal core versions 9.0.x and 9.1.x as allowed dependencies.

Composer, by default, installs the latest stable version that satisfies the defined constraints. Therefore, executing the following command:

composer create-project YCloudYUSA/yusaopeny-project:dev-9.2.x-development OPENY --no-interaction

will typically install YMCA Website Services with the latest stable 9.1.x Drupal core version (subject to the constraints in composer.json).

Pinning to a Specific Drupal Core Version

If you need to stay on a specific Drupal 9.0.x stable core version (e.g., for compatibility reasons), use the following commands:

composer create-project YCloudYUSA/yusaopeny-project:dev-9.2.x-development OPENY --no-interaction
cd OPENY
composer require drupal/core:~9.0.7

In this example, 9.0.7 represents the specific Drupal core version you want to use for your YMCA Website Services instance. Replace this with your desired version number.

Module Version Constraints

Refer to Composer-version-constraints-for-Open-Y for information about module version constraints within the Open Y distribution. This document provides guidance on how module versions are managed and constrained within the YMCA Website Services ecosystem.

20 - Drupal-SA-CORE-2018-004 Security Update

This document is archived but may contain useful information for troubleshooting future updates. For updated upgrade steps, visit How to upgrade YMCA Website Services.


This document provides instructions for applying the security fix described in Drupal core’s SA-CORE-2018-004 security advisory to your OpenY site.

The OpenY team suggests two options:

  • Apply a patch: Use this method for a quick resolution.
  • Upgrade Drupal core (or OpenY): This is a more comprehensive solution but may require more planning and testing.

Applying the patch is recommended to address the security issue promptly. You can then schedule a Drupal core or OpenY upgrade for a later date.

How to Apply the Patch

The following instructions are for patching OpenY releases 8.0.1 - 8.1.10, which correspond to Drupal cores 8.2.x, 8.3.x, and 8.4.x.

  1. Access your server via SSH:

    Log in to your production server environment via SSH and navigate to the docroot folder of your site codebase. If you followed a standard OpenY installation tutorial, your site is likely located in either /var/www/html or /var/www/openy.

    • If your site is located in /var/www/html:

      ssh -l root YOUR_SERVER_DOMAIN_NAME
      cd /var/www/html
      
    • If your site is located in /var/www/openy:

      ssh -l root YOUR_SERVER_DOMAIN_NAME
      cd /var/www/openy
      
  2. Download the patch:

    Download the appropriate patch file.

    wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/SA-CORE-2018-004.patch
    
  3. Back up the files to be patched:

    Before applying the patch, create backups of the files that will be modified. This allows you to revert the changes if necessary.

    sudo cp docroot/core/lib/Drupal/Core/Security/RequestSanitizer.php /var/backups/RequestSanitizer.php
    sudo cp docroot/core/modules/file/src/Element/ManagedFile.php /var/backups/ManagedFile.php
    
  4. Test the patch:

    Run the following command to test if the patch can be applied successfully:

    patch -p1 --dry-run < SA-CORE-2018-004.patch
    

    You should see the following output:

    # patch -p1 --dry-run < SA-CORE-2018-004.patch
    checking file core/lib/Drupal/Core/Security/RequestSanitizer.php
    checking file core/modules/file/src/Element/ManagedFile.php
    

    If the output is different, stop and seek assistance. A failed dry-run indicates a problem applying the patch, and applying it anyway could break your site.

  5. Apply the patch:

    If the dry run was successful, apply the patch with the following command:

    patch -p1 < SA-CORE-2018-004.patch
    

    You should see the same output as in the dry run. Your site is now patched.

    Important: Clear all caches after applying the patch. This can be done via the Drupal UI or using Drush: drush cr

  6. (Optional) Commit changes to your Git repository:

    If you are using Git for version control, add the patched files to your repository and commit the changes.

    git add docroot/core/modules/file/src/Element/ManagedFile.php docroot/core/lib/Drupal/Core/Security/RequestSanitizer.php
    git commit -m "Apply SA-CORE-2018-004 security patch"
    git push
    

Patching a DigitalOcean OpenY Installation

If you installed OpenY on a DigitalOcean server (droplet) using a tutorial, these steps provide a simplified patching method.

  1. Log in to the Drupal admin UI:

    Access your site’s admin interface by navigating to /user/login.

  2. Access the DigitalOcean console:

    Log in to the DigitalOcean cloud console at digitalocean.com and find the “Access Console” option in the dropdown menu for your OpenY droplet.

    DigitalOcean Access Console

  3. Log in to the console:

    A popup window with a black screen will appear, prompting for login credentials. Use root as the username and the password generated during droplet creation.

  4. Run the one-line script:

    Execute the following command in the console. This script automatically applies the patch:

    bash < <(curl -s https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/runSA-CORE-2018-004.sh)
    

    After the script completes, you should see the message OpenY was patched.

    Important: Clear all caches after applying the patch. This can be done via the Drupal UI or using Drush: drush cr

21 - Google Custom Search Configuration

YMCA Website Services release 8.2.4 introduces Google Custom Search (aka Google Programmable Search Engine) for the website. This feature allows you to integrate a custom search engine powered by Google, providing enhanced search capabilities for your website.

Enabling the module

Fresh installations

The search feature is automatically included in the Extended installation type. If you chose the Standard installation, refer to the Existing websites section for instructions on enabling the search feature.

During a fresh YMCA Website Services website installation via the web interface, the third-party integration step allows you to specify a Google Search ID. Providing the ID during this step configures the search feature to be up and running immediately.

Existing websites

If you are upgrading an existing YMCA Website Services website, the search feature is not automatically enabled. You must manually enable it.

To enable the search feature:

  1. Log in as an administrator (or a user with the administrator role).
  2. Navigate to the YMCA Website Services Extend page (Admin menu > YMCA Website Services > Extend > Install, or /admin/openy/extend/list).
  3. Locate the YMCA Website Services Google Search package.
  4. Tick the checkbox next to the package name.
  5. Submit the form to install the package.

After installation, the necessary modules are enabled, and a search field should appear in the website header. During installation, the module automatically creates a Landing page for search results and configures the header search form to point to this page.

Configuring the Google Search module

After enabling the module, you need to configure it with your Google Search Engine ID:

  1. Access the Google Search settings form (Admin menu > YMCA Website Services > Settings > Google Search settings, or /admin/openy/settings/google-search).
  2. Locate the Google Search ID field.
  3. Enter your Google Search ID (refer to the following section for instructions on obtaining your Search Engine ID).
  4. Submit the form to save the configuration.

Obtaining your Search Engine ID

To obtain your Google Search Engine ID:

  1. Go to https://cse.google.com/.
  2. Register for an account if you don’t already have one, and log in.
  3. Create a new Search Engine. Google provides detailed instructions on how to do this in their official documentation. The basic steps are:
    1. Click “New Search Engine”.
    2. Specify the domain of your website (e.g., www.example.com).
    3. Specify a name for the Search Engine (e.g., example.com).
    4. Click “Create”.
  4. Once the Search Engine is created, you will be redirected to its configuration page. The Search engine ID is displayed on this page. Copy this value.
  5. Paste the Search engine ID into the YMCA Website Services Google Search configuration form.

Configuring the Search Engine look and feel

To configure the look and feel of your Search Engine:

  1. Go to the Look and feel section of the Search Engine in the Google Programmable Search Engine control panel.
  2. In the Layout tab, select the Full width option and click Save.

If you do not select the Full width option, the search results may display in a popup window on your website.

Dealing with Ads

New Google Programmable Search Engines use the Free Edition (with ads) by default. As YMCAs are non-profit organizations, you can switch to the Non-profit Edition of the CSE, which allows you to disable ads.

If you are already registered as a Non-profit in Google:

  1. Go to the CSE Control Panel.
  2. Select the search engine you want to change.
  3. Click Overview then Ads.
  4. Toggle the Show Ads option to off.

The Google Custom Search Engine can also be integrated into pages using Layout Builder:

  1. Disable the old search page (if applicable):
    • Go to /search.
    • Edit the page.
    • Uncheck Generate automatic URL alias in the sidebar and delete /search.
    • Uncheck Published and Save to un-publish the page.
  2. Create a new Landing Page (Layout Builder):
    • Go to node/add/landing_page_lb.
    • Set the Title to “Search”.
    • Uncheck Generate automatic URL alias and set the alias to /search.
      • If you encounter an error using the /search alias, remove the existing one at Admin > Configuration > Search and metadata > URL aliases.
    • Check Published and Save and edit layout.
  3. Add a Small Banner to the header (optional): Use a Small Banner block to add a title, such as “Search”, to the top of the page.
  4. Add the search results code to the page:
    • In the Body section, click Add block and choose Code Block.

    • In the Code field, add the embed code from the CSE configuration. You may need to add an outer div to fit your page layout. For example:

      <div class="paragraph paragraph--type--google-search py-4">
        <script async src="https://cse.google.com/cse.js?cx=[your_search_engine_id]"></script>
        <div class="gcse-search"></div>
      </div>
      

      Replace [your_search_engine_id] with your actual Search Engine ID.

    • Save layout and check the page.

  5. Update the Google Search settings:
    • Go to Admin > YMCA Website Services > Settings > Google Search settings (/admin/openy/settings/google-search).

    • Set the Search page id to the node ID (nid) of your new “Search” Landing Page.

    • Alternatively, update the configuration using Drush:

      drush cset openy_google_search.settings search_page_id <nid>
      

      Replace <nid> with the actual node ID.

  6. Test the search box: Verify the search box in the Layout Builder page header functions correctly and displays results on the new search page.

Advanced setup

Google provides comprehensive documentation on advanced search features: Google Custom Search Developers documentation

You can configure the custom search engine to include multiple domains, which is useful if your association manages multiple websites (e.g., different websites for different camps).

You can also restrict the search to specific parts of a website by using URL patterns like example.com/blog/*. For more information, see Update sites in your search engine.

Refinements and facets

Use Refinements to narrow the scope of search

Refinements allow users to filter search results based on predefined categories.

Refinements are displayed as tabs on the search results page. You can configure the content of each tab in the “Search features > Refinement” section of the Custom Search Control Panel.

Example: Creating a “Blog” tab:

  1. In the Control panel, go to Search features > Refinements.
  2. Click Add.
    1. Set the name of the refinement to Blog.
    2. Select Search only the sites with this label for How to search sites with this label?.
    3. Click Ok.
  3. Go to Setup.
  4. Find Sites to search, click Add.
    1. Add example.org/blog/* in the text field.
    2. Select Blog in the Label dropdown.
    3. Select Include just this specific page or URL pattern I have entered.
    4. Click Save.

This configuration adds a “Blog” tab to the search results page, displaying only blog entries related to the search term.

Promotions

Use Promotions to highlight specific pages in search results

Information for developers

Google Custom Search Developers documentation

Enabling via Drush

To enable the module on existing websites, run the following Drush command:

drush en openy_google_search

Configuring the module via Drush

When installing YMCA Website Services using Drush, you can set the Search Engine ID using the following command:

drush site-install openy \
   --account-pass=password \
   --db-url="mysql://user:pass@host:3306/db" \
   --root=/var/www/docroot \
   openy_configure_profile.preset=extended \
   openy_theme_select.theme=openy_rose \
   openy_third_party_services.google_search_engine_id="01234567890123456789:abcdefgh"

The openy_third_party_services.google_search_engine_id parameter sets the Search Engine ID (01234567890123456789:abcdefgh in the example). Replace the example ID with your actual Search Engine ID.

To set the Search Engine ID on an already installed website, use the following Drush command:

drush config-set openy_google_search.settings google_engine_id "01234567890123456789:abcdefgh"

Replace 01234567890123456789:abcdefgh with your actual Search Engine ID.

22 - GroupEx PRO quick start

This document has been moved to ynorth-projects/openy_pef_gxp_sync. This repository contains the code to synchronize data between GroupEx Pro and the Open Y platform.

23 - How to Contribute Large Features (Back-porting, etc.)

These are our best practices for back-porting large features into YMCA Website Services and contributing code for others to use.

Summary

  • The YMCA Website Services core team is excited for you to contribute to the distribution for all to benefit from.
  • There’s a lot that goes into back-porting your code – details below.
  • These steps ensure that we are collaborating while continuing to support YMCA Website Services in a sustainable way.

Before getting started, please keep these notes in mind:

  • Back-porting requires a process called decoupling. This is where your developers remove any hard-coded variables or dependencies on any integration from your website code. This makes it so the feature you wish to contribute can work for anyone in the broader Y movement. For example, anything that ties into Personify APIs will have to have those hooks replaced with Program Event Framework so that it could function with any CRM source that a YMCA Website Services site might be using.
  • This decoupled code will then need to be thoroughly tested to ensure it can function when not relying on any fee-based, or non-secure, technology or systems.
  • Once the decoupling is complete, the YMCA Website Services core team will need to review every line of code before it goes into the distribution. This helps us ensure it won’t break any of the other elements of YMCA Website Services and that the code is 100% secure. As of 2019, we have 3 templates in YMCA Website Services that work across mobile, desktop, and tablet breakpoints. We need to test new features/code across all these templates to make sure nothing breaks across hundreds of possible use-case scenarios. For example, adding a schedule block to a location landing page using the Carnation template when on the mobile breakpoint that is powered by ActiveNet through Program Event Framework.
  • Once a feature is in YMCA Website Services, someone must pay to maintain that code. Does this code rely on any other Drupal modules to function? What if there’s an update to that module? That update needs to be tested to ensure it’s compatible with the now contributed code – and if it breaks, we have to write new code to fix it. What if there’s a security patch that involves the contributed code? We would then have to spend time applying the patch, etc.
  • Is your customization a new feature or a replacement of existing YMCA Website Services functionality/UX? We prefer you have A/B testing data demonstrating that your customization is a clear improvement over the current YMCA Website Services experience. There are many ways to run AB tests, so please consult with the YMCA Website Services team on your hypothesis, method, and success criteria to ensure that the results are valid and reliable.

Steps/process for back-porting code into YMCA Website Services:

Most problems have at least a generic component and can be approached in part through abstracted development.

We recommend beginning development with an eye toward these “abstracted” solutions - providing configuration instead of static templates, solving root causes instead of using local patches, using generic language instead of client specific. This will ensure that your features are easily contributed even before you begin this process.

  1. List each customization/feature you want to contribute to YMCA Website Services.

    • It’s plausible that there are portions of your code that it might not make sense to put into the distribution, either because it’s duplicative to what YMCA Website Services already has, or it might be cost-prohibitive to decouple it from your site for back-porting.
    • In the early days of YMCA Website Services, we were less stringent on this step. As long as there was no security or technical risk, we accepted any contribution into YMCA Website Services. This led to some problems, such as having two nearly identical paragraph types called Blog Post and News Post. These were contributed by two different associations. This caused significant confusion until we resolved the issue with the launch YMCA Website Services 2.0, where we deprecated some of this functionality.
    • You can start this process by taking an inventory of all your customizations that you feel would be good to backport into the distribution.
    • The deliverable of this step is a list of each independent feature you think it makes sense to contribute.
  2. Prioritize your list.

    • Rather than taking a ‘big bang’ approach of decoupling and back-porting all your features into YMCA Website Services, it is a better practice to take a bite-size approach, doing one feature at a time. This is because it can be cost and time intensive and expensive to decouple and backport your code into the distribution if you do it all at once.
    • As a guide, YMCA Website Services uses the following prioritization method: Demand for feature (1 to 3 with 1 being high), Impact/Benefit to Ys and visitors (1 to 3 with 1 being high), Effort to build/maintain (1 to 5 with 1 being extra low and 5 being extra high). The sum of these gives us a ‘score’ for each feature which helps us prioritize.
    • This will also help you decide how much, or little, of your back-porting you want to fund as you’ll be able to get a clear feature-by-feature time estimate for the work required.
    • The deliverable will be a prioritized list of the features that you want to contribute.
  3. Share your prioritized list with YMCA Website Services, and align roadmaps before spending money and time on decoupling.

    • There might be things the YMCA Website Services core team is already working on that are similar and would be finished before your decoupling would be complete, thus it would not be the best use of your funds to decouple/backport that feature.
    • There may be information the YMCA Website Services team has based on talks with other Ys that influence your demand/impact scores and thus your prioritization.
    • We might have technical knowledge that influences your effort scores as well.
    • This is when timelines will start to emerge on when your code would be available in the distribution.
  4. Decoupling.

    • Your developers and the YMCA Website Services team should align on best practices for code. At a high level, our best practices can be reviewed here: Development FAQ and How we release code.
    • When you are ready to begin the decoupling work, let us know, and we can either talk to you here, on Slack, or even set up a conference call if it would be helpful for you.
    • You would then start the technical/dev work of decoupling the features you wish to contribute back into YMCA Website Services.
    • You would test all of your decoupled code to ensure that these features work when no longer reliant on any paid or non-secure technology or partners.
    • The deliverable from this step is code that works in your own dev environment independent of any other Y association-specific code/technology.
  5. Contribute your code: Pull Requests (PRs).

    • Code gets submitted to YMCA Website Services for review via a process called a Pull Request.
    • The YMCA Website Services lead technical architect sees the code, runs it through automated test cases, and provides feedback on any issues detected that may cause problems for other portions of YMCA Website Services code.
    • Sometimes, the feedback from the YMCA Website Services lead technical architect requires re-work from the original developer making the PR before the code is accepted into the distribution. See Submitting Patches or Issues in the Blazy module documentation for tips on how to write good pull requests.
  6. Release.

    • The features contributed from you get scheduled into one of the YMCA Website Services quarterly releases, and we make sure you get ample credit for your contribution.
    • The movement then benefits from your contribution!
  7. Ongoing improvements, maintenance, etc.

    • Over time, you might want to make enhancements to your site due to analytics or other data inputs from customers and team members.
    • It would be great if you made those same enhancements to the now-decoupled version of your code that exists in YMCA Website Services if you feel it makes sense.
    • If you identify any bugs or issues over time on your site that involve code that was contributed to YMCA Website Services, it would be awesome if you fixed that code and contributed the fix via a Pull request (step 5 above).

To be clear, all of the above is only required if you want to get your code into the core YMCA Website Services distribution. You could always take your code as is, ensure any PII or secure information is scrubbed, and post it to your own GitHub repository – however it would be difficult for others to use this code as is if it hasn’t at least been decoupled. If you take this approach, please be sure to remove references to OpenY from the code so that the GitHub search engine does not confuse it with core YMCA Website Services. Further, please review the YMCA Website Services license agreement to make sure you are in alignment with GPL and Open Source sharing best practices.

24 - How to Develop Themes in YMCA Website Services

Developing Themes

Each YMCA Website Services theme was developed independently, either by the YMCA Website Services Core Team or by a partner for a specific Y and then contributed back. You can see demos of each theme on the Sandboxes.

Each theme has its own dependencies and build processes. Refer to the README file within each theme’s project for specific instructions.

Theme Inventory

As of December 2021, themes have been decoupled from the YMCA Website Services profile and exist as independent projects on Drupal.org.

Carnation

Lily

Rose

25 - Important versions for upgrade path

YMCA Website Services development moves quickly. This document highlights important versions that should not be skipped when upgrading your sites. Understanding the upgrade path ensures a smoother transition and avoids potential issues.

Determining your upgrade path

Example: If you are on YMCA Website Services 8.1.2 and want to upgrade to YMCA Website Services 8.2.8.5, you should follow these steps:

  1. Upgrade 8.1.2 to 8.1.13.1
  2. Upgrade 8.1.13.1 to 8.2.2.1
  3. Upgrade 8.2.2.1 to 8.2.7.3
  4. Upgrade 8.2.7.3 … and so on.

These supplemental documents provide more detailed information for specific upgrade scenarios:

Important Versions

The following versions are crucial milestones in the YMCA Website Services upgrade path. Pay close attention to the notes for each version to ensure a successful upgrade.

  • 8.1.13.1 - Optional, use this version if you have a lot of customized code and encounter issues with 8.2.2.1.

  • 8.2.2.1 - Critical. This is a mandatory step for all sites. After upgrading to this version, drush entup will no longer function. This version marks the migration to the core media subsystem. Upgrading your site to this version first is essential for proper media management in later versions.

  • 8.2.7.3 - Recommended. This is a very stable Drupal 8-based YMCA Website Services release with numerous updates to contributed modules. It’s one of the final Drupal 8-based versions before the upgrade to Drupal 9 core. From versions 8.2.7.0 and 8.2.7.1, multiple version constraints were introduced in composer.json, allowing developers to select between minimum or latest dependency versions for a more secure and flexible upgrade path.

  • 9.2.8.0 - A Drupal 9 version that is required in the upgrade path before moving to 9.2.8.1+. This version includes Drupal Core 9.0-9.1 and disables deprecated components.

  • 9.2.10.0 - This version removes several unused modules from the distribution, streamlining the codebase.

  • 9.2.11.3 - Last Open Y release based on Drupal core 9.3.*.

  • 9.2.11.4 - A technical release of YMCA Website Services with no functional differences compared to 9.2.11.3.

  • 9.2.13.0 - Important pre-Drupal 10 release. This is the last Drupal 9 release. Before upgrading to Drupal 10 and entering the Layout Builder era, it is highly recommended to uninstall the geysir, openy_inline_editing, quickedit, and rdf modules as a best practice.

  • 10.2.14 - A Drupal 10/9 release. When upgrading to this version, consider the following recommendations:

    1. Upgrade to the latest Drupal 9 core using version 10.2.14 of the distribution (released in June 2023): 10.2.14 Release.
    2. Upgrade all contributed modules and libraries to their latest Drupal 9-compatible versions using composer update.
    3. Utilize tools like drupal-rector, drupal-check, and PHPCS to prepare custom modules and themes for Drupal 10 compatibility.
    4. Upgrade to Drupal 10 and perform thorough regression testing to identify and resolve potential bugs. Update drupal/core-* projects in composer.json, then run composer update.
    5. Upgrade all contributed modules on the Drupal 10 site to their latest versions using composer update.
  • 10.3.0.1 - Drupal 10/9 release that precedes the introduction of new demo content and the initial replacement of Paragraphs with Blocks for a native Layout Builder experience.

  • 10.3.1 - Drupal 10/9 release that introduces new demo content and initiates the replacement of Paragraphs with Blocks for a native Layout Builder experience. A significant number of dependencies were also updated in this release.

  • 10.3.2 - Introduced recurring event support in the Event Content Type, which necessitates an automated migration between date_range and smart_date fields. If possible, update to this version during the upgrade process.

  • 10.3.2.3 - Introduced before 10.1 and 10.2 Drupal core. Also upgraded openy_map. This version ensures we support removed modules pre 10.1 for contrib modules.

Refer to Version Constraints practices for YMCA Website Services for more information on managing dependencies.

Known Issues

If you encounter an issue where composer installs an incorrect version of drupal/core for your chosen YMCA Website Services version, use the following command to downgrade:

composer require drupal/core-recommended:9.5.9

Run this command from your docroot. Replace 9.5.9 with the correct core version you need.

26 - Install Solr site search

YMCA Website Services leverages Apache Solr for a few features:

Prerequisites

Before you begin, ensure that you have:

  • A running Apache Solr server, version 6.4 or higher is recommended (refer to Apache Solr for installation instructions).
  • The YMCA Website Services Search API module installed and enabled.
  • Administrative access to your Drupal site.

Quick Start / Upgrade path

  1. Log in as admin.

  2. Go to admin/modules and enable the YMCA Website Services Search API module.

    image

  3. Approve the next step for enabling Database Search.

    image

  4. Go to the Search API configuration page admin/config/search/search-api.

  5. Verify that the “OpenY Database Search” server is enabled.

  6. Visit “Search content” index.

    image

    TIP: Admins can enable the Solr search and switch the index between servers.

  7. Index content by clicking “Index now”.

    image

  8. Go to the homepage and search for any keyword.

    image

  9. Verify search results are displayed correctly.

Starting from the YMCA Website Services installer

  • Find the Select search service step displayed during the YMCA Website Services installation.
  • Choose from one of these options during installation:
    • None
      • Nothing happens if the user chooses this option; search modules are displayed after installation.
    • YMCA Website Services Google Custom Search
      • Google Custom Search configuration form is displayed if the user chooses this option.
      • The YMCA Website Services Google Search module is enabled after installation and ready to use.
    • YMCA Website Services Search API
      • Search API backend options are displayed in this case with the following options:
        • Database
          • The YMCA Website Services Search API module is enabled after installation. The database search API server is enabled. The search is ready to use after content indexation.
        • Solr
          • Additional installation step with Solr configuration form is displayed in this case and user can specify all params for Solr connection. The YMCA Website Services Search API module is enabled after installation, Solr search API server is enabled. The search is ready to use after content indexing (if the correct Solr settings were used).

Switch from database search backend to Solr backend

Watch a video tutorial on how to switch an existing site from the database backend to a Solr server. This requires a Solr server to be configured in your environment.

  • Edit the “Solr search” server from the Search API configuration admin/config/search/search-api.
  • Add the configuration information for your Solr server. Refer to Drupal’s Search API Solr project for troubleshooting connection information.
  • Save the server and observe that Search API has successfully connected to your server.
  • Edit the “Search content” index and change the “Server” field to the newly configured “Solr Search” index.
  • Visit the “Search content” index and click “Index now” to re-index the content.

Solr search can be used with Layout Builder, and requires a few extra steps.

Configure Solr to index the new content types

In order for Solr to index the new content types, they need to be added to the index.

  1. Enable the YMCA Website Services Search API (openy_search_api) module if not already enabled.

  2. Go to Admin > Configuration > Search and metadata > Search API, then Edit the Search content index. (/admin/config/search/search-api/index/search_content/edit)

  3. Configure Solr to index the Layout Builder content types:

    • Scroll down, expand Configure the Content datasource, and check the content types that should be indexed for search.
      Configure the content datasource options
    • Save the form.
  4. Configure how Solr indexes the Layout Builder content types:

    • From the Search API configuration, open the dropdown for the Search content index and choose Fields.

      The fields option in the options dropdown of the Search API configuration

    • To the right of the Rendered HTML output field options, choose Edit.

    • For each newly added content type, switch “Don’t include the rendered item” to the right view mode.

      Choose the view mode for each content type.

      • In general, new Layout Builder specific content types will use the “Default” view mode, while older Layout Builder-compatible content types should use the “Full content” view mode.
        Content typeView mode
        Article (LB)Default
        BranchFull
        Event (LB)Default
        CampFull
        Camp SubpageFull
        FacilityFull
        Landing Page (LB)Default
        ProgramFull
        Program SubcategoryFull
    • Save the page.

  5. Once your changes have been saved, re-index the content to see the changes reflected in search results.

Set up a Layout Builder search page

  1. If you have an existing site, disable the old search page:

    • Go to /search.
    • Remove the URL alias by unchecking Generate automatic URL alias in the sidebar then deleting /search.
    • Uncheck Published and Save to un-publish the page.
  2. Create a new Landing Page (Layout Builder) (node/add/landing_page_lb):

    • Set the Title to “Search”.

    • Ensure Generate automatic URL alias is unchecked in the sidebar and set the alias to /search.

      • If that alias results in an error, you can remove the old one at Admin > Configuration > Search and metadata > URL aliases
    • Check Published then Save and edit layout.

  3. Add a Small Banner to the header with a title for the page, like “Search”.

  4. Add the search results block to the page:

    • In the Body section, Add block, then expand All system block and choose Content search block from the Paragraph Blocks section.
    • Optionally, choose to hide the title or change the number of items to display.
    • Save layout and check your page.
  5. Change the Search API config to use your new page:

    • Go to Admin > YMCA Website Services > Settings > Search API settings (/admin/openy/settings/search-api) and set the Search page id to the node id of your new page.

    • Or, change the config with drush:

      drush cset openy_search_api.settings search_page_id <nid>
      
  6. Test the search box in the Layout Builder page header to ensure the new configuration works as expected.

Legacy Solr Support

The contrib Search API Solr module supports a broad swath of Solr versions, but occasionally old versions are dropped from support in the main module. If, when enabling YMCA Website Services Search API, you encounter errors that your version of Solr is out of date, you may need to enable the Search API Solr Legacy module. As of January 2022, Search API Solr Legacy supports Solr 3.6 through 6.4.

The error message when using an old version of Solr may look something like this:

Notice: Undefined index: 4.x in Drupal\search_api_solr\Controller\SolrConfigSetController->getConfigFiles()

27 - Install SSL Certificate

Web Security and YMCA Website Services

As many parties have moved to Encrypt the Web, https sites and SSL certificates have shifted from a “nice to have” to a necessity.

If you’re running YMCA Website Services on a managed platform, you most likely have SSL already configured. If you choose to manage YMCA Website Services on your own, you’ll have to install a certificate.

Let’s Encrypt is “a free, automated, and open certificate authority (CA), run for the public’s benefit. It is a service provided by the Internet Security Research Group (ISRG).” Certbot is “a free, open source software tool for automatically using Let’s Encrypt certificates on manually-administrated websites to enable HTTPS.”

Certbot maintains detailed documentation for installing SSL certificates on a variety of systems. Simply visit Certbot’s instructions wizard and follow the instructions to configure your server.

28 - Installation With Drush

You can use the drush site-install command to quickly set up the OpenY distribution.

The basic syntax is:

drush site-install openy --account-pass=password --db-url="mysql://user:pass@host:3306/db" --root=/var/www/docroot

This command uses the complete YMCA Website Services profile preset and the YMCA Website Services Rose theme.

To specify a different profile preset or theme, use the openy_configure_profile.preset and openy_theme_select.theme variables:

drush site-install openy --account-pass=password --db-url="mysql://user:pass@host:3306/db" --root=/var/www/docroot openy_configure_profile.preset=extended openy_theme_select.theme=openy_rose

Explanation of parameters:

  • openy: Specifies the installation profile to use (OpenY).
  • --account-pass=password: Sets the administrator password. Replace "password" with a secure password.
  • --db-url="mysql://user:pass@host:3306/db": Defines the database connection details.
    • user: Database username.
    • pass: Database password.
    • host: Database host.
    • 3306: Database port (default MySQL port).
    • db: Database name.
  • --root=/var/www/docroot: Specifies the Drupal root directory. Adjust this to the correct path on your server.
  • openy_configure_profile.preset=extended: Selects the “extended” installation preset.
  • openy_theme_select.theme=openy_rose: Selects the “openy_rose” theme.

29 - Module Development

Module Content Removal

When deleting an entity where plugins or services of the removing module are used, content removal should be done in the hook_uninstall() function of that module. This ensures that no orphaned data or references remain in the system after the module is uninstalled.

Example:

See openy_prgf_camp_menu.install for an example of how to implement this. The hook_uninstall() function in this file removes paragraphs before the module uninstall to avoid errors related to missing services used in the camp menu block.

Creating a New Module

When creating a new module on Drupal.org, ensure the following:

  1. Add all current maintainers: Properly credit and involve all individuals actively contributing to the module.
  2. Add a module template: This template provides essential information and resources for users. Use the following HTML snippet and customize it for your module:
<table class="views-view-grid" bgcolor="#d4efcc">
  <tr>
    <td>
      <h2>🇺🇦</h2>
    </td>
    <td>
      This module is maintained by Ukrainian developers. Please consider
      <a href="https://supportukrainenow.org">supporting Ukraine</a> in a fight for their freedom and the safety of Europe.
    </td>
  </tr>
</table>

<!-- Edit this section with a short intro to the module -->
This component/module allows you to ... when using the
<a href="https://github.com/YCloudYUSA/y_lb">YMCA Layout Builder</a> package.

<!-- Leave this section as is -->

<ul>
  <li>
    Read our
    <a href="https://github.com/YCloudYUSA/yusaopeny#installation">instructions for getting started</a>.
  </li>
  <li>
    <a href="https://ds-docs.y.org/docs/">Search our documentation</a> for
    assistance.
  </li>
  <li>
    <a href="https://ds-docs.y.org/community/">Review our Community Resources</a>
    for more information.
  </li>
</ul>

<h3 id="project-requirements">Requirements</h3>

This project is meant to be used with the
<a href="https://www.drupal.org/project/openy">YMCA's Website Service distribution</a>.

30 - One-Click Install How-To

This walkthrough is outdated and is in the process of being updated. Consider using the resources below instead.

Installing YMCA Website Services on a DigitalOcean Droplet

These steps outline how to install YMCA Website Services on a DigitalOcean droplet.

  1. Create a new Ubuntu 16.04 LTS x64 droplet. Choose a region close to your location.

    DigitalOcean Droplet Creation

    Use a 2GB droplet or more powerful option, if needed. Do not use the 1GB option as YMCA Website Services may fail on it.

  2. Log in to the droplet via SSH.

  3. Execute the one-click install script. Run the following command as the root user:

    curl -Ls http://bit.ly/initopeny | bash -s
    

    This command will run for approximately 10 minutes.

  4. Access the installation URL. Upon completion, you should see a message similar to:

    Open http://127.0.0.1/core/install.php to proceed with OpenY installation.
    
  5. Open the provided URL in your browser. Access this link from your droplet’s IP address, not from this document. Then proceed with the YMCA Website Services installation.

    For example, if your droplet’s IP address is 192.0.2.0, you would access http://192.0.2.0/core/install.php.

Enjoy!


Installing the Latest Beta Release

To install the latest beta release of YMCA Website Services 2.0, modify the command in step 3:

curl -Ls http://bit.ly/initopeny | bash -s beta

Troubleshooting

If you encounter any issues, please report them in the issue queue:

https://github.com/YCloudYUSA/yusaopeny/issues

31 - Open Y Analytics Sunset

Preamble

On January 28, 2020, the Open Y initiative introduced an anonymous analytics module, openy_analytics. This module was designed as a free, opt-in/opt-out solution, allowing the Core Team to gather statistics from Open Y sites regarding the usage frequency of various components.

The primary goal was to collect data that would inform decision-making and enhance our understanding of component demand within the Open Y ecosystem.

Recently, the Open Y Core Team decided to sunset this functionality and remove both the openy_analytics and openy_update modules from the Open Y distribution due to low usage. This sunsetting reduces the server load on Open Y instances and allows us to archive the analytics server.

How to Opt-Out of the Analytics Subsystem

To opt-out, navigate to YMCA Website Services -> Terms and Conditions within your YMCA Website Services site instance and uncheck the Optional Permissions checkbox.

Terms and Conditions Checkbox

After submitting the form, your site will no longer transmit anonymous data. If the checkbox was already disabled, no action is needed, as you had not previously opted in.

Deprecation Details

The uninstall and deprecation process was implemented in Pull Request #2537.

The openy_analytics module was part of the Analytics package. This package, as described in openy.packages.yml, aimed to “integrate the website with analytic systems and capture website statistic.” It included modules like google_tag and google_analytics to configure integrations with Google Analytics or Google Tag Manager.

32 - Participant Agreement

YMCA Website Services PARTICIPATION AGREEMENT

This YMCA Website Services Participation Agreement (this “Agreement”) is between YMCA of the USA (“YUSA”), and participating YMCA member associations in the United States (“Member Associations”). YUSA has received license rights from the National Council of Young Men’s Christian Associations of the United States of America, an Illinois not-for-profit corporation (“National Board”) to provide the Platform (as defined below) to you.

The purpose of the YMCA Website Services community is to collectively advance YMCA web and online experiences to better serve the YMCA mission. The terms of this Agreement govern your use of YMCA Website Services’s open-source digital content management system. This system facilitates the sharing of National Board brand-compliant website templates, tools, applications, and related digital assets (“Platform”). The community provides a collaborative environment for individuals to positively interact and participate in the Platform. These guidelines address the standards and expectations of those contributing to and participating in the YMCA Website Services community. They are meant to help our YMCA community grow and thrive. Your participation in YMCA Website Services means that you agree to the following guidelines and to the YMCA Website Services Terms of Use.

YMCA BRAND ASSETS

No right is granted by this Agreement to use or license the YUSA brand assets. YMCA brand assets, which include, but are not limited to YMCA trademarks, trade dress, logos and other indicia of origin, are owned and controlled by YUSA. YUSA provides the Platform to you under license from YUSA. Accordingly, neither YUSA nor any Member Association shall, either directly or indirectly, at any time do any act or thing contesting the validity of YUSA’s trademarks or its rights thereto.

Only Member Associations in the United States will have access to use any YUSA brand assets included in YMCA Website Services. All use by Member Associations must be in compliance with YUSA brand standards and guidelines as established by the National Board. YUSA is a third party beneficiary to this Agreement, with the right to enforce each of the terms of this Agreement with respect to YMCA Website Services and you. YMCA Website Services shall send copies of all notices due to you under this Agreement to each of you and YUSA.

BEING A MEMBER OF OUR COMMUNITY

  • Participation: YMCA Website Services will be at its best if each member participates in the community. There are many different ways you can participate, including through using the platform, presentations, forums, summits, emails, calls, etc. We encourage your active participation to the extent you feel you are able and willing. YUSA may publicly disclose your participation in the project.

  • Contribution: YMCA Website Services encourages Members to contribute to the enhancement, editing, and building of YMCA Website Services. To ensure valuable contributions to the community, YMCA Website Services encourages Members to stay familiar and up-to-date with the YMCA Website Services roadmap, as well as new features in active development. When you make changes that improve YMCA Website Services features, please contribute those back to the community by ensuring they are re-useable and decoupled.

  • Collaboration: YMCA Website Services encourages Members to collaborate across the YMCA community to share costs and efforts on building new capabilities.

  • Transparency: Customizations of code provided by YMCA Website Services for your website will likely increase the initial fees, support, and upgrade costs for your website. When modifying or redistributing code, you must include a notice giving credit to YMCA Website Services for the portion of the YMCA Website Services code you use.

  • Promotion: YMCA Website Services encourages Members to share their expertise and YMCA Website Services experience to expand its reach and accessibility to experienced and new members alike. There will be many opportunities for members to support YMCA Website Services and its marketing and messaging initiatives.

Reporting Problems

If you believe someone has violated the YMCA Website Services Community Guidelines, or have any questions or concerns, please contact YUSA through the YMCA Website.

33 - Patch YMCA Website Services

Here you can find instructions on how to patch a YMCA Website Services distribution used in your project.

When to Patch YMCA Website Services

  • If you’ve found a bug and created a patch for YMCA Website Services on GitHub.
  • If you’ve developed a new feature that would benefit YMCA Website Services and created a Pull Request (PR) to the YMCA Website Services repository.
  • If you want to use a feature that has been added to YMCA Website Services but isn’t yet included in a released version.

How to Patch YMCA Website Services via Composer

If you followed the instructions in docs/Development/Start new YMCA Website Services project and your composer.json is configured correctly, follow these steps:

  1. Create a patch link using the Pull Request ID:

    https://patch-diff.githubusercontent.com/raw/YCloudYUSA/yusaopeny/pull/XXX.patch
    

    Replace XXX with the number of the pull request you want to use.

  2. Add a patches section to the extra section of your composer.json file:

    "extra": {
        "installer-paths": {
          ...
        },
        "enable-patching": true,
        "patches": {
            "YCloudYUSA/yusaopeny": {
                "Patch description": "https://patch-diff.githubusercontent.com/raw/YCloudYUSA/yusaopeny/pull/XXX.patch"
            }
        }
    }
    
    • Patch description: A brief description of what the patch does. This helps you remember the purpose of the patch later.
    • https://...XXX.patch: The patch link created in step 1.
  3. Run composer update:

    This command applies the patch to your project.

  4. Verify the Changes:

    Check that the changes from the patch are present in your YMCA Website Services installation.

  5. Enjoy!

34 - Profile custom configuration

The distribution supplements the Drupal install process with a number of custom additions.

There are many YAML configuration files at the root of the profile. Some are standard Drupal configuration, and others are YMCA Website Services specific.

Basic .yml files

The following files are very common and can be found in many Drupal modules:

  • openy.info.yml ( documentation) - Defines YMCA Website Services as a profile and defines its name and dependencies. See openy.info.yml file located in the /docroot/profiles/contrib/yusaopeny/ directory.
  • openy.libraries.yml ( documentation) - Defines global YMCA Website Services Drupal asset libraries.
  • openy.permissions.yml - Defines global YMCA Website Services permissions.
  • openy.services.yml ( documentation) - If you are introducing a service that is needed by all (or the majority of) YMCA Website Services modules, add it here and store the service class file in the openy/src directory.

YMCA Website Services specific .yml files

There are also a few configurations related to the YMCA Website Services installation process and the YMCA Website Services package system:

  • openy.installation_types.yml
  • openy.themes.yml
  • openy.packages.yml

YMCA Website Services packages

The YMCA Website Services package system introduces a new level of abstraction, shifting from the Drupal standard module level to packages. Packages represent complete YMCA Website Services features, which could include multiple modules. A package is a declaration of a group of several modules. You can enable and disable a package, which means the whole set of the associated Drupal modules are enabled or disabled.

This approach provides a convenient way of managing YMCA Website Services features.

The YMCA Website Services system module provides a page where the enabled and available packages are listed and can be installed/uninstalled. See the YMCA Website Services Extend page (at /admin/openy/extend).

YMCA Website Services Installation types

When an YMCA Website Services site is installed, there is also another abstraction level - the installation type - which groups packages.

The hierarchy is as follows:

  • installation type
    • package
      • module
      • module
    • package
      • module
      • module
      • module
    • package
      • module
  • installation type
    • package
      • module

openy.installation_types.yml

openy.installation_types.yml defines the high-level presets available during website installation.

File structure:

standard:
  name: Standard
  packages:
    - alerts
    - editorial
    - news
    - seo
    - webform

extended:
  name: Extended
  packages:
    - alerts
    - analytics
    - ...

complete:
  name: Complete/Developer
  hidden: true
  packages:
    - activenet
    - ...

Each installation type has a machine name which is a key of the top-level items.

Properties of installation types:

  • name (required) - A human-friendly name of the installation type.
  • packages (required) - A list of YMCA Website Services packages that are associated with the installation type. The packages are listed when a website is installed via the web-interface.
  • hidden (optional) - If the installation type must be hidden when a website is installed via the web interface.

If an YMCA Website Services site is installed using the web interface, there is a step where the installation type can be selected.

If an YMCA Website Services site is installed using Drush, then the installation type can be specified by an optional argument for the drush site-install command ( Installation with Drush):

drush site-install openy \
  --db-url="mysql://user:pass@host:3306/db" \
  --root=/docroot \
  openy_configure_profile.preset=extended

openy.packages.yml

Packages are defined in openy.packages.yml. This file is placed in the root of the profile, and it’s automatically detected and used by the YMCA Website Services installation process.

File structure

blog:
  name: "Blog"
  description: "Blog package provides a set of modules to maintain and create different blog post listings."
  help: '<p>Using Blog package you can create and maintain blog posts and create flexible listings of blog posts. Watch a video below to learn more about blog anatomy.</p>
  <iframe width="560" height="315"
               src="https://www.youtube.com/embed/Vg1fy29DhdQ"
               frameborder="0" allow="autoplay; encrypted-media"
               allowfullscreen></iframe>'
  modules:
    - openy_node_blog
    - openy_prgf_blog_listing
    - openy_prgf_featured_blogs
    - openy_prgf_blog_branch
    - openy_prgf_blog_camp
    - openy_prgf_blog_latest
    - openy_txnm_blog_category

camps:
  name: "Camps"
  description: "Camps package provides a set of modules to maintain camps and add them to the location finder page."
  help: '<p>Using Camps package you can create and maintain Camps and extend location finder page to include them.</p>'
  modules:
    - openy_prgf_camp_menu
    - openy_loc_camp

Each package has a machine name which is a key of the top-level items.

Properties of packages:

  • name (required) - A human-friendly name of the package.
  • description (required) - A short description of the package features to show up on the YMCA Website Services Extend page.
  • help (required) - An HTML markup for the installation via web interface. It contains a help message that pops up when the package name is clicked on the Select installation type step.
  • modules (required) - A list of Drupal modules that are associated with the package. When the package is installed/uninstalled, the associated modules are installed/uninstalled respectively. When a website is installed via the web interface, all the available packages are listed there but split into two groups - the ones that are to be installed (associated with the selected package) and all the rest.

openy.theme.yml

The file defines which YMCA Website Services themes are available for installation when a website is being installed.

If an YMCA Website Services site is installed using Drush, then the theme can be specified by an optional argument for the drush site-install command ( Installation with Drush):

drush site-install openy \
  --db-url="mysql://user:pass@host:3306/db" \
  --root=/docroot \
  openy_configure_profile.preset=extended \
  openy_theme_select.theme=openy_rose

35 - Program Event Framework

A robust set of content types and syncer modules that build interactive tools to help members find and book activities.

“Program Event Framework” (PEF) refers to the entire ecosystem of content and modules in YMCA Website Services that work together to build Activity Finder, Group Schedules, and more. PEF provides a structured approach to managing program-related content, ensuring consistency and ease of use.

Content Types

These content types provide the containers for PEF content in Drupal:

  • Program - Represents a high-level program (e.g., “Swimming”, “Camps”).
  • Program Subcategory - Represents a specific subcategory within a program (e.g., “Lap Swimming” within “Swimming”).
  • Activity, Class, Session - Represents the individual activities, classes, and sessions offered.

Syncers

These modules provide integrations to pull content from external systems into the content types listed above. They automate the process of importing data from various platforms into the YMCA Website Services ecosystem.

Displays

These modules and features display the content entered into the content types, allowing users to discover and engage with programs and activities.

Data Model

The network of data structures in PEF can be complex. This diagram illustrates the relationships between the main content types and their key fields.

---
title: PEF Relationships
---
erDiagram
    program {
        entityRefTerm field_program_color
        paragraph field_content
        paragraph field_header_content
        paragraph field_sidebar_content
        textFormattedLong field_program_description
        entityRefMedia field_program_icon
        entityRefMedia field_program_image
        layout layout_builder__layout
        meta field_meta_tags
        bool field_use_layout_builder
    }
    program_subcategory {
        paragraph field_bottom_content
        entityRefTerm field_category_color
        paragraph field_content
        paragraph field_sidebar_content
        textFormattedLong field_category_description
        paragraph field_header_content
        entityRefMedia field_category_image
        layout layout_builder__layout
        meta field_meta_tags
        entityRefProgram field_category_program
        bool field_use_layout_builder
    }
    program_subcategory }|--|| program : field_category_program
    activity {
        textFormattedLong field_activity_description
        entityRefProgSub field_activity_category
    }
    activity }o--|| program_subcategory : field_activity_category
    class {
        entityRefActivity field_class_activity
        paragraph field_bottom_content
        paragraph field_content
        textFormattedLong field_class_description
        paragraph field_header_content
        meta field_meta_tags
        paragraph field_sidebar_content
    }
    class }o--|| activity : field_class_activity
    session {
        listText field_activity_type
        entityRefClass field_session_class
        textFormattedLong field_session_description
        dateRange field_session_exclusions
        listText field_session_gender
        numberInt field_availability
        bool field_session_in_mbrsh
        textPlain field_session_instructor
        entityRefLoc field_session_location
        numberInt field_session_max_age
        listText field_session_max_grade
        numberDec field_session_mbr_price
        numberInt field_session_min_age
        listText field_session_min_grade
        numberDec field_session_nmbr_price
        bool field_session_online
        entityRef field_session_plocation
        numberInt field_productid
        link field_session_reg_link
        textPlain field_session_room
        paragraph field_session_time
        numberInt field_wait_list_availability
    }
    session }|--|| class : field_session_class
    session ||--o{ session_time_paragraph : field_session_type
    session_time_paragraph {
        dateRange field_session_time_date
        listText field_session_time_days
        textPlain field_session_time_override
    }
    branch {

    }
    camp {

    }
    facility {

    }
    session }o--|| branch : field_session_location
    session }o--|| camp : field_session_location
    session }o--|| facility : field_session_location
    session }o--|| facility : field_session_plocation

More information on how this data is displayed in each component will be added soon.

35.1 - Activity Finder

Provides an interactive tool to help members find and book activities.

Activity Finder combines data from the Activity, Class, and Session content types into an interactive tool that can be used with Paragraphs or Layout Builder pages.

YCloudYUSA/yusaopeny_activity_finder is bundled as a “decoupled application” that ships with the YMCA Website Services distribution.

Out-of-the-box, YMCA Website Services’s Activity Finder integrates with Daxko, ActiveNet, and Personify. Configuring these integrations is mostly user-friendly, but often is supported by a partner development team. Any other CRM will require custom developer work.

See the Program Event Framework developer docs for a full list of integrations.

Block configuration

When you add the Activity Finder block to a page, you have a number of options. These are in addition to the configuration at Admin > YMCA Website Services > Settings > Activity Finder Settings (/admin/openy/settings/activity-finder). See the Activity Finder module README for more information.

  • Location & Category Filters - Restrict this block to show sessions from only certain Locations or Categories. Limit will show only the specified options. Exclude will remove the specified options. Generally you should choose either Exclude or Limit, not both.
    • Limit by location - Only show sessions at specific locations in the results.
    • Exclude by location - Remove sessions at specific locations from the results.
    • Limit by category - Only show sessions related to specific Program Subcategories in the results.
    • Exclude by category - Remove sessions related to specific Program Subcategories from the results.
  • Legacy mode - Shows some data as it was in the previous version of Activity Finder (v3):
    • Disables bookmark functionality on the results screen.
    • Doesn’t display the age indicator in the result card of activities.
    • Changes the days + times wizard step. Displays only days of week, but not times of each day (doesn’t support DaysTimes filter)
  • Weeks filter - Changes the Day/Time filter to use custom defined Week filters.
    • This requires setting the Weeks configuration in the Activity Finder settings (/admin/openy/settings/activity-finder). Activity Finder Weeks configuration.
    • Note: Only sessions that have Camp in the title or room fields will return for this filter.
  • Additional filters - These filters are off by default, but can be enabled in the Block Configuration. Activity Finder additional filters
    • Start Month - Filters based on the month in the Session Time field.
    • In Membership - Shows Sessions that have In membership checked.
    • Duration - The length of the Session. This is configurable in the Activity Finder settings (/admin/openy/settings/activity-finder) and defaults to:
      • Single day
      • Multi-day (up to 5 days)
      • Weekly (up to 3 weeks)
      • Monthly (up to 5 weeks)
      • Season (up to 12 weeks)
      • School year (~9 months)
      • Full year
  • Hide Home Branch info block - Disables functionality related to the users selected home branch.
  • Background image - An image that’s displayed in the background of the banner above Activity Finder.

The Activity Finder block configuration.

Front-end

Once the Activity Finder Paragraph or Activity Finder Layout Builder Block has been added to a page, users can see its content.

A set of screenshots illustrating the Activity Finder application with items labeled as per the following descriptions.

Filters

  • Schedules - Filters by a number of facets, which are configurable in the Block Configuration or Activity Finder settings.
    • Age(s) - Filters based on the Min Age and Max Age. Age ranges are configurable in the Activity Finder settings (/admin/openy/settings/activity-finder).
    • Day(s) & Time(s) - Filters by the time of date on specific days of the week. This filter has no configuration.
    • Weeks - Replaces date/time filter when Weeks filter is selected in the Block Configuration. See configuration requirements above.
  • Activities - Program Subcategory filters grouped by Program.
  • Locations - Location filters grouped by Content type.

See Block Configuration for more detail on other available filters.

Results

The filtered results in the Activity Finder app are a list of Sessions that meet the given filter criteria.

Each row of results contains:

  • The Session Title.
  • The Session Time, which contains a date, days of the week, and times.
  • The Session Location
  • The Session Min/Max Age
  • The Member Price and Non-member price
  • An indication of the number of spots available, from the Initial Availability field.

Clicking on the row will bring up a pop-up with further details:

  • The Session Description
  • A Learn more link and Register button which both go to the URL in the Session Registration Link field.

Additional topics

Allowing UTM codes in Activity Finder

UTM codes can be used to track the effectiveness of marketing campaigns. Activity Finder uses query strings as filters, but as of version 4.2.0 it will also maintain UTM codes in the URL.

Activity Finder begins with a number of preset arguments, and those can be modified at Admin > YMCA Website Services > Settings > Activity Finder Settings (/admin/openy/settings/activity-finder) in the Allowed Query Arguments field.

A screenshot of the Activity Finder settings, focused on the Allowed Query Arguments field

Once those settings are saved, you can visit an Activity Finder page with UTM codes attached, for example:

https://example.com/activity_finder?step=results&selectedAges=24&selectedLocations=1541437&selectedActivities=2786027,2786083&utm_source=promotional_member&utm_medium=email&utm_content=button_register_now&utm_campaign=fall_group_swim_lessons_2021

and see that the codes are maintained as the filters are changed.

35.1.1 - Adding Activity Finder to your site

Both v4 and v3 can coexist as independent applications on your site, displaying the same data sourced from the Program Event Framework within Open Y.

Open Y Components for Activity Finder v3 and v4

The screenshot above illustrates the Open Y components listed for both Activity Finder v3 and v4.

Activity Finder v3 (Deprecated)

To implement the v3 Activity Finder, you’ll need to create two interconnected landing pages: one for the Activity Finder itself (deprecated) and another for the Activity Finder Search (deprecated).

Activity Finder v3 Landing Pages

Examples:

Activity Finder v3 Search Landing Pages

Examples:

Activity Finder v4

To implement the v4 Activity Finder, you only need to create one landing page and add the Activity Finder component to it.

Activity Finder v4 Landing Page

Sandbox Examples:

35.1.2 - Bootstrap version support for Activity Finder

The Carnation theme utilizes Bootstrap v4.6. To accommodate this, the Activity Finder v4 module includes a “Bootstrap version” setting located at /admin/openy/settings/activity-finder.

Activity Finder Bootstrap Version Setting

The Rose and Lily themes use Bootstrap v3, while the Carnation theme is built with Bootstrap v4. Setting the “Bootstrap version” to “4” ensures that the Activity Finder v4 result page displays correctly on tablet screens within the Carnation theme.

Activity Finder v4 Results on Tablet - Bootstrap v4

Activity Finder v4 Results on Tablet - Bootstrap v4 (Continued)

35.1.3 - Configuring Solr for Activity Finder

To install Open Y with Activity Finder v4, use the following command:

composer create-project ymcatwincities/openy-project build --no-interaction --prefer-dist

This command retrieves the latest stable version of Open Y (Drupal) along with the latest stable version of Activity Finder v4. Proceed with the standard installation, ensuring you enable demo content as outlined in the provided tutorials. For streamlined setup, choose either the Extended or Custom installation profile (Custom via Drush).

Once YMCA Website Services (formerly Open Y) is installed, enable Activity Finder v4 with these Drush commands:

# Solr 8.8.1, Activity Finder v4
drush en -y search_api_solr_legacy openy_prgf_activity_finder_4 || true
drush en -dvy openy_prgf_af4_demo || true

After enabling the modules, visit /admin/config/search/search-api to download the config.zip file. This ZIP archive contains the pre-configured Solr server settings for Open Y.

image

Hint: The Open Y module infrastructure is compatible with Solr versions 8 up to 8.8.1. Activity Finder v4 is specifically tested against Solr 8.8.1. Refer to the Drupal.org documentation for instructions on installing Solr. Note that Solr versions prior to 7.7 are End of Life (EOL). The Open Y team is actively working on upgrading support for newer Solr versions.

Install the downloaded configuration as a separate core on your Solr 8.8.1 server. Extract the contents of config.zip into the conf directory of your new Solr core.

image

After extracting the configuration, verify that the core name defined in the core.properties file matches the Solr Server configuration within Open Y.

image

You can find the Solr server configuration dropdown at /admin/config/search/search-api.

image image

Alternatively, you can configure Solr via Drush. Replace ${SOLR_CORE_IS_HERE} with the actual name of your Solr core in the commands below:

# Solr 8.8.1, Activity Finder v4

drush cset -y search_api.server.solr backend_config.connector_config.host 127.0.0.1 -y
drush cset -y search_api.server.solr backend_config.connector_config.core ${SOLR_CORE_IS_HERE} -y
drush cset -y search_api.server.solr backend_config.connector_config.solr_version 8 -y
drush search-api-mark-all -y
drush sapi-i -y

After executing these commands, confirm that the Solr server is enabled and indexed at /admin/config/search/search-api.

If you installed Open Y with demo content, create a landing page featuring the Activity Finder v4 component. The openy_prgf_af4_demo module automates this process. Enable it using Drush:

# Solr 8.8.1, Activity Finder v4
drush en -dvy openy_prgf_af4_demo || true

Enabling this module automatically creates the /activity-finder-v4 landing page.

image

Visiting /activity-finder-v4?step=results or clicking the suggested buttons displays activities, filters, and other features included in Activity Finder v4.

With the Open Y demo content, the Activity Finder v4 page should resemble the following:

image

Explore these sandboxes for examples:

Activity Finder v3 is also installed when choosing the Custom installation profile with demo content. It can be accessed via the /activity-finder URL.

Explore these sandboxes for Activity Finder v3 examples:

Development SOLR 8 Installation

Refer to the Solr Docker readme for details: https://github.com/docker-solr/docker-solr/blob/master/README.md

mkdir solr8
sudo chown 8983:8983 solr8
docker run -v "$PWD/solr8:/var/solr" -p 8984:8983 --name d9_sandbox_rose_custom solr solr-precreate d9_sandbox_rose_custom
# stop docker and remove created container
# unpack solr_8.x_config.zip into data/d9_sandbox_rose_custom/conf/

docker run -v "$PWD/solr8:/var/solr" -p 8984:8983 --name d9_sandbox_rose_custom solr solr-precreate d9_sandbox_rose_custom

To configure Open Y to use Solr 8.x, change the address port to 8984.

Rebuild and reindex the index information. Verify that Activity Finder v4 functions correctly.

35.2 - PEF Schedules

The PEF Schedules module allows Ys to create and manage schedules with a simple, calendar-based view. It leverages the FullCalendar library for a rich, interactive experience.

YCloudYUSA/y_pef_schedule

The “PEF Schedules” module provides a calendar-based interface for creating and managing branch schedules. It integrates with the Open Y platform, allowing for seamless schedule creation and display.

Key Features:

  • Calendar-Based Interface: Utilizes the FullCalendar library for an intuitive drag-and-drop scheduling experience.
  • Branch Schedules: Allows administrators to create and manage schedules for different branches.
  • Configuration Options: Settings include configurable time intervals for calendar slots, event snapping granularity, and slot label intervals.
  • Integration with Open Y: Works with existing Open Y content types like Activities and Classes.
  • Display Options: Schedules can be displayed using the Simple Schedule block, Activity Finder, or Group Schedules.
  • PDF Export: Option to download schedules as PDF documents.

Configuration

The module provides settings for customizing the calendar’s appearance and behavior:

  • Slot Duration: Defines the length of each time slot (e.g., 00:30:00 for 30 minutes).
  • Snap Duration: Determines the granularity of time slot selection and event dragging (e.g., 00:15:00 for 15 minutes).
  • Slot Label Interval: Specifies the interval between time labels displayed along the calendar’s axis (e.g., 01:00:00 for every hour).
  • Min Time: The earliest time visible on the calendar (e.g., 04:00:00).
  • Max Time: The latest time visible on the calendar (e.g., 23:00:00).
  • Default Color: Sets the default color for activities displayed on the calendar, using a hexadecimal color code (e.g., #3788d8).

These settings can be accessed at Admin > YMCA Website Services > Settings > Schedules calendar settings (/admin/openy/settings/schedules-calendar).

Block Content Type

The module introduces a new block content type:

  • Simple Schedule: Provides a calendar view of a branch schedule.

Menu Links

The module adds the following menu links:

  • Schedules Calendar: Located under Admin > Content, allows administrators to select a branch and view its schedule.
  • Schedules calendar settings: Located under Admin > YMCA Website Services > Settings, provides access to the module’s configuration settings.

Dependencies

  • drupal:openy_repeat
  • drupal:colorapi

Repeat Schedules Paragraph

The “Repeat Schedules” paragraph type provides additional configuration options for displaying schedules:

  • Display instructor: A boolean field to show or hide the instructor’s name in the schedule display.
  • Display end time: A boolean field to show or hide the end time in the schedule display.
  • Categories exclude: Allows excluding specific activity categories from the schedule display.
  • Filter: Allows filtering content by category, class name, or instructor name.

Templates

  • branches-list.html.twig: Template for displaying a list of branches with links to their respective schedules.
  • block--lb-simple-schedule.html.twig: Template for rendering the Simple Schedule block.

Additional Information

For installation instructions and usage details, refer to the following resources:

The Y PEF Schedule module provides a calendar functionality for scheduling events. It includes a Vue.js component, fullcalendar-app, to display and interact with the calendar.

Requirements

Installation

composer require ycloudyusa/y_pef_schedule
drush en y_pef_schedule lb_simple_schedule
  1. Install as you would normally install a contributed Drupal module. For further information, see Installing Drupal Modules.
  2. Enable the module by navigating to Admin > Extend (/admin/modules) in your Drupal admin interface, then enabling "Y PEF Schedules Admin tool" and "LB Simple Schedule".

Configuration

  1. Configure the calendar settings at Admin > YMCA Website Services > Settings > Schedules calendar settings (/admin/openy/settings/schedules-calendar)
  2. Go to Admin > Content > Schedules Calendar (/admin/openy/branch-schedules) and select a branch.

After choosing a branch, you can view the calendar. The calendar features include:

  1. Viewing events in weekly or daily format.
  2. Viewing the main information of the event (by clicking on the event).
  3. Creating a new event (using the Session Content Type).
  4. Updating existing events.
  5. Downloading the schedule in PDF format.
  6. Filtering results by categories.

Showing the calendar on a page

Once you have added sessions to a calendar, you can add the calendar block to a Layout Builder page to display on the site. Ensure the "LB Simple Schedule" is enabled first.

  1. Edit the Layout of a Layout Builder page (Branch, Landing Page, etc).
  2. Create or find a section, then Add Block.
  3. Choose Add custom/content block then Simple Schedule.
  4. Add a Title and choose a Branch to populate the calendar.
  5. Save the block and the page.

Customization

A few options are available for advanced customization of the calendar.

Retrieving Events

The module provides controllers to handle AJAX requests for fetching events. To create a custom request, use the following route in your JavaScript code:

axios.get(&#39;/fullcalendar-api/get-event-data-date-range/{location}/{start}/{end}/{category}&#39;)
  .then(response =&gt; {
    const events = response.data;
    // Process the received events as needed
  })
  .catch(error =&gt; {
    console.error(&#39;Error fetching events:&#39;, error);
  });

Replace {location}, {start}, {end}, and {category} with the appropriate values.

Creating Events

The fullcalendar-app component allows users to create events interactively. When a date is clicked, a modal form is displayed for users to enter event details such as title, category, time, and date.

To customize the form or extend the functionality, refer to the Vue.js component documentation and customize the handleDateClick and createEvent methods in the fullcalendar-app component.

Troubleshooting

Known issues

  1. After creating a series of events, it is created, but only one event is displayed in the calendar, the page must be refreshed to see the correct data
  2. The color is fixed to the session and not to the category
  3. PDF format is A3

35.3 - Traction Rec Integration

Instructions for configuring and importing data from Traction Rec into the Program Event Framework.

The Traction Rec Integration module (ycloudyusa/openy_traction_rec) facilitates data synchronization between Traction Rec and the Program Event Framework (PEF). This integration allows you to import program and event data from Traction Rec into your Drupal website.

Configuration and Import

Module Details

This module provides YMCA Website Services integration with the Traction Rec CRM.

Installation

Require this module:

composer require ycloudyusa/openy_traction_rec

Then enable the necessary modules and submodules:

drush en openy_traction_rec openy_traction_rec_import openy_tr_activity_finder

Usage

The main module itself provides only API that helps fetch data from TractionRec. More specific functionality is provided in submodules:

  • YMCA Website Services Traction Rec: PEF import provides PEF migrations.
  • YMCA Website Services Traction Rec: Activity Finder extends YMCA Website Services Activity Finder with the new fields and logic.

See modules/openy_traction_rec_import/README.md for details on how to import content once configuration is complete.

Configuration

Create a Connected App in Salesforce

  1. Create a new private key and X509 certificate, customizing the subj options in the command to suit your organization. (See the manual for openssl-req to understand the options here.)
    openssl req -x509 -noenc -sha256 -days 365 \
     -keyout traction_rec.key \
     -out traction_rec.crt \
     -subj &#34;/C=US/ST=Illinois/L=Chicago/O=My YMCA/OU=Org/emailAddress=youremail@example.com&#34;
    
    • The email address in the certificate does not need to match the email on the Connected App.
    • The certificate must be renewed yearly (or after the set number of --days). We recommend you set a reminder in order to prevent unwanted failures.
  2. In Salesforce > Setup > App Manager, create a New Connected App.
    • Set a Name and Email.
      • The Contact Email is not used for authentication.
    • Check Enable OAuth Settings
      • Set the callback url as the base URL of your site
      • Check Use digital signatures and upload the X509 certificate (.crt) created above.
      • Ensure the app has the following Selected OAuth Scopes
        • Full access (full)
        • Manage user data via APIs (api)
        • Manage user data via Web browsers (web)
        • Perform requests at any time (refresh_token, offline_access)
      • Check these options:
        • Require Proof Key for Code Exchange (PKCE) Extension for Supported Authorization Flows
        • Issue JSON Web Token (JWT)-based access tokens for named users
      • Uncheck all other options in the OAuth section.
    • Save the Connected App
  3. Once the app is saved, you will need to get the Consumer Details:
    • In the "My Connected App" screen that appears once you save (or via Setup > App Manager), click Manage Consumer Details.
    • Save the Consumer Key and Consumer Secret for the next step.
  4. Create a Profile OR Permission Set to assign permissions to your app. We recommend using a Permission Set as those are the option recommended by Salesforce.
    1. Your Traction Rec support team should be able to deploy the Traction Rec Activity Finder Permission Set from their dev1 instance. If this Permission Set is deployed, proceed straight to the User creation step. To create a Permission Set from scratch:
      • Setup > Users > Permission Sets > New
      • Fill in the Label as you wish, and leave License as --None--
      • In the new Permission Set, open Object Settings.
      • In the very long list of Object Settings, do the following for each of the 10 Objects listed below:
        • Find the object and click to open it. In the configuration screen for each Object:
          • Under Object Permissions, mark Read as Enabled.
          • Under Field Permissions, mark Read Access on the header field to provide access to all fields.
        • Save the Object Settings and search for the next one.
      • Finally, review the summary of access permissions and ensure Read access is provided for each of the necessary objects.
    2. Create a Profile:
      • You must do this before creating a user.
      • Setup > Users > Profiles > New
      • When asked what Existing Profile to clone from, select Standard User or Standard Platform User. Be sure to note the User License connected to the target profile.
      • In the very large configuration screen, click Edit, then:
      • Save those changes.
  5. Create a new User with the new Profile or Permission Set:
    • Setup > Users > New User
      • User License - The option under which you created the Profile in the previous step, or Salesforce.
      • Email - A working email that you will use to receive login verifications.
      • Username - This is not your email and must be unique across all Salesforce Organizations. This is the name that will be used in the Drupal connection below. If you enter a preexisting username, you will receive this error: > Error: Duplicate Username. > The username already exists in this or another Salesforce organization. Usernames must be unique across all Salesforce organizations. To resolve, use a different username (it doesn't need to match the user's email address).
      • Assign the User to the Profile you created above, or a Permission Set that has the necessary permissions.
        • Under Permission Set Assignments, click Edit Assignments
        • Find the Permission Set you created in the prior step, select it, click Add, then Save.
  6. Confirm your Connected App, Profile, and User are connected:
    • Go to Setup > Apps > Connected Apps > Manage Connected Apps and choose your new app. Assign the Profile or Permission Set that contains your new user if it does not already show under the relevant section.
      • Click Manage Profiles or Manage Permission Sets
      • Search for your Profile or Permission Set and Save.
    • In the Connect App Detail, click Edit Policies:
      • Under OAuth Policies > Permitted Users choose Admin approved users are pre-authorized.
      • Check Issue JSON Web Token (JWT)-based access tokens.
      • Save the Connected App details.

When the process is complete, you should have the following relationships between the User, Permission Set OR Profile, and Connected App:

  • the API User should be assigned the Permission Set OR Profile.
  • the Connected App should be assigned the same Permission Set OR Profile.

Review all of these steps carefully. Missing any of them can result in an inability to query the API.

Salesforce permissions

The Salesforce integration Permission Set OR Profile should have read access to all fields in the following objects:

  • Course Options
  • Courses
  • Course Session Options
  • Course Sessions
  • Locations
  • Products and Discounts
  • Program Categories
  • Program Category Tags
  • Programs
  • Sessions

If using a Profile, it should also have the following Systems Permissions:

  • Apex REST Services
  • View Restriction and Scoping Rules
  • Update Consent Preferences Using REST API

Configure the connection in Drupal

  1. Go to Admin > Configuration > System > Keys (/admin/config/system/keys) and create a new key to store the private key created above.
    • Add key
    • Add a Key name and Description
    • Choose Key Type: "TractionRec JWT Private Key"
    • Choose the Key provider depending on your configuration. See Managing Keys for details.
    • Configure the chosen provider then Save the key.
  2. Go to Admin > YMCA Website Services > Integrations > Traction Rec > Traction Rec auth settings (/admin/openy/integrations/traction-rec/auth) to configure the keys & secrets provided by Traction Rec.
    • Add the Consumer key and Consumer Secret from Manage Consumer Details in Salesforce.
    • Add the User connected to the Connected App.
      • This is the Username of the User, not the Contact email.
    • Enter a Login URL.
      • This will most likely be https://login.salesforce.com
    • Set the Services base URL and REST API Base URL as per their descriptions.
      • Ensure the REST API Base URL responds to curl -I with a 200 response. Replace URLs like *.lightning.force.com with *.my.salesforce.com because the lightning url may result in a redirect, which will cause an authentication error, like ([@&#34;message&#34;:&#34;Session expired or invalid&#34;,&#34;errorCode&#34;:&#34;INVALID_SESSION_ID&#34;]).
    • Set the Community URL based on the publicly accessible registration links.
      • This may be something like https://my-ymca.my.site.com
      • The URL can be found in Salesforce under Setup > Digital Experiences > All Sites.
    • Choose the key as configured above.

Mapping

The TractionRec importer pulls data from many Traction Rec Objects (see TractionRec.php for the full queries):

Object Mapping

The fetcher outputs these files:

  • classes.json - from Courses
    • Maps to both Activities and Classes. Since TREC does not have this distinction, information in the resulting Activities and Classes in Drupal is duplicated.
  • locations.json - from Locations
    • This file is unused, but Locations map to Location via the Session import.
  • program_categories.json - from Program Category Tags
    • Maps to Program.
  • programs.json - from Programs
    • Maps to Program Subcategory.
  • sessions.json - from Course Options
    • Maps to Session.

Note: Traction Rec's labels for "Programs" and their child groupings are different:

  • Traction Rec: "Program Category" is the parent of "Program".
  • Drupal: "Program" is the parent of "Program Subcategory".

Mapping to Drupal fields

Those files are then imported into Drupal content via importers (in config items that start with migrate_plus.). The import goes as follows:

> - Drupal Content Type (bundle) > - Salesforce/TractionRec source fieldDrupal destination field

  • Program - from programs.json / TREC Program Categories
    • Id → id
    • Name → Title
    • Available → Published (status)
  • Program Subcategory - from program_categories.json/ TREC Programs
    • Id → id
    • Name → Title
    • Program → Program (field_category_program) via a lookup to the Programs import
    • Available → Published (status)
  • Activity - from classes.json / TREC Courses
    • Id → id
    • Name → Title
    • Program/Id → Program Subcategory (field_activity_category) via a lookup to the Program Subcategory import
    • Available → Published (status)
  • Class - from classes.json / TREC Courses
    • Id → id
      • The Class Id will also be used to set the Activity (field_class_activity)
    • Name → Title
    • Program/Id → ignored
    • Description/Rich Description → Description (field_class_description)
      • If a Rich Description is set, it will be used, otherwise the Description field will be used.
    • Available → Published (status)
  • Session - from sessions.json / TREC Sessions
    • Course_Option/Name → Title
    • Course_Option/ID → id
      • Also used to generate the Registration link URL using the Community URL set in Traction Rec auth settings (/admin/openy/integrations/traction-rec/auth).
    • Course_Session/Course/Id → Class
    • Course_Session/Course/Name → Course
    • Course_Session/Course/Description & Rich_Description → Description (field_class_description)
      • If a Rich Description is set, it will be used, otherwise the Description field will be used.
    • Course_Option/Start_Date → Session Time > Start date
    • Course_Option/Start_Time → Session Time > Start time
    • Course_Option/End_Date → Session Time > End date
    • Course_Option/End_Time → Session Time > End time
    • Course_Option/Day_of_Week → Session Time > Days
    • Course_Option/Age_Min → Min Age (field_session_min_age) converted to months
    • Course_Option/Age_Max → Max Age (field_session_max_age) converted to months
    • Course_Option/Location/Name → Location (field_session_location)
      • Location Name is used as a backup in case the Location Mapping does not match.
    • Course_Option/Location/Id → Location (field_session_location)
      • Location ID is used to attempt to match a location in the Location mapping in the Traction Rec importer settings (/admin/openy/integrations/traction-rec/importer)
    • Course_Option/Instructor → Instructor (field_session_instructor) trimmed to 255 characters
    • Course_Option/Available_Online → Online registration (field_session_online)
    • Course_Option/Available → Published (status)
    • Course_Option/Register_Online_From_Date → not used
    • Course_Option/Register_Online_To_Date → not used
    • Course_Option/Capacity → Initial Availability (field_availability)
    • Course_Option/Total_Capacity_Available → Initial Availability (field_availability)
    • Course_Option/Unlimited_Capacity → if set, overrides Capacity and sets Initial Availability (field_availability) to 100
    • Course_Option/Unlimited_Waitlist_Capacity → Wait list Unlimited Capacity (waitlist_unlimited_capacity)
    • Course_Option/Waitlist_Total → Wait list capacity (waitlist_capacity)
    • Course_Option/Product/Price_Description → Price description (field_price_description)
    • Course_Session/Id → Class (field_session_class) via a lookup to the Class import

Data Model

This module assumes a Traction Rec "standard" data model in its queries. Any deviations from this model will require overriding the queries in src/TractionRec.php.

This model contains a subset of the fields in Traction Rec that are relevant to our usage. All entities have more fields than listed.

Field types are taken from Salesforce's Setup > Object Manager > {Entity} > Fields & Relationships.

  • Number field options are: number(length_decimal places)
erDiagram
    Program_Category__c {
        id Id
        text(80) Name
    }
    Program__c {
        id Id
        text(80) Name
        checkbox Available__c
        textArea(255) Description__c
    }
    Program_Category_Tag__c {
        id Id
        autoNumber Name
        lookup(Program) Program__c
        lookup(Program_Category) Program_Category_c
    }
    Course__c {
        id Id
        text(80) Name
        checkbox Available__c
        text(128) Code__c
        longTextArea(640) Description__c
        lookup(Program) Program__c
        richTextArea Rich_Description__c
    }
    Course_Session__c {
        id Id
        text(80) Name
        checkbox Available__C
        text(128) Code__c
        lookup(Course) Course__c
        longTextArea(640) Description__c
        number(18_0) Num_Option_Entitlements__c
        lookup(ProductAndDiscount) Product__C
        richTextArea Rich_Description__c
        sum Total_Option_Capacity__c
        formula(number) Total_Option_Capacity_Remaining__C
        sum Total_Option_Registrants__c
        count Total_Options_Available__c
    }
    Course_Option__c {
        id Id
        text(80) Name
        number(3_1) Age_Max__c
        number(3_1) Age_Min__c
        checkbox Available__c
        number(18_0) Capacity__c
        picklist(multiSelect) Day_of_Week__c
        date End_Date__c
        text(8) End_Time__c
        text(128) Instructor__c
        lookup(ProductAndDiscount) Product__c
        number(18_0) Registration_Total_c
        longTextArea(3500) Setup_Notes__c
        number(3_0) Setup_Time_Required___c
        date Start_Date__c
        text(8) Start_Time__c
        longTextArea(3500) Tear_Down_Notes__c
        number(3_0) Tear_Down_Time_Required__C
    }
    Course_Session_Option__c {
        id Id
        autoNumber Name
        lookup(CourseOption) Course_Option__c
        masterDetail(CourseSession) Course_Session__c
        checkbox Option_Available__c
        number(18_0) Option_Capacity__c
        number(18_0) Option_Registration_Total__c
    }
    Program_Category__c ||--|{ Program_Category_Tag__c : &#34;&#34;
    Program__c ||--|{ Program_Category_Tag__c : &#34;&#34;
    Program__c ||--|{ Course__c : &#34;&#34;
    Course__c ||--|{ Course_Session__c : &#34;&#34;
    Course_Session__c ||--|{ Course_Session_Option__c : &#34;&#34;
    Course_Option__c ||--|{ Course_Session_Option__c : &#34;&#34;

Using Google Tag Manager (GTM)

By integrating Google Tag Manager (GTM) with your Salesforce Community, you can enable your marketing team to manage the deployment of marketing tags and tracking pixels, without relying on a developer to modify any code.

You may also want to configure cross-domain tracking on your Drupal site.

Import Process

The module allows you to synchronize classes and programs from the Traction Rec CRM to the YMCA Website Services Program Event Framework (PEF).

It uses Migrate API to import data fetched from Traction Rec and provides Drush commands and a configuration UI.

The import process consists of 2 drush commands:

  1. openy-tr:fetch-all this command fetches required data from Traction Rec and saves it to JSON files.

    • Alias: tr:fetch
  2. openy-tr:import the command migrates fetched JSON files to YMCA Website Services and creates sessions, classes, activities, categories and programs.

    • Alias: tr:import

You can run the commands manually for one-time import or add both to cron jobs.

Other available drush commands:

  • openy-tr:rollback - Rolls back all imported nodes.

    • Alias: tr:rollback
  • openy-tr:reset-lock - Resets import lock.

    • Alias: tr:reset-lock
  • openy-tr:clean-up - Removes imported JSON files from the filesystem.

    • Alias: tr:clean-up
  • openy-tr:quick-availability-sync - Sync total availability data for sessions.

    • Alias: tr:qas

36 - Pull Request Review Standard

Refer to the technical guidelines for code quality best practices.

Adherence to Standards

The YMCA Website Services Core Team adheres to the same standards set for the community across all development areas and technologies, as outlined in the YMCA Website Services documentation.

The YMCA Website Services Core Team reserves the right to deviate from these standards only in the following situations:

  • Emergency: A critical defect or security vulnerability requiring immediate and drastic measures for resolution.
  • When standards are not met, the YMCA Website Services Core Team is responsible for explaining the reasons behind the deviation and defining the updated standards moving forward.
  • This explanation will be communicated via the YMCA Website Services message board, Slack, and the documentation on GitHub, reflecting the new standards.

Requirements for Pull Requests

  • Code in Pull Requests must adhere to our established best practices.
  • Submitters’ profiles on GitHub or Drupal.org should include a name and organization.

Pull Request Template

To ensure high-quality Pull Requests, a PR template is automatically applied to new Pull Requests on GitHub.

The template includes the following requirements:

  • Issue Link: A link to the original issue addressed by the PR.

  • Coding Standards: Confirmation that all coding styles are followed, and no issues are reported by CodeSniffer. Refer to the Code of Conduct.

  • Documentation Updates: Verification that documentation has been updated to reflect the PR changes.

  • Review Steps: Detailed steps for review based on the PR changes.

    Steps for review
  • Upgrade Path Support: Inclusion of all necessary hook_update_N functions to support the upgrade path.

  • Drupal.org Email Association: Confirmation that your Git email is associated with a Drupal.org account to ensure commit attribution.

    drupal.org email
  • Drupal.org Credits: If you want credits on drupal.org, consult the documentation.

37 - Release processes

Repositories Involved in Releases

The following repositories are involved in the release process for YMCA Website Services:

  1. YMCA Website Services Drupal Profile Distribution: YCloudYUSA/yusaopeny - This repository contains the core Drupal profile distribution for YMCA Website Services.
  2. YMCA Website Services Project: YCloudYUSA/yusaopeny-project - This repository is used to initiate a new YMCA Website Services instance. It typically includes the composer.json file and installation scripts.
  3. Continuous Integration/DevOps for YMCA Website Services: YCloudYUSA/yusaopeny-cibox-build - This repository manages the CI/CD processes for rebuilding and installing YMCA Website Services.
  4. CIBox Development Environment: YCloudYUSA/yusaopeny-cibox-vm - This repository contains the configuration for the CIBox development environment, which uses Virtualbox, Docker, and Vagrant.
  5. Docksal Development Environment: YCloudYUSA/yusaopeny-docksal - This repository provides a Docksal-based development environment using Docker and VirtualBox.

Release Management Process

The Lead Architect follows these steps when tagging a new release of YMCA Website Services:

  1. Update the Project Repository: Review, merge, and update the YCloudYUSA/yusaopeny-project repository. This usually involves updating the composer.json file or the one-line installation script. Tag a new release in this repository.
  2. Review and Merge Pull Requests: Review and merge all pull requests in the YCloudYUSA/yusaopeny repository that are planned for the release.
  3. Update the Distribution Version: Change the YMCA Website Services version in the openy.info.yml file located in the yusaopeny repository. The file path is openy.info.yml.
  4. Update Module Versions: If there were changes to major modules (e.g., Activity Finder, PEF), update the YMCA Website Services version in those modules as well.
  5. Create Changelog Release Notes: Create a draft changelog with release notes. Include a list of contributors and major issues fixed or introduced in the release.
  6. Regression Testing: Spin up a copy of an YMCA Website Services site and check top-priority functionality for regressions.
  7. Core Team Review and Approval: Send the release candidate to the Core Team for review and get their approval.
  8. Update Development Version: After approval, change the YMCA Website Services version in openy.info.yml to the next version with the -dev suffix for developers.
  9. Refresh Private Mirror: Refresh the YMCA Website Services private mirror on the openy.cibox.tools CI server.
  10. Verify Version in Site Info: Ensure the version of YMCA Website Services is correct in the site information page (admin/reports/status).
  11. Announce Release - Developers: Publish an announcement in the #developers YMCA Website Services Slack channel.
  12. Announce Release - General: Publish an announcement in the #general YMCA Website Services Slack channel.

38 - Release Schedule and Guidelines

YMCA Website Services Release Guidelines

YMCA Website Services releases major releases of the base project YMCA Website Services and Virtual Y quarterly. Minor releases and sub-project releases occur as needed. These releases impact the base theme openy_lily and modules like ws_small_y.

Major Releases (Quarterly)

Major releases are scheduled for the second Tuesday of the second month of each quarter (February, May, August, November). They are numbered 2.x and may consist of:

  • New Features
  • New Enhancements
  • Bug Fixes

Minor Releases

Minor releases are numbered 2.x.x and consist of:

  • Bug Fixes
  • No new features or major enhancements

Release Schedule

2021

OpenY/VirtualY Releases for 2021

Prior Years

39 - SA-CORE-2018-002 security update

This document is archived but may contain useful information for troubleshooting future updates. For updated update steps, visit How to upgrade YMCA Website Services.


To update your OpenY site with the security fix from Drupal core SA-CORE-2018-002, the OpenY team suggests two options: applying a patch or upgrading Drupal core (or upgrading OpenY). While a Drupal core or OpenY upgrade isn’t always immediately feasible, security issues should be addressed as soon as possible. Therefore, consider applying the patch and planning an OpenY upgrade for later.

How to Apply the Patch

Before you begin, it is crucial to identify the OpenY release version you are using. This will determine the correct patch to apply. You can find your OpenY version in the openy.info.yml file located in the root of your OpenY installation (e.g., /docroot/profiles/contrib/yusaopeny/openy.info.yml). The version key in that file indicates your OpenY version.

Patching OpenY Releases 8.0.1 - 8.1.0 (Drupal core 8.2.x)

For older OpenY releases, it’s highly recommended to upgrade to the latest version of OpenY or at least to a version between 8.1.1 and 8.1.6 (Drupal core 8.3.x) and then upgrade Drupal core to 8.3.9 ( Drupal 8.3.9 Release Notes). If an immediate upgrade isn’t possible, follow these steps:

  1. Log in to your production server: Access your server environment via SSH and locate the docroot folder of your site’s codebase. If you followed an OpenY installation tutorial, you should:

    ssh -l root YOUR_SERVER_DOMAIN_NAME
    cd /var/www/html
    wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/8.2.x.patch
    
  2. Back up the file to be patched: Before applying the patch, create a backup of DrupalKernel.php:

    cp docroot/core/lib/Drupal/Core/DrupalKernel.php /var/backups/DrupalKernel.php
    
  3. Test the patch: Run the following command to check if the patch can be applied successfully:

    patch -p1 --dry-run < 8.2.x.patch
    

    You should see the following output:

    # patch -p1 --dry-run < 8.2.x.patch
    checking file docroot/core/lib/Drupal/Core/DrupalKernel.php
    checking file docroot/core/lib/Drupal/Core/Security/RequestSanitizer.php
    

    If the output differs, stop and seek assistance.

  4. Apply the patch: If the dry run was successful, apply the patch with the following command:

    patch -p1 < 8.2.x.patch
    

    You should see the same output as the dry run, indicating that your site is now patched.

    If the patch fails with an error message like “Hunk #1 FAILED at 123”, this means the file has been modified since the patch was created. You will need to manually resolve the conflicts or revert to a clean version of the file before applying the patch.

    Common causes for patch failures include:

    • The file has been previously patched with a different patch.
    • The file has been customized or modified.
    • The patch is for a different version of Drupal core.

    If you encounter issues, consult the Drupal documentation on patching or seek assistance from the OpenY community.

    After successfully applying the patch, clear the Drupal cache to ensure the changes take effect:

    drush cr
    

Tip: If you’re using a Git repository for your site, run the following commands to commit and push the patched core:

git add docroot/core/lib/Drupal/Core/DrupalKernel.php docroot/core/lib/Drupal/Core/Security/RequestSanitizer.php && git commit -m "Patching OpenY core" && git push

This will store the patched core in your repository.

Patching OpenY Releases 8.1.1 - 8.1.6 (Drupal core 8.3.x)

For these OpenY releases, upgrading to the latest version or at least to one of the 8.1.7-8.1.10 releases (Drupal core 8.4.x) with a Drupal core upgrade to 8.4.6 ( Drupal 8.4.6 Release Notes) is highly recommended. If that is not currently possible, follow these steps:

  1. Log in to your production server: Access your server environment via SSH and locate the docroot folder of your site’s codebase. If you followed an OpenY installation tutorial, you should:

    ssh -l root YOUR_SERVER_DOMAIN_NAME
    cd /var/www/html
    wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/8.3.x.patch
    
  2. Back up the file to be patched: Before applying the patch, create a backup of DrupalKernel.php:

    cp docroot/core/lib/Drupal/Core/DrupalKernel.php /var/backups/DrupalKernel.php
    
  3. Test the patch: Run the following command to check if the patch can be applied successfully:

    patch -p1 --dry-run < 8.3.x.patch
    

    You should see the following output:

    # patch -p1 --dry-run < 8.3.x.patch
    checking file docroot/core/lib/Drupal/Core/DrupalKernel.php
    checking file docroot/core/lib/Drupal/Core/Security/RequestSanitizer.php
    

    If the output differs, stop and seek assistance.

  4. Apply the patch: If the dry run was successful, apply the patch with the following command:

    patch -p1 < 8.3.x.patch
    

    You should see the same output as previously, indicating that your site is now patched.

    After successfully applying the patch, clear the Drupal cache to ensure the changes take effect:

    drush cr
    

Tip: If you’re using a Git repository for your site, run:

git add docroot/core/lib/Drupal/Core/DrupalKernel.php docroot/core/lib/Drupal/Core/Security/RequestSanitizer.php && git commit -m "Patching OpenY core" && git push

to store your patched core into your own repository.

Patching OpenY Releases 8.1.7 - 8.1.9 (Drupal core 8.4.x)

For these OpenY releases, it is highly recommended to upgrade to the latest version (8.1.10 or later) or at least to version 8.1.10 (Drupal core 8.4.x) with a Drupal core upgrade to 8.4.6 ( Drupal 8.4.6 Release Notes). If that is not currently possible, follow these steps:

  1. Log in to your production server: Access your server environment via SSH and locate the docroot folder of your site’s codebase. If you followed an OpenY installation tutorial, you should:

    ssh -l root YOUR_SERVER_DOMAIN_NAME
    cd /var/www/html
    wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/8.4.x.patch
    
  2. Back up the file to be patched: Before applying the patch, create a backup of DrupalKernel.php:

    cp docroot/core/lib/Drupal/Core/DrupalKernel.php /var/backups/DrupalKernel.php
    
  3. Test the patch: Run the following command to check if the patch can be applied successfully:

    patch -p1 --dry-run < 8.4.x.patch
    

    You should see the following output:

    # patch -p1 --dry-run < 8.4.x.patch
    checking file docroot/core/lib/Drupal/Core/DrupalKernel.php
    checking file docroot/core/lib/Drupal/Core/Security/RequestSanitizer.php
    

    If the output differs, stop and seek assistance.

  4. Apply the patch: If the dry run was successful, apply the patch with the following command:

    patch -p1 < 8.4.x.patch
    

    You should see the same output as previously, indicating that your site is now patched.

    After successfully applying the patch, clear the Drupal cache to ensure the changes take effect:

    drush cr
    

Tip: If you’re using a Git repository for your site, run:

git add docroot/core/lib/Drupal/Core/DrupalKernel.php docroot/core/lib/Drupal/Core/Security/RequestSanitizer.php && git commit -m "Patching OpenY core" && git push

to store your patched core into your own repository.

==========================

How to Patch Your DigitalOcean OpenY Install

If you followed a tutorial to install OpenY on DigitalOcean, your OpenY installation should be located in a predictable folder. This section provides a simplified method for patching your OpenY site, designed for users who are not technical experts.

  1. Log in to your site: Log in to your site’s administrative interface as an administrator by visiting the /user/login URL.

  2. Check Drupal Version: Go to /admin/reports/status after login and search for Drupal Version string. It should be something like 8.2.x, 8.3.x or 8.4.x (x - some number too, like 8.4.2, for example). Based on your finding follow the steps below to your version

  3. Access the DigitalOcean Console: Log in to your DigitalOcean cloud console at digitalocean.com and find “Access Console” in the dropdown menu for the droplet you’re using for OpenY.

    DigitalOcean Access Console

  4. Log in to the Console: A popup window with a black screen will appear, prompting you for login credentials. Use root as the username and the password generated for you when the droplet was created.

  5. Run the Patch Script: After logging in to the console, run the command corresponding to your Drupal core version.

One-Line Script to Patch 8.2.x Drupal Core for OpenY

Type the following line manually and press Enter:

bash < <(curl -s https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/run8.2.x.sh)

You should see the message OpenY was patched.

One-Line Script to Patch 8.3.x Drupal Core for OpenY

Type the following line manually and press Enter:

bash < <(curl -s https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/run8.3.x.sh)

You should see the message OpenY was patched.

One-Line Script to Patch 8.4.x Drupal Core for OpenY

Type the following line manually and press Enter:

bash < <(curl -s https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/run8.2.x.sh)

You should see the message OpenY was patched.

40 - Sandboxes

YMCA Website Services Sandboxes for Evaluation and QA

The YMCA Website Services core team manages sandboxes for various configurations of the distribution. These sandboxes facilitate evaluation, assist with QA, and enable investigation of issues.

Getting Started

Anyone can browse the sandboxes at sandboxes.y.org.

Sandbox Access

To test the content editor experience or explore the Drupal configuration, request login access by emailing us or contacting a project team member on the Y-USA Slack. Please include the specific sandbox you need access to and a brief explanation of your testing goals.

Learn More

Sandbox Contents

Each set of sandboxes includes these profile variations:

  • Standard
  • Extended
  • Custom

Currently, all sandboxes use only one theme:

  • Carnation

Multiple sandbox environments are available:

Stable Sandboxes

sandboxes.y.org

Stable sandboxes are based on the latest stable release of YMCA Website Services. They rebuild completely overnight and clear their database and files every 2 hours. This ensures a clean testing environment.

These sandboxes are built on CI by running:
composer create-project YCloudYUSA/yusaopeny-project buildnew --no-interaction --prefer-dist

ansible-playbook docroot/reinstall.yml -i /tmp/inventory5068801741271597001.ini -f 5 -e php_env_vars=APP_ENV=dev -e mysql_user=*** -e mysql_password=*** -e mysql_db=sandbox_carnation_custom -e drupal_folder=/var/www/sandbox_carnation_custom -e site_url=https://sandbox-carnation-cus.y.org -e pp_environment=demo -e run_reinstall=true -e "openy_profile_install_settings='openy_configure_profile.preset=complete openy_theme_select.theme=openy_carnation'" -e use_solr=false -i localhost, --connection=local -vvvv

Development Sandboxes

These sandboxes are based on the latest development version of YMCA Website Services or other branches as necessary. They rebuild daily but are not guaranteed. If one isn’t working, try another.

These sandboxes are built on CI by running:
composer create-project YCloudYUSA/yusaopeny-project:dev-9.2.x-development buildnew --no-interaction --prefer-dist

ansible-playbook docroot/reinstall.yml -i /tmp/inventory5068801741271597001.ini -f 5 -e php_env_vars=APP_ENV=dev -e mysql_user=*** -e mysql_password=*** -e mysql_db=sandbox_carnation_custom -e drupal_folder=/var/www/sandbox_carnation_custom -e site_url=https://sandbox-carnation-cus.y.org -e pp_environment=demo -e run_reinstall=true -e "openy_profile_install_settings='openy_configure_profile.preset=complete openy_theme_select.theme=openy_carnation'" -e use_solr=false -i localhost, --connection=local -vvvv

Feature-Based Sandboxes

Sandboxes with specific features enabled are also maintained. Each of these builds include the listed features:

Virtual Y Sandboxes

These sandboxes use the YMCA Website Services stable Standard profile and the Virtual Experience Platform (aka “Virtual Y”, aka “Open Y Gated Content”) project.

Membership Framework Sandboxes

These sandboxes use the YMCA Website Services stable Standard profile and the development version of the Membership Framework.

To rebuild the sandbox, CI is running:
composer create-project YCloudYUSA/yusaopeny-project buildnew --no-interaction --prefer-dist
cd buildnew
composer config minimum-stability dev
composer require "openy/openy_memberships":"dev-master as 1.0.0"
ansible-playbook docroot/reinstall.yml -i /tmp/inventory13097841656330601319.ini -f 5 -e php_env_vars=APP_ENV=dev -e mysql_user=*** -e mysql_password=*** -e mysql_db=d9_sandbox_carnation_std_membership_framework -e drupal_folder=/var/www/d9_sandbox_carnation_std_membership_framework -e site_url=https://sandbox-carnation-std-membership-framework-d9.y.org -e pp_environment=membership_framework -e run_reinstall=true -e "openy_profile_install_settings='openy_configure_profile.preset=standard openy_theme_select.theme=openy_carnation openy_select_content.content=0'" -e use_solr=false -i localhost, --connection=local -vvvv

Activity Finder Sandboxes

ThemeLinkWS ProfileActivity FinderThemeBootstrap
CarnationActivity FinderStableCustomv4 devv4
Carnation (with TractionRec importer)Traction WSStableCustomv4 devv4
To rebuild the sandbox, CI is running:
composer create-project YCloudYUSA/yusaopeny-project:dev-9.2.x-development-af4 build --no-interaction --prefer-dist
cd ${WORKSPACE}/build
composer require YCloudYUSA/yusaopeny_activity_finder:"4.x-dev as 4.0"

ansible-playbook docroot/reinstall.yml -i /tmp/inventory4660848605526222353.ini -f 5 -e php_env_vars=APP_ENV=dev -e mysql_user=*** -e mysql_password=*** -e mysql_db=d9_sandbox_carnation_custom -e drupal_folder=/var/www/d9_sandbox_carnation_custom -e site_url=https://sandbox-carnation-cus-d9.y.org -e pp_environment=demo -e run_reinstall=true -e "openy_profile_install_settings='openy_configure_profile.preset=complete openy_theme_select.theme=openy_carnation'" -i localhost, --connection=local -vvvv

# Solr 4.5-4.9, Activity Finder v4
drush en -y search_api_solr_legacy openy_prgf_activity_finder_4 || true
drush cset -y search_api.server.solr backend_config.connector_config.host 127.0.0.1 -y || true
drush cset -y search_api.server.solr backend_config.connector_config.core ${VHOST_FOLDER} -y
drush cset -y search_api.server.solr backend_config.connector_config.solr_version 4.5 -y
drush search-api-mark-all || true
drush sapi-i || true
drush en -dvy openy_prgf_af4_demo || true

# Solr 4.5-4.9, Activity Finder v4, Carnation theme, bootstrap v4
drush cset -y openy_activity_finder.settings bs_version 4 || true

41 - Secure DevOps for Composer 2 Release

This article primarily applies to long-term users of YMCA Website Services. YMCA Website Services supports Composer 2 as of version 8.2.7, released in November 2020. New installations of YMCA Website Services use Composer 2 by default. You can find the release notes here.


Composer was upgraded to version 2.x on October 30, 2020. An older Composer version (1.x) might accidentally auto-update to version 2.x, potentially causing instability. Issues might include Composer failing to run commands, which would block OpenY upgrades or maintenance. This instability would occur in the developer environment, not within YMCA Website Services or Drupal itself.

The YMCA Website Services team prepared an avoidance plan for the community to take action before the release, while YMCA Website Services verified that Composer 2.x caused no issues or regressions.

If you use Docksal or Vagrant local environments, your Composer version will not update automatically, so you are currently safe from inadvertent updates. Instructions for updating these environments will be included with any necessary YMCA Website Services updates at a later date.

If you are on Composer 1.x before October 30, 2020

With Composer 2 on the horizon, older versions of Composer 1.x may display the following message:

Composer 2.0 is about to be released and the older 1.x releases will self-update directly to it once it is released. To avoid surprises update now to the latest 1.x version

If you see this message, ensure your environments have updated Composer to the latest 1.x version by running:

composer selfupdate --1

To verify that the command updated to version 1.x, check the Composer version:

composer --version

You should see output similar to the following:

MacBook-Pro-Andrii:www podarok$ composer --version
Composer version 1.10.15 2020-10-13 15:59:09

If you accidentally upgrade to Composer 2.x before upgrading to the latest 1.x version (before October 30, 2020)

If Composer has updated to version 2 and you are experiencing issues, downgrade Composer to the latest 1.x version by running:

composer selfupdate --1

If you encounter any issues, connect with the YMCA Website Services team on GitHub ( create issue) or the #developers channel on Slack.

42 - Server Requirements

If you need to prepare a server for the YMCA Website Services instance, the information below outlines the necessary software and configurations.

Requirements

  1. Operating System: Ubuntu LTS (Long Term Support) versions 14 or 16 are preferred. CentOS is also acceptable. Other Linux distributions may work, but have not been fully tested by the YMCA Website Services team.

  2. Drupal 8/9/10 Requirements: Meet the server requirements specified by Drupal.

  3. PHP: PHP 7.4 or higher is strongly recommended for performance and security reasons. Refer to the specific Drupal version’s documentation for supported PHP versions.

PHP Modules

The following PHP modules are required:

  • php
  • php-cli
  • php-common
  • php-curl
  • php-fpm
  • php-gd
  • php-mysql or php-pgsql (depending on your database)
  • php-intl
  • php-mbstring
  • php-xml
  • php-zip
  • php-opcache (recommended)
  • imagick (recommended for image processing)
  • memcached or redis (for caching)

Note: Replace php with the specific PHP version (e.g., php7.4, php8.1). Use your system’s package manager (e.g., apt, yum) to install these modules.

  1. Database Server: MySQL 5.7+ or MariaDB 10.3+ are recommended. PostgreSQL is also supported. Optimized MySQL settings can be found at cibox/cibox. Note that these settings may need adjustments based on your specific server resources and workload.

  2. Web Server: Apache 2 with mod_php (known for stability) or Nginx with php-fpm (better for speed and scalability)

    • Apache: libapache2-mod-php
    • Nginx: Requires configuration to proxy PHP requests to php-fpm.
  3. Caching (Optional but Recommended):

    • Memcached server
    • Redis server
  4. Server Tools (Optional):

    • Ansible (for provisioning and configuration management)
    • Docker (for containerization)
    • SOLR 4.x or higher (for advanced search functionality)
    • Varnish (for HTTP caching and acceleration)

Note: Ensure that your firewall is properly configured and only necessary ports are open for security reasons. Regularly update your server software to patch security vulnerabilities.

43 - Smoke Tests Index

Smoke Tests Overview

Smoke tests are a type of software testing that verifies the most important functions of a system are working. The purpose is to ensure that the application is stable enough for further testing. The following links provide access to smoke tests for various components of the YMCA Website Services platform.

Core and Dependencies Smoke Tests

YMCA Website Services Features Smoke Tests

44 - Start new YMCA Website Services project

Here you can find instructions on how you can start a project based on the YMCA Website Services distribution.

New project from scratch based on YMCA Website Services

To start a new project from scratch, you can use the installation instructions. These instructions will guide you through building your project and even setting up a development environment.

Add YMCA Website Services to an existing Drupal 10 project

To add YMCA Website Services to an existing Drupal 10 project, you’ll need to modify your composer.json file. Here’s a step-by-step guide:

Please take a look at the full composer.json file below that you should eventually get.

Example composer.json (Drupal 10 + YMCA Website Services)
{
    "name": "drupal/drupal",
    "description": "Drupal is an open source content management platform powering millions of websites and applications.",
    "type": "project",
    "license": "GPL-2.0+",
    "require": {
        "composer/installers": "^1.9",
        "wikimedia/composer-merge-plugin": "~2.0",
        "YCloudYUSA/yusaopeny": "2.0.*",
        "cweagans/composer-patches": "^1.7"
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "config": {
        "preferred-install": "dist",
        "sort-packages": true,
        "platform-check": false
    },
    "extra": {
        "drupal-scaffold": {
            "locations": {
                "web-root": "docroot/"
            }
        },
        "installer-types": [
            "drupal-module",
            "drupal-theme",
            "drupal-profile",
            "drupal-drush",
            "drupal-library",
            "drupal-core"
        ],
        "installer-paths": {
            "docroot/core": [
                "type:drupal-core"
            ],
            "docroot/libraries/{$name}": [
                "type:drupal-library"
            ],
            "docroot/modules/contrib/{$name}": [
                "type:drupal-module"
            ],
            "docroot/profiles/contrib/{$name}": [
                "type:drupal-profile"
            ],
            "docroot/themes/contrib/{$name}": [
                "type:drupal-theme"
            ],
            "docroot/drush/contrib/{$name}": [
                "type:drupal-drush"
            ],
            "docroot/modules/custom/{$name}": [
                "type:drupal-custom-module"
            ],
            "docroot/themes/custom/{$name}": [
                "type:drupal-custom-theme"
            ]
        },
        "enable-patching": true,
        "patchLevel": {
            "drupal/core": "-p2"
        }
    },
    "autoload": {
        "classmap": [
            "scripts/composer/ScriptHandler.php"
        ],
        "files": [
            "docroot/core/includes/bootstrap.inc"
        ]
    },
    "scripts": {
        "drupal-scaffold": "DrupalComposer\\DrupalScaffold::scaffold",
        "pre-install-cmd": [
            "DrupalComposer\\DrupalScaffold::preInstallCmd"
        ],
        "pre-update-cmd": [
            "DrupalComposer\\DrupalScaffold::preUpdateCmd"
        ],
        "post-install-cmd": [
            "DrupalComposer\\DrupalScaffold::postInstallCmd",
            "DrupalComposer\\DrupalScaffold::createRequiredFiles",
            "DrupalComposer\\DrupalScaffold::removePatchesDir",
            "DrupalComposer\\DrupalScaffold::removeVendorGitFolders"
        ],
        "post-update-cmd": [
            "DrupalComposer\\DrupalScaffold::postUpdateCmd",
            "DrupalComposer\\DrupalScaffold::createRequiredFiles",
            "DrupalComposer\\DrupalScaffold::removePatchesDir",
            "DrupalComposer\\DrupalScaffold::removeVendorGitFolders"
        ],
        "post-create-project-cmd": [
            "DrupalComposer\\DrupalScaffold::postCreateProjectCmd",
            "DrupalComposer\\DrupalScaffold::removePatchesDir",
            "DrupalComposer\\DrupalScaffold::removeVendorGitFolders"
        ],
        "remove-vendor-git-folders": [
            "bash scripts/remove_vendor_git_folders.sh || :"
        ]
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://packages.drupal.org/10"
        },
        {
            "type": "package",
            "package": {
                "name": "library-kenwheeler/slick",
                "version": "1.8.1",
                "type": "drupal-library",
                "source": {
                    "url": "https://github.com/kenwheeler/slick",
                    "type": "git",
                    "reference": "1.8.1"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-dinbror/blazy",
                "version": "1.10.3",
                "type": "drupal-library",
                "source": {
                    "url": "https://github.com/dinbror/blazy",
                    "type": "git",
                    "reference": "v1.10.3"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-gdsmith/jquery.easing",
                "version": "1.4.1",
                "type": "drupal-library",
                "source": {
                    "url": "https://github.com/gdsmith/jquery.easing",
                    "type": "git",
                    "reference": "1.4.1"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-enyo/dropzone",
                "version": "5.7.6",
                "type": "drupal-library",
                "source": {
                    "url": "https://github.com/enyo/dropzone",
                    "type": "git",
                    "reference": "v5.7.6"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-jaypan/jquery_colorpicker",
                "version": "1.0.1",
                "type": "drupal-library",
                "source": {
                    "url": "https://github.com/jaypan/jquery_colorpicker",
                    "type": "git",
                    "reference": "da978ae124c57817021b3166a31881876882f5f9"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-ckeditor/panelbutton",
                "version": "4.7.0",
                "type": "drupal-library",
                "dist": {
                    "url": "http://download.ckeditor.com/panelbutton/releases/panelbutton_4.7.0.zip",
                    "type": "zip"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-ckeditor/colorbutton",
                "version": "4.7.0",
                "type": "drupal-library",
                "dist": {
                    "url": "http://download.ckeditor.com/colorbutton/releases/colorbutton_4.7.0.zip",
                    "type": "zip"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-ckeditor/colordialog",
                "version": "4.7.0",
                "type": "drupal-library",
                "dist": {
                    "url": "http://download.ckeditor.com/colordialog/releases/colordialog_4.7.0.zip",
                    "type": "zip"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-ckeditor/glyphicons",
                "version": "2.2",
                "type": "drupal-library",
                "dist": {
                    "url": "http://download.ckeditor.com/glyphicons/releases/glyphicons_2.2.zip",
                    "type": "zip"
                }
            }
        }
    ]
}
  1. Add YMCA Website Services as a dependency:

    Add "YCloudYUSA/yusaopeny": "2.0.*" to the require section of your composer.json. This line specifies that you want to include the YMCA Website Services package, version 2.x, in your project. See example.

  2. Add required repositories:

    Add all the necessary repositories, as listed here, to your composer.json. These repositories provide information about where to find the required libraries and packages.

  3. Configure installer paths:

    Add the installer paths configuration to your composer.json. This configuration tells Composer where to place different types of packages (modules, themes, etc.) within your Drupal installation. See example.

    • If your composer.json is located inside the docroot directory, use the following:

      "installer-paths": {
          "core": ["type:drupal-core"],
          "libraries/{$name}": ["type:drupal-library"],
          "modules/contrib/{$name}": ["type:drupal-module"],
          "profiles/contrib/{$name}": ["type:drupal-profile"],
          "themes/contrib/{$name}": ["type:drupal-theme"],
          "drush/contrib/{$name}": ["type:drupal-drush"],
          "modules/custom/{$name}": ["type:drupal-custom-module"],
          "themes/custom/{$name}": ["type:drupal-custom-theme"]
      }
      
    • If your composer.json is located outside the docroot directory, use the following:

      "installer-paths": {
          "docroot/core": ["type:drupal-core"],
          "docroot/libraries/{$name}": ["type:drupal-library"],
          "docroot/modules/contrib/{$name}": ["type:drupal-module"],
          "docroot/profiles/contrib/{$name}": ["type:drupal-profile"],
          "docroot/themes/contrib/{$name}": ["type:drupal-theme"],
          "docroot/drush/contrib/{$name}": ["type:drupal-drush"],
          "docroot/modules/custom/{$name}": ["type:drupal-custom-module"],
          "docroot/themes/custom/{$name}": ["type:drupal-custom-theme"]
      }
      
  4. Enable Composer Patches:

    Add "cweagans/composer-patches": "^1.7" to the require section of your composer.json. This allows you to apply patches to contributed modules and themes. See example.

  5. Enable patching in extra section:

    Add "enable-patching": true to the extra section in your composer.json. See example.

  6. Disable Secure HTTP:

    Add "secure-http": false to the config section in your composer.json. See example.

  7. Clean up:

    Remove the composer.lock file and the vendor directory from your project if they exist. This ensures that you’re starting with a clean slate and that Composer will resolve all dependencies correctly.

  8. Remove “replace” section:

    Remove the "replace" section from your composer.json file. This section is not typically needed and can sometimes cause conflicts.

  9. (Optional) Clean up vendor Git folders:

    If you keep the vendor directory in your Git repository, it’s recommended to remove the .git folders inside modules and libraries. To do this:

    • Add the cleaner script from the YMCA Website Services composer package to your project. You can copy and paste the script.

    • Adjust the folders that you want to clean up in the script.

    • Execute the script in the post-install-cmd and post-update-cmd sections of your composer.json:

      "post-install-cmd": [
          "bash scripts/remove_vendor_git_folders.sh || :"
      ],
      "post-update-cmd": [
          "bash scripts/remove_vendor_git_folders.sh || :"
      ]
      
  10. Run Composer Install:

    Run composer install to install the YMCA Website Services and its dependencies. This command reads your composer.json file and downloads the specified packages into the vendor directory.

CIBox

In this section you can learn how to configure development environment and CI server using Open Source product CIBox.

Create project

  1. Generate project based on this quickstart

  2. Add YMCA Website Services to the project using (Add YMCA Website Services to already existing Drupal 10 project)

  3. Init git and add initial commit

cd OPENY_PROJECT
git init
git commit -m "Init YMCA Website Services project"
git remote add origin git@github.com:NAMESPACE/PROJECT.git
git push -u origin master
  1. Spin up your local vagrant machine
vagrant up --provision
  1. Setup CI server for new project based on CIBox documentation.
  • Follow quick start starting from Jenkins Provisioning Step http://docs.cibox.tools/en/latest/Quickstart/#jenkins-provisioning (Here we will get PR builds and DEMO site (DEV environment) with credentials to it )
  • Setup hosting STAGE environment (it should be a 1:1 copy of existing or expected hosting account for ability to provide performance testing there)
  • Setup deployment plans for CI by reusing DEMO builder job

Install YMCA Website Services on DigitalOcean

  1. Create new Droplet using “One-click apps” image Drupal 8.*.* on 14.04
  2. Login to server via SSH or web console
  3. Run command
bash <(curl -s https://raw.githubusercontent.com/YCloudYUSA/yusaopeny/8.x-1.x/build/openy-digital-ocean.sh)
  1. Open link(e.g. http://IP/core/install.php) from console output and finish YMCA Website Services installation

Video tutorial

YMCA Website Services v1.0b - Install Tutorial

End to end installation

YMCA Website Services install - in 16 minutes end to end, no tutorial

45 - technology pipeline

To deliver the best technologies for the YMCA movement, the YMCA Website Services development community maintains the following documents and best practices. This pipeline outlines the standards, processes, and resources used to develop and maintain the YMCA Website Services platform.

  1. Development FAQ
  2. YMCA Website Services Coding Standards
  3. How new technologies and features are added to YMCA Website Services
  4. Sandboxes - Development environments for testing and experimentation.
  5. Smoke Tests
  6. A Slack Team by invite with a #developers channel where we discuss technical issues with our partners and YUSA. Request an invitation to join the Slack team for real-time collaboration and discussions.
  7. A YouTube playlist for Developers - A collection of helpful videos for developers.
  8. A list of 3rd party dependencies which are reviewed periodically for new features and deprecations. - Regularly reviewed for updates, security vulnerabilities, and compatibility.

46 - Terms and Conditions

These Terms & Conditions must be agreed to upon installing YMCA Website Services

These terms are maintained in the distribution codebase at TermsOfUseForm.php and are subject to change at any time. Any change in the terms will require site owners to agree to the new terms and a record of the date of agreement is maintained in the site database. Terms can be viewed on your site at Admin > YMCA Website Services > Terms and Conditions (/admin/openy/terms-and-conditions).


  • We agree to the Participant Agreement and Terms of Use
  • YMCA of the USA supports the Website Services platform with respect to use by its Member Associations but is not responsible for and does not control the services provided by 3rd party agencies, which are using and modifying YMCA Website Service distribution.
  • YMCA of the USA recommends that each participating YMCA association develop and implement its own cybersecurity policies and obtain cyber liability and data privacy insurance.
  • I acknowledge that YMCA Website Service is open source content and that all content is provided “as is” without any warranty of any kind. YMCA of the USA makes no warranty that its services will meet your requirements, be safe, secure, uninterrupted, timely, accurate, or error-free, or that your information will be secure. YMCA of the USA will not maintain and support YMCA Website Service templates indefinitely. The entire risk as to the quality and performance of the content is with you.
  • YMCA of the USA recommends obtaining a reputable agency to assist with the implementation of the YMCA Website Service platform and further development for your specific needs.
  • All demonstration content, including but not limited to text, images, graphics, videos, audio, and any other materials displayed on this website, is the exclusive property of YMCA of the USA. The demonstration content is provided solely for illustrative purposes and to showcase the capabilities of YMCA’s Website Service. Nonetheless, YMCA member associations may use demonstration content for their websites, as applicable.
    • By accessing and/or using this website, you agree to respect the ownership and intellectual property rights of YMCA of the USA over the demonstration content. Users and visitors are strictly prohibited from reproducing, distributing, modifying, or otherwise using the demonstration content without explicit written permission from YMCA of the USA.
    • Any unauthorized use or misuse of the demonstration content is a violation of these Terms and Conditions and may be subject to applicable laws and regulations, result in your access being revoked, and/or legal action taken, if applicable.
    • YMCA of the USA reserves the right to change, modify, or remove the demonstration content from the website at any time without prior notice. We are not responsible for any inaccuracies or errors in the demonstration content and make no guarantees about its accuracy or completeness.

47 - Testing YMCA Website Services for PHP 7.4 version support

Requirements

  • php-cli 7.4 ( memory_limit value should be large (2000M) or unlimited (-1) in order to not fail)
  • Composer 2

Steps

  1. Obtain the latest development code of YMCA Website Services.

    composer create-project YCloudYUSA/yusaopeny-project:9.2.x-development-dev openy7.4
    
  2. Add phpcompatibility to the require-dev section.

    cd openy7.4
    composer require --dev phpcompatibility/php-compatibility
    ./vendor/bin/phpcs -p . --standard=PHPCompatibility --runtime-set testVersion 7.4 --config-set installed_paths vendor/phpcompatibility/php-compatibility
    
  3. Generate a report.

    ./vendor/bin/phpcs -p . --standard=PHPCompatibility --runtime-set testVersion 7.4 --report-file=report.txt
    

    Or, if you need to skip warnings:

    ./vendor/bin/phpcs -p . --standard=PHPCompatibility --runtime-set testVersion 7.4 --report-file=report.txt -n
    

    In report.txt, you’d find a full list of findings to be resolved in order to pass compatibility.

48 - Tests

These instructions explain how you can run tests.

Behat

Requirements

Run Full Test Suite

  1. Execute the following commands:

    cd profiles/contrib/openy
    sh runtests.sh
    
  2. Open http://site.com/profiles/contrib/openy/build/reports/behat in your browser to view the test results.

Run Selenium Container + Behat Tests

To run only the Selenium container and Behat tests:

cd profiles/contrib/openy
sh runtests.sh --tags run_selenium
bin/behat

Stop Selenium Container

To stop the Selenium container:

cd profiles/contrib/openy
sh runtests.sh --tags stop_selenium

If necessary, edit behat.local.yml to match your environment.

Visual Debugging - Video

When developing JS tests, it’s important to see what’s happening on the Selenium screen. You can easily do this during development.

  1. Install the RealVNC Viewer.

  2. Run Selenium using the following command:

    cd profiles/contrib/openy
    sh runtests.sh --tags run_selenium
    
  3. Open the installed VNC Viewer and connect to the server with IP 192.168.56.132:5901.

    • Password: secret
  4. Run the tests. You should see everything performed by the Behat tests in the VNC client.

    bin/behat
    

Debugging JavaScript Behat tests

Custom Behat Functionality

  • Create entities in table forms, with a key to use for reference and reference entities by key.

    • KEY is optional and must be all CAPS.

    • Taxonomy

      Given I create "taxonomy_term" of type "color" with key for reference:
        | KEY  | name  | field_color |
        | Blue | Blue  | 0000FF      |
        | Red  | Red   | FF0000      |
      
    • Paragraphs

      Given I create "paragraph" of type "small_banner" with key for reference:
        | KEY     | field_prgf_headline | field_prgf_color |
        | banner1 | Headline 1          | Blue             |
        | banner2 | Headline 2          | Red              |
      
    • Media entities

      Given I create "media" of type "image" with key for reference:
        | KEY       | name            | file         |
        | gallery_1 | Gallery image 1 | gallery.png  |
        | gallery_2 | Gallery image 2 | gallery2.png |
        | gallery_3 | Gallery image 3 | gallery3.png |
      
  • Create nodes in table forms, with a key to use for reference and reference entities by key.

    • KEY is optional and must be all CAPS.

    • Basic create

      Given I create "landing_page" content:
        | KEY       | title           | field_lp_layout | field_content |
        | landing_1 | Test Landing 01 | one_column      | banner1       |
        | landing_2 | Test Landing 02 | one_column      | banner2       |
      
    • Vertical field table

      Given I create large "landing_page" content:
        | KEY             | landing_3       | landing_4       |
        | title           | Test Landing 03 | Test Landing 04 |
        | field_lp_layout | one_column      | one_column      |
        | field_content   | banner1         | banner2         |
      
    • Create & view immediately

      Given I view a "landing_page" content:
        | KEY             | landing_5       |
        | title           | Test Landing 05 |
        | field_lp_layout | one_column      |
        | field_content   | banner1         |
      
    • Multiple referenced entities by key on a field.

      Given I create "landing_page" content:
        | KEY       | title           | field_lp_layout | field_content    |
        | landing_6 | Test Landing 06 | one_column      | banner1, banner2 |
      

Example Address and Latitude + Longitude

Fields with subfields/columns: The machine name and columns can be found in the form markup in the field name property.

Inspect form field name depicted

The first portion, field_location_address, represents the Drupal field machine name, while the second array key, address_line1, represents the column.

  • Add Address

    Given I view a "branch" content:
        | title                                | Branch Example  |
        | field_location_address:country_code  | US             |
        | :address_line1                       | Main road 10   |
        | :locality                            | Seattle        |
        | :administrative_area                 | WA             |
        | :postal_code                         | 98101          |
    
  • Add Latitude and Longitude

    Given I view a "branch" content:
      | title                          | Branch Example 2 |
      | field_location_coordinates:lat | 47.293433        |
      | :lng                           | -122.238717      |
      | field_location_phone           | +1234567890      |
    

49 - Theming and Design

Welcome to YMCA Website Services Theming and Design documentation.

How to Change Styles on a Content Type Level

Given: As a YMCA Website Services site developer, I want to be able to easily change the CSS for a Camp page independently from a Location page, so I can better customize the site to meet the needs of my customers.

How to:

  1. Enable Custom CSS: Navigate to the theme configuration page and check “Enable or disable custom CSS” within the “Custom CSS” section.
  2. Input CSS Code: Enter your custom CSS code into the provided textarea.

To target CSS changes to specific pages, use the following selectors:

  • .page-node-type-{node-type} - Targets pages based on their content type. For example, .page-node-type-camp would apply styles only to Camp pages.
  • .node-id-{node-ID} - Targets a specific page based on its node ID. For example, .node-id-123 would apply styles only to the page with a node ID of 123.
  • .path-frontpage - Targets the site’s front page.

Here’s a list of existing node types in the YMCA Website Services distribution:

  • activity
  • alert
  • blog
  • branch
  • camp
  • class
  • facility
  • landing-page
  • membership
  • news
  • program
  • program-subcategory
  • session

Example:

To change the background color of all Camp pages to light blue, you would add the following CSS to the Custom CSS textarea:

.page-node-type-camp {
  background-color: lightblue;
}

Important Considerations:

  • CSS Specificity: Be aware of CSS specificity when writing your custom styles. More specific selectors will override less specific selectors. You may need to use !important in some cases, but it’s generally best to avoid it if possible by writing more specific selectors.
  • Theme Updates: Custom CSS is stored in the database. Theme updates will not overwrite your CSS changes.
  • Performance: While Custom CSS provides flexibility, excessive use of custom CSS can impact site performance. Consider using a child theme for more extensive customizations.
  • Alternative approach: If you are developing a new module or a small customization, consider using SASS following the info in /docroot/modules/contrib/paragraphs/css/README.md or /docroot/modules/contrib/ws_small_y/README.md.

50 - Tour

Using YMCA Website Services Tour Tokens

Some modules offer tour tips. To enhance interactivity, you can add a token that triggers an action (like a click) on a specific selector.

Important: Tours provide users with guided tours of the administrative interface, highlighting elements and explaining key concepts. Users need “Access tour” permission and JavaScript enabled in their browsers to view tours.

Adding a Token

  1. Locate the Tour YAML file: Open the tour’s YAML configuration file within your module. Configuration project add/update form

  2. Edit the Tip: Select the specific tour tip you want to modify. Within the tip’s body, insert the token using the following format: [openy_tour:click:button_name:selector] Configuration project add/update form

  3. Apply the Changes: Implement a hook update for your changes and run drush updb -y in the command line to apply the database updates.

Token Components

[openy_tour:click:button_name:selector]
  • openy_tour: (Required) This is the base token name.
  • click: (Required) This is the command to execute. Currently, click is the only supported command, which simulates a user click.
  • button_name: (Required) The text to display on the button within the tour tip.
  • selector: (Required) A jQuery selector that identifies the element to be clicked. Ensure the selector accurately targets the desired element on the page.

Example:

[openy_tour:click:Add content:.toolbar-icon-node-add]

This token will render a button with the text “Add content” in the tour tip. When clicked, it will trigger a click event on the element matching the selector .toolbar-icon-node-add.

Important Considerations:

  • jQuery Selectors: Use precise jQuery selectors to avoid unintended clicks on other elements. Test your selectors thoroughly.
  • Accessibility: Consider the accessibility implications of automated clicks. Ensure the tour remains navigable and understandable for all users, including those using assistive technologies.
  • Alternative Creation: Tours can be written as YAML documents or by using the contributed Tour UI module.

51 - Upgrade OpenY 8.1.3 to 8.2.2.1

This document is archived but may contain useful information for troubleshooting future updates. For updated update steps, visit How to upgrade YMCA Website Services.


Video tutorials

Upgrade OpenY from 8.0.7 to 8.2.2.1 - https://www.youtube.com/watch?v=U_mg0-yKGOI

Document is work in progress

These are instructions for upgrading a very old version of YMCA Website Services to the latest version. Given the fact Drupal 8.7+ has no support for automatic entity updates ( BaseFieldDefinitions ) we have to upgrade to 8.2.2.1 of OpenY, which is still on Drupal 8.6 Core, and then update to the latest YMCA Website Services version as usual.

Environment

vagrant@vagrant:/var/www/docroot$ uname -a
Linux vagrant 4.15.0-29-generic #31-Ubuntu SMP Tue Jul 17 15:39:52 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
vagrant@vagrant:/var/www/docroot$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.1 LTS
Release:	18.04
Codename:	bionic
vagrant@vagrant:/var/www/docroot$ php -v
**PHP 7.1.31-1**+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Aug  7 2019 10:23:12) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.1.31-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies
    with Xdebug v2.7.2, Copyright (c) 2002-2019, by Derick Rethans
vagrant@vagrant:/var/www/docroot$ drush --version
 **Drush Version   :  8.2.3**
vagrant@vagrant:/var/www/docroot$ composer --version
**Composer version 1.7.2** 2018-08-16 16:57:12

Step-by-step guide for update

  • Use PHP7.1 for upgrade and install php7.1-mysql php7.1-mcrypt php7.1-cli php7.1-common php7.1-curl php7.1-dev php7.1-fpm php7.1-gd php7.1-mysql php7.1-memcached php7.1-imagic php7.1-xml php7.1-xdebug php7.1-mbstring php7.1-soap php7.1-zip php7.1-xml

  • Go to the folder of OpenY code tree where docroot folder is contained

  • mv composer.json composer.json.orig

  • wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.2.x/composer.json

  • mkdir -p scripts ; cd scripts && wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.2.x/scripts/remove_libraries_gitignore_files.sh && cd ..

  • composer require YCloudYUSA/yusaopeny:8.2.2.1 --no-suggest --no-update

  • composer install --ignore-platform-reqs --no-suggest

  • composer update --prefer-stable --no-suggest

  • cd docroot

  • drush dl -y plugin-8.x-2.5 contribute-8.x-1.0-beta7 scheduler-8.x-1.0 views_block_filter_block datalayer simple_menu_icons rabbit_hole metatag simple_sitemap-8.x-3.0 easy_breadcrumb-8.x-1.6

  • drush en openy_upgrade_tool openy_er openy_prgf_loc_finder openy_map openy_data_wrapper openy_loc_branch content_moderation focal_point

  • drush ev "Drupal::service('module_installer')->install(['openy']);" <- This steps fixes some hidden bug when openy profile removed from core.extension configuration for unknown reason.

  • Manual step (optional, if you have issues with drush updatedb): Edit all yml files in profiles folder to comment media.type.image , field.field.node.program.field_header_content, field.field.node.branch.field_location_amenities in dependencies sections.

    image

    image

    image

  • run drush updatedb -y <- this will fail for the first time ( Media not installed yet ), disregard

  • run drush updatedb -y <- this should run properly.

  • run drush entup

52 - Upgrade path

All changes in configurations should be added to the appropriate hook_update_N function in order to update already existing environments. We suggest using the Config installer module for working with hook_update_N.

openy.install in profile

In this file, include updates that are related to the distribution in general and don’t fit into any specific feature. Examples include:

  • Enabling/disabling modules
  • General configuration changes

openy_*.install in modules

If you are updating a configuration for a specific feature, be sure to place the updates into the appropriate module’s .install file.

Updating specific configuration properties

With the help of the openy_upgrade_tool.param_updater service, you can update only a specific part of a full configuration.

To update a specific property in a configuration:

  1. Go to the module related to the configuration.
  2. Create a new hook_update_N function in the openy_*.install file.
  3. Add the code similar to the example below:
$config = \Drupal::service('extension.list.module')->getPath('openy_media_image') . '/config/install/views.view.images_library.yml';
$config_importer = \Drupal::service('openy_upgrade_tool.param_updater');
$config_importer->update($config, 'views.view.images_library', 'display.default.display_options.pager');

Where:

  • $config variable contains the full path to the configuration file.
  • views.view.images_library - is the configuration name.
  • display.default.display_options.pager - is the specific property within the configuration that you want to update. You can target values within nested arrays of variable depth.

Example using openy_block_basic module:

use Drupal\Core\Extension\Extension;

/**
 * Update description for field and block.
 */
function openy_block_basic_update_8001() {
  $config_dir = \Drupal::service('extension.list.module')->getPath('openy_block_basic') . '/config/install/';
  // Update multiple configurations.
  $configs = [
    'block_content.type.basic_block' => [
      'description',
    ],
    'field.field.block_content.basic_block.field_block_content' => [
      'description',
    ],
  ];

  $config_updater = \Drupal::service('openy_upgrade_tool.param_updater');
  foreach ($configs as $config_name => $params) {
    $config = $config_dir . $config_name . '.yml';
    foreach ($params as $param) {
      $config_updater->update($config, $config_name, $param);
    }
  }
}

Updating entire configurations

To update an entire configuration or multiple configurations from a directory, use the openy_upgrade_tool.importer service.

$config_dir = \Drupal::service('extension.list.module')->getPath('openy_media_image') . '/config/install';
$config_importer = \Drupal::service('openy_upgrade_tool.importer');
$config_importer->setDirectory($config_dir);
$config_importer->importConfigs(['views.view.images_library']);

Where:

  • $config_dir is the path to the directory containing the configuration files.
  • views.view.images_library is the name of the configuration to import.

You can also update several configurations from a directory at once:

$config_importer->importConfigs([
  'views.view.images_library',
  'views.view.example_view',
]);

53 - Upgrade to Open Y 1.x

This document is archived but may contain useful information for troubleshooting future updates. For updated update steps, visit How to upgrade YMCA Website Services.


Upgrade to old, Open Y 1.x version (tested on upgrading 8.0.2 to 8.1.1.14)

See upgrade from 8.1.3 to 8.2.2.1

We found the oldest OpenY instance working on 8.0.2 version of OpenY so this document should cover all the way of updating it to the latest version.

Prepare a dedicated environment for upgrade testing

Ensure you have a working computer or virtual machine with:

  • Ubuntu 14.04 (16.04 or any decent Ubuntu LTS versions) 64 bit
  • MySQL 5.5+
  • Apache 2.4
  • PHP 5.6-7.1 (7.2 is not supported yet)

The OpenY team maintains a Vagrant preconfigured Virtualbox based virtual machine with OpenY. Feel free to use it to get a working virtual environment.

Your own OpenY instance should have a Virtual machine injected into your site codebase. Just find Vagrantfile and proceed with vagrant up accordingly to the documentation.

Obtain a local copy of your production site

You have to create a local copy of your site locally to be able to proceed with the upgrade.

For that:

  • Make a backup of your production database and copy it to your local machine.
  • Make a copy of your production site codebase and copy it to your local machine.

Detect the version of your OpenY

Starting from OpenY 1.10 release, you should see the version of OpenY in your site reports dashboard. For previous versions, the best way to check your version is to analyze the creation date of index.php or README.txt file in the docroot folder of your site and compare it to the release date from https://github.com/YCloudYUSA/yusaopeny/releases. Your OpenY version should be the one which is older than the creation date of the files.

Run the command with the next never version

In the same folder where your docroot folder is located, run:

mv composer.json composer.json.bak || true
wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/composer.json
cd docroot/profiles/contrib/openy/
rm -f yparse*
wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/yparse.sh
drush cr
sh yparse.sh | xargs drush en -y
cd ../../../../
composer require YCloudYUSA/yusaopeny:NEW_VERSION_HERE --no-update
composer update --prefer-dist --with-dependencies --prefer-stable --update-with-all-dependencies --no-suggest

Update the site

Go to the docroot folder of your codebase and run:

drush updatedb
drush entup

Sometimes, when updatedb fails, it is important to get a stable version of some modules we found causing problems:

drush dl -y plugin-8.x-2.5 contribute-8.x-1.0-beta7 scheduler-8.x-1.0 views_block_filter_block datalayer simple_menu_icons rabbit_hole metatag simple_sitemap-8.x-2.9 easy_breadcrumb-8.x-1.6
drush en -y plugin contribute scheduler views_block_filter_block datalayer simple_menu_icons rabbit_hole metatag simple_sitemap || true
drush ev "Drupal::service('module_installer')->install(['content_moderation','openy']);"

Ensure the commands above finished with no error messages. The best way to check it - run them one more time. If the next run shows:

$ drush updatedb
No database updates required                                                                                    [success]
$ drush entup
No entity schema updates required                                                                               [success]

You almost 100% proved the updates were executed correctly.

Check for regressions

Backup current state of the updated site

Proceed with an update to the next version until succeeded (Start from item 1)

54 - Upgrade use case from 8.2.2.3 to 8.2.7.3

This document is archived but may contain useful information for troubleshooting future updates. For updated upgrade steps, visit How to upgrade YMCA Website Services.


Follow these steps to upgrade from version 8.2.2.3 to 8.2.7.3.

  1. Uninstall the lndr and optimizely modules before running the composer update commands.

  2. Remove the image.style.browser_thumbnail configuration:

    drush cdel image.style.browser_thumbnail
    
  3. Enable the openy_focal_point and media_directories_ui modules.

  4. Run drush updatedb and follow the remaining steps in the upgrade tutorial.

55 - Upgrading from 9.2.11.5 to 10.3

Scenario

A YMCA website is currently running on Y USA Open Y (openy-9.x-2.11.5) using Drupal 9. They want to upgrade to the latest YMCA Website Services distribution (10.3) on Drupal 10.

Upgrade Steps

Note: Before starting, ensure you have a backup of your database and files. It is highly recommended to perform these steps on a staging environment first.

  1. Prepare for Upgrade to WS

    • Ensure your site is on the latest Y USA Open Y 9.x release (9.2.13.0). This step is crucial for a smooth transition.

      composer require -W ycloudyusa/yusaopeny:9.2.13.0 drupal/core-project-message:^9.5 drupal/core-composer-scaffold:^9.5 drupal/core-recommended:^9.5
      
    • Run database updates using Drush. Replace $SITE_URL with your actual site URL.

      ../vendor/drush/drush/drush updatedb -l $SITE_URL
      
  2. Upgrade to WS 10.2

    • Require the 10.2.14 release of Y USA Open Y and update Drupal core and its dependencies. This step upgrades Drupal core to version 10.

      composer require -W ycloudyusa/yusaopeny:10.2.14 drupal/core-project-message:^10.0.11 drupal/core-composer-scaffold:^10.0.11 drupal/core-recommended:^10.0.11 drupal/core:^10.0.11 'drupal/smtp:^1.4' consolidation/robo:^4
      
  3. Address QuickEdit/RDF Dependency Issue

    • Temporarily require the quickedit and rdf modules.

      composer require drupal/quickedit drupal/rdf
      
    • Run database updates.

      ../vendor/drush/drush/drush updatedb -l $SITE_URL
      
    • Remove and re-add quickedit to resolve potential dependency conflicts.

      composer remove drupal/quickedit
      composer require drupal/quickedit drupal/rdf
      
  4. Upgrade to WS 10.3.0.1

    • Require the 10.3.0.1 release.

      composer require -W ycloudyusa/yusaopeny:10.3.0.1 drupal/core-project-message:^10.0.11 drupal/core-composer-scaffold:^10.0.11 drupal/core-recommended:^10.0.11 drupal/core:^10.0.11
      
    • Run database updates.

      ../vendor/drush/drush/drush updatedb -l $SITE_URL
      
  5. Upgrade to WS 10.3.1

    • Require the 10.3.1 release.

      composer require -W ycloudyusa/yusaopeny:10.3.1 drupal/core-project-message:^10.0.11 drupal/core-composer-scaffold:^10.0.11 drupal/core-recommended:^10.0.11 drupal/core:^10.0.11
      
  6. Add CKEditor5 Paste Filter

    • Require the ckeditor5_paste_filter module. This module enhances the CKEditor 5 experience by providing better control over pasted content.

      composer require drupal/ckeditor5_paste_filter
      
    • Run database updates.

      ../vendor/drush/drush/drush updatedb -l $SITE_URL
      
  7. Upgrade to WS 10.3.2

    • Require the 10.3.2 release.

      composer require -W ycloudyusa/yusaopeny:10.3.2 drupal/core-project-message:^10.0.11 drupal/core-composer-scaffold:^10.0.11 drupal/core-recommended:^10.0.11 drupal/core:^10.0.11
      
  8. Upgrade to WS 10.3.3.2

    • Require the 10.3.3.2 release.

      composer require -W ycloudyusa/yusaopeny:10.3.3.2
      
    • Run database updates.

      ../vendor/drush/drush/drush updatedb -l $SITE_URL
      
  9. Address CKEditor5 Font Issue

    • Uninstall the existing ckeditor5_font module.

      drush pmu ckeditor5_font -y
      
    • Require the latest beta version of ckeditor5_font.

      composer require 'drupal/ckeditor5_font:^1.1@beta'
      
    • Enable the ckeditor5_font module.

      ../vendor/drush/drush/drush en ckeditor5_font -y
      

Important Considerations

  • Backup: Always back up your site and database before performing any major upgrades.
  • Testing: Thoroughly test your site after each upgrade step on a staging environment before deploying to production.
  • Customizations: If you have made significant customizations to your site, consult with a Drupal developer to ensure a smooth upgrade process.
  • Drush Path: Adjust the ../vendor/drush/drush/drush path if your Drush installation is located elsewhere.
  • $SITE_URL: Replace $SITE_URL with the actual URL of your site.
  • Configuration Management: After upgrading, review your site’s configuration and ensure it aligns with the new features and settings in version 10.3.
  • Module Compatibility: Verify that all contributed modules are compatible with Drupal 10. Update or replace modules as needed.
  • Theme Compatibility: Ensure your theme is compatible with Drupal 10. You may need to update your theme or switch to a compatible theme.
  • Clear Caches: After each major step, clear Drupal’s caches to ensure the changes are reflected. Use drush cr or navigate to Configuration > Development > Performance > Clear all caches.

Disclaimer: This use case provides a general outline for upgrading the YMCA Website Services Drupal distribution. Specific steps and commands may vary depending on your site’s configuration and any additional modules or customizations you have installed. Always refer to the official YMCA Website Services documentation and Drupal.org for the most up-to-date information and best practices.

56 - Upgrading to a new version of the distribution

Review a video about this document.

Before upgrading, please review the required version steps for your upgrade path.

Overview

Upgrade Steps

Prepare a Dedicated Environment for Upgrade Testing

Ensure you have a working computer or virtual machine with:

  • Ubuntu 20.04 (16.04, 18.04, or any decent Ubuntu LTS version) 64 bit
  • MySQL 5.7+ (8+ is preferred because of the performance improvements)
  • Apache 2.4 (or Nginx + php-fpm, but be aware of potential .htaccess issues)
  • PHP 8.1 (older versions might have issues with some contributed modules)
  • Drush 12, 11, or 10

The YMCA Website Services team maintains a Vagrant preconfigured Virtualbox based virtual machine with OpenY. Feel free to use it to get a working virtual environment. Follow the Vagrant documentation after locating the Vagrantfile within your YMCA Website Services instance’s codebase. Execute vagrant up to provision the virtual machine.

Obtain a Local Copy of Your Production Site

To proceed with the upgrade, create a local copy of your production site.

  1. Database Backup: Make a backup of your production database and copy it to your local machine.
  2. Codebase Copy: Make a copy of your production site codebase and copy it to your local machine.
  3. Check for Manually Removed Modules: Ensure you have not manually removed Drupal modules in your database without uninstalling them first! If you have, return the module to the codebase and uninstall it via the Drupal Extend UI or Drush before proceeding.
  4. Upgrade to the latest Open Y 9.2.x version: Ensure your site is on the latest 9.2.x release before proceeding to newer major versions. See the Open Y documentation for specific instructions on upgrading to the latest 9.2.x release.

Run the Composer Update Command

In the same folder as your docroot, run the following commands:

mv composer.json composer.json.bak || true
wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/9.2.x/composer.json
composer update -W

This script replaces your composer.json file. Therefore, it is only suitable for websites with an unmodified composer.json.

If your composer.json file has been modified, manually merge the changes. The most important part is usually updating the repositories section.

Update the Database

Navigate to the docroot folder of your codebase and run:

drush updatedb

If updatedb Fails…

You can use Drupal’s hook_update_dependencies API to alter the order of updates. See this example for guidance.

Ensure the commands finish without errors. Run them a second time. If the output is:

$ drush updatedb
No database updates required                                                                                    [success]

This confirms the updates were executed correctly.

If Loading the Site Fails…

You might encounter an error like this:

Error: Class … not found in …

This occurs when Drupal cannot find renamed modules. Manually clear Drupal’s caches:

drush ev "drupal_flush_all_caches();"
drush cr

This should resolve the errors.

Visit the OpenY Upgrade Tool Dashboard

Review and revert or apply updated configuration versions after the upgrade.

OpenY Upgrade Tool Dashboard

Check for Regressions/Run Smoke Tests

Perform smoke tests to identify regressions after the upgrade. The YMCA Website Services team maintains a smoke tests database document to assist with this process.

Backup the Updated Site

Use drush sql-dump or another backup tool to create a backup of the site in its current state.

Proceed to the Next Version (Repeat from Step 1)

Repeat these steps to upgrade to the next desired version.

57 - Videos

Video Tutorials

The YMCA Digital Services team maintains a YouTube channel with video tutorials for developers, content editors, evaluators, and more. Visit YouTube for the full list of content.

Playlists

58 - Virtual Y Configuration

Virtual Y Predefined Pages

Once Virtual Y is installed, the system creates a set of required landing pages with predefined URLs. These pages are:

  • Virtual Y Landing page - /virtual-ymca
  • Virtual Y Login Landing page - /virtual-y-login

The URLs to the pages above are then set as configuration values at /admin/openy/virtual-ymca.

It is the administrator’s responsibility to keep these pages in the system or to properly update the configuration with new values to ensure Virtual Y functionality continues to work correctly. These pages are built using the “Landing Page (Layout Builder)” content type.

Protecting Virtual Y Pages

If content editors modify the alias or remove the Virtual Y pages above, the Virtual Y site may break. Site administrators may want to add additional protections to the site to prevent editors from making those changes. We recommend Node Keep for this purpose:

  • Add node_keep to your repo with composer require 'drupal/node_keep'
  • Enable the module in Drupal
  • Edit each of the pages above and set the Node Keep options as you wish to protect the pages

Screenshot displaying Node Keep options

Virtual Y Log Module

The Virtual Y Log module can be configured via configuration files. Available settings:

  • activity_granularity_interval: Default value 600 - sets the interval in seconds to track user activity on the site.
  • archiver_enabled: Default value true - enables/disables the activity logs archiver cron execution.
  • archiver_store_period: Default value 1 year - sets the period for which activity logs will be collected and placed in the same archive. This value should be set as a Relative Date/Time PHP string, e.g., 1 week, 2 months, 1 year, etc.

59 - Website Services Terms of Use

Version 2.1, December 2022

This is a free service provided by YUSA (“we,” “us,” and “our”) for users in the YMCA community (“users,” “you,” and “your”). By using the Website Services distribution repository, you agree to these Terms of Use.

We reserve the right to modify or discontinue, temporarily or permanently, any services or the Terms of Use at any time, with or without prior notice to users. YUSA is not liable for any damage to any user or other third party that may result from any such modification, suspension, or discontinuance of the service or of the Terms of Use.

Downloading

YUSA is not responsible for the content maintained in the repository. Any material downloaded or otherwise obtained through your use of our services is done at your own discretion and risk, and you will be solely responsible for any damage to your computer system or loss of data that results from the download of any such material. You agree that we have no responsibility or liability for the deletion of, or the failure to store or to transmit, any content or communication maintained by the service. We retain the right to create limits on use and storage at our sole discretion at any time with or without notice.

We are not responsible for the content, data, or actions of third parties, and you release YUSA, our directors, officers, employees, and agents from any claims and damages, known and unknown, arising out of or in any way connected with any claim you have against any such third parties. No advice or information, whether oral or written, obtained by you from us or through or from our services, creates any warranty not expressly stated in these Terms of Use.

All code downloaded from Website Services distribution is based on the Drupal® code base, which is subject to the terms of the Drupal license ( www.drupal.org). Website Services distribution code is a derivative work of Drupal, and any distribution must be under the terms of the GNU General Public License version 2 or later versions.

Unless otherwise stated, all content (excluding code), including user-generated content, such as comments and discussions on the Website Services distribution web site, is licensed under Creative Commons License, Attribution-ShareAlike 2.0.

Contributing

The term “contribution” means any source code, object code, patch, tool, sample, graphic, specification, manual, documentation, comments, or any other content posted or submitted by you to Website Services distribution. We welcome proposed contributions; however, all contributions are subject to review and approval, and potential modification, before inclusion in a release as part of Website Services distribution.

It is your responsibility to obtain appropriate licensing and attribution for content that you submit to Website Services distribution. Content without appropriate licensing or attribution will be removed.

You represent and warrant that:

  • Each contribution that you submit is an original work of authorship, and you can legally grant the rights set out in these Terms of Use;

  • To the best of your knowledge, each contribution will not violate any third party’s copyrights, trademarks, patents, or other intellectual property rights;

  • Each contribution shall be in compliance with U.S. export control laws and other applicable export and import laws.

You agree to notify us if you become aware of any circumstance which would make any of the foregoing representations inaccurate in any respect.

All code must comply with the reasonable standards issued by Website Services distribution, including architecture and security protocols. All code submitted to the repository that is a derivative work must be GPLv2+ compatible and will automatically be redistributed as GPLv2+.

YUSA, in its sole discretion, will review, modify, and determine whether to include code in its next release. We can refuse or remove any contributions at our discretion and without prior notice.

Disclaimer

All content is provided “as is,” without any warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement; (ii) YUSA makes no other warranty that its services will meet your requirements, be safe, secure, uninterrupted, timely, accurate, or error-free, or that your information will be secure; and (iii) the entire risk as to the quality and performance of the content is with you.

Limit of Liability

In no event will YUSA, its affiliates, or their licensors, service providers, employees, agents, officers, or directors be liable for any indirect, special, incidental, consequential, or punitive damages, including but not limited to loss of revenue, loss of profits, loss of business or anticipated savings, loss of goodwill, and whether caused by tort (including negligence), breach of contract or otherwise, even if foreseeable. The foregoing does not affect any liability which cannot be excluded or limited under applicable law.

If a user or other third party believes that its content has been copied in a way that constitutes copyright infringement, that user or third party should provide YUSA with the following information: (a) an electronic or physical signature of the person authorized to act on behalf of the owner of the copyright interest; (b) a description of the copyrighted work that has been infringed; (c) a description of where the allegedly infringing material is located; (d) the affected user or third party’s address, telephone number, and email address; (e) a statement by the affected user or third party that he or she has a good faith belief that the disputed use is not authorized by the copyright owner, its agent, or the law; and (f) a statement by the affected user or third party, under penalty of perjury, that the above information is accurate and that such user or third party is the copyright owner or is otherwise authorized to act on the copyright owner’s behalf. Please report any alleged copyright infringements to https://ymca.org.

Venue and Governing Law

This Agreement shall be governed by, and construed in accordance with, the laws of the State of Minnesota, without reference to conflicts of laws principles. The parties agree that the federal and state courts in the county of Hennepin, Minnesota will have exclusive jurisdiction and venue under this Agreement, and each party hereby agrees to submit to such jurisdiction exclusively.