├── .gitignore ├── .github └── pull_request_template.md ├── assets └── logo.png ├── docs ├── development │ ├── third-party │ │ ├── drupal │ │ │ ├── index.md │ │ │ ├── routing-sytem.md │ │ │ ├── forms.md │ │ │ └── services-dependency-injection.md │ │ └── drone.md │ ├── feature-development.md │ ├── configuration-management.md │ ├── release-workflow.md │ ├── ci-deployment-workflow.md │ ├── code-reviews.md │ ├── development-workflow.md │ ├── module-update-policy.md │ ├── dependency-management-and-patching.md │ ├── coding-standards.md │ ├── content-architecture.md │ ├── automated-testing.md │ ├── testing.md │ └── tooling.md ├── templates │ ├── pull-request-template.md │ └── issue-template.md ├── starting │ ├── repository-scaffolding.md │ └── solution-definition.md ├── initiative │ ├── code-of-conduct.md │ ├── contribution-workflow.md │ ├── release-cycle.md │ └── how-to-contribute.md └── openeuropa-components.md ├── README.md └── LICENCE.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ../docs/templates/pull-request-template.md -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openeuropa/documentation/HEAD/assets/logo.png -------------------------------------------------------------------------------- /docs/development/third-party/drupal/index.md: -------------------------------------------------------------------------------- 1 | # Drupal development 2 | 3 | Some resources to supoprt development in Drupal: 4 | 5 | - [Routing system](routing-sytem.md) 6 | - [Services dependency injection](services-dependency-injection.md) 7 | - [Form System](forms.md) 8 | -------------------------------------------------------------------------------- /docs/templates/pull-request-template.md: -------------------------------------------------------------------------------- 1 | ## OPENEUROPA-[Insert ticket number here] 2 | 3 | ### Description 4 | 5 | [Insert description here] 6 | 7 | ### Changelog 8 | 9 | - Added: 10 | - Changed: 11 | - Deprecated: 12 | - Removed: 13 | - Fixed: 14 | - Security: 15 | -------------------------------------------------------------------------------- /docs/development/feature-development.md: -------------------------------------------------------------------------------- 1 | # Feature implementation 2 | 3 | Definition of mandatory steps of feature development 4 | 5 | -- TO BE DEFINED -- 6 | 7 | ## Purpose and scope 8 | 9 | ## Implementation 10 | 11 | ## Reviewing performance/security/configuration management 12 | 13 | ## Feature Documentation 14 | 15 | ## Feature Test coverage 16 | -------------------------------------------------------------------------------- /docs/development/configuration-management.md: -------------------------------------------------------------------------------- 1 | # Configuration management 2 | 3 | OpenEuropa components are responsible for shipping with the configuration defaults. After installation, the site owners take ownership over this configuration. 4 | 5 | During the development life-cycle of a component, the maintainers undertake to make updates to these configuration values and provide upgrade paths whenever it makes sense. -------------------------------------------------------------------------------- /docs/development/release-workflow.md: -------------------------------------------------------------------------------- 1 | # Release workflow 2 | 3 | OpenEuropa components follow a semantic version release cycle. For more information about this, go [here](../initiative/release-cycle.md). 4 | 5 | They are released every time the maintainers decide enough functionality has been included to create a new minor version or when the new functionality is needed by an existing European Commission distribution. 6 | 7 | Patch (or security) updates can be done more often and as needed. -------------------------------------------------------------------------------- /docs/development/ci-deployment-workflow.md: -------------------------------------------------------------------------------- 1 | # CI Deployment Workflow 2 | 3 | OpenEuropa is using [Drone](https://drone.fpfis.eu) for continuous integration and continuous delivery of its components. It is integrated with the Github repositories in order to trigger automatically build pipelines for commits and pull requests. 4 | 5 | You can see a default Drone pipeline configuration in the [Drupal module template repository](https://github.com/openeuropa/drupal-module-template/blob/master/.drone.yml). -------------------------------------------------------------------------------- /docs/starting/repository-scaffolding.md: -------------------------------------------------------------------------------- 1 | # Repository scaffolding 2 | 3 | Repositories follow a certain structure that allows for a fast and easy development setup. 4 | 5 | Creating new Drupal module repositories can be done by using the [OpenEuropa module template](https://github.com/openeuropa/drupal-module-template). 6 | 7 | In addition, the OpenEuropa project also provides a [site template](https://github.com/openeuropa/drupal-site-template) that can be used to quickly set up a site using a lightweight profile and the more common components already included. -------------------------------------------------------------------------------- /docs/development/code-reviews.md: -------------------------------------------------------------------------------- 1 | # Code reviews 2 | 3 | Pull Requests introducing changes in the Openeuropa components are manually reviewed. 4 | 5 | The following aspects should be checked: 6 | - Implementation follows the ticket instruction and the defined solution. 7 | - Correct code split between components, and inside components correct split between services, plugins, .module file, and .install file. 8 | - Prefixing on configuration provided. 9 | - Type-hinting for code that is not inherited. 10 | - Comments explain complex logic. 11 | - Test cover introduced all introduced functionality. 12 | -------------------------------------------------------------------------------- /docs/development/development-workflow.md: -------------------------------------------------------------------------------- 1 | # Development workflow 2 | 3 | OpenEuropa component development starts from business requirements provided by the European Commission to support various corporate solutions. 4 | 5 | The DIGIT core team responsible for the OpenEuropa project analyses these requirements and turns them into generic technical solutions that could support these business goals as well as others. 6 | 7 | After the completion of a given requirement in the component, if the latter is used in any European Commission distribution, it is updated and configured to meet the original business requirement. -------------------------------------------------------------------------------- /docs/starting/solution-definition.md: -------------------------------------------------------------------------------- 1 | # Solution definition 2 | 3 | Solution definition for OpenEuropa components is defined by OpenEuropa Solution design team. 4 | Major changes or introductions of new components respect a defined workflow. 5 | 6 | For work in new components, the following needs to happen: 7 | - Technical proposal by development team and validated by the Solutions Design Team. 8 | - Code repository correctly created and handed over to dev team. 9 | - Future maintainership of the component is clear and assigned before the work is started. 10 | 11 | For small changes in existing components: 12 | - Discuss with OpenEuropa team by opening an issue on Github or ping on #openeuropa slack chat 13 | - Create a PR on the component 14 | - Component maintainers will review and approve 15 | -------------------------------------------------------------------------------- /docs/templates/issue-template.md: -------------------------------------------------------------------------------- 1 | ### Prerequisites 2 | 3 | Check completed tasks from the checklist below: 4 | 5 | - [ ] Reproduced the problem in the component's latest version. 6 | - [ ] Read the associated Readme and user guides for common solutions. 7 | - [ ] Checked that your issue isn't already filed [here](https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aopeneuropa) 8 | - [ ] Checked that there is not already an OpenEuropa component that provides the described functionality: [OpenEuropa component list](openeuropa-components.md) 9 | 10 | ### Description 11 | 12 | [Description of the issue] 13 | 14 | ### Steps to reproduce 15 | 16 | 1. [First Step] 17 | 2. [Second Step] 18 | 3. [and so on...] 19 | 20 | **Expected behavior:** [What you expect to happen] 21 | 22 | **Actual behavior:** [What actually happens] 23 | 24 | **Reproduces how often:** [What percentage of the time does it reproduce?] 25 | 26 | ### Versions 27 | 28 | Please add the version of the component you found the bug in. 29 | 30 | ### Additional information 31 | 32 | Any additional information, configuration or data that might be necessary to reproduce the issue. -------------------------------------------------------------------------------- /docs/development/module-update-policy.md: -------------------------------------------------------------------------------- 1 | # Module update policy 2 | 3 | Drupal modules are updated using the [update API for Drupal 8][1] by implementing the following hooks: 4 | 5 | - [`hook_update_N`][2] 6 | - [`hook_post_update_NAME`][3] 7 | 8 | Since `hook_post_update_NAME` hooks are executed alphabetically we prepend `_NAME` with an incremental numeric string, 9 | so that we can be sure they are executed in the right order. 10 | 11 | Our current convention is a 5-digits numeric string starting from `00001`, as shown below: 12 | 13 | ``` 14 | /** 15 |  * A meaningful comment describing the first update. 16 |  */ 17 | function MY_MODULE_post_update_00001() { ... } 18 | 19 | /** 20 |  * Another meaningful comment describing the second update. 21 |  */ 22 | function MY_MODULE_post_update_00002() { ... } 23 | ``` 24 | 25 | We suggest not to append anything after the sequence number as doing so will eliminate the risk of having hooks with the same number. Instead, we suggest to add a meaningful comment on top of each hook, that will be displayed when running `drush updb`. 26 | 27 | [1]: https://www.drupal.org/docs/8/api/update-api/introduction-to-update-api-for-drupal-8 28 | [2]: https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Extension!module.api.php/function/hook_update_N 29 | [3]: https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Extension!module.api.php/function/hook_post_update_NAME 30 | -------------------------------------------------------------------------------- /docs/development/dependency-management-and-patching.md: -------------------------------------------------------------------------------- 1 | # Dependency management 2 | 3 | OpenEuropa components often depend on external libraries or Drupal modules. These are included in the component's `composer.json` file but their version 4 | is not locked using a `composer.lock` file. This means that every time the component is installed for development purposes, it will use the latest version 5 | of its dependencies. 6 | 7 | In order to ensure that components works with a wide range of dependency versions, the Drone-based continuous integration pipelines install and test them using 8 | both the lowest and highest version of the dependencies allowed in the `composer.json` file. You can see how this is set up in the [Drupal module template repository](https://github.com/openeuropa/drupal-module-template/blob/master/.drone.yml). 9 | 10 | Components made for Drupal modules can and very often do include submodules that may have their own dependencies which are not necessarily needed by the parent component as a whole or the other submodules. 11 | In such cases, the dependencies are not declared in the `composer.json` of the main component but are mentioned in the submodule's README file. They are however included in the list of Composer development dependencies 12 | so that they can be loaded and tested during the development of the component. 13 | 14 | Dependencies can also be patched using the Composer-based patching plugin. However, if patches are needed for production use (as opposed to patching development dependencies), they should be declared in the component README file. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |

The OpenEuropa Initiative

