Your career: publications, typed and shaped like BibTeX entries #687
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#687
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A career record has nowhere to put a paper, a book chapter or a thesis, except a Link of the kind “Publication”, which holds a title and an address and nothing a reader could cite. The maintainer's list asks for it: "Ability to add publications. Kind of publications and main details mirror BibTEX. (A step closer to a potential BibTEX import/export plugin.) Suggestion for adding can be obtained using ORCID or DOI search. * Still not sure if this kind of item should be on the career or on the portfolio. *" This issue is the record and where it lives; the suggestion from a DOI or ORCID is #688.
What exists today
LinkKind.PUBLICATION(src/postulo/resume/models.py:280) onLink(title, address, kind, description, reachability check;:291-318).portfoliothat selects from the same career record: "a portfolio is a selection from the career record with its own layout", and a researcher's portfolio is "answered by the theme" and by what is selected (src/postulo/documents/models.py:174-192; wikiCVs.md:11-26). "On the portfolio" can only mean printed by a portfolio theme, or a new store, and no such store exists.SECTIONSandOVERVIEW_ORDER(resume/registry.py:28-91, read by the career page, its sidebar counts,resume/views.py:65-85, and the CV picker,documents/forms.py:386-432); the archive'sRESUME_FIELDS,RESUME_MODELSandTRANSLATION_SECTIONS(core/export.py:153-162,:343-415); the candidate file'sKINDS(resume/candidate.py:176-276, withnames/datessaying what identifies an entry); the importer'ssection_models(core/importer.py:532-540);SECTION_LABELSand the plain-text and Word renderers (documents/rendering.py:41-49,:336-385); a branch per kind inbase_cv.html:91-159andbase_portfolio.html:61-135, where an unknown kind falls into anelsethat printsitem.nameanditem.role; and, for kinds that are not "a title and highlights", a branch intemplates/resume/overview.html:74-99. Search covers five career models by hand (core/search.py:458-515) and links to anchors (#experience…) that the overview does not have (its ids aresection-<slug>,resume/views.py:77-78); a new group should use the real one.Certificationtranslates nothing and a test says so (resume/translatable.py:16-35,tests/test_career_languages.py:83-86); a paper's title is the same sort of thing.core/export.py:80), candidate 4 (:104, fingerprintSHAPESintests/test_candidate_file.py:372-387). The candidate reader's dates must be whole (^\d{4}-\d{2}-\d{2}$,resume/candidate.py:106).core/gdpr.py's processing record is drawn from plugins, so neither changes. ORCID is a stored, checksum-checked person identifier (#46); there is no DOI scheme. The Europass reader namesPublicationHistoryamong sections "with nowhere to go" (tests/test_europass_candidate.py:561-577, wikiYour-career-record.md:415-418).core/export.py:781; a link is"link"), but the importer's name map has nolink(core/importer.py:905-912), so a link on a CV is skipped on restore with "no such record" (:968-972). No test restores a CV holding one. (Tracked as #470, a bug in 0.5.0 with its own round-trip test; the fix is a line, and this issue does not need to wait for it.)What BibTeX says (BibTeXing, O. Patashnik,
btxdoc.texon CTAN; the biblatex manual 3.22a, CTAN, 2026-09-24). BibTeX has 14 standard entry types:article,book,booklet,conference(an alias ofinproceedings),inbook,incollection,inproceedings,manual,mastersthesis,misc,phdthesis,proceedings,techreport,unpublished. Each has required, optional and ignored fields: "BibTeX ignores any field that is not required or optional".authorandeditorare name lists "in the format described in the LaTeX book", separated byand. biblatex addsonline,dataset,software,report,thesis,patentand more, renamesjournaltojournaltitle,addresstolocationandschooltoinstitution, changes the profile ofinbook, makesdatean ISO 8601-2 value andmonthan integer, and has no ORCID field.Checked against
mainatf09b6010b.Proposal
Publication, aResumeItem(owner-scoped,order, deleted with the account):entry_type(closed list),title,authorsandeditors(names as typed, one per line),container_title(the journal, book or proceedings),publisher,institution,date(reduced ISO 8601 text as #679 settles it:2024,2024-05,2024-05-17; year required),volume,number,pages,edition,series,chapter,location,doi,url,note,language(LanguageField),cite_key. One table with a type, as BibTeX has it.publications; format one more than whatever it is when the commit lands, with its history line), candidate file (identity: DOI, else title and year; candidate format one more), importer (the missinglinkin the CV-entry map is #470's fix, not this issue's; this issue adds its own entry and a round-trip test for the new section), renderers, both base themes, search by title, author and container, demo data.https://doi.org/<doi>, never resolved here (#688 is the one place that asks anyone).PublicationjoinsCertificationas translating nothing.Decisions
conferencealias; (b) those plus biblatex'sonline,dataset,software; (c) all of biblatex's. Recommended: (b): a preprint, a dataset and software are what a researcher lists, and BibTeX has no home for them. A BibTeX-only exporter writes them as@misc. One table, so a type is one entry.container_titlehiding thejournal/journaltitle/booktitlesplit; the column names are Postulo's and the mapping lives with the type table.- _ : . + /(Postulo's own bound), generated from author, year and a title word when blank, never printed.abstract,isbn,issn,eprint,keywords, anything imported). Recommended: none now; the plugin states what it loses. BibTeX itself ignores unknown fields.PublicationHistory. Recommended: its own commit once the section exists.Prior art
bibtexparser: MIT; 2.1.0, released 2026-10-02 (2.0.0 on 2026-09-08, 1.4.4 on 2026-01-29); needspylatexenc(MIT, 2.11, 2026-07-25); no OSV advisory; not a dependency. Not needed here, since nothing reads or writes a.bibfile; it is the library for the later BibTeX plugin (MIT, so compatible with AGPL-3.0), and "library first" applies there.pybtex: MIT; 0.26.1, 2026-04-03, beta; needslatexcodecandpyyaml; no advisory. Same verdict.citeproc-py: BSD-2-Clause-Views; 0.11.1, 2026-09-01, alpha; needslxml, declined before (docs/PLAN.md:133); no advisory. Rejected: a named style is out of scope.applications/ical.pyanddocuments/docx.pyare hand-written file formats; the precedent is not needed: this is a table.Builds on
#46 (ORCID), #54 (Europass import), #131 (translations), #133 and
documents/models.py:174-192(a portfolio selects from the career record), #175 (career sections), #181 (candidate file), #308 (what a CV prints), #337 (BCP 47).Needed by
#688 (suggestions from a DOI or ORCID), #697 (citations of a publication); #679 shares the date validator; a BibTeX plugin, to be recorded as an idea on #241.
Done when
tests/test_publications.py: each type offers its fields and hides the rest; a value survives a type change; DOI shape, key alphabet and partial dates are checked;tests/test_career_sections.pypasses with the new anchor;tests/test_career_languages.pygains "a publication translates nothing".tests/test_export.py: archive carriespublicationsat the new format, restore brings them back, and a CV holding a publication and a link keeps both.tests/test_candidate_file.pyholds the new fingerprint and review rows for a good and a refused entry;tests/security/test_candidate_file.pya hostile value.tests/security/test_isolation_sweep.pyandtests/test_account_deletion.pycover another account's entries; search finds one and links to#section-publication.core/gdpr.pyand the plugin surface are unchanged (tests/test_wiki_surface.pyuntouched). New strings in the working catalogues (en-GB, fr-FR, pt-PT as drafts) and Weblate (#349); wiki pages and CHANGELOG (ends(#N)) in the same commit.From the list of improvements of 2026-10-02.
Landed on main with a green Forgejo CI run. Its entry in the CHANGELOG's Unreleased section ends in (#687).