Skip to content

model_processor

process_fields(entry, string_processors)

Apply string processors to all entry fields except skipped technical fields.

Why

Entry fields need markdown parsing and formatting, but dates, DOIs, and URLs must remain unprocessed for correct linking and formatting. Field- level processing enables selective transformation.

Parameters:

  • entry (Entry) –

    Entry to process (model or string).

  • string_processors (list[Callable[[str], str]]) –

    Transformation functions to apply.

Returns:

  • Entry

    Entry with processed fields.

Source code in src/rendercv/renderer/templater/model_processor.py
def process_fields(
    entry: Entry, string_processors: list[Callable[[str], str]]
) -> Entry:
    """Apply string processors to all entry fields except skipped technical fields.

    Why:
        Entry fields need markdown parsing and formatting, but dates, DOIs, and
        URLs must remain unprocessed for correct linking and formatting. Field-
        level processing enables selective transformation.

    Args:
        entry: Entry to process (model or string).
        string_processors: Transformation functions to apply.

    Returns:
        Entry with processed fields.
    """
    skipped = {"start_date", "end_date", "doi", "url"}

    if isinstance(entry, str):
        return apply_string_processors(entry, string_processors)

    data = entry.model_dump(exclude_none=True)
    for field, value in data.items():
        if field in skipped or field.startswith("_"):
            continue

        if isinstance(value, str):
            setattr(entry, field, apply_string_processors(value, string_processors))
        elif isinstance(value, list):
            setattr(
                entry,
                field,
                [apply_string_processors(v, string_processors) for v in value],
            )
        else:
            setattr(
                entry, field, apply_string_processors(str(value), string_processors)
            )

    return entry

process_model(rendercv_model, file_type)

Pre-process CV model for template rendering with format-specific transformations.

Why

Templates need processed data, not raw model. This applies markdown parsing, keyword bolding, connection formatting, date rendering, and entry template expansion before templates execute.

Parameters:

  • rendercv_model (RenderCVModel) –

    Validated CV model.

  • file_type (Literal['typst', 'markdown']) –

    Target format for format-specific processors.

Returns:

Source code in src/rendercv/renderer/templater/model_processor.py
def process_model(
    rendercv_model: RenderCVModel, file_type: Literal["typst", "markdown"]
) -> RenderCVModel:
    """Pre-process CV model for template rendering with format-specific transformations.

    Why:
        Templates need processed data, not raw model. This applies markdown
        parsing, keyword bolding, connection formatting, date rendering, and
        entry template expansion before templates execute.

    Args:
        rendercv_model: Validated CV model.
        file_type: Target format for format-specific processors.

    Returns:
        Processed model ready for templates.
    """
    string_processors: list[Callable[[str], str]] = [
        lambda string: make_keywords_bold(string, rendercv_model.settings.bold_keywords)
    ]
    if file_type == "typst":
        string_processors.extend([markdown_to_typst])

    rendercv_model.cv.plain_name = rendercv_model.cv.name  # pyright: ignore[reportAttributeAccessIssue]
    rendercv_model.cv.name = apply_string_processors(
        rendercv_model.cv.name, string_processors
    )
    rendercv_model.cv.headline = apply_string_processors(
        rendercv_model.cv.headline, string_processors
    )
    rendercv_model.cv.connections = compute_connections(rendercv_model, file_type)  # pyright: ignore[reportAttributeAccessIssue]
    rendercv_model.cv.top_note = render_top_note_template(  # pyright: ignore[reportAttributeAccessIssue]
        rendercv_model.design.templates.top_note,
        locale=rendercv_model.locale,
        current_date=rendercv_model.settings.current_date,
        name=rendercv_model.cv.name,
        single_date_template=rendercv_model.design.templates.single_date,
        string_processors=string_processors,
    )

    rendercv_model.cv.footer = render_footer_template(  # pyright: ignore[reportAttributeAccessIssue]
        rendercv_model.design.templates.footer,
        locale=rendercv_model.locale,
        current_date=rendercv_model.settings.current_date,
        name=rendercv_model.cv.name,
        single_date_template=rendercv_model.design.templates.single_date,
        string_processors=string_processors,
    )
    if rendercv_model.cv.sections is None:
        return rendercv_model

    for section in rendercv_model.cv.rendercv_sections:
        section.title = apply_string_processors(section.title, string_processors)
        show_time_span = (
            section.snake_case_title
            in rendercv_model.design.sections.show_time_spans_in
        )
        for i, entry in enumerate(section.entries):
            entry = render_entry_templates(  # NOQA: PLW2901
                entry,
                templates=rendercv_model.design.templates,
                locale=rendercv_model.locale,
                show_time_span=show_time_span,
                current_date=rendercv_model.settings.current_date,
            )
            section.entries[i] = process_fields(entry, string_processors)

    return rendercv_model