3 | 4 | OpenEuropa is a [Directorate-General for Informatics (DIGIT)][1] initiative aiming at strengthening the adoption 5 | of [open source][2] tools and practices in consolidating the European Institutions' web presence. 6 | 7 | In order to achieve such a goal the OpenEuropa Initiative will focus on the following activities: 8 | 9 | - Build, maintain and release loosely-coupled, reusable software [components](docs/openeuropa-components.md) , licensed under [EUPL-1.2][3]. 10 | - Build, maintain and release fully-fledged solutions for the European Institutions. 11 | - Provide a high-level architecture overview of web-related information systems. 12 | - Establish reusable technical governance guidelines. 13 | - Contribute back to upstream open source projects. 14 | 15 | For more information please check: 16 | 17 | * OpenEuropa initiative 18 | * [Code of Conduct](docs/initiative/code-of-conduct.md) 19 | * [Release cycle](docs/initiative/release-cycle.md) 20 | * [How to contribute](docs/initiative/how-to-contribute.md) 21 | * [Contribution workflow](docs/initiative/contribution-workflow.md) 22 | * [Components](docs/openeuropa-components.md) 23 | * Before you start 24 | * [Solution definition](docs/starting/solution-definition.md) 25 | * [Repositories scaffolding](docs/starting/repository-scaffolding.md) 26 | * Development guidelines 27 | * [Content architecture](docs/development/content-architecture.md) 28 | * [Configuration management](docs/development/configuration-management.md) 29 | * [Writing tests](docs/development/testing.md) 30 | * [Module update policy](docs/development/module-update-policy.md) 31 | * [Tooling](docs/development/tooling.md) 32 | * [Dependency management](docs/development/dependency-management-and-patching.md) 33 | * [Development Workflow](docs/development/development-workflow.md) 34 | * [Coding standards](docs/development/coding-standards.md) 35 | * [Frontend development](docs/development/frontend/index.md) 36 | * [CI And deployment workflow](docs/development/ci-deployment-workflow.md) 37 | * [Code reviews](docs/development/code-reviews.md) 38 | * [Release workflow](docs/development/release-workflow.md) 39 | * Templates 40 | * [Issue template](docs/templates/issue-template.md) 41 | * [Pull request template](docs/templates/pull-request-template.md) 42 | * Development guides 43 | * [Drupal](docs/development/third-party/drupal/index.md) 44 | * [Automated testing](docs/development/automated-testing.md) 45 | 46 | [1]: https://ec.europa.eu/info/departments/informatics 47 | [2]: https://opensource.org 48 | [3]: https://joinup.ec.europa.eu/page/eupl-text-11-12 49 | -------------------------------------------------------------------------------- /docs/development/coding-standards.md: -------------------------------------------------------------------------------- 1 | # OpenEuropa Coding Standards 2 | 3 | OpenEuropa and all its components are built with public contribution in mind. 4 | In order for all contributions and components to look and feel familiar, 5 | OpenEuropa has agreed on a set of coding standards that all contributors must follow. 6 | 7 | Although OpenEuropa does not define any coding standard as such, all the standards it follows 8 | are usually based on well known standards such as [PSR-1][1] and [PSR-2][2]. 9 | 10 | The following are a list of coding standards guidelines, 11 | defined using [IETF RFC 2119][3] conformance keywords. 12 | 13 | ## How to make your code follow the Coding Standards 14 | 15 | In order to make it easier for contributors to create new components or to modify existing ones 16 | the [Code Review][4] component has been created. 17 | 18 | Coding standards MUST be validated using the OpenEuropa Code Review component 19 | across all different OpenEuropa components. 20 | 21 | Please refer to the Code Review [documentation][5] for more information on its usage. 22 | 23 | ## Coding Standards for Drupal Components 24 | 25 | All Drupal based components MUST follow the already defined [Drupal Coding Standards][6]. 26 | 27 | ## Coding Standards for Drupal Themes 28 | 29 | Drupal themes are based on the Europa Component Library and should follow the [ECL Coding Standards][7]. 30 | 31 | ## Coding Standards for PHP based components 32 | 33 | All PHP based components that are not part of the Drupal ecosystem MUST adhere to the [PSR-2][2] standards. 34 | This applies to any library or component that is mainly developed in PHP. 35 | 36 | ## Additional rules 37 | [Type declarations][8] are mandatory for both parameters and return values in all methods. 38 | No type declaration should be added when extending/implementing existing classes/interfaces that do not have type 39 | declarations in their method signatures already, to keep intact the signature itself. 40 | To ensure that only variables of exact type of the type declaration are accepted, all PHP files should have the [strict 41 | type declaration][9] statement at the top. 42 | 43 | 44 | [1]: https://www.php-fig.org/psr/psr-1/ 45 | [2]: https://www.php-fig.org/psr/psr-2/ 46 | [3]: https://www.ietf.org/rfc/rfc2119.txt 47 | [4]: https://github.com/openeuropa/code-review 48 | [5]: https://github.com/openeuropa/code-review/blob/master/README.md 49 | [6]: https://www.drupal.org/docs/develop/standards 50 | [7]: https://ec-europa.github.io/europa-component-library/ec/docs/conventions/component 51 | [8]: https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration 52 | [9]: https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict 53 | -------------------------------------------------------------------------------- /docs/development/third-party/drone.md: -------------------------------------------------------------------------------- 1 | # Drone 2 | 3 | OpenEuropa is using [Drone][1] for continuous integration and continuous delivery. 4 | For more information about policies regarding the use of the FPFIS Drone service 5 | please refer to [this issue][4]. 6 | 7 | ## Enabling Drone for a new repository 8 | 9 | The repository should be enabled in the web interface at [Account > Repositories][2]. 10 | This action can only be taken by the repository maintainer. 11 | 12 | In the repository settings for the Drone application on Github the necessary 13 | actions should then be configured, so that the tests will run on all branches, 14 | ull requests, tags, etc. 15 | 16 | ## Testing Drone in a local development environment 17 | 18 | * Install the Drone CLI tool, ref. [Drone CLI installation][1]. 19 | * In the root folder of the repository (where the `.drone.yml` file is 20 | located), execute the Drone pipeline with: 21 | 22 | $ drone exec --local 23 | 24 | * You can simulate any git events that might occur on the repository. Refer to 25 | the Drone CLI documentation for more information. For example to simulate new 26 | commits being pushed to the master branch: 27 | 28 | $ drone exec --build-event push --commit-branch master 29 | 30 | ### Tips regarding the use of the Drone CLI tool 31 | 32 | * If the tool appears to 'hang' for a long time, it is probably downloading 33 | Docker containers in the background. Be patient. Ref. 34 | https://github.com/drone/drone-cli/issues/46. 35 | * If you get unexpected errors, make sure your local checkout of the repository 36 | is clean. Remove folders such as `vendor/` and `npm_modules`, remove your 37 | local `runner.yml` file, etc. Ideally you should clone a brand new 38 | repository, since this is also what the Drone server is doing at the start of 39 | the process. 40 | * On many Linux based systems Docker is running as a service which means it has 41 | root access to the file system. Take precautions to not run untrusted 42 | containers, and be prepared to handle files being written as root into your 43 | working directory. There is a feature request to solve this in Drone (ref. 44 | https://github.com/drone/drone/issues/1492). You can also get in touch with 45 | your container maintainer to solve this on container level, e.g. by checking 46 | an environment variable `UID` and running as this user. 47 | * We are currently using some containers that include an older version of the 48 | Linux kernel (more specifically, CentOS 6 which runs on the 2.6 kernel). 49 | There is an incompatibility that occurs when running these on a host OS that 50 | has a more kernel (4.15 or newer). The problem currently manifests itself 51 | with the container exiting with exit code 139. To solve this, run the host 52 | system with the kernel parameter `vsyscall=emulate`. See for example: 53 | https://bugs.archlinux.org/task/57336 54 | 55 | [1]: https://drone.io 56 | [2]: https://drone.fpfis.eu/account/repos 57 | [3]: http://docs.drone.io/cli-installation 58 | [4]: https://webgate.ec.europa.eu/CITnet/jira/browse/OPENEUROPA-571 -------------------------------------------------------------------------------- /docs/initiative/code-of-conduct.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making 6 | participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, 7 | disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, 8 | religion, or sexual identity and orientation. 9 | 10 | ## Our standards 11 | 12 | Examples of behavior that contributes to creating a positive environment include: 13 | 14 | * Using welcoming and inclusive language 15 | * Being respectful of differing viewpoints and experiences 16 | * Gracefully accepting constructive criticism 17 | * Focusing on what is best for the community 18 | * Showing empathy towards other community members 19 | 20 | Examples of unacceptable behavior by participants include: 21 | 22 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 23 | * Trolling, insulting/derogatory comments, and personal or political attacks 24 | * Public or private harassment 25 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 26 | * Other conduct which could reasonably be considered inappropriate in a professional setting 27 | 28 | ## Our responsibilities 29 | 30 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take 31 | appropriate and fair corrective action in response to any instances of unacceptable behavior. 32 | 33 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, 34 | issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any 35 | contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 36 | 37 | ## Scope 38 | 39 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the 40 | project or its community. Examples of representing a project or community include using an official project e-mail 41 | address, posting via an official social media account, or acting as an appointed representative at an online or offline 42 | event. Representation of a project may be further defined and clarified by project maintainers. 43 | 44 | ## Enforcement 45 | 46 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at 47 | [EC-EUROPA-IT-PLATFORM@ec.europa.eu](mailto:EC-EUROPA-IT-PLATFORM@ec.europa.eu). All complaints will be 48 | reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. 49 | The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of 50 | specific enforcement policies may be posted separately. 51 | 52 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent 53 | repercussions as determined by other members of the project's leadership. 54 | 55 | ## Attribution 56 | 57 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at 58 | [https://contributor-covenant.org/version/1/4][version]. 59 | 60 | [homepage]: https://contributor-covenant.org 61 | [version]: https://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /docs/development/third-party/drupal/routing-sytem.md: -------------------------------------------------------------------------------- 1 | # Routing system 2 | 3 | The routing system in Drupal 8 is based on the [Symfony Routing component](https://symfony.com/doc/current/routing.html). It is essentially responsible for mapping user requests to business logic in the site, typically via Controllers. 4 | 5 | You can find a basic overview of this system [here](https://www.drupal.org/docs/8/api/routing-system/routing-system-overview). 6 | 7 | 8 | ## Why a new routing system 9 | 10 | In Drupal 7, the task of routing user requests to business logic was handled by `hook_menu()`. However, this hook was procedural and handled a lot more than just routing. This needed to be separated into various subsystems. 11 | 12 | ## How the routing system works 13 | 14 | The most common use case of the routing system is defining a route (with a path) that maps to a Controller class. The latter is then responsible for delivering the contents of that page. 15 | 16 | A good example of how to do this can be found [here](https://www.drupal.org/docs/8/api/routing-system/introductory-drupal-8-routes-and-controllers-example). 17 | 18 | ## Structure of routes 19 | 20 | The route definition can contain a lot of information needed in handling the routing, such as access checks. 21 | 22 | A complete list of *keys* you can specify inside a route definition can be found [here](https://www.drupal.org/docs/8/api/routing-system/structure-of-routes). 23 | 24 | The most common you will encounter, however, are the following: 25 | 26 | * `path` -> the path that needs to be requested to match this route. For more information on how the path can take parameters, read [this](https://www.drupal.org/docs/8/api/routing-system/using-parameters-in-routes) 27 | * `defaults` -> this is where, among other things, the business logic is mapped. Under `defaults` we typically have: 28 | * `_controller` -> mapping to a fully qualified name of a Controller class or 29 | * `_form` -> mapping to a fully qualified name of a Form class for a form page 30 | * `requirements` -> contains, among others, access related information that needs to be met for the route to be accessible (such as `_permission`). For more information on access checking on routes, read [this](https://www.drupal.org/docs/8/api/routing-system/access-checking-on-routes). 31 | 32 | ## Adding dynamic routes 33 | 34 | For more complex uses cases, routes can also be declared dynamically, not only via the static `.routing.yml` file. In order to do this, we subscribe to the route building event and provide our definitions dynamically. 35 | 36 | In the same way, we can alter route definitions that have already been defined. 37 | 38 | For an example of how to do this, check [here](https://www.drupal.org/docs/8/api/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones). 39 | 40 | For more information on the Event Dispatcher and subscribing to events, check out [this entry]() (@todo add URL). 41 | 42 | ## Route related objects 43 | 44 | Very often we encounter and have to work with objects that deal with the routing system. The most important are `Request` (and `RequestStack` service), `Route`, `RouteMatch`, `CurrentRouteMatch`, `Url`. 45 | 46 | For more information on what these do, check [here](https://www.drupal.org/docs/8/api/routing-system/routing-related-objects-route-currentroutematch-routematch-url) 47 | 48 | ## Useful links 49 | 50 | * [Routing system documentation](https://www.drupal.org/docs/8/api/routing-system) on Drupal.org. 51 | * The Drupal 8 [render pipeline](https://www.drupal.org/docs/8/api/render-api/the-drupal-8-render-pipeline) documents the internals of transforming a user request into an actual page output. 52 | * Drupal [examples module](https://www.drupal.org/project/examples). 53 | * [Change log](https://www.drupal.org/node/1800686) for `hook_menu()` 54 | -------------------------------------------------------------------------------- /docs/initiative/contribution-workflow.md: -------------------------------------------------------------------------------- 1 | # Contribution workflow 2 | 3 | ## Governance 4 | 5 | OpenEuropa is a project owned and maintained by the European Commission's DG DIGIT. 6 | 7 | OpenEuropa components and features are created for European Commission internal web projects, 8 | but they are made as generic as possible and released as [Open Source Software](https://github.com/openeuropa/openeuropa/blob/master/LICENCE.txt) 9 | so they can also be used in other projects and receive contributions from the Open Source Community (hereinafter referred to as "external contributors"). 10 | 11 | DG DIGIT's OpenEuropa Core team is in charge of OpenEuropa developments and maintenance, under the supervision of its Product Owner, 12 | who decides on the priorities, depending on European Commission needs. 13 | 14 | While the OpenEuropa team strongly welcomes and encourages contributions, European Commission projects have the priority over external entities needs, 15 | which means an external contribution or support request might be handled after a certain period of time, depending on available resources, 16 | or might be rejected at the sole discretion of the OpenEuropa team representatives (hereinafter referred to as "maintainers"). 17 | 18 | ## OpenEuropa contribution rules 19 | 20 | Contributions are governed by [OpenEuropa contribution guidelines](../initiative/how-to-contribute.md). 21 | 22 | ## Lifecycle of proposed issues 23 | 24 | All contributed issues, both bug reports and feature requests, are handled as GitHub issues. 25 | This allows external contributors to follow up on the progress without the need to access DIGIT's internal ticketing system. 26 | 27 | Contributed issues are regularly examined by the maintainers of the repository they were created in. 28 | Maintainers are able to decide whether the contributed issue has value or not, in which case it will be duplicated into an internal ticket 29 | in order to be able to track resources and deal with internal comments. 30 | 31 | Although there is no set of rules defining if an issue has value to the OpenEuropa project, here is a set of guidelines: 32 | 33 | * The issue reports a critical bug that renders the component unusable. 34 | * The issue reports a bug that is clear and is unmistakably the component's fault. 35 | * The issue requests a feature that was described in the component but not provided. 36 | * The issue requests a modification that does not break backwards compatibility. 37 | * The issue requests a feature without which the component is unusable. 38 | 39 | Maintainers are advised to use their know-how and best common sense to filter these issues to the best of their capabilities. 40 | 41 | Once the issues have been moved to an internal ticket, the maintainers have to decide together with the OpenEuropa Product Owner on the priority of issues, 42 | after which the tickets are handled following the usual development workflow of all OpenEuropa tickets (which itself is based on Agile methodologies). 43 | 44 | Information on the progress has to be regularly added in the associated GitHub ticket as well, in order for the external contributor(s) to be kept informed. 45 | 46 | ## Lifecycle of proposed pull requests 47 | 48 | All contributed pull requests are to be created together with a related GitHub issue. 49 | These issues follow the lifecycle described above, regardless of whether the pull request was created together with the issue or not. 50 | 51 | In the case the issue was created together with a pull request or the issue has not been examined yet, the issue is handled as described above 52 | and the related internal ticket has to be reviewed. It is the responsibility of the contributor to handle any required modification to the proposed code. 53 | 54 | In the case the pull request is created in a later state and the related internal ticket is already available, 55 | the proposed pull request is evaluated as part of the development of the ticket, and it is the responsibility of the developer in charge of the ticket 56 | to handle any required modification to the proposed code. 57 | -------------------------------------------------------------------------------- /docs/development/content-architecture.md: -------------------------------------------------------------------------------- 1 | # Content architecture 2 | 3 | The OpenEuropa project does not enforce a strict content architecture but provides corporate solutions used by the European Commission. 4 | 5 | ## Content types 6 | 7 | The [OpenEuropa Content](https://github.com/openeuropa/oe_content) component provides a growing number of corporate content types intended to harmonize the content architecture across the sites of the European Commission. Moreover, it provides RDF-based support for the corporate vocabularies published by the [European Publication Office (OP)](https://publications.europa.eu/en/home). 8 | 9 | Corporate content types result from content governance work at DG COMM and they should be approved by it, before any implementation work can start. 10 | 11 | 12 | ### Development guidelines for content types 13 | When implementing corporate content types stick to the following guidelines: 14 | 15 | - One dedicated submodule with content type configuration in oe_content. 16 | - One dedicated submodule theming that content type in oe_theme. 17 | 18 | #### oe_content submodule 19 | A corporate content submodule should only have basic configuration and logic and basic data related dependencies: 20 | - bundle definition; 21 | - content type specific field storages and field instances; 22 | - view modes. 23 | 24 | Configuration shipped as content submodules is intended as initial configuration: 25 | - After being installed and imported the content type belongs to the site. 26 | - The submodule will not update existing configuration after install. 27 | 28 | Content should be made translatable providing the related language configuration in the config/optional folder. 29 | 30 | The following points should be followed on content types development: 31 | - Check if existing fields could be reused before implementing a new one. 32 | - Prefix corporate fields only with oe_ so to reduce the risk of naming conflict. 33 | - Base fields are common to all bundles and should already be present in all content types, no need to implement in new ones. 34 | - Prefer API validation, do not rely on Form API validation. 35 | - Publication Office (PO) vocabularies are the only allowed taxonomies. 36 | - If not yet imported, it can be added in the triple-store. 37 | - Select the appropriated field types: 38 | - Core/contrib field types preferred. 39 | - New field types if required. 40 | - Compound fields as corporate content entities if required. 41 | 42 | Any custom field type, entity validation, entity wrappers, etc. should be covered by PHPUnit tests. 43 | 44 | The business requirements should be covered in a Behat test: 45 | - available fields and their configuration (required, max length, etc.). 46 | - referenceable content entities. 47 | 48 | #### oe_theme submodule 49 | All theming logic for the content type should be created in the appropriated oe_theme submodule. 50 | 51 | A theming submodule provides: 52 | - view mode display overrides in the config/overrides folder. 53 | - display overrides will be installed once and replace any existing configuration. 54 | - `PageHeaderMetadata` plugin if needed. 55 | - templates specific to this content type rendering. 56 | - any other configuration that is needed for this content type, properly namespaced (dates, image styles). 57 | 58 | Test coverage should cover: 59 | - any business related functionality on the frontend level, e.g.: 60 | - changing of labels in the frontend based on a condition (field value, time, etc.) 61 | - rendering of data in the expected way. 62 | - access checks. 63 | - caching. 64 | 65 | Tests should be executed as anonymous user, using the existing entity creation and update steps to ensure cache invalidation, and with the correct user to ensure access checks. 66 | 67 | ## Page building 68 | 69 | To support the building of pages with a variety of page-level elements, the [OpenEuropa Paragraphs](https://github.com/openeuropa/oe_paragraphs) component provides a number of Drupal paragraph types that can be used 70 | on any content type. Combined with the [OpenEuropa Theme](https://github.com/openeuropa/oe_theme), these are displayed using the [Europa Component Library (ECL)](https://ec.europa.eu/component-library) style guide. -------------------------------------------------------------------------------- /docs/development/third-party/drupal/forms.md: -------------------------------------------------------------------------------- 1 | # Forms 2 | 3 | The Form API in Drupal 8 has taken steps towards an object oriented architecture, forms now being defined as classes. With this come many of the OOP benefits such as [dependency injection](services-dependency-injection.md) and testability. 4 | 5 | ## Creating a form 6 | 7 | Form classes need to implement `\Drupal\Core\Form\FormInterface` but typically extend `Drupal\Core\Form\FormBase`. As such there are a few methods that need to be implemented for processing of a form. 8 | 9 | The concepts, however, are similar to Drupal 7: 10 | 11 | * A form has an ID -> the `getFormId()` method 12 | * A form is defined as a multitude of form elements (render array) -> the `buildForm(array $form, FormStateInterface $form_state)` method 13 | * A form can be validated before it is submitted -> the `validateForm(array &$form, FormStateInterface $form_state)` method 14 | * A form is submitted -> the `submitForm(array &$form, FormStateInterface $form_state)` method 15 | 16 | Another difference is that the *form state* is no longer an array but a `Drupal\Core\Form\FormStateInterface` object. 17 | 18 | For an example of a simple form definition and the methods that can/need to be implemented in a form, check out [this page](https://www.drupal.org/docs/8/api/form-api/introduction-to-form-api). 19 | 20 | ## Form elements 21 | 22 | A form definition is a collection of form elements, defined as arrays. Just like in Drupal 7, the Form API comes with a number of form elements by default. 23 | 24 | See here the [complete list](https://api.drupal.org/api/drupal/elements/8.6.x) of form elements provided by core. Look for the ones of the type `FormElement`. 25 | 26 | Form elements (`FormElementInterface`) extend render elements (`ElementInterface`) and integrate with the [render system](). // @todo add link to theming entry 27 | 28 | The best way to discover how to use a particular form element (or render element for that mater) is to inspect the class and its documentation. For example, the `textfield` form element is defined in `Drupal\Core\Render\Element\Textfield` and an example of how it's used can be found in the class documentation. 29 | 30 | ## Building and rendering a form 31 | 32 | There are 2 main ways to build and render a form: from a route definition (form page) or programmatically. 33 | 34 | ### Route handler 35 | 36 | Forms can be mapped to a route by using the `_form` key inside the `defaults` section of the route definition. See [this example](https://www.drupal.org/docs/8/api/form-api/introduction-to-form-api#fapi-in-route) and read more about the [routing system](routing-sytem.md). 37 | 38 | ### Programmatically 39 | 40 | Forms can also be retrieved and rendered from controllers and other places. The `Drupal\Core\Form\FormBuilder` service can be used for this (service key: `form_builder`). See an example [here](https://www.drupal.org/docs/8/api/form-api/introduction-to-form-api#fapi-build-programatically). 41 | 42 | ## Altering forms 43 | 44 | Just like in Drupal 7, the forms can be altered using [hook_form_alter()](https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21form.api.php/function/hook_form_alter/8.6.x), [hook_form_FORM_ID_alter()](https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21form.api.php/function/hook_form_FORM_ID_alter/8.6.x) and [hook_form_BASE_FORM_ID_alter()](https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21form.api.php/function/hook_form_FORM_ID_alter/8.6.x). 45 | 46 | ## Form bases 47 | 48 | Typically, forms in Drupal 8 extend `Drupal\Core\Form\FormBase`. However, there are a few other base classes that can be used depending on the purpose of the form: 49 | 50 | * `Drupal\Core\Form\ConfigFormBase` -> provides defaults for interacting with the configuration API for storing config defined via the form 51 | * see [here](https://www.drupal.org/docs/8/api/form-api/configformbase-with-simple-configuration-api) an example on how to use this 52 | * see [here]() more information about the Config API and // @todo add link to config entry 53 | * `Drupal\Core\Form\ConfirmFormBase` -> provides defaults for creating a confirmation form (see [here](https://www.drupal.org/docs/8/api/form-api/confirmformbase-to-confirm-an-action) an example on how to use this) 54 | 55 | -------------------------------------------------------------------------------- /docs/initiative/release-cycle.md: -------------------------------------------------------------------------------- 1 | # OpenEuropa Release Cycle 2 | This document explains the release process followed by OpenEuropa project for its components. 3 | OpenEuropa releases its component following semantic versioning (https://semver.org/) 4 | 5 | There are three types of releases: 6 | 7 | - **MAJOR**: Incompatible API changes, very rare and planned in. 8 | - **MINOR**: Adds backwards-compatible manner functionalities and bug fixes. 9 | - **PATCH**: Adds backwards-compatible bug/security fixes and can be deployed instantaneously. No new functionality will be introduced. 10 | 11 | OpenEuropa components release plan don't follow a fixed overall timeline and can happen in different planned slots. Each component roadmap and release plan will be made available to the public. 12 | 13 | ## Release preparation and testing 14 | 15 | The OpenEuropa team commits to have its components aligned with the API of the supported Drupal versions. 16 | 17 | It is predicted that the majority of changes will come in the form of MINOR and PATCH releases. However, if there is a need to change API provided by the component in a way that it is not backwards compatible a new MAJOR release can be produced. 18 | 19 | Each OpenEuropa component defines in its dependencies the minimum requirements for components version it depends upon. Each minor version can have development, beta, and release candidate phases. 20 | 21 | ## Release support 22 | 23 | For Drupal components, OpenEuropa team have a support policy inspired by Drupal core: 24 | - Components support current and previous Drupal Core minor versions. New minor versions for components are made compatible with these respective core versions. 25 | - When a new minor core version (n) is supported, the support for release n-2 is dropped. 26 | 27 | This follows a similar release cycle proposed for Drupal Core from a security standpoint and guarantees that all users of OpenEuropa components are running current minor release of supported Drupal Core (n) or previous (n-1). 28 | As Drupal core minor releases happen every 6 months, website and application owners should be prepared to update to every minor release at least every 6 months. 29 | 30 | ## Backwards compatibility 31 | 32 | Our Backward Compatibility Promise allows developers to upgrade with confidence from one minor version to the next one. Whenever keeping backward compatibility is not possible, the feature, the enhancement or the bug fix will be scheduled for the next major version. 33 | 34 | ## Deprecation policy 35 | 36 | New minor versions can introduce new APIs and new features. When a new API replaces an old one, the later cannot be 37 | removed because it would break the backwards compatibility pledge. Instead, the old API will be deprecated in favor of 38 | the new one. 39 | 40 | ### How to deprecate 41 | 42 | A deprecation consists of two parts: 43 | 44 | * A `@deprecated` PHPDoc tag that indicates when the code was deprecated, when it will be removed, and what to use 45 | instead. An optional `@see` link to a relevant issue, explaining the API change. 46 | * A `@trigger_error('...', E_USER_DEPRECATED)` at runtime to notify developers that deprecated code is being used. The 47 | `@` suppression should be used in most cases so that we can customize the error handling and avoid flooding logs on 48 | production. In some cases, we will omit the `@` if it is important to notify developers of a behavior or BC break 49 | (e.g. for a critical issue). 50 | 51 | Additionally, developers and QA may consider adding a third part: A unit test proving the deprecation notice will be 52 | triggered when the deprecated code is called. Use a `@group` legacy annotation in conjunction with calls to 53 | `$this->expectDeprecation()`. 54 | 55 | Note that Drupal deprecation message template is very coupled to Drupal core and contrib use-cases and it doesn't fit 56 | the OpenEuropa components case, but it's important that the message contain all the elements described above. 57 | 58 | ### What to deprecate 59 | 60 | OpenEuropa is following the Drupal's Deprecation Policy regarding what is 61 | subject to deprecation: https://www.drupal.org/about/core/policies/core-change-policies/drupal-core-deprecation-policy#what 62 | 63 | ## References 64 | 65 | * [Drupal core release cycle: major, minor, and patch releases](https://www.drupal.org/core/release-cycle-overview) 66 | * [Drupal core deprecation policy](https://www.drupal.org/about/core/policies/core-change-policies/drupal-core-deprecation-policy) 67 | -------------------------------------------------------------------------------- /docs/development/automated-testing.md: -------------------------------------------------------------------------------- 1 | # Automated testing 2 | 3 | OpenEuropa requires automated tests to be written for every new feature or 4 | bugfix to ensure that the functionality will keep working as expected in the 5 | future. 6 | 7 | ## Acceptance criteria 8 | 9 | * Pull requests without sufficient test coverage will not be accepted. 10 | * As a general rule any non-trivial code should be covered with tests. Trivial 11 | code that does not contain any business logic (such as getters and setters, 12 | object constructors, factory methods, ...) does not require tests. However, 13 | any code that is non-trivial (e.g. containing switches, loops, arithmetic 14 | operations or any other business logic) should be fully covered by tests. 15 | * Whether or not a piece of code is missing necessary coverage is at the 16 | discretion of the QA engineers. Any request for additional test coverage 17 | during code review needs to be honoured or the pull request will not be 18 | accepted. 19 | * For a pull request to be accepted, both the previously existing and the newly 20 | added tests should be passing. 21 | * Existing test code should not be modified unless this is backed up by a change 22 | request originating from project stakeholders. 23 | 24 | ## Types of tests 25 | 26 | ### User stories 27 | 28 | OpenEuropa practices [Behaviour Driven Development][1] to facilitate effective 29 | communication between business and development teams. 30 | 31 | User stories, or business requirements in general, should be accompanied by a 32 | test scenario that is written in non-technical domain specific language. This 33 | scenario should be verified by the business during user acceptance testing. 34 | After the story is accepted this scenario can then be used to perform automated 35 | tests to ensure that the business requirements work as designed, and keep 36 | working for the entire lifetime of the project. 37 | 38 | Every OpenEuropa component should write their test scenarios in [Gherkin][2] 39 | and use a BDD framework appropriate for their programming language to execute 40 | and verify the scenarios. For example, in PHP based code we can use [Behat][3]. 41 | 42 | For many user stories having a BDD user scenario can be sufficient to fully 43 | test all code that has been written to fulfill the user story. However since it 44 | might happen that business requirements change in the future this may cause 45 | existing scenarios to be rewritten, which might leave parts of the code 46 | untested. For this reason it is highly recommended to provide unit tests in 47 | addition to BDD scenarios, especially for business critical components and code 48 | that is intended to be reused. 49 | 50 | Note that according to BDD principles the user scenarios are solely intended 51 | for describing expected user behaviour. They should not be used to provide test 52 | coverage for any code that does not directly correspond to a user story that 53 | was provided by the business. The main audience for these user scenarios are 54 | the product owner and business stakeholders who can inspect the scenarios at 55 | any time to verify that the business value is being realized by the project. 56 | Any change or addition to the user scenarios can be seen as a change to the 57 | business requirements, and should be approved by business stakeholders. 58 | 59 | ### Unit tests 60 | 61 | Any pull requests that do not result from user stories should be covered by 62 | unit tests rather than BDD user scenarios. Use the appropriate unit testing 63 | frameworks that are available for the programming language in which your 64 | component is developed. 65 | 66 | ## Running tests 67 | 68 | In order to ensure that the project fully benefits from the advantages of 69 | automated testing we require the following: 70 | 71 | * Every project and component in the OpenEuropa space should use a Continuous 72 | Integration service to automatically test every PR before they get accepted. 73 | The OpenEuropa team provides this service. For more information see [CI 74 | Deployment Workflow](../docs/development/ci-deployment-workflow.md). 75 | * Every component is required to add a section to the main README file that 76 | explains how to run the test suite on a local development environment. This 77 | will ensure that any contributor will have this important information readily 78 | available. 79 | 80 | [1]: https://en.wikipedia.org/wiki/Behavior-driven_development 81 | [2]: https://github.com/cucumber/cucumber/wiki/Gherkin 82 | [3]: http://behat.org/ 83 | -------------------------------------------------------------------------------- /docs/development/testing.md: -------------------------------------------------------------------------------- 1 | # Testing Drupal components 2 | 3 | This document contains information specific to testing Drupal based components. 4 | More general information about our testing policy can be found in the 5 | [Automated testing](../development/automated-testing.md) section. 6 | 7 | ## Choosing the right test framework 8 | 9 | In addition to the built-in testing frameworks that ship with Drupal core, 10 | OpenEuropa also uses Behat to describe business requirements. This section 11 | details which test framework to use under which circumstances. 12 | 13 | ### Behat 14 | 15 | Whenever a PR intends to change end user behaviour it is required to describe 16 | the expected user behaviour in a Behat scenario. In practice this means: 17 | 18 | * Every user story is accompanied by a Behat scenario. This scenario will be 19 | provided to the project stakeholders for acceptance testing. 20 | * The target audience for these scenarios are the project stakeholders. The 21 | Behat scenarios prove to project stakeholders that the project fulfills all 22 | business requirements. 23 | * Every Behat test scenario is written in domain specific business language. 24 | The scenarios should avoid the use of technical terms, machine names or 25 | references to underlying technology which might not be understood by 26 | non-technical stakeholders. 27 | * Behat tests should only be used to describe expected user behaviour as 28 | specified by project stakeholders. It should *not* be used to test code. Any 29 | code written that does not directly affect the expected end user behaviour 30 | should be covered by unit tests instead. At no point the business should see 31 | a Behat scenario that describes a behaviour that was not directly requested 32 | by them. 33 | * For many user stories the Behat scenario will be sufficient to cover the full 34 | extent of the code that was written. However, business requirements are known 35 | to change which might leave critical code paths untested. For this reason it 36 | is recommended that any non-trivial code is covered by unit tests in addition 37 | to Behat scenarios. 38 | 39 | ### Unit tests 40 | 41 | Pull requests that are not part of user stories should be covered by unit tests 42 | rather than Behat scenarios. It is also recommended to provide unit tests for 43 | any code that is non-trivial or is intended to be reused (like services or 44 | plugins). 45 | 46 | Guidelines for writing unit tests: 47 | 48 | * The different test frameworks are described in [Types of tests in Drupal 49 | 8][1]. 50 | * Provide tests for the public API: public methods as described in interfaces. 51 | * Prefer low level testing frameworks over higher level ones. Choose the lowest 52 | level that covers your needs. `UnitTestCase` is preferred. Only use 53 | `KernelTestBase` if you actually need to test the interaction of your code 54 | with the Drupal API. 55 | * Functional tests (`BrowserTestBase`) should be rarely needed since this tests 56 | end user behaviour. If any end user behaviour needs to be tested, please 57 | consult the business stakeholders if this behaviour can be captured in actual 58 | business requirements instead. This would allow us to use Behat scenarios 59 | which are prefered over functional tests in PHPUnit. 60 | * Javascript code is most commonly written in function of business requirements 61 | that directly affect end user behaviour. Work with business stakeholders to 62 | see if this can be put into a user story, and a corresponding Behat scenario. 63 | Only in the rare case that JS code is not correlating with requested end user 64 | behaviour `JavascriptTestBase` should be used. 65 | 66 | ## Writing tests for bug fixes 67 | 68 | * Tickets that are marked as bug fixes might affect end user behaviour. In many 69 | cases a bug fix might be caused by a previously undescribed user behaviour, or 70 | insufficient coverage of edge cases in Behat scenarios. If a ticket is marked 71 | as a bugfix but might necessitate changes in Behat scenarios this should be 72 | discussed with the business stakeholders and approved by them. 73 | * Other types of bugs might not directly affect the expected end user 74 | behaviour. Examples are error messages, crashes, cache invalidation problems 75 | etc. These can often be fixed without requiring changes to the business 76 | requirements, and hence no changes to Behat scenarios are required. 77 | * When writing a test for a bug fix it is highly recommended to write and 78 | commit the test first, so it can be demonstrated that the test correctly fails 79 | when the bug is present, and passes when the bug is fixed. 80 | 81 | ## Running tests 82 | 83 | * Every Drupal component should have a section in the README explaining how to 84 | run the tests on a local development environment. 85 | * Provide the necessary configuration files (like `phpunit.xml.dist` and 86 | `behat.yml.dist`) in the root of the project to make execution of tests as 87 | trivial as possible. 88 | * Ensure that the tests can run on our Continuous Integration environments by 89 | supplying a `.drone.yml` file. 90 | 91 | [1]: https://www.drupal.org/docs/8/testing/types-of-tests-in-drupal-8 92 | -------------------------------------------------------------------------------- /docs/development/third-party/drupal/services-dependency-injection.md: -------------------------------------------------------------------------------- 1 | # Services and Dependency Injection 2 | 3 | Dependency injection is a very scary concept in Object Oriented Programming (OOP) but is actually very simple to understand. It is the practice of providing classes or functions with the dependencies they need rather than making them responsible for retrieving them. In other words, and in simple terms, having parameters. 4 | 5 | Most typically, dependency injection refers to class constructor dependencies (parameters) that allow objects of that class to perform their functions. In this way, the dependencies can also be swapped. 6 | 7 | In more complex applications like Symfony or Drupal, managing these dependencies is done via a `Container` (Service Container in Symfony and Drupal 8). The latter is responsible for collecting objects and their dependencies and making them available to the application when needed (constructing them). It provides the glue between objects, their dependencies and the application. 8 | 9 | Check out [this article](https://www.webomelette.com/drupal-8-dependency-injection-service-container-and-all-jazz) for an introduction to dependency injection and the service container. 10 | 11 | ## What are services in Drupal 12 | 13 | Services are objects meant to contain reusable and decoupled functionality. These objects are *registered* with the service container and can be fetched by the application at any point. 14 | 15 | Typically, services are meant to encapsulate the business logic of the application in a decoupled way. In order words, the objective of a service is to "implement" a piece of functionality. And as a consequence of dependency injection, the service can be replaced with another that "implements" the same functionality differently. 16 | 17 | However, services can also be used to contain singular business logic as a way to encapsulate and logically break down functionality. This allows it to also be more easily tested. 18 | 19 | ## How to define a service 20 | 21 | The typical service definition contains a name (something to identify the service) and a class name (the class which gets instantiated by the Container when the service is requested). 22 | 23 | Moreover, the service definition typically specifies other services that need to be *injected* into it via the constructor, something that is also handled by the Container. 24 | 25 | For more information on how to define a service, check [here](https://www.drupal.org/docs/8/api/services-and-dependency-injection/structure-of-a-service-file). 26 | 27 | ## Fetching services 28 | 29 | The simplest way to fetch services from the Container is by using the static `\Drupal` class: 30 | 31 | ``` 32 | $service = \Drupal::service('my_service_name'); 33 | ``` 34 | 35 | Some services even have accessor shortcuts on the `\Drupal` class. Some notable examples: 36 | 37 | ``` 38 | $entity_type_manager = \Drupal::entityTypeManager(); 39 | $database = \Drupal::database(); 40 | $config_factory = \Drupal::configFactory(); 41 | $logger = \Drupal::logger(); 42 | ... 43 | ``` 44 | 45 | This method of loading services is static. This means they are fetched from the global scope and therefore are not injected. So it's the least recommended way of accessing services and should only be done from a static 46 | scope such as `.module` or `.install` files. 47 | 48 | ## How to inject services in Drupal 8 49 | 50 | Instead of accessing the services statically, it's recommended to inject them. And depending on the use case, the injection happens differently. 51 | 52 | Check out this [article](https://code.tutsplus.com/tutorials/drupal-8-properly-injecting-dependencies-using-di--cms-26314) for an outline on the most typical use cases of injecting dependencies in Drupal 8 and an explanation of the mechanics behind that. 53 | 54 | ### In other services 55 | 56 | Services may depend on other services for performing their functions. In this case, these dependencies are specified inside the service definition as arguments. The latter are then passed by the Container and *received* by the service via the constructor. 57 | 58 | ### In controllers (and forms) 59 | 60 | Controllers are the typical entry point for creating pages in Drupal 8. They extend `ControllerBase` which already provides some methods for accessing common and any other services. However, using these directly **is not dependency injection** as it is handled statically. 61 | 62 | Instead, we should use the `create()` method of the `ContainerInjectionInterface` to *ask* the container for the services we need and then *receive* them in the constructor. See [here](https://code.tutsplus.com/tutorials/drupal-8-properly-injecting-dependencies-using-di--cms-26314) the `Controllers` heading for an example and explanation on how this works internally. 63 | 64 | In Form classes, the process is exactly the same. See [this entry]() for more information on the Form API (@todo add link). 65 | 66 | ### In plugins 67 | 68 | Plugins are slightly more complicated as they receive some extra arguments from the plugin manager when they are instantiated (they are not resolved like the controllers). But the concept is similar. See [here](https://code.tutsplus.com/tutorials/drupal-8-properly-injecting-dependencies-using-di--cms-26314) the `Plugins` heading for an example and explanation on how this works internally. 69 | 70 | ### Where we cannot inject services 71 | 72 | Dependency injection should be used (instead of static service fetching) whenever possible. However, there are a few exceptions where this is not possible: 73 | 74 | * Static files (such as `.module` or `.install`) 75 | * `FieldType` plugins which are not container aware 76 | 77 | ## Where can we quickly find existing core services? 78 | 79 | Drupal core comes with loads of services that can and should be used. These are defined typically in two places: 80 | 81 | * Individual core module `.services.yml` files 82 | * The `core.services.yml` file 83 | 84 | These are the quick reference points for service definitions that can be used as dependencies for custom services. 85 | 86 | ## Tagged services and service collectors 87 | 88 | Service tags are used to specify that a given service is used (collected) by a subsystem or belongs to a category. 89 | 90 | Popular examples of tagged services are the event subscriber services which are collected by the event dispatcher and registered as listeners to specific events. For more information on the event dispatcher, read [this entry]() (@todo add link). 91 | 92 | For an example of how a tagged based service collector works, read [this](https://www.drupal.org/docs/8/api/services-and-dependency-injection/service-tags). 93 | 94 | ## Dynamic services and altering existing ones 95 | 96 | Apart from the static definition inside `.services.yml` files, services can also be declared dynamically. This is done by implementing a specially named class and altering the `ContainerBuilder`. 97 | 98 | At this point new service definitions can be added and existing ones altered. See [here](https://www.drupal.org/docs/8/api/services-and-dependency-injection/altering-existing-services-providing-dynamic-services) for an example on how to do this. 99 | 100 | ## Useful links 101 | 102 | * [Services and dependency injection in Drupal 8](https://www.drupal.org/docs/8/api/services-and-dependency-injection/services-and-dependency-injection-in-drupal-8) on Drupal.org 103 | -------------------------------------------------------------------------------- /docs/initiative/how-to-contribute.md: -------------------------------------------------------------------------------- 1 | # Contributing to OpenEuropa 2 | 3 | The following is a set of guidelines for contributing to OpenEuropa and its components, which are hosted in the 4 | [OpenEuropa project](https://github.com/openeuropa) on GitHub. These are mostly guidelines, not rules. 5 | Use your best judgment, and feel free to propose changes to this document in a pull request. 6 | 7 | **Table of contents** 8 | 9 | * [Code of conduct](#code-of-conduct) 10 | * [Before getting started](#before-getting-started) 11 | * [How can I contribute?](#how-can-i-contribute) 12 | * [Reporting bugs](#reporting-bugs) 13 | * [Feature requests](#feature-requests) 14 | * [Pull requests](#pull-requests) 15 | * [Style guide](#style-guide) 16 | * [Git commit messages](#git-commit-messages) 17 | * [Code styling](#code-styling) 18 | 19 | ## Code of conduct 20 | 21 | This project and everyone participating in it is governed by the [OpenEuropa Code of Conduct](code-of-conduct.md). 22 | By participating, you are expected to uphold this code. Please report unacceptable behaviour to [EC-EUROPA-IT-PLATFORM@ec.europa.eu](mailto:EC-EUROPA-IT-PLATFORM@ec.europa.eu). 23 | 24 | ## Before getting started 25 | 26 | OpenEuropa is an open source project made up of several components. Before you report anything please make 27 | sure you are using the correct repository for the component you are referring to. 28 | 29 | A comprehensive list of components built and maintained by the OpenEuropa team is available [here](../openeuropa-components.md). 30 | 31 | ## How can I contribute? 32 | 33 | ### Reporting bugs 34 | 35 | This section guides you through submitting a bug report for any OpenEuropa component. Following these guidelines helps 36 | everyone involved to understand your report and react efficiently. 37 | 38 | Before creating bug reports, please check [this checklist](#before-submitting-a-bug-report) as you might find out that 39 | you don't actually need to create one. When you are creating a bug report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report) 40 | and use [the required template](../templates/issue-template.md), this will allows us to resolve issues faster. 41 | 42 | #### Before submitting a bug report 43 | 44 | * Determine [which repository the problem should be reported in](#before-getting-started). 45 | * Make sure the issue is really a bug and not an intended behaviour by reading the component's documentation. 46 | * Check if you can reproduce the problem in the latest version of the related component. 47 | * Perform a [cursory search](https://github.com/search?q=+is%3Aissue+user%3Aopeneuropa) to see if the problem has 48 | already been reported. If it has and the issue is still open, please add a comment to the existing issue instead of 49 | opening a new one. 50 | 51 | #### How do I submit a (good) bug report? 52 | 53 | Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues). After you've determined [which repository](#before-getting-started) 54 | your bug is related to, create an issue on that repository and provide the following information by filling in 55 | [the issue template](../templates/issue-template.md). 56 | 57 | Explain the problem and include additional details to help maintainers reproduce the issue: 58 | 59 | * Use a clear and descriptive title that describes the problem. 60 | * Describe the exact steps necessary to reproduce the problem with as many details as possible. 61 | * Describe the behaviour you observed after following the steps and point out exactly what the problem is with that 62 | behaviour. 63 | * Explain what the expected behaviour is and why. 64 | * When applicable include screenshots or any other supporting material. 65 | 66 | Provide more context by answering these questions: 67 | 68 | * Did the problem start happening recently (e.g. after updating to a newer version of the component) or was it always a 69 | problem? 70 | * If the problem started happening recently, can you reproduce the problem in an older version of the component? 71 | * What's the most recent version in which the problem does not occur? 72 | * Can you reliably reproduce the issue? If not, provide details about how often the problem happens and under which 73 | circumstances. 74 | 75 | Include details about your configuration and environment: 76 | 77 | * Which version of the component are you using? 78 | * What's the name and version of the browser you are using? 79 | * Which other components or modules do you have installed? 80 | 81 | ### Feature requests 82 | 83 | This section guides you through submitting a feature request for OpenEuropa, such as completely new features or 84 | improvements to existing functionality. 85 | 86 | Before creating a feature request, please check [this checklist](#before-submitting-a-feature-request) as you might find 87 | out that you don't need to create one. When you are creating a feature request, please 88 | [include as many details as possible](#how-do-i-submit-a-good-feature-request). 89 | 90 | Fill in [the issue template](../templates/issue-template.md), including the steps that you imagine you would take if the feature 91 | you're requesting existed. 92 | 93 | #### Before submitting a feature request 94 | 95 | * Check if there's already [a component](../openeuropa-components.md) which provides that enhancement. 96 | * Check the project roadmap to understand if the feature is already being planned for future releases associated dates. 97 | * Determine [which repository the feature should be suggested in](#before-getting-started). 98 | * Perform a [cursory search](https://github.com/search?q=+is%3Aissue+user%3Aopeneuropa) to see if the feature has 99 | already been suggested. If it has, add a comment to the existing issue instead of opening a new one. 100 | 101 | #### How do I submit a (good) feature request? 102 | 103 | Feature requests are tracked as [GitHub issues](https://guides.github.com/features/issues/). After you've determined 104 | [which repository](#before-getting-started) your feature suggestion is related to, create an issue on that repository 105 | and provide the following information: 106 | 107 | * Use a clear and descriptive title for the issue to identify the suggestion. 108 | * Provide a step-by-step description of the suggested enhancement in as many details as possible. 109 | * Describe the current behaviour and explain which behaviour you expected to see instead and why. 110 | * Include screenshots which will help demonstrate the feature you would like to include. 111 | * Explain why this enhancement would be useful to the users of the component and isn't something that can or should be 112 | implemented as a custom component. 113 | 114 | ### Pull requests 115 | 116 | * Fill in the provided template. You can see a sample [here](../templates/pull-request-template.md). 117 | * Make sure to include (if not available yet) and run the [Code Review component](https://github.com/openeuropa/code-review) 118 | before submitting the pull request. 119 | * End all files with a newline. 120 | 121 | ## Style guide 122 | 123 | ### Git commit messages 124 | 125 | * If the commit refers to an issue or a ticket, start the comment with the issue or ticket number, 126 | then add a colon and a space (e.g. "OPENEUROPA-1234: "). 127 | * Prefer the present tense ("Add feature" not "Added feature"). 128 | * Prefer the imperative mood ("Move element to..." not "Moves element to..."). 129 | * Limit the first line to 72 characters or less. 130 | * Do not end the first line with a period. 131 | 132 | Example of commit message: "OPENEUROPA-1234: Implement automatic feature generator". 133 | 134 | ### Code styling 135 | 136 | OpenEuropa provides a specific component to enforce a series of code styling rules. Please make sure that the 137 | [Code Review component](https://github.com/openeuropa/code-review) is included in the component you are working with and 138 | that the results are all green before committing anything. 139 | -------------------------------------------------------------------------------- /docs/development/tooling.md: -------------------------------------------------------------------------------- 1 | # Tooling documentation 2 | 3 | The following is a list of technologies and tools used in components, sites and projects developed under the OpenEuropa Initiative. 4 | 5 | ## Table of Contents 6 | 7 | - [Development environment](#development-environment) 8 | - [System-level packages](#system-level-packages) 9 | - [PHP](#php) 10 | - [Composer](#composer) 11 | - [Git](#git) 12 | - [Drush](#drush) 13 | - [Robo](#robo) 14 | - [Node.js](#node\.js) 15 | - [Validation and testing tools](#validation-and-testing-tools) 16 | - [Behat](#behat) 17 | - [PHPUnit](#phpunit) 18 | - [GrumPhp](#grumphp) 19 | - [CI/CD solutions](#ci\/cd-solutions) 20 | - [Docker](#docker) 21 | - [Supported Docker images](#supported-docker-images) 22 | - [Using Docker Compose](#using-docker-compose) 23 | - [Using Docker on macOS](#using-docker-on-macos) 24 | 25 | ### Development environment 26 | 27 | OpenEuropa does not impose a development environment as long as the following software packages are used. Nevertheless, all system requirements for each component are containerized using Docker. 28 | 29 | #### System-level packages 30 | 31 | | Tool | Required | Purpose | 32 | |-|-|-| 33 | | [PHP](#php) | Yes | Required by Composer, Drush, TaskRunner, etc. | 34 | | [Composer](#composer) | Yes | Package manager for PHP. | 35 | | [Git](#git) | Yes | Version control system. | 36 | | [Drush](#drush) | Yes | CLI integration with Drupal. | 37 | | [Robo](#robo) | Yes | Required by OpenEuropa task runner. | 38 | | [Node.js](#npm) | No | Required to develop OpenEuropa theme. | 39 | 40 | #### PHP 41 | 42 | [PHP](http://php.net/manual/en/install.php) is required by various tools, including Composer, Drush, Robo, and Drupal itself. Please ensure that: 43 | 44 | * OpenEuropa components require usage of PHP 7.2+. You can check your existing version by executing `php -v`. 45 | 46 | #### Composer 47 | 48 | [Composer](https://getcomposer.org/) is used to manage dependencies of PHP projects. It has natural integration with Drupal.org. 49 | All projects developed under OpenEuropa initiative require to use it. 50 | All dependencies specific for given component are defined in its composer.json file. 51 | 52 | #### Git 53 | 54 | [Git](https://git-scm.com/) is the distributed version control system used as a foundation of the OpenEuropa ecosystem. Components created by OpenEuropa teams are stored in separated repositories hosted on Github. 55 | 56 | #### Drush 57 | 58 | [Drush](http://www.drush.org/en/master/) is a command line shell and Unix scripting interface for Drupal. Drush is used to interact with Drupal websites through the command line. 59 | 60 | #### Robo 61 | 62 | [Robo](https://robo.li) is a modern and simple PHP task runner inspired by Gulp and Rake aimed to automate common tasks. It is the main dependency of OpenEuropa [Task Runner](https://github.com/openeuropa/task-runner) project. 63 | 64 | #### Node.js 65 | 66 | [Node.js (>= 8)](https://nodejs.org/en) is required for the development of OpenEuropa theme. The same development practices described in OpenEuropa theme are recommended also for the development of custom themes. 67 | All required development dependencies are defined in the package.json file. 68 | 69 | ### Validation and testing tools 70 | 71 | | Tool | 72 | |----------------------------| 73 | | [Behat](#behat) | 74 | | [PHPUnit](#phpunit) | 75 | | [GrumPhp](#grumphp) | 76 | 77 | #### Behat 78 | 79 | [Behat](http://behat.org/) is a php framework for autotesting business expectations. It shall be used to develop automated tests using Gherkin scenarios in order to cover business functionalities. 80 | 81 | #### PHPUnit 82 | 83 | [PHPUnit](https://phpunit.de/) is used by OpenEuropa components to perform unit testing against developed code. PHPUnit is broadly adopted by Drupal community. More information about its usage can be found [here](https://www.drupal.org/docs/8/phpunit). 84 | 85 | #### GrumPhp 86 | 87 | [GrumpPhp](https://github.com/phpro/grumphp) is used as the dependency in [OpenEuropa Code Review component](https://github.com/openeuropa/code-review) to enforce that PHP coding standards are correctly applied to newly developed code. 88 | 89 | ### CI/CD solutions 90 | 91 | | Tool | 92 | |----------------------------| 93 | | [Drone](#drone) | 94 | 95 | #### Drone 96 | 97 | Drone is the recommended CI/CD solution for OpenEuropa Initiative. More information about drone can be found [here](docs/development/third-party/drone.md). 98 | 99 | ### Docker 100 | 101 | In order to setup and isolate individual components of the overall OpenEuropa solution, components need to be able to be containerised. Moreover, components should provide a standard solution for a final user to interact with them when used in containers. 102 | 103 | Therefore maintainers decided to use Docker technology orchestrated by the usage of docker-compose. In case of any specific information related to the usage and configuration of containers for custom or different purposes, you can find additional documentation at the component repository. 104 | 105 | Docker is a platform for developers and sysadmins to develop, deploy, and run applications with containers. 106 | 107 | #### Supported Docker images 108 | 109 | Containers used in OpenEuropa Initiative projects are based on images crafted by the FPFIS DevOps team. Information about supported images and their configuration can be find under following link [Docker images](https://docs.fpfis.eu/docker-images/). 110 | 111 | #### Using Docker Compose 112 | 113 | Projects which are delivered under the OpenEuropa Initiative offers a set of containers to mimic software packages used on the IT infrastructure and provide an easy way of setting up an environment to work. If you want to run the containerised environment in order to work with a given component, project or site, you can follow these steps to set up it using Docker Compose. 114 | 115 | Requirements: 116 | 117 | - [Docker](https://www.docker.com/get-docker) 118 | - [Docker-compose](https://docs.docker.com/compose) 119 | 120 | Run: 121 | 122 | ```bash 123 | docker-compose up -d 124 | ``` 125 | 126 | This will set up and run the environment. After spawning, please follow the set of commands specified in the documentation of a given component, site or a project. 127 | Usually the next step is to execute Composer script to download and set up dependencies. 128 | 129 | ```bash 130 | docker-compose exec web composer install 131 | ``` 132 | 133 | In order to tweak settings or adjust configuration of a specific container, please edit the `docker-compose.yml` file accordingly to your current needs. 134 | 135 | #### Using Docker on macOS 136 | 137 | In order to maximise the performance of using Docker on macOS, we strongly advise using at least version 18.03.1 of Docker which supports native NFS integration. You can find a very comprehensive article about this topic under following link [Set Up Docker For Mac with Native NFS](https://medium.com/@sean.handley/how-to-set-up-docker-for-mac-with-native-nfs-145151458adc). 138 | 139 | What is required can be defined in two steps. 140 | 141 | First is to run the bash script in order to configure Docker native NFS support. 142 | You can find the source of a script in the article or by using this link [setup_native_nfs_docker_osx.sh](https://gist.githubusercontent.com/seanhandley/7dad300420e5f8f02e7243b7651c6657/raw/fdd77fe66cf9ce893fa0175d735cbede2bb065e4/setup_native_nfs_docker_osx.sh). 143 | 144 | Next, you must include an additional volume definition inside the `docker-compose.override.yml` file. OpenEuropa components ship with the volume definition in their `docker-compose.yml` file, commented out. But you can also find the example of how to do so below. 145 | 146 | In the second part keyed by `volumes`, the volume `nfsmount` is defined and configured to use NFS native support. Then you can reference the defined volume as a storage of a container. 147 | 148 | In the example below, the `nfsmount` volume is used as a storage for the `web` container and mount to the `var/www/html` directory inside the container. From the local machine perspective it mounts the main directory where the `docker-compose.yml` file is located into the directory configured in a give container (`/var/www/html` in this particular case). 149 | 150 | ```yml 151 | # Example of the docker-compose.yml file with the additional volume definition. 152 | 153 | version: '2' 154 | services: 155 | web: 156 | image: fpfis/httpd-php-dev:5.6 157 | working_dir: /var/www/html 158 | environment: 159 | - DOCUMENT_ROOT=/var/www/html 160 | volumes: 161 | - nfsmount:/var/www/html 162 | ports: 163 | - 8080:8080 164 | 165 | volumes: 166 | nfsmount: 167 | driver: local 168 | driver_opts: 169 | type: nfs 170 | o: addr=host.docker.internal,rw,nolock,hard,nointr,nfsvers=3 171 | device: ":${PWD}/" 172 | ``` 173 | -------------------------------------------------------------------------------- /LICENCE.txt: -------------------------------------------------------------------------------- 1 | EUROPEAN UNION PUBLIC LICENCE v. 1.2 2 | EUPL © the European Union 2007, 2016 3 | 4 | This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined below) which is provided under the 5 | terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such 6 | use is covered by a right of the copyright holder of the Work). 7 | The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following 8 | notice immediately following the copyright notice for the Work: 9 | Licensed under the EUPL 10 | or has expressed by any other means his willingness to license under the EUPL. 11 | 12 | 1.Definitions 13 | In this Licence, the following terms have the following meaning: 14 | — ‘The Licence’:this Licence. 15 | — ‘The Original Work’:the work or software distributed or communicated by the Licensor under this Licence, available 16 | as Source Code and also as Executable Code as the case may be. 17 | — ‘Derivative Works’:the works or software that could be created by the Licensee, based upon the Original Work or 18 | modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work 19 | required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in 20 | the country mentioned in Article 15. 21 | — ‘The Work’:the Original Work or its Derivative Works. 22 | — ‘The Source Code’:the human-readable form of the Work which is the most convenient for people to study and 23 | modify. 24 | — ‘The Executable Code’:any code which has generally been compiled and which is meant to be interpreted by 25 | a computer as a program. 26 | — ‘The Licensor’:the natural or legal person that distributes or communicates the Work under the Licence. 27 | — ‘Contributor(s)’:any natural or legal person who modifies the Work under the Licence, or otherwise contributes to 28 | the creation of a Derivative Work. 29 | — ‘The Licensee’ or ‘You’:any natural or legal person who makes any usage of the Work under the terms of the 30 | Licence. 31 | — ‘Distribution’ or ‘Communication’:any act of selling, giving, lending, renting, distributing, communicating, 32 | transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential 33 | functionalities at the disposal of any other natural or legal person. 34 | 35 | 2.Scope of the rights granted by the Licence 36 | The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for 37 | the duration of copyright vested in the Original Work: 38 | — use the Work in any circumstance and for all usage, 39 | — reproduce the Work, 40 | — modify the Work, and make Derivative Works based upon the Work, 41 | — communicate to the public, including the right to make available or display the Work or copies thereof to the public 42 | and perform publicly, as the case may be, the Work, 43 | — distribute the Work or copies thereof, 44 | — lend and rent the Work or copies thereof, 45 | — sublicense rights in the Work or copies thereof. 46 | Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the 47 | applicable law permits so. 48 | In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed 49 | by law in order to make effective the licence of the economic rights here above listed. 50 | The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the 51 | extent necessary to make use of the rights granted on the Work under this Licence. 52 | 53 | 3.Communication of the Source Code 54 | The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as 55 | Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with 56 | each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to 57 | the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to 58 | distribute or communicate the Work. 59 | 60 | 4.Limitations on copyright 61 | Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the 62 | exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations 63 | thereto. 64 | 65 | 5.Obligations of the Licensee 66 | The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those 67 | obligations are the following: 68 | 69 | Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to 70 | the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the 71 | Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work 72 | to carry prominent notices stating that the Work has been modified and the date of modification. 73 | 74 | Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this 75 | Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless 76 | the Original Work is expressly distributed only under this version of the Licence — for example by communicating 77 | ‘EUPL v. 1.2 only’. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the 78 | Work or Derivative Work that alter or restrict the terms of the Licence. 79 | 80 | Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both 81 | the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done 82 | under the terms of this Compatible Licence. For the sake of this clause, ‘Compatible Licence’ refers to the licences listed 83 | in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with 84 | his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail. 85 | 86 | Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide 87 | a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available 88 | for as long as the Licensee continues to distribute or communicate the Work. 89 | Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names 90 | of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and 91 | reproducing the content of the copyright notice. 92 | 93 | 6.Chain of Authorship 94 | The original Licensor warrants that the copyright in the Original Work granted hereunder is owned by him/her or 95 | licensed to him/her and that he/she has the power and authority to grant the Licence. 96 | Each Contributor warrants that the copyright in the modifications he/she brings to the Work are owned by him/her or 97 | licensed to him/her and that he/she has the power and authority to grant the Licence. 98 | Each time You accept the Licence, the original Licensor and subsequent Contributors grant You a licence to their contributions 99 | to the Work, under the terms of this Licence. 100 | 101 | 7.Disclaimer of Warranty 102 | The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work 103 | and may therefore contain defects or ‘bugs’ inherent to this type of development. 104 | For the above reason, the Work is provided under the Licence on an ‘as is’ basis and without warranties of any kind 105 | concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or 106 | errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this 107 | Licence. 108 | This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work. 109 | 110 | 8.Disclaimer of Liability 111 | Except in the cases of wilful misconduct or damages directly caused to natural persons, the Licensor will in no event be 112 | liable for any direct or indirect, material or moral, damages of any kind, arising out of the Licence or of the use of the 113 | Work, including without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, loss 114 | of data or any commercial damage, even if the Licensor has been advised of the possibility of such damage. However, 115 | the Licensor will be liable under statutory product liability laws as far such laws apply to the Work. 116 | 117 | 9.Additional agreements 118 | While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services 119 | consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole 120 | responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, 121 | defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by 122 | the fact You have accepted any warranty or additional liability. 123 | 124 | 10.Acceptance of the Licence 125 | The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ placed under the bottom of a window 126 | displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of 127 | applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms 128 | and conditions. 129 | Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You 130 | by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution 131 | or Communication by You of the Work or copies thereof. 132 | 133 | 11.Information to the public 134 | In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, 135 | by offering to download the Work from a remote location) the distribution channel or media (for example, a website) 136 | must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence 137 | and the way it may be accessible, concluded, stored and reproduced by the Licensee. 138 | 139 | 12.Termination of the Licence 140 | The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms 141 | of the Licence. 142 | Such a termination will not terminate the licences of any person who has received the Work from the Licensee under 143 | the Licence, provided such persons remain in full compliance with the Licence. 144 | 145 | 13.Miscellaneous 146 | Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the 147 | Work. 148 | If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or 149 | enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid 150 | and enforceable. 151 | The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of 152 | the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. 153 | New versions of the Licence will be published with a unique version number. 154 | All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take 155 | advantage of the linguistic version of their choice. 156 | 157 | 14.Jurisdiction 158 | Without prejudice to specific agreement between parties, 159 | — any litigation resulting from the interpretation of this License, arising between the European Union institutions, 160 | bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice 161 | of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union, 162 | — any litigation arising between other parties and resulting from the interpretation of this License, will be subject to 163 | the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business. 164 | 165 | 15.Applicable Law 166 | Without prejudice to specific agreement between parties, 167 | — this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, 168 | resides or has his registered office, 169 | — this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside 170 | a European Union Member State. 171 | 172 | 173 | Appendix 174 | 175 | ‘Compatible Licences’ according to Article 5 EUPL are: 176 | — GNU General Public License (GPL) v. 2, v. 3 177 | — GNU Affero General Public License (AGPL) v. 3 178 | — Open Software License (OSL) v. 2.1, v. 3.0 179 | — Eclipse Public License (EPL) v. 1.0 180 | — CeCILL v. 2.0, v. 2.1 181 | — Mozilla Public Licence (MPL) v. 2 182 | — GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 183 | — Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software 184 | — European Union Public Licence (EUPL) v. 1.1, v. 1.2 185 | — Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). 186 | 187 | The European Commission may update this Appendix to later versions of the above licences without producing 188 | a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the 189 | covered Source Code from exclusive appropriation. 190 | All other changes or additions to this Appendix require the production of a new EUPL version. 191 | -------------------------------------------------------------------------------- /docs/openeuropa-components.md: -------------------------------------------------------------------------------- 1 | # OpenEuropa components 2 | 3 | Below the list of loosely coupled, reusable PHP projects provided by the OpenEuropa Initiative. 4 | Each project complies with [PHP-FIG][1] standards and adhere to the best-practices put forward by [PHP The "Right" Way][2]. 5 | 6 | Most code is distributed on [Packagist][3] and released under the [EUPL-1.2 license][4]. 7 | 8 | All projects use Semantic Versioning. Attention is drawn to [item 4 of the Semantic Version specification](https://semver.org/#spec-item-4) 9 | 'Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.' 10 | 11 | ### Drupal projects 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 28 | 29 | 34 | 39 | 40 | 44 | 49 | 50 | 54 | 59 | 60 | 61 | 65 | 70 | 71 | 72 | 76 | 81 | 82 | 83 | 87 | 92 | 93 | 97 | 102 | 103 | 107 | 112 | 113 | 117 | 122 | 123 | 127 | 132 | 133 | 137 | 142 | 143 | 147 | 152 | 153 | 157 | 162 | 163 | 167 | 172 | 173 | 177 | 182 | 183 | 187 | 192 | 193 | 197 | 202 | 203 | 207 | 212 | 213 | 217 | 222 | 223 | 227 | 232 | 233 | 237 | 242 | 243 | 247 | 252 | 253 | 257 | 262 | 263 | 267 | 272 | 273 | 277 | 282 | 283 | 287 | 292 | 293 | 297 | 302 | 303 | 307 | 312 | 313 | 317 | 322 | 323 | 327 | 332 | 333 | 337 | 342 |
ComponentStatus
20 | OpenEuropa Authentication
21 | This module allows to authenticate users against the European Commission login service. Details of this service can be found here. 22 |
24 | 25 | 26 | 27 |
30 | OpenEuropa Content
31 | This component ships with corporate and standardised content and entity types, as well as content modelling and handling functionalities. 32 | Additionally, it uses the OpenEuropa RDF SKOS component to integrate the Publications Office (OP) vocabularies. 33 |
35 | 36 | 37 | 38 |
41 | OpenEuropa Corporate Blocks
42 | This simple component contains the European Commission corporate blocks meant to display standardised parts of EC sites, such as the footer. It integrates with the OpenEuropa Theme for styling. 43 |
45 | 46 | 47 | 48 |
51 | OpenEuropa Drupal Module Template
52 | Builds the default files for a component to be used with the OpenEuropa project. 53 |
55 | 56 | 57 | 58 |
62 | OpenEuropa Editorial
63 | This component provides various editorial features (workflow, versioning, etc), shipped as indiviual submodules. 64 |
66 | 67 | 68 | 69 |
73 | OpenEuropa Link Lists
74 | This component provides site building features that allow the creation of lists of links, external and to internal content, dynamic and manual. 75 |
77 | 78 | 79 | 80 |
84 | OpenEuropa Media
85 | This component provides functionality for using Media of various types. Things like images, remote videos and integration with the EC AV Portal service are included. 86 |
88 | 89 | 90 | 91 |
94 | OpenEuropa Multilingual
95 | This component provides EC corporate multilingual features such as the official EU languages, language switcher, language negotiation, etc. 96 |
98 | 99 | 100 | 101 |
104 | OpenEuropa Paragraphs
105 | This component provides various Drupal paragraph types meant that display using the ECL components via the OpenEuropa Theme. 106 |
108 | 109 | 110 | 111 |
114 | OpenEuropa Profile
115 | A basic installation profile that can be used for sites that use OpenEuropa components. 116 |
118 | 119 | 120 | 121 |
124 | OpenEuropa RDF SKOS
125 | An RDF Entity based implementation for SKOS vocabularies located in triple stores. This can be used for integrating the taxonomies provided by the EC Publications Office (OP). See also the OpenEuropa Content component. 126 |
128 | 129 | 130 | 131 |
134 | OpenEuropa Search
135 | This component provides corporate search functionalities. 136 |
138 | 139 | 140 | 141 |
144 | OpenEuropa Theme
145 | Drupal 10 theme based on the Europa Component Library (ECL). 146 |
148 | 149 | 150 | 151 |
154 | OpenEuropa Translation
155 | This component provides translation capabilities for multilingual sites and integrations with various external translation services such as DGT Poetry. 156 |
158 | 159 | 160 | 161 |
164 | OpenEuropa Webtools
165 | This component provides integration with the EC Webtools service for various widgets and functionalities such as analytics, LACO, cookie consent, etc. 166 |
168 | 169 | 170 | 171 |
174 | OpenEuropa Time Caching
175 | The OpenEuropa Time Caching provides a cache tag service to generate and invalidate cache tags that deal with time. 176 |
178 | 179 | 180 | 181 |
184 | OpenEuropa oEmbed
185 | The OpenEuropa oEmbed module allows the embedding of entities into content in an agnostic (non-Drupal) way. 186 |
188 | 189 | 190 | 191 |
194 | Open Vocabularies
195 | The Open Vocabularies module allows users to choose how a piece of content will be categorised without having to change the related content type field definition. 196 |
198 | 199 | 200 | 201 |
204 | OpenEuropa Corporate Site Information
205 | The OpenEuropa Corporate Site Information module provides corporate information about the site, such as site owner, content owners, etc. 206 |
208 | 209 | 210 | 211 |
214 | OpenEuropa Newsroom
215 | The OpenEuropa oe_newsroom provides integration with the Newsroom service. 216 |
218 | 219 | 220 | 221 |
224 | OpenEuropa GraphQL
225 | GraphQL integration module for OpenEuropa components, based on the GraphQL Core Schema module. 226 |
228 | 229 | 230 | 231 |
234 | OpenEuropa Agenda
235 | Drupal module that exposes an agenda. The module defines the Agenda, Day, and Session sub-entity types and their default bundles. 236 |
238 | 239 | 240 | 241 |
244 | OpenEuropa Starter Content
245 | The OpenEuropa Starter Content provides a series of content types to quickstart a project. 246 |
248 | 249 | 250 | 251 |
254 | OpenEuropa Content Extra
255 | Enhances the basic OpenEuropa Content module with additional fields and entity types. 256 |
258 | 259 | 260 | 261 |
264 | OpenEuropa Subscriptions
265 | The OpenEuropa Subscriptions module provides a system that allows both registered users and anonymous visitors to subscribe to content and receive notifications using the Message stack and Symfony Mailer. 266 |
268 | 269 | 270 | 271 |
274 | OpenEuropa Bootstrap base theme
275 | Drupal theme based on Bootstrap 5, UI Patterns and the OpenEuropa Bootstrap Component Library. 276 |
278 | 279 | 280 | 281 |
284 | OpenEuropa Whitelabel theme
285 | Sub-theme of OpenEuropa Bootstrap base theme, with theming for OpenEuropa library features. 286 |
288 | 289 | 290 | 291 |
294 | OpenEuropa Showcase
295 | Installation profile to demo openeuropa library features. 296 |
298 | 299 | 300 | 301 |
304 | OpenEuropa List Pages
305 | The OpenEuropa List Pages component allows creation and management of list pages with configurable options. 306 |
308 | 309 | 310 | 311 |
314 | OpenEuropa Corporate countries
315 | This module provides integration of EC Corporate countries with Drupal. 316 |
318 | 319 | 320 | 321 |
324 | OpenEuropa Contact Forms
325 | This is a Drupal module that is an extension to drupal core contact forms and defines the European Commission corporate forms. 326 |
328 | 329 | 330 | 331 |
334 | OpenEuropa Dashboard Agent
335 | Drupal module that integrates with the central Dashboard. 336 |
338 | 339 | 340 | 341 |
343 | 344 | ### PHP projects 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 356 | 360 | 361 | 362 | 366 | 371 | 372 | 376 | 381 | 382 | 386 | 391 | 392 | 396 | 401 | 402 | 406 | 411 | 412 | 416 | 421 | 422 | 426 | 431 | 432 | 436 | 441 | 442 | 446 | 451 | 452 | 456 | 461 | 462 | 466 | 471 | 472 | 476 | 481 | 482 | 486 | 491 | 492 | 496 | 501 |
ComponentStatus
353 | Behat Transformation Context
354 | This package provides a Behat context allowing to transform human readable labels to selectors or page paths. 355 |
357 | 358 | 359 |
363 | Code Review
364 | Automated quality assurance checks based on GrumPHP. 365 |
367 | 368 | 369 | 370 |
373 | Code Review Drupal
374 | Extends the Code Review with Drupal based rules. 375 |
377 | 378 | 379 | 380 |
383 | Code Review Library
384 | Coding standard dependencies for PHP libraries. 385 |
387 | 388 | 389 | 390 |
393 | Composer artifacts
394 | Composer plugin that allows to download a specified artifact instead of the project source. 395 |
397 | 398 | 399 | 400 |
403 | Drupal Core require dev
404 | This package provides the require dependencies of drupal/core as a standalone package. 405 |
407 | 408 | 409 | 410 |
413 | ECL Twig loader
414 | Twig loader for Europa Component Library, it allows to load components by accessing them via a configurable ecl-twig-loaderspace. 415 |
417 | 418 | 419 | 420 |
423 | Task Runner
424 | PHP task runner based on Robo, focused on extensibility. 425 |
427 | 428 | 429 | 430 |
433 | Webtools Geolocation provider
434 | This is a provider for the Geocoder PHP library that integrates the Webtools Geolocation service from the European Commission. 435 |
437 | 438 | 439 | 440 |
443 | Europa Search Client
444 | Europa Search Client is a library offering a PHP API to consume Europa Search services. 445 |
447 | 448 | 449 | 450 |
453 | Content layer development triple store
454 | Triple storage containing default data to kick-start content layer local development based on OpenLink Virtuoso. 455 |
457 | 458 | 459 | 460 |
463 | ePoetry PHP client
464 | PHP client for the ePoetry service. 465 |
467 | 468 | 469 | 470 |
473 | ePoetry PHP client
474 | PHP client for the ePoetry service. 475 |
477 | 478 | 479 | 480 |
483 | OpenEuropa Task Runner: Drupal project symlink
484 | The Drupal project symlink "Task Runner command aims at simplifying Drupal development, when using a Composer-based workflow. 485 |
487 | 488 | 489 | 490 |
493 | OpenEuropa CDT Client
494 | CDT Client is a library offering a PHP API to consume Translation Centre For the Bodies of the EU services. 495 |
497 | 498 | 499 | 500 |
502 | 503 | [1]: http://www.php-fig.org 504 | [2]: http://www.phptherightway.com 505 | [3]: https://packagist.org/packages/openeuropa/ 506 | [4]: https://joinup.ec.europa.eu/page/eupl-text-11-12 507 | --------------------------------------------------------------------------------