PHPackages                             heimrichhannot/salutation-creator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. heimrichhannot/salutation-creator

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

heimrichhannot/salutation-creator
=================================

A php library to create salutations.

0.1.2(5mo ago)011GPL-3.0-or-laterPHPPHP ^8.2CI passing

Since Dec 9Pushed 5mo agoCompare

[ Source](https://github.com/heimrichhannot/salutation-creator)[ Packagist](https://packagist.org/packages/heimrichhannot/salutation-creator)[ RSS](/packages/heimrichhannot-salutation-creator/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (5)Versions (3)Used By (0)

Salutation Creator
==================

[](#salutation-creator)

[![](https://camo.githubusercontent.com/2b1732baa25914ee5ccbeaf42980d671de29700b49e0639e1edc8e66181f6905/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c25323031302d627269676874677265656e2e7376673f7374796c653d666c6174)](https://camo.githubusercontent.com/2b1732baa25914ee5ccbeaf42980d671de29700b49e0639e1edc8e66181f6905/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c25323031302d627269676874677265656e2e7376673f7374796c653d666c6174)

A PHP library for creating personalized salutations for different contexts with support for titles, gender, and multilingual translations.

Installation
------------

[](#installation)

```
composer require heimrichhannot/salutation-creator
```

Requirements
------------

[](#requirements)

- PHP ^8.1
- symfony/translation-contracts ^1 || ^2 || ^3

Features
--------

[](#features)

- ✅ Flexible salutation generation (formal/informal)
- ✅ Support for academic titles (Dr., Prof., etc.)
- ✅ Gender-sensitive salutations
- ✅ Prefix and suffix titles with priorities
- ✅ Multilingual translations via Symfony Translation
- ✅ Extensible with custom name, gender, and title classes

Basic Usage
-----------

[](#basic-usage)

Basic example:

```
use HeimrichHannot\SalutationCreator\SalutationCreator;
use HeimrichHannot\SalutationCreator\SalutationContext;
use HeimrichHannot\SalutationCreator\Context\Name\GermanTypeName;
use HeimrichHannot\SalutationCreator\Context\Gender\Gender;

$salutationCreator = new SalutationCreator($translator);

$context = (new SalutationContext())
    ->setName(new GermanTypeName('Max', 'Mustermann'))
    ->setGender(Gender::MALE);

echo $salutationCreator->generate($context);
// Output: "Sehr geehrter Herr Mustermann"
```

With (academic) Titles:

```
use HeimrichHannot\SalutationCreator\Context\Title\GermanDoctorTitle;
use HeimrichHannot\SalutationCreator\Context\Title\GermanProfessorTitle;
use HeimrichHannot\SalutationCreator\Context\Title\PrefixTitle;
use HeimrichHannot\SalutationCreator\Helper\Titles;

$context = (new SalutationContext())
    ->setName(new GermanTypeName('Anna', 'Schmidt'))
    ->setGender(Gender::FEMALE)
    ->addTitle(new GermanDoctorTitle())
    ->addTitle(new GermanProfessorTitle())
    ->addTitle(new PrefixTitle('Hero')
    ->addTitles(Titles::fromString('dr phd unknown')); // Adding titles from string
    ;

echo $salutationCreator->generate($context);
// Output: "Sehr geehrte Frau Prof. Dr. Hero Dr. Schmidt PhD."
```

Custom translation key (e.g. informal salutation):

```
$context = (new SalutationContext())
    ->setName(new GermanTypeName('Lisa', 'Müller'))
    ->setTranslationConfig('format.informal');

echo $salutationCreator->generate($context);
// Output: "Hallo Lisa"
```

Gender from string:

```
use HeimrichHannot\SalutationCreator\SalutationCreator;
use HeimrichHannot\SalutationCreator\SalutationContext;
use HeimrichHannot\SalutationCreator\Context\Gender\Gender;

$data = [
    'firstname' => 'Lisa',
    'lastname' => 'Müller',
    'gender' => 'female',
];

$salutationContext = (new SalutationContext())
    ->setName(new GermanTypeName($data['firstname'], $data['lastname']))
    ->addTitles(Gender::tryFromString($data['gender'])));

echo (new SalutationCreator($this->translator))->generate($salutationContext);
// Outputs "Sehr geehrte Frau Müller"
```

Translations / Translation files
--------------------------------

[](#translations--translation-files)

Since this library in framework-agnostic, you need to register the translation files manually or copy them to your project's translation directory. You'll find translation files in the symfony translation ICU format in the `translations` directory of this package.

### Register Translation Files with Symfony

[](#register-translation-files-with-symfony)

In your `config/packages/framework.yaml`:

```
framework:
  translator:
    paths:
      - '%kernel.project_dir%/vendor/heimrichhannot/salutation-creator/translations'
```

### Usage in a Controller

[](#usage-in-a-controller)

```
use HeimrichHannot\SalutationCreator\SalutationCreator;
use HeimrichHannot\SalutationCreator\SalutationContext;
use HeimrichHannot\SalutationCreator\Context\Name\GermanTypeName;
use Symfony\Contracts\Translation\TranslatorInterface;

class MessageController
{
    public function __construct(
        private readonly TranslatorInterface $translator,
    ) {}

    public function sendMessage($firstName, $lastName): string
    {
        $salutation = (new SalutationCreator($this->translator))
            ->generate(
                (new SalutationContext())
                    ->setName(new GermanTypeName($firstName, $lastName))
            );

        return $salutation;
    }
}
```

### Custom Translations

[](#custom-translations)

Create a translation file `translations/salutation_creator+intl-icu.{locale}.yaml`:

```
format.formal: >
  {gender, select,
    m {Sehr geehrter {gender_name} {prefix_titles} {formal_name} {suffix_titles}}
    w {Sehr geehrte {gender_name} {prefix_titles} {formal_name} {suffix_titles}}
    nb {Sehr geehrte*r {gender_name} {prefix_titles} {formal_name} {suffix_titles}}
    other {Sehr geehrter {gender_name} {prefix_titles} {formal_name} {suffix_titles}}
  }
format.informal: 'Hallo {given_name}'

gender.m: 'Herr'
gender.f: 'Frau'
gender.d: ''
gender.nb: ''

title.german_doctor: 'Dr.'
title.german_professor: 'Prof.'
```

**Note:** The example and the bundles translation files follow the [Symfony ICU MessageFormat](https://symfony.com/doc/current/translation/message_format.html), which supports the `select` syntax for conditional translations based on variables like gender. This allows for flexible, gender-sensitive formatting.

### Use custom translation keys and domain

[](#use-custom-translation-keys-and-domain)

```
$context->setTranslationConfig(
    formatKey: 'my_custom.format',
    domain: 'my_domain'
);
```

### Available format parameters

[](#available-format-parameters)

The following parameters are available in translations:

- `%prefix_titles%` - All titles before the name
- `%suffix_titles%` - All titles after the name
- `%gender_name%` - Gender designation (Mr./Ms.)
- `%gender%` - Gender abbreviation (m/f/d)
- `%name%` - Full name
- `%formal_name%` - Formal name (usually last name)
- `%given_name%` - First name

Available (bundled) Classes
---------------------------

[](#available-bundled-classes)

### Name Classes

[](#name-classes)

- `GermanTypeName`: German names with first and last name

### Gender

[](#gender)

- `Gender::MALE` - Male
- `Gender::FEMALE` - Female
- `Gender::DIVERSE` - Diverse

### Title Classes

[](#title-classes)

- `GermanDoctorTitle`: Doctor title (Dr.)
- `GermanProfessorTitle`: Professor title (Prof.)
- `PrefixTitle`: Custom title before the name
- `SuffixTitle`: Custom title after the name

### Custom Titles

[](#custom-titles)

```
use HeimrichHannot\SalutationCreator\Context\Title\PrefixTitle;

$context->addTitle(new PrefixTitle(
    message: 'Dr. med.',
    priority: 5
));
```

Customization and Extension
---------------------------

[](#customization-and-extension)

### Create Custom Gender

[](#create-custom-gender)

You can create custom gender classes by implementing the `GenderInterface`:

```
use HeimrichHannot\SalutationCreator\Context\Gender\GenderInterface;
use HeimrichHannot\SalutationCreator\SalutationPartResult;

enum CustomGender: string implements GenderInterface
{
    case NON_BINARY = 'nb';
    case PREFER_NOT_TO_SAY = 'x';

    public function build(): SalutationPartResult
    {
        return new SalutationPartResult(
            'gender.' . $this->value,
            domain: 'my_custom_domain',
            fallback: ucfirst($this->value),
        );
    }

    public function getKey(): string
    {
        return $this->value;
    }
}
```

### Create Custom Title Class

[](#create-custom-title-class)

You can create custom title classes by extending `AbstractTitle`:

```
use HeimrichHannot\SalutationCreator\Context\Title\AbstractTitle;
use HeimrichHannot\SalutationCreator\Context\Position;
use HeimrichHannot\SalutationCreator\SalutationPartResult;

class CustomTitle extends AbstractTitle
{
    public function build(): SalutationPartResult
    {
        return new SalutationPartResult(
            message: 'title.custom',
            domain: 'my_custom_domain',
            fallback: 'Custom Title'
        );
    }

    public function getPosition(): Position
    {
        return Position::PREFIX;
    }

    public function getPriority(): int
    {
        return 10; // Higher priority = appears first
    }
}
```

### Create Custom Name Class

[](#create-custom-name-class)

```
use HeimrichHannot\SalutationCreator\Context\Name\AbstractName;

class IcelandTypeName extends AbstractName
{
    public function __construct(
        private readonly string $firstName,
        private readonly string $lastName
    ) {}

    public function getFullName(): string
    {
        return $this->firstName . ' ' . $this->lastName;
    }

    public function getFormalName(): string
    {
        return $this->firstName;
    }

    public function getGivenName(): string
    {
        return $this->firstName;
    }
}
```

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance72

Regular maintenance activity

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

160d ago

PHP version history (2 changes)0.1.0PHP ^8.1

0.1.2PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/28ad3224d8727b622ebd229840eea6b9dbcb83eb0bd609e6ce65b614830ff538?d=identicon)[digitales@heimrich-hannot.de](/maintainers/digitales@heimrich-hannot.de)

---

Top Contributors

[![koertho](https://avatars.githubusercontent.com/u/12064642?v=4)](https://github.com/koertho "koertho (15 commits)")

###  Code Quality

Static AnalysisPHPStan, Rector

Code StyleECS

Type Coverage Yes

### Embed Badge

![Health badge](/badges/heimrichhannot-salutation-creator/health.svg)

```
[![Health](https://phpackages.com/badges/heimrichhannot-salutation-creator/health.svg)](https://phpackages.com/packages/heimrichhannot-salutation-creator)
```

###  Alternatives

[sylius/theme-bundle

Themes management for Symfony projects.

1038.1M19](/packages/sylius-theme-bundle)[limenius/liform

Library to transform Symfony Forms into Json Schema

1461.3M4](/packages/limenius-liform)[jbtronics/settings-bundle

A symfony bundle to easily create typesafe, user-configurable settings for symfony applications

9546.7k2](/packages/jbtronics-settings-bundle)[caseyamcl/toc

Simple Table-of-Contents Generator for PHP. Generates TOCs based off H1...H6 tags

92344.9k5](/packages/caseyamcl-toc)[netgen/tagsbundle

Netgen Tags Bundle is an Ibexa DXP bundle for taxonomy management and easier classification of content, providing more functionality for tagging content than ibexa\_keyword field type included in Ibexa core.

49456.8k21](/packages/netgen-tagsbundle)[php-tuf/composer-stager

Stages Composer commands so they can be safely run on a production codebase.

173.5M2](/packages/php-tuf-composer-stager)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
