Metadata-Version: 2.4
Name: collective.person
Version: 1.0.0b5
Summary: A Person content type for Plone.
Project-URL: Changelog, https://github.com/collective/collective.person/blob/main/CHANGELOG.md
Project-URL: Homepage, https://github.com/collective/collective.person
Project-URL: Issues, https://github.com/collective/collective.person/issues
Project-URL: Repository, https://github.com/collective/collective.person/
Author-email: Érico Andrei <ericof@plone.org>
License: GNU General Public License v2 (GPLv2)
License-File: LICENSE.md
Keywords: Plone,Python
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: Plone
Classifier: Framework :: Plone :: 6.0
Classifier: Framework :: Plone :: 6.1
Classifier: Framework :: Plone :: Addon
Classifier: Framework :: Zope
Classifier: Framework :: Zope :: 5
Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: collective-contact-behaviors>=1.0.0b6
Requires-Dist: plone-api
Requires-Dist: plone-exportimport
Requires-Dist: plone-restapi
Requires-Dist: plone-volto
Requires-Dist: products-cmfplone>=6.0.0
Provides-Extra: test
Requires-Dist: horse-with-no-namespace>=20250705.0; extra == 'test'
Requires-Dist: plone-app-testing; extra == 'test'
Requires-Dist: plone-restapi[test]; extra == 'test'
Requires-Dist: pytest-cov; extra == 'test'
Requires-Dist: pytest-plone>=1.0.0a1; extra == 'test'
Requires-Dist: zest-releaser[recommended]>=9.5.0; extra == 'test'
Requires-Dist: zestreleaser-towncrier>=1.3.0; extra == 'test'
Description-Content-Type: text/markdown

<div align="center"><img alt="logo" src="https://raw.githubusercontent.com/collective/collective.person/main/docs/logo.svg" width="100" /></div>

<h1 align="center">Person content type for Plone</h1>

<div align="center">

[![PyPI](https://img.shields.io/pypi/v/collective.person)](https://pypi.org/project/collective.person/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/collective.person)](https://pypi.org/project/collective.person/)
[![PyPI - Wheel](https://img.shields.io/pypi/wheel/collective.person)](https://pypi.org/project/collective.person/)
[![PyPI - License](https://img.shields.io/pypi/l/collective.person)](https://pypi.org/project/collective.person/)
[![PyPI - Status](https://img.shields.io/pypi/status/collective.person)](https://pypi.org/project/collective.person/)


[![PyPI - Plone Versions](https://img.shields.io/pypi/frameworkversions/plone/collective.person)](https://pypi.org/project/collective.person/)

[![CI](https://github.com/collective/collective.person/actions/workflows/ci.yml/badge.svg)](https://github.com/collective/collective.person/actions/workflows/ci.yml)

[![GitHub contributors](https://img.shields.io/github/contributors/collective/collective.person)](https://github.com/collective/collective.person)
[![GitHub Repo stars](https://img.shields.io/github/stars/collective/collective.person?style=social)](https://github.com/collective/collective.person)

</div>

## Features

`collective.person` provides a content type representing a Person.

### Content Types

* `Person`: A content type representing a person

### Behaviors

| name | title | description |
| -- | -- | -- |
| `collective.person.person` | Person Behavior | Fields with basic person information |
| `collective.person.user` | Link Person to Plone User | Adapts a Person to link it to a Plone User |
| `collective.person.namefromusername` | Name from username |Use the username field as name (basis for the id) |

### Permissions

| id | title | Usage |
| -- | -- | -- |
| collective.person.person.add | collective.person: Add Person | Control the creation of a new Person content item |

### Catalog Indexes

This package adds Indexes and Metadata to Portal Catalog.

| Content Attribute | Index Type | Metadata | Comment |
| -- | -- | -- | -- |
| roles | KeywordIndex | ✅ | -- |
| username | FieldIndex | ✅ | Used when `collective.person.user` behavior is enabled |

## See it in action

This package is being used by the following sites:

* TODO

## Documentation

### Installation

Add `collective.person` as a dependency on your package's `setup.py`

```python
    install_requires = [
        "Plone",
        "plone.restapi",
        "collective.person",
    ],
```

Also, add `collective.person` to your package's `configure.zcml` (or `dependencies.zcml`):

```xml
<include package="collective.person" />
```

### Generic Setup

To automatically enable this package when your add-on is installed, add the following line inside the package's `profiles/default/metadata.xml` `dependencies` element:

```xml
    <dependency>profile-collective.person:default</dependency>
```

## Source Code and Contributions

We welcome contributions to `collective.person`.

You can create an issue in the issue tracker, or contact a maintainer.

- [Issue Tracker](https://github.com/collective/collective.person/issues)
- [Source Code](https://github.com/collective/collective.person/)


### Development setup

You need a working Python environment version 3.8 or later.

Then install the dependencies and a development instance using:

```bash
make install
```

By default, we use the latest Plone version in the 6.x series.

### Update translations

```bash
make i18n
```
### Format codebase

```bash
make format
```
### Lint codebase

```bash
make lint
```
### Run tests

```bash
make test
```

## Extending collective.person

### Customizing how the title is generated

`collective.person` provides two built-in strategies for generating the title of a **Person** object:

- **First and Last Name** (`first_last`):
  The title is generated using the template `{first_name} {last_name}`.
  Example: `first_name="Douglas"`, `last_name="Adams"` → **Douglas Adams**

- **Last and First Name** (`last_first`):
  The title is generated using the template `{last_name}, {first_name}`.
  Example: `first_name="Douglas"`, `last_name="Adams"` → **Adams, Douglas**

You can select the preferred option in the **Person control panel**.


### Providing your own title generator

If the default options do not fit your needs, you can register a custom utility that implements the `collective.person.interfaces.IPersonTitle` interface.

#### Step 1: Create your generator

For example, create a file called `title_generator.py` in your package:

```python
from collective.person.content.person import Person
from collective.person.interfaces import IPersonTitle
from zope.interface import implementer


@implementer(IPersonTitle)
class MyTitleGenerator:
    """Return the title with a custom prefix."""

    name: str = "My title generator"

    def title(self, context: Person) -> str:
        """Return the title of the person."""
        first_name = context.first_name
        last_name = context.last_name or ""
        return f"Human {first_name} {last_name}".strip()
```

#### Step 2: Register the utility

In your `configure.zcml`, add:

```xml
<utility
    factory=".title_generator.MyTitleGenerator"
    name="my_title_generator"
/>
```

#### Step 3: Activate your generator

To make your generator the default after installation, update the registry via GenericSetup by adding a `registry.xml` file in your profile:

```xml
<?xml version="1.0" encoding="utf-8"?>
<registry>
  <records
      interface="collective.person.controlpanel.interfaces.IPersonSettings"
      prefix="person">
    <value key="title_utility" purge="false">my_title_generator</value>
  </records>
</registry>
```


## License

The project is licensed under GPLv2.
