문서 내보내기 사용자 지정 템플릿
Requirements & Systems Portal의 Document Export 마법사는 요구사항 및 V&V 활동에서 바로 편집 가능한 Microsoft Word *.docx 파일을 생성할 때 가장 유용한 도구입니다. 미리 정의된 템플릿을 사용할 수도 있고, 자체 템플릿을 업로드할 수도 있습니다. 이 마법사는 Python-Docx-Template 라이브러리를 기반으로 하며, 이 라이브러리는 다시 Jinja Templating Engine을 활용합니다. 이 강력한 조합을 통해 사용자 지정 템플릿을 만들 수 있습니다.
Python-Docx-Template Library
Python-Docx-Template 라이브러리는 Python-Docx 라이브러리의 기능을 확장하는 강력한 도구입니다. Jinja Templating Engine을 통합하여 Word 파일 내에서 동적 콘텐츠 생성을 가능하게 합니다. 즉, 변수, 루프, 조건문을 사용하여 문서에 데이터를 실시간으로 채워 넣을 수 있습니다. 쉽게 말해, Word 문서에 강력한 기능을 더해주는 셈입니다.
내보내기 템플릿 관리
Requirements & Systems Portal 인스턴스에서 사용할 수 있는 템플릿은 Export templates 페이지 » Settings » Export templates)에 나열됩니다.
-
기본적으로 6개의 템플릿이 제공되며, 이 중 3개는 요구사항 문서 내보내기용이고 나머지 3개는 V&V 활동 문서 내보내기용입니다.
-
요구사항 내보내기 템플릿에 대한 자세한 내용은 Document Export 페이지를 참조하십시오.
-
V&V 활동 내보내기 템플릿에 대한 자세한 내용은 Document Export 페이지를 참조하십시오.
-
-
새 사용자 정의 템플릿을 추가하려면 페이지 오른쪽 상단의
버튼을 클릭합니다. 표시되는 Add template 창에서 Applicable objects 드롭다운을 사용해 새 템플릿을 Requirements 또는 V&V Activities 중 어디에 적용할지 선택한 다음, Select template 영역에서 템플릿 파일을 선택합니다.
대화상자에서
버튼을 클릭하여 템플릿을 추가합니다. 그러면 해당 템플릿이 Export templates 페이지의 목록에 표시되며 이후 문서 내보내기에 사용할 수 있습니다.
-
모든 템플릿의 파일은 다운로드할 수 있습니다. 다운로드하려면 필요한 템플릿의 Name 열에서
버튼을 클릭한 다음 Download 명령을 선택합니다. 개인 브라우저 설정에 따라 브라우저가 파일을 미리 정의된 위치에 자동으로 다운로드하거나, 하드 드라이브의 저장 위치를 직접 묻습니다.
-
사용자 정의 템플릿은 새 템플릿 파일로 덮어쓸 수 있습니다. 이렇게 하려면 필요한 템플릿의 Name 열에서
버튼을 클릭한 다음, 표시되는 메뉴에서 Overwrite Template 명령을 선택합니다. 열리는 Overwrite template 창에서 템플릿 적용 대상을 지정하고 새 파일을 선택합니다. I confirm I want to overwrite 옵션을 활성화한 다음
버튼을 클릭하여 프로세스를 완료합니다.
부록 – 요구사항 내보내기 템플릿의 데이터 객체 구조
다음은 요구사항 내보내기 템플릿이 정보를 가져오는 객체의 기본 구조입니다.
Requirement Export Templates – Data Object Structure
{
"specifications": [
{
"id": "number",
"name": "string",
"description": "string",
"requirements": [
{
"id": "string",
"identifier": "string",
"text": "RichText",
"title": "string",
"rationale": "RichText",
"images": ["image"],
"type": "string",
"verification_methods": [{
"name": "string",
"text": "string",
"component_vms": [{
"name": "string",
"closeout_reference": "string"
}]
}],
"specification_id": "number",
"group_id": "number",
"applicability_conditions": ["string"],
"content_type": {
"id": "string",
"name": "string"
},
"state": "string",
"compliance": "string",
"compliance_comment": "string",
"tags": ["string"],
"parents": [{
"id": "string",
"identifier": "string",
"text": "RichText",
"title": "string"
}],
"children": [{
"id": "string",
"identifier": "string",
"text": "RichText",
"title": "string"
}],
"owner": {
"user": {
"username": "string",
"first_name": "string",
"last_name": "string",
"groups": ["string"]
},
"group": {
"name": "string",
"users": ["string"]
}
},
"files": [{
"name": "string",
"description": "string",
"version": "string",
"is_reference": "boolean",
"tags": ["string"]
}],
"custom_fields": [{
"field": "string",
"value": ["string"]
}],
"position": "number",
"verification_items_verified": "number",
"verification_items_total": "number",
"verification_items": [{
"status": "string",
"component": "string",
"tags": ["string"],
"activity": {
"name": "string",
"verification_methods": ["string"]
},
"last_item_run": {
"status": "string",
"comment": "string"
}
}],
"linked_components": [{
"id": "number",
"name": "string",
"description": "string",
"valis": [{
"id": "number",
"name": "string",
"value": "string",
"formula": "string"
}],
"textvalis": [{
"id": "number",
"name": "string",
"text": "string"
}],
"matrices": [{
"id": "number",
"name": "string",
"value": "string",
"formula": "string"
}],
"datevalis": [{
"id": "number",
"name": "string",
"date": "string"
}],
"creator": "string",
"attachments": [{
"name": "string",
"description": "string",
"version": "string",
"is_reference": "boolean",
"tags": ["string"]
}]
}]
}
],
"content_type": {
"id": "number",
"name": "string"
}
}
],
"requirements": [
{
"id": "string",
"identifier": "string",
"text": "RichText",
"title": "string",
"rationale": "RichText",
"images": ["image"],
"type": "string",
"verification_methods": [{
"name": "string",
"text": "string",
"component_vms": [{
"name": "string",
"closeout_reference": "string"
}]
}],
"specification_id": "number",
"group_id": "number",
"applicability_conditions": ["string"],
"content_type": {
"id": "string",
"name": "string"
},
"state": "string",
"compliance": "string",
"compliance_comment": "string",
"tags": ["string"],
"parents": [{
"id": "string",
"identifier": "string",
"text": "RichText",
"title": "string"
}],
"children": [{
"id": "string",
"identifier": "string",
"text": "RichText",
"title": "string"
}],
"owner": {
"user": {
"username": "string",
"first_name": "string",
"last_name": "string",
"groups": ["string"]
},
"group": {
"name": "string",
"users": ["string"]
}
},
"files": [{
"name": "string",
"description": "string",
"version": "string",
"is_reference": "boolean",
"tags": ["string"]
}],
"custom_fields": [{
"field": "string",
"value": ["string"]
}],
"position": "number",
"verification_items_verified": "number",
"verification_items_total": "number",
"verification_items": [{
"status": "string",
"component": "string",
"tags": ["string"],
"activity": {
"name": "string",
"verification_methods": ["string"]
},
"last_item_run": {
"status": "string",
"comment": "string"
}
}],
"linked_components": [{
"id": "number",
"name": "string",
"valis": [{
"id": "number",
"name": "string",
"value": "string",
"formula": "string"
}],
"textvalis": [{
"id": "number",
"name": "string",
"text": "string"
}],
"matrices": [{
"id": "number",
"name": "string",
"value": "string",
"formula": "string"
}],
"datevalis": [{
"id": "number",
"name": "string",
"date": "string"
}],
"creator": "string",
"attachments": [{
"name": "string",
"description": "string",
"version": "string",
"is_reference": "boolean",
"tags": ["string"]
}]
}]
}
],
"requirements_groups": [
{
"id": "number",
"name": "string",
"description": "string",
"specification_id": "number",
"requirements": [
{
"id": "string",
"identifier": "string",
"text": "RichText",
"title": "string",
"rationale": "RichText",
"images": ["image"],
"type": "string",
"verification_methods": [{
"name": "string",
"text": "string",
"component_vms": [{
"name": "string",
"closeout_reference": "string"
}]
}],
"specification_id": "number",
"group_id": "number",
"applicability_conditions": ["string"],
"content_type": {
"id": "string",
"name": "string"
},
"state": "string",
"compliance": "string",
"compliance_comment": "string",
"tags": ["string"],
"parents": [{
"id": "string",
"identifier": "string",
"text": "RichText",
"title": "string"
}],
"children": [{
"id": "string",
"identifier": "string",
"text": "RichText",
"title": "string"
}],
"owner": {
"user": {
"username": "string",
"first_name": "string",
"last_name": "string",
"groups": ["string"]
},
"group": {
"name": "string",
"users": ["string"]
}
},
"files": [{
"name": "string",
"description": "string",
"version": "string",
"is_reference": "boolean",
"tags": ["string"]
}],
"custom_fields": [{
"field": "string",
"value": ["string"]
}],
"position": "number",
"verification_items_verified": "number",
"verification_items_total": "number",
"verification_items": [{
"status": "string",
"component": "string",
"tags": ["string"],
"activity": {
"name": "string",
"verification_methods": ["string"]
},
"last_item_run": {
"status": "string",
"comment": "string"
}
}],
"linked_components": [{
"id": "number",
"name": "string",
"valis": [{
"id": "number",
"name": "string",
"value": "string",
"formula": "string"
}],
"textvalis": [{
"id": "number",
"name": "string",
"text": "string"
}],
"matrices": [{
"id": "number",
"name": "string",
"value": "string",
"formula": "string"
}],
"datevalis": [{
"id": "number",
"name": "string",
"date": "string"
}],
"creator": "string",
"attachments": [{
"name": "string",
"description": "string",
"version": "string",
"is_reference": "boolean",
"tags": ["string"]
}]
}]
}
],
"content_type": {
"id": "number",
"name": "string"
}
}
],
"timestamp": "datetime",
"template_name": "string",
"verification_and_validation_methods": [{
"id": "number",
"name": "string",
"description": "string"
}]
}
필드 정렬
Jinja 템플릿 문서에서 Sort 함수를 사용하여 요구사항을 정렬할 수 있습니다. 예를 들어, 식별자 열을 기준으로 요구사항을 영숫자 순으로 정렬하려면 |sort(attribute='identifier') 를 추가할 수 있습니다.
예:
{% for requirement in requirements|selectattr("specification_id", "equalto", specification.id)|selectattr("group_id", "none") |sort(attribute='identifier') -%}
사용자 정의 열
현재 문서 내보내기 기능을 사용하면 사용자 정의 열 값을 쉽게 내보낼 수 있습니다. 단순한 텍스트 기반 사용자 정의 열의 경우, 다음과 같은 일반 구조를 사용할 수 있습니다.
{% for custom_field in requirement.custom_fields|selectattr(“field”, “equalto”, “Name of Custom Column”) %}{{r custom_field.value }}{% endfor %}
반드시 Name of Custom Column 텍스트를 열 머리글에 표시된 실제 열 이름으로 바꾸십시오.
사용자 정의 열이 텍스트 형식이 아니고 다중 선택 옵션인 경우에는 다음 코드를 사용하고, 사용 사례에 맞게 수정하면 됩니다.
{%- if requirement.custom_fields -%}
{%- set additional_info_values = [] -%}
{%- set category_values = [] -%}
{%- set additional_info_custom_fields = requirement.custom_fields | selectattr('field', 'equalto', 'Additional Information') -%}
{% for custom_field in additional_info_custom_fields -%}
{%- set additional_info_values = additional_info_values + custom_field.value -%}
{% endfor -%}
{%- set category_custom_fields = requirement.custom_fields | selectattr('field', 'equalto', 'Category') -%}
{% for custom_field in category_custom_fields -%}
{%- set category_values = category_values + custom_field.value -%}
{% endfor -%}
{%- set additional_info_string = additional_info_values | join(';') -%}
{%- set category_string = category_info_values | join(';') -%}
{%- endif -%}
부록 – V&V 활동 내보내기 템플릿의 데이터 객체 구조
다음은 V&V 활동 내보내기 템플릿이 정보를 가져오는 객체의 기본 구조입니다.
V&V Activity Export Templates – Data Object Structure
# TOP LEVEL
{
activities: [{}] # List of all Activities
folders: [{
name: string
activities: [{}] # List of Activities
}]
timestamp: datetime
template_name: string
}
# Activity
{
id: number
name: string
description: string
expected_results: string
tags: [string]
verification_methods: [{
name: string
description: string
}]
owner: User or Group
custom_fields: [] # List of CustomFields
approvals: boolean
items: [{}] # List of VVItems
step_definitions: [{}] # List of StepDefinitions
runs: [{}] # List of ActivityRuns
}
# VVItem
{
id: number
requirement_identifier: string
component: { # Same as linked components in the reqs doc export
id: number
name: string
valis: [{
id: number
name: string
value: string
formula: string
}]
textvalis: [{
id: number
name: string
text: string
}]
matrices: [{
id: number
name: string
value: string
formula: string
}]
datevalis: [{
id: number
name: string
date: string
}]
creator: string
attachments: [{
name: string
description: string
version: string
is_reference: boolean
tags: [string]
}]
}
compliance: string
compliance_comment: string
last_item_run: {} # VVItemRun
last_item_run_status: str
item_runs: [{}] # List of VVItemRuns
}
# StepDefinition
{
id: int
activity_id: int
step_number: int
position: float
full_step_number: str
full_step_path: str
parent_step_id: int
name: string
description: string
expected_results: string
tags: [string]
item_ids: [] # List of VVItems ids
}
# ActivityRun
{
id: int
name: string
description: string
timestamp: string
start_date: string # Format use same as in reqs doc export
finish_date: string
completion_state: int
completed_on: string
completed_by: User
activity_id: int
default_run: bool
position: float
steps_synced: bool
expected_results: string
evidence: string # File/Doc name
custom_fields: [] # List of CustomFields
tags: [string]
run_executor: {} # User or Group
approver: {} # User or Group
approved: boolean
approved_by: User
approved_at: string
item_runs: [] # List of VVItemRuns
step_runs: [{}] # List of VVStepRuns
}
# VVItemRun
{
id: int
status: string
verified_by: User
activity_run_id: int
status: "status-display-name"
comment: string
serial_number: string
step_run_id: int # StepRun
verification_item:{} # VVItem
verification_item_requirement_identifier: string
verification_item_component_name: string
}
# StepRun
{
id: int
name: string
comment: string
status: string
description: string
activity_run_id: int
full_step_number: str
step_number: int
position: float
full_step_run_path: str
parent_step_run_id: int
expected_results: string
tags: [string]
item_run_ids: [] # List of VVItemRun ids
item_requirement_identifiers: str
}