From 8564fefc21105caaf9a75f921b117d553a21854c Mon Sep 17 00:00:00 2001 From: Tati Micheletti Date: Mon, 11 May 2026 16:17:20 +0200 Subject: [PATCH 1/6] Add structured publications rendering pipeline - Setup Hugo parsing for CSL-JSON fields - fix missing index from code `{{ index . "container-title" }}` --- assets/publications/publications.bib | 128 ++++++ content/en/resources/publications.md | 7 +- data/publications.json | 546 ++++++++++++++++++++++++ layouts/docs/awesome-list.html | 2 + layouts/partials/publications-list.html | 26 ++ layouts/resources/publications.html | 16 + 6 files changed, 721 insertions(+), 4 deletions(-) create mode 100644 assets/publications/publications.bib create mode 100644 data/publications.json create mode 100644 layouts/partials/publications-list.html create mode 100644 layouts/resources/publications.html diff --git a/assets/publications/publications.bib b/assets/publications/publications.bib new file mode 100644 index 00000000..62be5267 --- /dev/null +++ b/assets/publications/publications.bib @@ -0,0 +1,128 @@ +@article{sun_catalogue_2026, + title = {A catalogue of {Do}'s and {Don}'ts in the modeling of environmental systems}, + volume = {198}, + issn = {13648152}, + url = {https://linkinghub.elsevier.com/retrieve/pii/S136481522600040X}, + doi = {10.1016/j.envsoft.2026.106893}, + language = {en}, + urldate = {2026-05-11}, + journal = {Environmental Modelling \& Software}, + author = {Sun, Xifu and Jakeman, Anthony and Hamilton, Serena H. and Grimm, Volker and Hunt, Randall J. and El Sawah, Sondoss and Wang, Hsiao-Hsuan and Croke, Barry and Chen, Min}, + month = mar, + year = {2026}, + pages = {106893}, +} + +@article{elsawah_overview_2017, + title = {An overview of the system dynamics process for integrated modelling of socio-ecological systems: {Lessons} on good modelling practice from five case studies}, + volume = {93}, + issn = {13648152}, + shorttitle = {An overview of the system dynamics process for integrated modelling of socio-ecological systems}, + url = {https://linkinghub.elsevier.com/retrieve/pii/S136481521631091X}, + doi = {10.1016/j.envsoft.2017.03.001}, + language = {en}, + urldate = {2026-05-11}, + journal = {Environmental Modelling \& Software}, + author = {Elsawah, Sondoss and Pierce, Suzanne A. and Hamilton, Serena H. and Van Delden, Hedwig and Haase, Dagmar and Elmahdi, Amgad and Jakeman, Anthony J.}, + month = jul, + year = {2017}, + pages = {127--145}, +} + +@article{micheletti_beyond_2024, + title = {Beyond guides, protocols and acronyms: {Adoption} of good modelling practices depends on challenging academia's status quo in ecology}, + volume = {496}, + issn = {03043800}, + shorttitle = {Beyond guides, protocols and acronyms}, + url = {https://linkinghub.elsevier.com/retrieve/pii/S0304380024002175}, + doi = {10.1016/j.ecolmodel.2024.110829}, + language = {en}, + urldate = {2026-05-11}, + journal = {Ecological Modelling}, + author = {Micheletti, Tatiane and Wimmler, Marie-Christin and Berger, Uta and Grimm, Volker and McIntire, Eliot J.}, + month = oct, + year = {2024}, + pages = {110829}, +} + +@article{swannack_cracking_2025, + title = {Cracking the code: {Linking} good modeling and coding practices for new ecological modelers}, + volume = {499}, + issn = {03043800}, + shorttitle = {Cracking the code}, + url = {https://linkinghub.elsevier.com/retrieve/pii/S0304380024003144}, + doi = {10.1016/j.ecolmodel.2024.110926}, + language = {en}, + urldate = {2026-05-11}, + journal = {Ecological Modelling}, + author = {Swannack, Todd M. and Cushway, Kiara C. and Carrillo, Carra C. and Calvo, Clementina and Determan, Kierra R. and Mierzejewski, Caroline M. and Quintana, Vanessa M. and Riggins, Christopher L. and Sams, Miranda D. and Wadsworth, Waverly E.}, + month = jan, + year = {2025}, + pages = {110926}, +} + +@article{hamilton_fit-for-purpose_2022, + title = {Fit-for-purpose environmental modeling: {Targeting} the intersection of usability, reliability and feasibility}, + volume = {148}, + issn = {13648152}, + shorttitle = {Fit-for-purpose environmental modeling}, + url = {https://linkinghub.elsevier.com/retrieve/pii/S1364815221003200}, + doi = {10.1016/j.envsoft.2021.105278}, + language = {en}, + urldate = {2026-05-11}, + journal = {Environmental Modelling \& Software}, + author = {Hamilton, Serena H. and Pollino, Carmel A. and Stratford, Danial S. and Fu, Baihua and Jakeman, Anthony J.}, + month = feb, + year = {2022}, + pages = {105278}, +} + +@article{lemmen_good_2024, + title = {Good modelling software practices}, + volume = {498}, + issn = {03043800}, + url = {https://linkinghub.elsevier.com/retrieve/pii/S0304380024002783}, + doi = {10.1016/j.ecolmodel.2024.110890}, + language = {en}, + urldate = {2026-05-11}, + journal = {Ecological Modelling}, + author = {Lemmen, Carsten and Sommer, Philipp Sebastian}, + month = dec, + year = {2024}, + pages = {110890}, +} + +@article{kherroubi_garcia_ten_2025, + title = {Ten simple rules for good model-sharing practices}, + volume = {21}, + issn = {1553-7358}, + url = {https://dx.plos.org/10.1371/journal.pcbi.1012702}, + doi = {10.1371/journal.pcbi.1012702}, + abstract = {Computational models are complex scientific constructs that have become essential for us to better understand the world. Many models are valuable for peers within and beyond disciplinary boundaries. However, there are no widely agreed-upon standards for sharing models. This paper suggests 10 simple rules for you to both (i) ensure you share models in a way that is at least “good enough,” and (ii) enable others to lead the change towards better model-sharing practices.}, + language = {en}, + number = {1}, + urldate = {2026-05-11}, + journal = {PLOS Computational Biology}, + author = {Kherroubi Garcia, Ismael and Erdmann, Christopher and Gesing, Sandra and Barton, Michael and Cadwallader, Lauren and Hengeveld, Geerten and Kirkpatrick, Christine R. and Knight, Kathryn and Lemmen, Carsten and Ringuette, Rebecca and Zhan, Qing and Harrison, Melissa and Mac Gabhann, Feilim and Meyers, Natalie and Osborne, Cailean and Till, Charlotte and Brenner, Paul and Buys, Matt and Chen, Min and Lee, Allen and Papin, Jason and Rao, Yuhan}, + editor = {Schwartz, Russell}, + month = jan, + year = {2025}, + pages = {e1012702}, +} + +@article{jakeman_towards_2024, + title = {Towards normalizing good practice across the whole modeling cycle: its instrumentation and future research topics}, + volume = {6}, + copyright = {http://creativecommons.org/licenses/by-nc/4.0}, + issn = {2663-3027}, + shorttitle = {Towards normalizing good practice across the whole modeling cycle}, + url = {https://sesmo.org/article/view/18755}, + doi = {10.18174/sesmo.18755}, + abstract = {Choices made in modeling matter and demand more explication since they determine how much we can trust modeling insights and predictions within their social, political and ethical contexts. Good Modeling Practice (GMP) is a key research area for strengthening and maturing the modeling field and community, through identifying, formulating and sharing knowledge about the craft of modeling. This craft represents the knowledge that modelers learn in practice about how they get things done, and how they adapt their practices to new situations. This Joint Special Issue is motivated by the importance of sharing good modeling practices from a whole modeling lifecycle viewpoint. We attempt to add conceptual clarity to this research area by defining the plethora of concepts and decision points used to characterize the choices to be made throughout the modeling process, and by synthesizing some of the existing efforts on GMP. We characterize a broad list of articles in the literature on GMP and identify a list of essential topics demanding more attention. This list is only a preliminary one as we anticipate that a more comprehensive list of knowledge gaps will be unearthed from the submissions to the Joint Special Issue collection on GMP, of which this is an introduction. We also propose a vision for GMP and suggest instrumental ways that good practice can become not just well-known but normal practice. This instrumentation focuses on journal standards, collective commitment and culture especially by research community societies, early career awards for advancing GMP, and legal requirements or accreditation. A vital instrument in all this is the design and development of a modeling curriculum that distills core requisite knowledge about modeling, as well as proven-to-work routines and practices that can be scaled up in different contexts.}, + urldate = {2026-05-11}, + journal = {Socio-Environmental Systems Modelling}, + author = {Jakeman, Anthony J. and Elsawah, Sondoss and Wang, Hsiao-Hsuan and Hamilton, Serena H. and Melsen, Lieke and Grimm, Volker}, + month = sep, + year = {2024}, + pages = {18755}, +} diff --git a/content/en/resources/publications.md b/content/en/resources/publications.md index 5f345ae7..e1a505c9 100644 --- a/content/en/resources/publications.md +++ b/content/en/resources/publications.md @@ -1,9 +1,8 @@ --- title: "Publications" -linkTitle: "Publications" -description: "Published artifacts from OMF activities (reports, manuscripts, presentations, etc.)" +description: "Published artifacts from OMF activities (reports, manuscripts, preprints, publications)." +layout: "publications" weight: 20 --- -- [Ten simple rules for good model-sharing practices](https://doi.org/10.1371/journal.pcbi.1012702) -- Standards-related manuscripts and reports developed by OMF working groups will be added here as they are published. \ No newline at end of file +The publications list is generated dynamically from the OMF bibliography database. \ No newline at end of file diff --git a/data/publications.json b/data/publications.json new file mode 100644 index 00000000..0fad7957 --- /dev/null +++ b/data/publications.json @@ -0,0 +1,546 @@ +[ + { + "id": "http://zotero.org/groups/6548795/items/6ZTTIC2K", + "type": "article-journal", + "container-title": "Environmental Modelling & Software", + "DOI": "10.1016/j.envsoft.2026.106893", + "ISSN": "13648152", + "journalAbbreviation": "Environmental Modelling & Software", + "language": "en", + "page": "106893", + "source": "DOI.org (Crossref)", + "title": "A catalogue of Do's and Don'ts in the modeling of environmental systems", + "URL": "https://linkinghub.elsevier.com/retrieve/pii/S136481522600040X", + "volume": "198", + "author": [ + { + "family": "Sun", + "given": "Xifu" + }, + { + "family": "Jakeman", + "given": "Anthony" + }, + { + "family": "Hamilton", + "given": "Serena H." + }, + { + "family": "Grimm", + "given": "Volker" + }, + { + "family": "Hunt", + "given": "Randall J." + }, + { + "family": "El Sawah", + "given": "Sondoss" + }, + { + "family": "Wang", + "given": "Hsiao-Hsuan" + }, + { + "family": "Croke", + "given": "Barry" + }, + { + "family": "Chen", + "given": "Min" + } + ], + "accessed": { + "date-parts": [ + [ + "2026", + 5, + 11 + ] + ] + }, + "issued": { + "date-parts": [ + [ + "2026", + 3 + ] + ] + } + }, + { + "id": "http://zotero.org/groups/6548795/items/FSVNQZUL", + "type": "article-journal", + "container-title": "Environmental Modelling & Software", + "DOI": "10.1016/j.envsoft.2017.03.001", + "ISSN": "13648152", + "journalAbbreviation": "Environmental Modelling & Software", + "language": "en", + "page": "127-145", + "source": "DOI.org (Crossref)", + "title": "An overview of the system dynamics process for integrated modelling of socio-ecological systems: Lessons on good modelling practice from five case studies", + "title-short": "An overview of the system dynamics process for integrated modelling of socio-ecological systems", + "URL": "https://linkinghub.elsevier.com/retrieve/pii/S136481521631091X", + "volume": "93", + "author": [ + { + "family": "Elsawah", + "given": "Sondoss" + }, + { + "family": "Pierce", + "given": "Suzanne A." + }, + { + "family": "Hamilton", + "given": "Serena H." + }, + { + "family": "Van Delden", + "given": "Hedwig" + }, + { + "family": "Haase", + "given": "Dagmar" + }, + { + "family": "Elmahdi", + "given": "Amgad" + }, + { + "family": "Jakeman", + "given": "Anthony J." + } + ], + "accessed": { + "date-parts": [ + [ + "2026", + 5, + 11 + ] + ] + }, + "issued": { + "date-parts": [ + [ + "2017", + 7 + ] + ] + } + }, + { + "id": "http://zotero.org/groups/6548795/items/K4KSIUC5", + "type": "article-journal", + "container-title": "Ecological Modelling", + "DOI": "10.1016/j.ecolmodel.2024.110829", + "ISSN": "03043800", + "journalAbbreviation": "Ecological Modelling", + "language": "en", + "page": "110829", + "source": "DOI.org (Crossref)", + "title": "Beyond guides, protocols and acronyms: Adoption of good modelling practices depends on challenging academia's status quo in ecology", + "title-short": "Beyond guides, protocols and acronyms", + "URL": "https://linkinghub.elsevier.com/retrieve/pii/S0304380024002175", + "volume": "496", + "author": [ + { + "family": "Micheletti", + "given": "Tatiane" + }, + { + "family": "Wimmler", + "given": "Marie-Christin" + }, + { + "family": "Berger", + "given": "Uta" + }, + { + "family": "Grimm", + "given": "Volker" + }, + { + "family": "McIntire", + "given": "Eliot J." + } + ], + "accessed": { + "date-parts": [ + [ + "2026", + 5, + 11 + ] + ] + }, + "issued": { + "date-parts": [ + [ + "2024", + 10 + ] + ] + } + }, + { + "id": "http://zotero.org/groups/6548795/items/K3WEAI7V", + "type": "article-journal", + "container-title": "Ecological Modelling", + "DOI": "10.1016/j.ecolmodel.2024.110926", + "ISSN": "03043800", + "journalAbbreviation": "Ecological Modelling", + "language": "en", + "page": "110926", + "source": "DOI.org (Crossref)", + "title": "Cracking the code: Linking good modeling and coding practices for new ecological modelers", + "title-short": "Cracking the code", + "URL": "https://linkinghub.elsevier.com/retrieve/pii/S0304380024003144", + "volume": "499", + "author": [ + { + "family": "Swannack", + "given": "Todd M." + }, + { + "family": "Cushway", + "given": "Kiara C." + }, + { + "family": "Carrillo", + "given": "Carra C." + }, + { + "family": "Calvo", + "given": "Clementina" + }, + { + "family": "Determan", + "given": "Kierra R." + }, + { + "family": "Mierzejewski", + "given": "Caroline M." + }, + { + "family": "Quintana", + "given": "Vanessa M." + }, + { + "family": "Riggins", + "given": "Christopher L." + }, + { + "family": "Sams", + "given": "Miranda D." + }, + { + "family": "Wadsworth", + "given": "Waverly E." + } + ], + "accessed": { + "date-parts": [ + [ + "2026", + 5, + 11 + ] + ] + }, + "issued": { + "date-parts": [ + [ + "2025", + 1 + ] + ] + } + }, + { + "id": "http://zotero.org/groups/6548795/items/J9SPA2CM", + "type": "article-journal", + "container-title": "Environmental Modelling & Software", + "DOI": "10.1016/j.envsoft.2021.105278", + "ISSN": "13648152", + "journalAbbreviation": "Environmental Modelling & Software", + "language": "en", + "page": "105278", + "source": "DOI.org (Crossref)", + "title": "Fit-for-purpose environmental modeling: Targeting the intersection of usability, reliability and feasibility", + "title-short": "Fit-for-purpose environmental modeling", + "URL": "https://linkinghub.elsevier.com/retrieve/pii/S1364815221003200", + "volume": "148", + "author": [ + { + "family": "Hamilton", + "given": "Serena H." + }, + { + "family": "Pollino", + "given": "Carmel A." + }, + { + "family": "Stratford", + "given": "Danial S." + }, + { + "family": "Fu", + "given": "Baihua" + }, + { + "family": "Jakeman", + "given": "Anthony J." + } + ], + "accessed": { + "date-parts": [ + [ + "2026", + 5, + 11 + ] + ] + }, + "issued": { + "date-parts": [ + [ + "2022", + 2 + ] + ] + } + }, + { + "id": "http://zotero.org/groups/6548795/items/BSAU9ZEL", + "type": "article-journal", + "container-title": "Ecological Modelling", + "DOI": "10.1016/j.ecolmodel.2024.110890", + "ISSN": "03043800", + "journalAbbreviation": "Ecological Modelling", + "language": "en", + "page": "110890", + "source": "DOI.org (Crossref)", + "title": "Good modelling software practices", + "URL": "https://linkinghub.elsevier.com/retrieve/pii/S0304380024002783", + "volume": "498", + "author": [ + { + "family": "Lemmen", + "given": "Carsten" + }, + { + "family": "Sommer", + "given": "Philipp Sebastian" + } + ], + "accessed": { + "date-parts": [ + [ + "2026", + 5, + 11 + ] + ] + }, + "issued": { + "date-parts": [ + [ + "2024", + 12 + ] + ] + } + }, + { + "id": "http://zotero.org/groups/6548795/items/PP2AF5MQ", + "type": "article-journal", + "abstract": "Computational models are complex scientific constructs that have become essential for us to better understand the world. Many models are valuable for peers within and beyond disciplinary boundaries. However, there are no widely agreed-upon standards for sharing models. This paper suggests 10 simple rules for you to both (i) ensure you share models in a way that is at least “good enough,” and (ii) enable others to lead the change towards better model-sharing practices.", + "container-title": "PLOS Computational Biology", + "DOI": "10.1371/journal.pcbi.1012702", + "ISSN": "1553-7358", + "issue": "1", + "journalAbbreviation": "PLoS Comput Biol", + "language": "en", + "page": "e1012702", + "source": "DOI.org (Crossref)", + "title": "Ten simple rules for good model-sharing practices", + "URL": "https://dx.plos.org/10.1371/journal.pcbi.1012702", + "volume": "21", + "author": [ + { + "family": "Kherroubi Garcia", + "given": "Ismael" + }, + { + "family": "Erdmann", + "given": "Christopher" + }, + { + "family": "Gesing", + "given": "Sandra" + }, + { + "family": "Barton", + "given": "Michael" + }, + { + "family": "Cadwallader", + "given": "Lauren" + }, + { + "family": "Hengeveld", + "given": "Geerten" + }, + { + "family": "Kirkpatrick", + "given": "Christine R." + }, + { + "family": "Knight", + "given": "Kathryn" + }, + { + "family": "Lemmen", + "given": "Carsten" + }, + { + "family": "Ringuette", + "given": "Rebecca" + }, + { + "family": "Zhan", + "given": "Qing" + }, + { + "family": "Harrison", + "given": "Melissa" + }, + { + "family": "Mac Gabhann", + "given": "Feilim" + }, + { + "family": "Meyers", + "given": "Natalie" + }, + { + "family": "Osborne", + "given": "Cailean" + }, + { + "family": "Till", + "given": "Charlotte" + }, + { + "family": "Brenner", + "given": "Paul" + }, + { + "family": "Buys", + "given": "Matt" + }, + { + "family": "Chen", + "given": "Min" + }, + { + "family": "Lee", + "given": "Allen" + }, + { + "family": "Papin", + "given": "Jason" + }, + { + "family": "Rao", + "given": "Yuhan" + } + ], + "editor": [ + { + "family": "Schwartz", + "given": "Russell" + } + ], + "accessed": { + "date-parts": [ + [ + "2026", + 5, + 11 + ] + ] + }, + "issued": { + "date-parts": [ + [ + "2025", + 1, + 10 + ] + ] + } + }, + { + "id": "http://zotero.org/groups/6548795/items/IRUPHYGV", + "type": "article-journal", + "abstract": "Choices made in modeling matter and demand more explication since they determine how much we can trust modeling insights and predictions within their social, political and ethical contexts. Good Modeling Practice (GMP) is a key research area for strengthening and maturing the modeling field and community, through identifying, formulating and sharing knowledge about the craft of modeling. This craft represents the knowledge that modelers learn in practice about how they get things done, and how they adapt their practices to new situations. This Joint Special Issue is motivated by the importance of sharing good modeling practices from a whole modeling lifecycle viewpoint. We attempt to add conceptual clarity to this research area by defining the plethora of concepts and decision points used to characterize the choices to be made throughout the modeling process, and by synthesizing some of the existing efforts on GMP. We characterize a broad list of articles in the literature on GMP and identify a list of essential topics demanding more attention. This list is only a preliminary one as we anticipate that a more comprehensive list of knowledge gaps will be unearthed from the submissions to the Joint Special Issue collection on GMP, of which this is an introduction. We also propose a vision for GMP and suggest instrumental ways that good practice can become not just well-known but normal practice. This instrumentation focuses on journal standards, collective commitment and culture especially by research community societies, early career awards for advancing GMP, and legal requirements or accreditation. A vital instrument in all this is the design and development of a modeling curriculum that distills core requisite knowledge about modeling, as well as proven-to-work routines and practices that can be scaled up in different contexts.", + "container-title": "Socio-Environmental Systems Modelling", + "DOI": "10.18174/sesmo.18755", + "ISSN": "2663-3027", + "journalAbbreviation": "SESMO", + "license": "http://creativecommons.org/licenses/by-nc/4.0", + "page": "18755", + "source": "DOI.org (Crossref)", + "title": "Towards normalizing good practice across the whole modeling cycle: its instrumentation and future research topics", + "title-short": "Towards normalizing good practice across the whole modeling cycle", + "URL": "https://sesmo.org/article/view/18755", + "volume": "6", + "author": [ + { + "family": "Jakeman", + "given": "Anthony J." + }, + { + "family": "Elsawah", + "given": "Sondoss" + }, + { + "family": "Wang", + "given": "Hsiao-Hsuan" + }, + { + "family": "Hamilton", + "given": "Serena H." + }, + { + "family": "Melsen", + "given": "Lieke" + }, + { + "family": "Grimm", + "given": "Volker" + } + ], + "accessed": { + "date-parts": [ + [ + "2026", + 5, + 11 + ] + ] + }, + "issued": { + "date-parts": [ + [ + "2024", + 9, + 10 + ] + ] + } + } +] \ No newline at end of file diff --git a/layouts/docs/awesome-list.html b/layouts/docs/awesome-list.html index 8cda4274..43b2d077 100644 --- a/layouts/docs/awesome-list.html +++ b/layouts/docs/awesome-list.html @@ -36,6 +36,8 @@

{{ .Title }}

{{ $content := string .Content }} {{ $content = replaceRE `(?m)^#\s+[^\n]+\n` "" $content }} {{ $content = replaceRE `\]\((/openmodelingfoundation/awesome-modeling-practices[^)]*)\)` "](https://github.com$1)" $content }} + {{ $pubs := partial "publications-list.html" . }} + {{ $content = replace $content "OMF_PUBLICATIONS_LIST" $pubs }} {{ $html := $content | markdownify }} diff --git a/layouts/partials/publications-list.html b/layouts/partials/publications-list.html new file mode 100644 index 00000000..d7895011 --- /dev/null +++ b/layouts/partials/publications-list.html @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/layouts/resources/publications.html b/layouts/resources/publications.html new file mode 100644 index 00000000..cccd24a4 --- /dev/null +++ b/layouts/resources/publications.html @@ -0,0 +1,16 @@ +{{ define "main" }} +
+

{{ .Title }}

+ + {{ with .Description }} +

{{ . }}

+ {{ end }} + +

+ Download the bibliography database: + publications.bib +

+ + {{ partial "publications-list.html" . }} +
+{{ end }} \ No newline at end of file From 7742bc5981b25f6d346bab9d019de3f03e2d700e Mon Sep 17 00:00:00 2001 From: Tati Micheletti Date: Mon, 18 May 2026 09:10:55 +0200 Subject: [PATCH 2/6] Add article annotation --- assets/publications/publications.bib | 9 +++++++++ layouts/docs/awesome-list.html | 6 ++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/assets/publications/publications.bib b/assets/publications/publications.bib index 62be5267..b606b4be 100644 --- a/assets/publications/publications.bib +++ b/assets/publications/publications.bib @@ -11,6 +11,7 @@ @article{sun_catalogue_2026 month = mar, year = {2026}, pages = {106893}, + annote = {Offers practical “Do's and Don'ts” guide for defensible modeling in every phase.} } @article{elsawah_overview_2017, @@ -27,6 +28,7 @@ @article{elsawah_overview_2017 month = jul, year = {2017}, pages = {127--145}, + annote = {Shares lessons from five system-dynamics cases to guide good practice in integrated socio-ecological modeling.} } @article{micheletti_beyond_2024, @@ -43,6 +45,7 @@ @article{micheletti_beyond_2024 month = oct, year = {2024}, pages = {110829}, + annote = {Identifies academic barriers to good modeling practice and proposed changes to promote broader adoption of reproducible modeling.} } @article{swannack_cracking_2025, @@ -59,6 +62,7 @@ @article{swannack_cracking_2025 month = jan, year = {2025}, pages = {110926}, + annote = {Offers guidance for new modelers building strong coding and documentation habits to support reproducible ecological models.} } @article{hamilton_fit-for-purpose_2022, @@ -75,6 +79,7 @@ @article{hamilton_fit-for-purpose_2022 month = feb, year = {2022}, pages = {105278}, + annote = {Proposes a fit-for-purpose framework to ensure models are useful, reliable, and feasible for decision support.} } @article{lemmen_good_2024, @@ -90,6 +95,7 @@ @article{lemmen_good_2024 month = dec, year = {2024}, pages = {110890}, + annote = {Contextualise cherry-picked and hands-on practices for supporting Good Modelling Practice, demonstrating their applications in an example.} } @article{kherroubi_garcia_ten_2025, @@ -108,6 +114,7 @@ @article{kherroubi_garcia_ten_2025 month = jan, year = {2025}, pages = {e1012702}, + annote = {Presents ten practical rules to help researchers share computational models effectively and promote wider adoption of better model-sharing practices.} } @article{jakeman_towards_2024, @@ -125,4 +132,6 @@ @article{jakeman_towards_2024 month = sep, year = {2024}, pages = {18755}, + annote = {Outlines research gaps and concrete actions to embed good modeling practice across the entire modeling cycle.} } + diff --git a/layouts/docs/awesome-list.html b/layouts/docs/awesome-list.html index 43b2d077..8ed99bee 100644 --- a/layouts/docs/awesome-list.html +++ b/layouts/docs/awesome-list.html @@ -36,10 +36,12 @@

{{ .Title }}

{{ $content := string .Content }} {{ $content = replaceRE `(?m)^#\s+[^\n]+\n` "" $content }} {{ $content = replaceRE `\]\((/openmodelingfoundation/awesome-modeling-practices[^)]*)\)` "](https://github.com$1)" $content }} + + {{ $html := $content | markdownify }} + {{ $pubs := partial "publications-list.html" . }} - {{ $content = replace $content "OMF_PUBLICATIONS_LIST" $pubs }} + {{ $content = replace $content "

OMF_PUBLICATIONS_LIST

" $pubs }} - {{ $html := $content | markdownify }} {{/* Content handling policy (intentional lightweight processing): From cc53e3fe400bdb194403aeb38900b9b7ca721f76 Mon Sep 17 00:00:00 2001 From: Allen Lee Date: Thu, 21 May 2026 21:36:59 -0700 Subject: [PATCH 3/6] fix: refine publication list rendering --- .agent/working-memory/session.md | 24 +- .env | 2 +- AGENTS.md | 2 +- Dockerfile | 2 +- assets/bibliographies/publications.bib | 145 +++++ assets/publications/publications.bib | 137 ----- assets/scss/_styles_project.scss | 124 ++++ content/en/resources/_index.md | 4 +- data/publications.json | 546 ------------------ hugo.yaml | 8 +- layouts/docs/awesome-list.html | 32 +- layouts/{resources => docs}/publications.html | 6 +- layouts/partials/publications-list.html | 137 ++++- 13 files changed, 443 insertions(+), 726 deletions(-) create mode 100644 assets/bibliographies/publications.bib delete mode 100644 assets/publications/publications.bib delete mode 100644 data/publications.json rename layouts/{resources => docs}/publications.html (57%) diff --git a/.agent/working-memory/session.md b/.agent/working-memory/session.md index f2a32777..aadcb4f1 100644 --- a/.agent/working-memory/session.md +++ b/.agent/working-memory/session.md @@ -2,13 +2,29 @@ ## Active task -- awesome-modeling-practices embed plan is ready: `.agent/working-memory/plan-awesome-list.md`. -- navigation/resources refactor issue plan is ready: `.agent/working-memory/plan-navigation-resources-refactor.md`. -- UI refactor plan artifact is ready: `.agent/working-memory/plan-ui-refactor-docsy-theme.md`. -- Next step on request: complete visual QA pass for key pages and tune any contrast/spacing edge cases. +- Publications pipeline is now BibTeX-driven from `assets/bibliographies/publications.bib`. +- Publications rendering is shared via `layouts/partials/publications-list.html` and consumed by both publications and awesome pages. +- Awesome page inserts publications in the `Papers` section and uses fallback rendering when remote README fetch fails. +- Next step on request: commit-ready QA and final content/link review. ## Notes by date (newest first) +### 2026-05-22 + +- Synced publications architecture: + - Canonical bibliography source: `assets/bibliographies/publications.bib`. + - Removed stale `data/publications.json` path and old `layouts/resources/publications.html` override. + - `layouts/docs/publications.html` is now the canonical publications template. +- Static BibTeX exposure now uses Hugo module mount: + - `hugo.yaml` mount: `assets/bibliographies` -> `static/bibliographies`. + - Publications page links BibTeX via static URL (`bibliographies/publications.bib`). +- Awesome list integration updates: + - Publications block renders under `Papers`. + - Compact publication card UI with expandable full metadata. + - Fallback path retains publications visibility when remote README retrieval fails. +- Validation: + - Containerized production build path (`.github/scripts/build-site.sh`) passed after each major step. + ### 2026-04-15 - Resumed UI theme refactor handoff and implemented Phase 1 + Phase 2 baseline in SCSS: diff --git a/.env b/.env index d4c2da7d..e66bc7e4 100644 --- a/.env +++ b/.env @@ -1,2 +1,2 @@ -HUGO_VERSION="v0.160.1" +HUGO_VERSION="v0.161.1" DOCSY_VERSION="v0.14.3" diff --git a/AGENTS.md b/AGENTS.md index 6bd8b159..283ecb48 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -45,7 +45,7 @@ Agent-generated artifacts must be written under `.agent/`. ## Important dependency versions -- Hugo (Docker build arg): `0.160.1` (`Dockerfile`) +- Hugo (Docker build arg): `0.161.1` (`Dockerfile`) - Docsy module: `v0.14.3` (`go.mod` and `Dockerfile`) - Go toolchain declaration: `1.18` (`go.mod`) - npm package manifest version: `1.0.0` (`package.json`) diff --git a/Dockerfile b/Dockerfile index 7f47d158..e7620680 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG HUGO_VERSION=v0.160.1 +ARG HUGO_VERSION=v0.161.1 FROM ghcr.io/gohugoio/hugo:${HUGO_VERSION} ARG DOCSY_VERSION=v0.14.3 diff --git a/assets/bibliographies/publications.bib b/assets/bibliographies/publications.bib new file mode 100644 index 00000000..451c582f --- /dev/null +++ b/assets/bibliographies/publications.bib @@ -0,0 +1,145 @@ +@article{jakeman_towards_2024, + title = {Towards normalizing good practice across the whole modeling cycle: its instrumentation and future research topics}, + volume = {6}, + copyright = {Copyright (c) 2024 Anthony J. Jakeman, Sondoss Elsawah, Hsiao-Hsuan Wang, Serena H. Hamilton, Lieke Melsen, Volker Grimm}, + issn = {2663-3027}, + shorttitle = {Towards normalizing good practice across the whole modeling cycle}, + url = {https://sesmo.org/article/view/18755}, + doi = {10.18174/sesmo.18755}, + abstract = {Choices made in modeling matter and demand more explication since they determine how much we can trust modeling insights and predictions within their social, political and ethical contexts. Good Modeling Practice (GMP) is a key research area for strengthening and maturing the modeling field and community, through identifying, formulating and sharing knowledge about the craft of modeling. This craft represents the knowledge that modelers learn in practice about how they get things done, and how they adapt their practices to new situations. This Joint Special Issue is motivated by the importance of sharing good modeling practices from a whole modeling lifecycle viewpoint. We attempt to add conceptual clarity to this research area by defining the plethora of concepts and decision points used to characterize the choices to be made throughout the modeling process, and by synthesizing some of the existing efforts on GMP. We characterize a broad list of articles in the literature on GMP and identify a list of essential topics demanding more attention. This list is only a preliminary one as we anticipate that a more comprehensive list of knowledge gaps will be unearthed from the submissions to the Joint Special Issue collection on GMP, of which this is an introduction. We also propose a vision for GMP and suggest instrumental ways that good practice can become not just well-known but normal practice. This instrumentation focuses on journal standards, collective commitment and culture especially by research community societies, early career awards for advancing GMP, and legal requirements or accreditation. A vital instrument in all this is the design and development of a modeling curriculum that distills core requisite knowledge about modeling, as well as proven-to-work routines and practices that can be scaled up in different contexts.}, + language = {en}, + urldate = {2026-05-06}, + journal = {Socio-Environmental Systems Modelling}, + author = {Jakeman, Anthony J. and Elsawah, Sondoss and Wang, Hsiao-Hsuan and Hamilton, Serena H. and Melsen, Lieke and Grimm, Volker}, + month = sep, + year = {2024}, + keywords = {fit for purpose, good modelling practice, modelling choices, modelling lifecycle}, + pages = {18755--18755}, + annotation = {Outlines research gaps and concrete actions to embed good modeling practice across the entire modeling cycle.}, +} + +@article{elsawah_overview_2017, + title = {An overview of the system dynamics process for integrated modelling of socio-ecological systems: {Lessons} on good modelling practice from five case studies}, + volume = {93}, + issn = {1364-8152}, + shorttitle = {An overview of the system dynamics process for integrated modelling of socio-ecological systems}, + url = {https://www.sciencedirect.com/science/article/pii/S136481521631091X}, + doi = {10.1016/j.envsoft.2017.03.001}, + abstract = {Similar to other modelling methodologies, the potential of system dynamics to contribute to system understanding and decision making depends upon the practices applied by the modeller. However lessons about many of these practices are often unreported. This paper contributes to the methodology of system dynamics modelling of socio-ecological systems by 1) examining issues modellers face during the modelling process, and 2) providing guidance on how to effectively design and implement system dynamics modelling. This is achieved through an investigation of five case studies, drawing on lessons from these experiences. This is complemented by a literature review of system dynamics applied within the context of integrated modelling and environmental DSS. The case studies cover a variety of environmental issues and system dynamics modelling methods and tools. Although we used system dynamics as the common lens from which lessons are drawn, many of these insights transcend to other integrated modelling approaches.}, + urldate = {2026-05-06}, + journal = {Environmental Modelling \& Software}, + author = {Elsawah, Sondoss and Pierce, Suzanne A. and Hamilton, Serena H. and van Delden, Hedwig and Haase, Dagmar and Elmahdi, Amgad and Jakeman, Anthony J.}, + month = jul, + year = {2017}, + keywords = {Decision support, Integrated assessment, Integrated modelling, Modelling practices, Socio-ecological systems, System dynamics}, + pages = {127--145}, + annotation = {Shares lessons from five system-dynamics cases to guide good practice in integrated socio-ecological modeling.}, +} + +@article{micheletti_beyond_2024, + title = {Beyond guides, protocols and acronyms: {Adoption} of good modelling practices depends on challenging academia's status quo in ecology}, + volume = {496}, + issn = {0304-3800}, + shorttitle = {Beyond guides, protocols and acronyms}, + url = {https://www.sciencedirect.com/science/article/pii/S0304380024002175}, + doi = {10.1016/j.ecolmodel.2024.110829}, + abstract = {Implementing good modelling practices (GMP) in ecological sciences is key to improving scientific reliability. Despite the increased availability of guidelines and protocols detailing how principles such as FAIR and PERFICT can be implemented to improve good modelling practices, the sharing of code which can reproduce results and workflows remains remarkably low. In this work, we explore potential root causes of this discrepancy. We identify three key factors inherent to the current academic structure that, in our experience, might play a role in hindering a wider adoption of GMP: (1) acknowledgment of the time required to implement GMP in projects, (2) the lack of GMP and software development training among ecologists, and (3) perception of GMP as unrewarding in the short-term. We argue that there is an urgent need for systemic changes. Such changes include (1) a cultural shift to value the incorporation of GMP across projects, emphasising the need for explicit budget allocation and careful scheduling of its implementation, (2) redesigning academic curricula to explicitly include GMP and software development as fundamental disciplines in ecology, and (3) an increase in recognition of open and functional code and workflows for career advancement. We call for concerted efforts for bridging this gap, and propose a hopeful outlook emphasising the role of a new generation of scientists and tools committed to good science. Proposing concrete actions, we aim to start a discussion on challenging academia's status quo in ecology and support scientists in bringing a significant paradigm shift to ecological modelling.}, + urldate = {2026-05-06}, + journal = {Ecological Modelling}, + author = {Micheletti, Tatiane and Wimmler, Marie-Christin and Berger, Uta and Grimm, Volker and McIntire, Eliot J.}, + month = oct, + year = {2024}, + keywords = {Academic reform, Ecological modelling, FAIR principles, PERFICT, Reproducibility, Scientific reliability}, + pages = {110829}, + annotation = {Identifies academic barriers to good modeling practice and proposed changes to promote broader adoption of reproducible modeling.}, +} + +@article{hamilton_fit-for-purpose_2022, + title = {Fit-for-purpose environmental modeling: {Targeting} the intersection of usability, reliability and feasibility}, + volume = {148}, + issn = {1364-8152}, + shorttitle = {Fit-for-purpose environmental modeling}, + url = {https://www.sciencedirect.com/science/article/pii/S1364815221003200}, + doi = {10.1016/j.envsoft.2021.105278}, + abstract = {Although it is widely acknowledged as a fundamental principle that models be fit-for-purpose, there remains lack of clarity on what this notion actually means and therefore how it is achieved. We contend that fitness-for-purpose must go beyond the functional use of the model to include its management, problem and project contexts. Accordingly, we propose a practical framework that considers fit-for-purpose modeling as the intersection of three requirements, in that the modeling be: useful, addressing the needs of the end user; reliable, obtaining an adequate level of certainty or trust; and feasible, within practical constraints of the project. Modeling choices, including the selection of spatial and temporal scales, system features and processes to include, and the type of model, can be better informed when the bounds of these fit-for-purpose requirements are defined. We focus on modeling in decision and management support settings, and demonstrate the framework with ecohydrological models designed for managing environmental flows. By explicitly linking its intended functional use and context to modeling choices, this framework can facilitate the design and development of environmental models that more effectively bridge science and management.}, + urldate = {2026-05-06}, + journal = {Environmental Modelling \& Software}, + author = {Hamilton, Serena H. and Pollino, Carmel A. and Stratford, Danial S. and Fu, Baihua and Jakeman, Anthony J.}, + month = feb, + year = {2022}, + keywords = {Best practices, e-flows, Ecological models, Environmental water, Fit-for-purpose modeling, Model design}, + pages = {105278}, + annotation = {Proposes a fit-for-purpose framework to ensure models are useful, reliable, and feasible for decision support.}, +} + +@article{garcia_ten_2025, + title = {Ten simple rules for good model-sharing practices}, + volume = {21}, + issn = {1553-7358}, + url = {https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1012702}, + doi = {10.1371/journal.pcbi.1012702}, + abstract = {Computational models are complex scientific constructs that have become essential for us to better understand the world. Many models are valuable for peers within and beyond disciplinary boundaries. However, there are no widely agreed-upon standards for sharing models. This paper suggests 10 simple rules for you to both (i) ensure you share models in a way that is at least “good enough,” and (ii) enable others to lead the change towards better model-sharing practices.}, + language = {en}, + number = {1}, + urldate = {2026-05-06}, + journal = {PLOS Computational Biology}, + publisher = {Public Library of Science}, + author = {Garcia, Ismael Kherroubi and Erdmann, Christopher and Gesing, Sandra and Barton, Michael and Cadwallader, Lauren and Hengeveld, Geerten and Kirkpatrick, Christine R. and Knight, Kathryn and Lemmen, Carsten and Ringuette, Rebecca and Zhan, Qing and Harrison, Melissa and Gabhann, Feilim Mac and Meyers, Natalie and Osborne, Cailean and Till, Charlotte and Brenner, Paul and Buys, Matt and Chen, Min and Lee, Allen and Papin, Jason and Rao, Yuhan}, + month = jan, + year = {2025}, + keywords = {Careers, Computer software, Metadata, Open science, Science policy, Taxonomy, User interfaces, Workshops}, + pages = {e1012702}, + annotation = {Presents ten practical rules to help researchers share computational models effectively and promote wider adoption of better model-sharing practices.}, +} + +@article{swannack_cracking_2025, + title = {Cracking the code: {Linking} good modeling and coding practices for new ecological modelers}, + volume = {499}, + issn = {0304-3800}, + shorttitle = {Cracking the code}, + url = {https://www.sciencedirect.com/science/article/pii/S0304380024003144}, + doi = {10.1016/j.ecolmodel.2024.110926}, + abstract = {Good modeling practices are essential for producing reliable and reproducible ecological models. Inherent to good modeling practices are fundamental coding and documentation skills, which not only implement the desired modeling capabilities but also clearly outline the goals, methods, and components of a model that are necessary to reproduce the desired results. One of the largest challenges for new ecological modelers can be implementing a model into computer code. In fact, coding represents a significant barrier for entry into ecological modeling, since most ecologists have not had formal training in computer science or software development. While software packages do exist that facilitate model development, we have observed that newer modelers still struggle with developing good coding practice throughout the modeling process. During a series of agent-based modeling short-courses and full semester graduate courses, both taught in NetLogo, we identified some common challenges encountered by graduate students and environmental professionals as they learn to code an ecological model, many for the first time. We were able to categorize and provide examples of the main challenges and obstacles, which fell into three main groups that follow the steps of good modeling practice: problem scoping and conceptualization, formulation, and evaluation. We then provide guidance on how to overcome these obstacles while developing good coding and modeling practices that will result in more scientifically defensible models.}, + urldate = {2026-05-06}, + journal = {Ecological Modelling}, + author = {Swannack, Todd M. and Cushway, Kiara C. and Carrillo, Carra C. and Calvo, Clementina and Determan, Kierra R. and Mierzejewski, Caroline M. and Quintana, Vanessa M. and Riggins, Christopher L. and Sams, Miranda D. and Wadsworth, Waverly E.}, + month = jan, + year = {2025}, + keywords = {Coding, Documentation, Evaluation, Good practice, Model development}, + pages = {110926}, + annotation = {Offers guidance for new modelers building strong coding and documentation habits to support reproducible ecological models.}, +} + +@article{lemmen_good_2024, + title = {Good modelling software practices}, + volume = {498}, + issn = {0304-3800}, + url = {https://www.sciencedirect.com/science/article/pii/S0304380024002783}, + doi = {10.1016/j.ecolmodel.2024.110890}, + abstract = {Frequently in socio-environmental sciences, models are used as tools to represent, understand, project and predict the behaviour of these complex systems. Along the modelling chain, Good Modelling Practices have been evolving that ensure — amongst others — that models are transparent and their results replicable. Whenever such models are represented in software, Good Modelling meet Good Software Practices, such as a tractable development workflow, good code, collaborative development and governance, continuous integration and deployment; and they meet Good Scientific Practices, such as attribution of copyrights and acknowledgement of intellectual property, publication of a software paper and archiving. Too often in existing socio-environmental model software, these practices have been regarded as an add-on to be considered at a later stage only; modellers have shied away from publishing their model as open source out of fear that having to add good practices is too demanding. We here argue for making a habit of following a list of simple and not so simple practices early on in the implementation of the model life cycle. We contextualise cherry-picked and hands-on practices for supporting Good Modelling Practice, and we demonstrate their application in the example context of the Viable North Sea fisheries socio-ecological systems model.}, + urldate = {2026-05-06}, + journal = {Ecological Modelling}, + author = {Lemmen, Carsten and Sommer, Philipp Sebastian}, + month = dec, + year = {2024}, + keywords = {Good modelling practice, Good scientific practice, Good software practice}, + pages = {110890}, + annotation = {Contextualise cherry-picked and hands-on practices for supporting Good Modelling Practice, demonstrating their applications in an example.}, +} + +@article{sun_catalogue_2026, + title = {A catalogue of {Do}'s and {Don}'ts in the modeling of environmental systems}, + volume = {198}, + issn = {1364-8152}, + url = {https://www.sciencedirect.com/science/article/pii/S136481522600040X}, + doi = {10.1016/j.envsoft.2026.106893}, + abstract = {Modeling plays a vital role in understanding and managing complex environmental systems, but its credibility and quality depend heavily on a comprehensive set of defensible model activities and practices, especially when the system of interest is plagued with uncertainties and conflicting stakeholder perspectives. This paper proposes a catalogue of Do's and Don'ts to guide modelers in addressing the many pertinent considerations through the whole modeling cycle. This practical tool provides advice on approaching modeling effectively through adhering to good modeling practice. It emphasizes model choices that align with the model purpose and context, and the justification and documentation of modeling decisions and assumptions. Managing uncertainty is a core consideration. The identification, assessment and reporting of these uncertainties is important across the entire modeling process, which spans problem framing, technical design, implementation and application phases. Such good practices are critical for transparency and reliability of the modeling.}, + urldate = {2026-05-06}, + journal = {Environmental Modelling \& Software}, + author = {Sun, Xifu and Jakeman, Anthony and Hamilton, Serena H. and Grimm, Volker and Hunt, Randall J. and El Sawah, Sondoss and Wang, Hsiao-Hsuan and Croke, Barry and Chen, Min}, + month = mar, + year = {2026}, + keywords = {Environmental modeling, Good modeling practice, Modeling cycle, Transparency, Uncertainty management}, + pages = {106893}, + annotation = {Offers practical "Do's and Don'ts" guide for defensible modeling in every phase.}, +} diff --git a/assets/publications/publications.bib b/assets/publications/publications.bib deleted file mode 100644 index b606b4be..00000000 --- a/assets/publications/publications.bib +++ /dev/null @@ -1,137 +0,0 @@ -@article{sun_catalogue_2026, - title = {A catalogue of {Do}'s and {Don}'ts in the modeling of environmental systems}, - volume = {198}, - issn = {13648152}, - url = {https://linkinghub.elsevier.com/retrieve/pii/S136481522600040X}, - doi = {10.1016/j.envsoft.2026.106893}, - language = {en}, - urldate = {2026-05-11}, - journal = {Environmental Modelling \& Software}, - author = {Sun, Xifu and Jakeman, Anthony and Hamilton, Serena H. and Grimm, Volker and Hunt, Randall J. and El Sawah, Sondoss and Wang, Hsiao-Hsuan and Croke, Barry and Chen, Min}, - month = mar, - year = {2026}, - pages = {106893}, - annote = {Offers practical “Do's and Don'ts” guide for defensible modeling in every phase.} -} - -@article{elsawah_overview_2017, - title = {An overview of the system dynamics process for integrated modelling of socio-ecological systems: {Lessons} on good modelling practice from five case studies}, - volume = {93}, - issn = {13648152}, - shorttitle = {An overview of the system dynamics process for integrated modelling of socio-ecological systems}, - url = {https://linkinghub.elsevier.com/retrieve/pii/S136481521631091X}, - doi = {10.1016/j.envsoft.2017.03.001}, - language = {en}, - urldate = {2026-05-11}, - journal = {Environmental Modelling \& Software}, - author = {Elsawah, Sondoss and Pierce, Suzanne A. and Hamilton, Serena H. and Van Delden, Hedwig and Haase, Dagmar and Elmahdi, Amgad and Jakeman, Anthony J.}, - month = jul, - year = {2017}, - pages = {127--145}, - annote = {Shares lessons from five system-dynamics cases to guide good practice in integrated socio-ecological modeling.} -} - -@article{micheletti_beyond_2024, - title = {Beyond guides, protocols and acronyms: {Adoption} of good modelling practices depends on challenging academia's status quo in ecology}, - volume = {496}, - issn = {03043800}, - shorttitle = {Beyond guides, protocols and acronyms}, - url = {https://linkinghub.elsevier.com/retrieve/pii/S0304380024002175}, - doi = {10.1016/j.ecolmodel.2024.110829}, - language = {en}, - urldate = {2026-05-11}, - journal = {Ecological Modelling}, - author = {Micheletti, Tatiane and Wimmler, Marie-Christin and Berger, Uta and Grimm, Volker and McIntire, Eliot J.}, - month = oct, - year = {2024}, - pages = {110829}, - annote = {Identifies academic barriers to good modeling practice and proposed changes to promote broader adoption of reproducible modeling.} -} - -@article{swannack_cracking_2025, - title = {Cracking the code: {Linking} good modeling and coding practices for new ecological modelers}, - volume = {499}, - issn = {03043800}, - shorttitle = {Cracking the code}, - url = {https://linkinghub.elsevier.com/retrieve/pii/S0304380024003144}, - doi = {10.1016/j.ecolmodel.2024.110926}, - language = {en}, - urldate = {2026-05-11}, - journal = {Ecological Modelling}, - author = {Swannack, Todd M. and Cushway, Kiara C. and Carrillo, Carra C. and Calvo, Clementina and Determan, Kierra R. and Mierzejewski, Caroline M. and Quintana, Vanessa M. and Riggins, Christopher L. and Sams, Miranda D. and Wadsworth, Waverly E.}, - month = jan, - year = {2025}, - pages = {110926}, - annote = {Offers guidance for new modelers building strong coding and documentation habits to support reproducible ecological models.} -} - -@article{hamilton_fit-for-purpose_2022, - title = {Fit-for-purpose environmental modeling: {Targeting} the intersection of usability, reliability and feasibility}, - volume = {148}, - issn = {13648152}, - shorttitle = {Fit-for-purpose environmental modeling}, - url = {https://linkinghub.elsevier.com/retrieve/pii/S1364815221003200}, - doi = {10.1016/j.envsoft.2021.105278}, - language = {en}, - urldate = {2026-05-11}, - journal = {Environmental Modelling \& Software}, - author = {Hamilton, Serena H. and Pollino, Carmel A. and Stratford, Danial S. and Fu, Baihua and Jakeman, Anthony J.}, - month = feb, - year = {2022}, - pages = {105278}, - annote = {Proposes a fit-for-purpose framework to ensure models are useful, reliable, and feasible for decision support.} -} - -@article{lemmen_good_2024, - title = {Good modelling software practices}, - volume = {498}, - issn = {03043800}, - url = {https://linkinghub.elsevier.com/retrieve/pii/S0304380024002783}, - doi = {10.1016/j.ecolmodel.2024.110890}, - language = {en}, - urldate = {2026-05-11}, - journal = {Ecological Modelling}, - author = {Lemmen, Carsten and Sommer, Philipp Sebastian}, - month = dec, - year = {2024}, - pages = {110890}, - annote = {Contextualise cherry-picked and hands-on practices for supporting Good Modelling Practice, demonstrating their applications in an example.} -} - -@article{kherroubi_garcia_ten_2025, - title = {Ten simple rules for good model-sharing practices}, - volume = {21}, - issn = {1553-7358}, - url = {https://dx.plos.org/10.1371/journal.pcbi.1012702}, - doi = {10.1371/journal.pcbi.1012702}, - abstract = {Computational models are complex scientific constructs that have become essential for us to better understand the world. Many models are valuable for peers within and beyond disciplinary boundaries. However, there are no widely agreed-upon standards for sharing models. This paper suggests 10 simple rules for you to both (i) ensure you share models in a way that is at least “good enough,” and (ii) enable others to lead the change towards better model-sharing practices.}, - language = {en}, - number = {1}, - urldate = {2026-05-11}, - journal = {PLOS Computational Biology}, - author = {Kherroubi Garcia, Ismael and Erdmann, Christopher and Gesing, Sandra and Barton, Michael and Cadwallader, Lauren and Hengeveld, Geerten and Kirkpatrick, Christine R. and Knight, Kathryn and Lemmen, Carsten and Ringuette, Rebecca and Zhan, Qing and Harrison, Melissa and Mac Gabhann, Feilim and Meyers, Natalie and Osborne, Cailean and Till, Charlotte and Brenner, Paul and Buys, Matt and Chen, Min and Lee, Allen and Papin, Jason and Rao, Yuhan}, - editor = {Schwartz, Russell}, - month = jan, - year = {2025}, - pages = {e1012702}, - annote = {Presents ten practical rules to help researchers share computational models effectively and promote wider adoption of better model-sharing practices.} -} - -@article{jakeman_towards_2024, - title = {Towards normalizing good practice across the whole modeling cycle: its instrumentation and future research topics}, - volume = {6}, - copyright = {http://creativecommons.org/licenses/by-nc/4.0}, - issn = {2663-3027}, - shorttitle = {Towards normalizing good practice across the whole modeling cycle}, - url = {https://sesmo.org/article/view/18755}, - doi = {10.18174/sesmo.18755}, - abstract = {Choices made in modeling matter and demand more explication since they determine how much we can trust modeling insights and predictions within their social, political and ethical contexts. Good Modeling Practice (GMP) is a key research area for strengthening and maturing the modeling field and community, through identifying, formulating and sharing knowledge about the craft of modeling. This craft represents the knowledge that modelers learn in practice about how they get things done, and how they adapt their practices to new situations. This Joint Special Issue is motivated by the importance of sharing good modeling practices from a whole modeling lifecycle viewpoint. We attempt to add conceptual clarity to this research area by defining the plethora of concepts and decision points used to characterize the choices to be made throughout the modeling process, and by synthesizing some of the existing efforts on GMP. We characterize a broad list of articles in the literature on GMP and identify a list of essential topics demanding more attention. This list is only a preliminary one as we anticipate that a more comprehensive list of knowledge gaps will be unearthed from the submissions to the Joint Special Issue collection on GMP, of which this is an introduction. We also propose a vision for GMP and suggest instrumental ways that good practice can become not just well-known but normal practice. This instrumentation focuses on journal standards, collective commitment and culture especially by research community societies, early career awards for advancing GMP, and legal requirements or accreditation. A vital instrument in all this is the design and development of a modeling curriculum that distills core requisite knowledge about modeling, as well as proven-to-work routines and practices that can be scaled up in different contexts.}, - urldate = {2026-05-11}, - journal = {Socio-Environmental Systems Modelling}, - author = {Jakeman, Anthony J. and Elsawah, Sondoss and Wang, Hsiao-Hsuan and Hamilton, Serena H. and Melsen, Lieke and Grimm, Volker}, - month = sep, - year = {2024}, - pages = {18755}, - annote = {Outlines research gaps and concrete actions to embed good modeling practice across the entire modeling cycle.} -} - diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index 357bff16..084bae62 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -537,6 +537,130 @@ footer { } } +.compact-publications-list { + list-style: none; + padding-left: 0; + margin: 1.25rem 0 0; + display: grid; + gap: 0.95rem; + + .publication-item { + margin: 0; + } + + .publication-card { + padding: 0.95rem 1rem; + border: 1px solid rgba($primary, 0.16); + border-left: 4px solid rgba($secondary, 0.65); + border-radius: 0.8rem; + background: linear-gradient(160deg, rgba($white, 0.95), rgba($secondary, 0.06)); + box-shadow: 0 12px 22px -20px rgba($primary, 0.45); + } + + .publication-title { + margin: 0; + color: $primary; + font-family: "Source Serif 4", Georgia, serif; + font-size: clamp(1.05rem, 1.35vw, 1.28rem); + line-height: 1.35; + letter-spacing: 0.01em; + } + + .publication-meta { + margin: 0.48rem 0 0; + display: flex; + flex-wrap: wrap; + gap: 0.4rem; + } + + .publication-chip { + display: inline-block; + padding: 0.16rem 0.5rem; + border-radius: 999px; + border: 1px solid rgba($secondary, 0.42); + background: rgba($secondary, 0.12); + color: mix($primary, $dark, 80%); + font-size: 0.8rem; + line-height: 1.25; + } + + .publication-annotation { + margin: 0.62rem 0 0; + color: var(--omf-text); + font-size: 0.94rem; + line-height: 1.55; + } + + .publication-links { + margin: 0.6rem 0 0; + display: flex; + gap: 0.8rem; + flex-wrap: wrap; + + a { + font-size: 0.84rem; + font-weight: 600; + text-decoration: none; + + &:hover, + &:focus-visible { + text-decoration: underline; + } + } + } + + .publication-details { + margin-top: 0.58rem; + + summary { + cursor: pointer; + color: var(--omf-text-muted); + font-size: 0.84rem; + font-weight: 600; + width: fit-content; + } + } + + .publication-fields { + margin: 0.65rem 0 0; + display: grid; + grid-template-columns: minmax(110px, auto) 1fr; + gap: 0.12rem 0.7rem; + + dt, + dd { + margin: 0; + font-size: 0.83rem; + line-height: 1.4; + word-break: break-word; + } + + dt { + color: var(--omf-text-muted); + font-family: "IBM Plex Mono", monospace; + } + } +} + +.awesome-publications-fallback { + margin-top: 1.25rem; +} + +@include media-breakpoint-down(md) { + .compact-publications-list { + gap: 0.75rem; + + .publication-card { + padding: 0.86rem 0.82rem; + } + + .publication-fields { + grid-template-columns: 1fr; + gap: 0.08rem; + } + } +} + @media (prefers-reduced-motion: reduce) { * { transition: none !important; diff --git a/content/en/resources/_index.md b/content/en/resources/_index.md index d1247f8e..d9194ed8 100644 --- a/content/en/resources/_index.md +++ b/content/en/resources/_index.md @@ -15,8 +15,8 @@ The Resources section highlights concrete Open Modeling Foundation outputs and r

Standards

-

View OMF standards and guidance in the dedicated standards section.

- View OMF standards +

OMF standards are still under active development by individual Working Groups and are works-in-progress.

+ }}">View Workshop Discussions on OMF standards
diff --git a/data/publications.json b/data/publications.json deleted file mode 100644 index 0fad7957..00000000 --- a/data/publications.json +++ /dev/null @@ -1,546 +0,0 @@ -[ - { - "id": "http://zotero.org/groups/6548795/items/6ZTTIC2K", - "type": "article-journal", - "container-title": "Environmental Modelling & Software", - "DOI": "10.1016/j.envsoft.2026.106893", - "ISSN": "13648152", - "journalAbbreviation": "Environmental Modelling & Software", - "language": "en", - "page": "106893", - "source": "DOI.org (Crossref)", - "title": "A catalogue of Do's and Don'ts in the modeling of environmental systems", - "URL": "https://linkinghub.elsevier.com/retrieve/pii/S136481522600040X", - "volume": "198", - "author": [ - { - "family": "Sun", - "given": "Xifu" - }, - { - "family": "Jakeman", - "given": "Anthony" - }, - { - "family": "Hamilton", - "given": "Serena H." - }, - { - "family": "Grimm", - "given": "Volker" - }, - { - "family": "Hunt", - "given": "Randall J." - }, - { - "family": "El Sawah", - "given": "Sondoss" - }, - { - "family": "Wang", - "given": "Hsiao-Hsuan" - }, - { - "family": "Croke", - "given": "Barry" - }, - { - "family": "Chen", - "given": "Min" - } - ], - "accessed": { - "date-parts": [ - [ - "2026", - 5, - 11 - ] - ] - }, - "issued": { - "date-parts": [ - [ - "2026", - 3 - ] - ] - } - }, - { - "id": "http://zotero.org/groups/6548795/items/FSVNQZUL", - "type": "article-journal", - "container-title": "Environmental Modelling & Software", - "DOI": "10.1016/j.envsoft.2017.03.001", - "ISSN": "13648152", - "journalAbbreviation": "Environmental Modelling & Software", - "language": "en", - "page": "127-145", - "source": "DOI.org (Crossref)", - "title": "An overview of the system dynamics process for integrated modelling of socio-ecological systems: Lessons on good modelling practice from five case studies", - "title-short": "An overview of the system dynamics process for integrated modelling of socio-ecological systems", - "URL": "https://linkinghub.elsevier.com/retrieve/pii/S136481521631091X", - "volume": "93", - "author": [ - { - "family": "Elsawah", - "given": "Sondoss" - }, - { - "family": "Pierce", - "given": "Suzanne A." - }, - { - "family": "Hamilton", - "given": "Serena H." - }, - { - "family": "Van Delden", - "given": "Hedwig" - }, - { - "family": "Haase", - "given": "Dagmar" - }, - { - "family": "Elmahdi", - "given": "Amgad" - }, - { - "family": "Jakeman", - "given": "Anthony J." - } - ], - "accessed": { - "date-parts": [ - [ - "2026", - 5, - 11 - ] - ] - }, - "issued": { - "date-parts": [ - [ - "2017", - 7 - ] - ] - } - }, - { - "id": "http://zotero.org/groups/6548795/items/K4KSIUC5", - "type": "article-journal", - "container-title": "Ecological Modelling", - "DOI": "10.1016/j.ecolmodel.2024.110829", - "ISSN": "03043800", - "journalAbbreviation": "Ecological Modelling", - "language": "en", - "page": "110829", - "source": "DOI.org (Crossref)", - "title": "Beyond guides, protocols and acronyms: Adoption of good modelling practices depends on challenging academia's status quo in ecology", - "title-short": "Beyond guides, protocols and acronyms", - "URL": "https://linkinghub.elsevier.com/retrieve/pii/S0304380024002175", - "volume": "496", - "author": [ - { - "family": "Micheletti", - "given": "Tatiane" - }, - { - "family": "Wimmler", - "given": "Marie-Christin" - }, - { - "family": "Berger", - "given": "Uta" - }, - { - "family": "Grimm", - "given": "Volker" - }, - { - "family": "McIntire", - "given": "Eliot J." - } - ], - "accessed": { - "date-parts": [ - [ - "2026", - 5, - 11 - ] - ] - }, - "issued": { - "date-parts": [ - [ - "2024", - 10 - ] - ] - } - }, - { - "id": "http://zotero.org/groups/6548795/items/K3WEAI7V", - "type": "article-journal", - "container-title": "Ecological Modelling", - "DOI": "10.1016/j.ecolmodel.2024.110926", - "ISSN": "03043800", - "journalAbbreviation": "Ecological Modelling", - "language": "en", - "page": "110926", - "source": "DOI.org (Crossref)", - "title": "Cracking the code: Linking good modeling and coding practices for new ecological modelers", - "title-short": "Cracking the code", - "URL": "https://linkinghub.elsevier.com/retrieve/pii/S0304380024003144", - "volume": "499", - "author": [ - { - "family": "Swannack", - "given": "Todd M." - }, - { - "family": "Cushway", - "given": "Kiara C." - }, - { - "family": "Carrillo", - "given": "Carra C." - }, - { - "family": "Calvo", - "given": "Clementina" - }, - { - "family": "Determan", - "given": "Kierra R." - }, - { - "family": "Mierzejewski", - "given": "Caroline M." - }, - { - "family": "Quintana", - "given": "Vanessa M." - }, - { - "family": "Riggins", - "given": "Christopher L." - }, - { - "family": "Sams", - "given": "Miranda D." - }, - { - "family": "Wadsworth", - "given": "Waverly E." - } - ], - "accessed": { - "date-parts": [ - [ - "2026", - 5, - 11 - ] - ] - }, - "issued": { - "date-parts": [ - [ - "2025", - 1 - ] - ] - } - }, - { - "id": "http://zotero.org/groups/6548795/items/J9SPA2CM", - "type": "article-journal", - "container-title": "Environmental Modelling & Software", - "DOI": "10.1016/j.envsoft.2021.105278", - "ISSN": "13648152", - "journalAbbreviation": "Environmental Modelling & Software", - "language": "en", - "page": "105278", - "source": "DOI.org (Crossref)", - "title": "Fit-for-purpose environmental modeling: Targeting the intersection of usability, reliability and feasibility", - "title-short": "Fit-for-purpose environmental modeling", - "URL": "https://linkinghub.elsevier.com/retrieve/pii/S1364815221003200", - "volume": "148", - "author": [ - { - "family": "Hamilton", - "given": "Serena H." - }, - { - "family": "Pollino", - "given": "Carmel A." - }, - { - "family": "Stratford", - "given": "Danial S." - }, - { - "family": "Fu", - "given": "Baihua" - }, - { - "family": "Jakeman", - "given": "Anthony J." - } - ], - "accessed": { - "date-parts": [ - [ - "2026", - 5, - 11 - ] - ] - }, - "issued": { - "date-parts": [ - [ - "2022", - 2 - ] - ] - } - }, - { - "id": "http://zotero.org/groups/6548795/items/BSAU9ZEL", - "type": "article-journal", - "container-title": "Ecological Modelling", - "DOI": "10.1016/j.ecolmodel.2024.110890", - "ISSN": "03043800", - "journalAbbreviation": "Ecological Modelling", - "language": "en", - "page": "110890", - "source": "DOI.org (Crossref)", - "title": "Good modelling software practices", - "URL": "https://linkinghub.elsevier.com/retrieve/pii/S0304380024002783", - "volume": "498", - "author": [ - { - "family": "Lemmen", - "given": "Carsten" - }, - { - "family": "Sommer", - "given": "Philipp Sebastian" - } - ], - "accessed": { - "date-parts": [ - [ - "2026", - 5, - 11 - ] - ] - }, - "issued": { - "date-parts": [ - [ - "2024", - 12 - ] - ] - } - }, - { - "id": "http://zotero.org/groups/6548795/items/PP2AF5MQ", - "type": "article-journal", - "abstract": "Computational models are complex scientific constructs that have become essential for us to better understand the world. Many models are valuable for peers within and beyond disciplinary boundaries. However, there are no widely agreed-upon standards for sharing models. This paper suggests 10 simple rules for you to both (i) ensure you share models in a way that is at least “good enough,” and (ii) enable others to lead the change towards better model-sharing practices.", - "container-title": "PLOS Computational Biology", - "DOI": "10.1371/journal.pcbi.1012702", - "ISSN": "1553-7358", - "issue": "1", - "journalAbbreviation": "PLoS Comput Biol", - "language": "en", - "page": "e1012702", - "source": "DOI.org (Crossref)", - "title": "Ten simple rules for good model-sharing practices", - "URL": "https://dx.plos.org/10.1371/journal.pcbi.1012702", - "volume": "21", - "author": [ - { - "family": "Kherroubi Garcia", - "given": "Ismael" - }, - { - "family": "Erdmann", - "given": "Christopher" - }, - { - "family": "Gesing", - "given": "Sandra" - }, - { - "family": "Barton", - "given": "Michael" - }, - { - "family": "Cadwallader", - "given": "Lauren" - }, - { - "family": "Hengeveld", - "given": "Geerten" - }, - { - "family": "Kirkpatrick", - "given": "Christine R." - }, - { - "family": "Knight", - "given": "Kathryn" - }, - { - "family": "Lemmen", - "given": "Carsten" - }, - { - "family": "Ringuette", - "given": "Rebecca" - }, - { - "family": "Zhan", - "given": "Qing" - }, - { - "family": "Harrison", - "given": "Melissa" - }, - { - "family": "Mac Gabhann", - "given": "Feilim" - }, - { - "family": "Meyers", - "given": "Natalie" - }, - { - "family": "Osborne", - "given": "Cailean" - }, - { - "family": "Till", - "given": "Charlotte" - }, - { - "family": "Brenner", - "given": "Paul" - }, - { - "family": "Buys", - "given": "Matt" - }, - { - "family": "Chen", - "given": "Min" - }, - { - "family": "Lee", - "given": "Allen" - }, - { - "family": "Papin", - "given": "Jason" - }, - { - "family": "Rao", - "given": "Yuhan" - } - ], - "editor": [ - { - "family": "Schwartz", - "given": "Russell" - } - ], - "accessed": { - "date-parts": [ - [ - "2026", - 5, - 11 - ] - ] - }, - "issued": { - "date-parts": [ - [ - "2025", - 1, - 10 - ] - ] - } - }, - { - "id": "http://zotero.org/groups/6548795/items/IRUPHYGV", - "type": "article-journal", - "abstract": "Choices made in modeling matter and demand more explication since they determine how much we can trust modeling insights and predictions within their social, political and ethical contexts. Good Modeling Practice (GMP) is a key research area for strengthening and maturing the modeling field and community, through identifying, formulating and sharing knowledge about the craft of modeling. This craft represents the knowledge that modelers learn in practice about how they get things done, and how they adapt their practices to new situations. This Joint Special Issue is motivated by the importance of sharing good modeling practices from a whole modeling lifecycle viewpoint. We attempt to add conceptual clarity to this research area by defining the plethora of concepts and decision points used to characterize the choices to be made throughout the modeling process, and by synthesizing some of the existing efforts on GMP. We characterize a broad list of articles in the literature on GMP and identify a list of essential topics demanding more attention. This list is only a preliminary one as we anticipate that a more comprehensive list of knowledge gaps will be unearthed from the submissions to the Joint Special Issue collection on GMP, of which this is an introduction. We also propose a vision for GMP and suggest instrumental ways that good practice can become not just well-known but normal practice. This instrumentation focuses on journal standards, collective commitment and culture especially by research community societies, early career awards for advancing GMP, and legal requirements or accreditation. A vital instrument in all this is the design and development of a modeling curriculum that distills core requisite knowledge about modeling, as well as proven-to-work routines and practices that can be scaled up in different contexts.", - "container-title": "Socio-Environmental Systems Modelling", - "DOI": "10.18174/sesmo.18755", - "ISSN": "2663-3027", - "journalAbbreviation": "SESMO", - "license": "http://creativecommons.org/licenses/by-nc/4.0", - "page": "18755", - "source": "DOI.org (Crossref)", - "title": "Towards normalizing good practice across the whole modeling cycle: its instrumentation and future research topics", - "title-short": "Towards normalizing good practice across the whole modeling cycle", - "URL": "https://sesmo.org/article/view/18755", - "volume": "6", - "author": [ - { - "family": "Jakeman", - "given": "Anthony J." - }, - { - "family": "Elsawah", - "given": "Sondoss" - }, - { - "family": "Wang", - "given": "Hsiao-Hsuan" - }, - { - "family": "Hamilton", - "given": "Serena H." - }, - { - "family": "Melsen", - "given": "Lieke" - }, - { - "family": "Grimm", - "given": "Volker" - } - ], - "accessed": { - "date-parts": [ - [ - "2026", - 5, - 11 - ] - ] - }, - "issued": { - "date-parts": [ - [ - "2024", - 9, - 10 - ] - ] - } - } -] \ No newline at end of file diff --git a/hugo.yaml b/hugo.yaml index 36a4b774..11e6fcf6 100644 --- a/hugo.yaml +++ b/hugo.yaml @@ -29,7 +29,7 @@ module: proxy: "direct" hugoVersion: extended: true - min: "0.160.1" + min: "0.161.1" imports: - path: "github.com/google/docsy" disable: false @@ -41,6 +41,8 @@ module: target: "content" - source: ".github/ISSUE_TEMPLATE" target: "content/issue_templates" + - source: "assets/bibliographies" + target: "static/bibliographies" # Configure how URLs look like per section. permalinks: @@ -90,6 +92,10 @@ security: - '^HUGO_' - '^CI$' - '^BUILD_TIMESTAMP_UTC$' + node: + permissions: + allowRead: + - '*' params: working_group_request_form: "https://asu.questionpro.com/omf-wg-joinrequest" diff --git a/layouts/docs/awesome-list.html b/layouts/docs/awesome-list.html index 8ed99bee..45930819 100644 --- a/layouts/docs/awesome-list.html +++ b/layouts/docs/awesome-list.html @@ -9,6 +9,7 @@ {{ with $buildTimestampRaw }} {{ $buildTimestamp = time . }} {{ end }} + {{ $pubs := partial "publications-list.html" . }}

{{ .Title }}

@@ -32,15 +33,30 @@

{{ .Title }}

Live list unavailable. We could not load the latest list during this build. Please visit openmodelingfoundation/awesome-modeling-practices directly.
+
+

OMF Publications

+ {{ $pubs }} +
{{ else with .Value }} {{ $content := string .Content }} {{ $content = replaceRE `(?m)^#\s+[^\n]+\n` "" $content }} {{ $content = replaceRE `\]\((/openmodelingfoundation/awesome-modeling-practices[^)]*)\)` "](https://github.com$1)" $content }} - + + {{ if in $content "Publications list generated dynamically on the OMF website" }} + {{ $content = replaceRE `(?m)^[\-\*]\s*Publications list generated dynamically on the OMF website\s*$` "OMF_PUBLICATIONS_LIST" $content }} + {{ end }} + + {{ if not (in $content "OMF_PUBLICATIONS_LIST") }} + {{ if in $content "## Papers" }} + {{ $content = replace $content "## Papers" "## Papers\n\nOMF_PUBLICATIONS_LIST" }} + {{ else }} + {{ $content = printf "%s\n\n## OMF Publications\n\nOMF_PUBLICATIONS_LIST" $content }} + {{ end }} + {{ end }} + {{ $html := $content | markdownify }} - - {{ $pubs := partial "publications-list.html" . }} - {{ $content = replace $content "

OMF_PUBLICATIONS_LIST

" $pubs }} + {{ $html = replace $html "

OMF_PUBLICATIONS_LIST

" $pubs }} + {{ $html = replace $html "OMF_PUBLICATIONS_LIST" $pubs }} {{/* @@ -99,12 +115,20 @@

{{ .Title }}

Live list unavailable. Please visit openmodelingfoundation/awesome-modeling-practices directly. +
+

OMF Publications

+ {{ $pubs }} +
{{ end }} {{ else }} +
+

OMF Publications

+ {{ $pubs }} +
{{ end }} {{ end }} \ No newline at end of file diff --git a/layouts/resources/publications.html b/layouts/docs/publications.html similarity index 57% rename from layouts/resources/publications.html rename to layouts/docs/publications.html index cccd24a4..139dcf96 100644 --- a/layouts/resources/publications.html +++ b/layouts/docs/publications.html @@ -7,10 +7,10 @@

{{ .Title }}

{{ end }}

- Download the bibliography database: - publications.bib + Download the bibliography database as BibTeX: + publications.bib

{{ partial "publications-list.html" . }} -{{ end }} \ No newline at end of file +{{ end }} diff --git a/layouts/partials/publications-list.html b/layouts/partials/publications-list.html index d7895011..0e660b76 100644 --- a/layouts/partials/publications-list.html +++ b/layouts/partials/publications-list.html @@ -1,26 +1,111 @@ -
    -{{ range site.Data.publications }} -
  • - {{ range $index, $author := .author }} - {{ if $index }}, {{ end }} - {{ $author.family }}, {{ $author.given }} - {{ end }} - ({{ index (index .issued "date-parts") 0 0 }}). - - {{ .title }}. - - {{ index . "container-title" }}. - - {{ with .volume }}Vol. {{ . }}.{{ end }} - - {{ with .page }} pp. {{ . }}.{{ end }} - - {{ with .DOI }} - DOI: - - {{ . }} - - {{ end }} -
  • -{{ end }} -
\ No newline at end of file +{{- $bib := resources.Get "bibliographies/publications.bib" -}} + +{{- if not $bib -}} + +{{- else -}} + {{- $lines := split (string $bib.Content) "\n" -}} + {{- $publications := slice -}} + {{- $inEntry := false -}} + {{- $entry := dict -}} + {{- $fields := slice -}} + {{- $fieldMap := dict -}} + + {{- range $lines -}} + {{- $line := trim . " \t\r" -}} + + {{- if and (not $inEntry) (hasPrefix $line "@") -}} + {{- $inEntry = true -}} + {{- $fields = slice -}} + {{- $fieldMap = dict -}} + {{- $entryKey := replaceRE `^@\w+\{([^,]+),\s*$` `$1` $line -}} + {{- $entryType := lower (replaceRE `^@(\w+)\{[^,]+,\s*$` `$1` $line) -}} + {{- $entry = dict "key" $entryKey "type" $entryType -}} + + {{- else if and $inEntry (eq $line "}") -}} + {{- $entry = merge $entry (dict "fields" $fields "fieldMap" $fieldMap) -}} + {{- $publications = $publications | append $entry -}} + {{- $inEntry = false -}} + + {{- else if and $inEntry (in $line "=") -}} + {{- $fieldName := replaceRE `^([A-Za-z0-9_-]+)\s*=.*$` `$1` $line -}} + {{- $fieldValue := replaceRE `^[A-Za-z0-9_-]+\s*=\s*(.+?)\s*,?\s*$` `$1` $line -}} + {{- $fieldValue = trim $fieldValue " \t" -}} + + {{- if and (hasPrefix $fieldValue "{") (hasSuffix $fieldValue "}") -}} + {{- $fieldValue = strings.TrimPrefix "{" $fieldValue -}} + {{- $fieldValue = strings.TrimSuffix "}" $fieldValue -}} + {{- else if and (hasPrefix $fieldValue "\"") (hasSuffix $fieldValue "\"") -}} + {{- $fieldValue = strings.TrimPrefix "\"" $fieldValue -}} + {{- $fieldValue = strings.TrimSuffix "\"" $fieldValue -}} + {{- end -}} + + {{- $fields = $fields | append (dict "name" $fieldName "value" $fieldValue) -}} + {{- $fieldMap = merge $fieldMap (dict $fieldName $fieldValue) -}} + {{- end -}} + {{- end -}} + +
    + {{- range $publications }} + {{- $title := or (index .fieldMap "title") .key -}} + {{- $year := index .fieldMap "year" -}} + {{- $journal := index .fieldMap "journal" -}} + {{- $volume := index .fieldMap "volume" -}} + {{- $pages := index .fieldMap "pages" -}} + {{- $doi := index .fieldMap "doi" -}} + {{- $url := index .fieldMap "url" -}} + {{- $annotation := index .fieldMap "annotation" -}} +
  • +
    +

    {{ $title }}

    + +

    + {{- with $year }}{{ . }}{{ end -}} + {{- with $journal }}{{ . }}{{ end -}} + {{- with $volume }}Vol. {{ . }}{{ end -}} + {{- with $pages }}pp. {{ . }}{{ end -}} +

    + + {{- with $annotation -}} +

    {{ . }}

    + {{- end -}} + + + +
    + Full record +
    +
    key
    +
    {{ .key }}
    + +
    entrytype
    +
    {{ .type }}
    + + {{- range .fields -}} +
    {{ .name }}
    +
    + {{- $name := lower .name -}} + {{- if eq $name "doi" -}} + {{ .value }} + {{- else if eq $name "url" -}} + {{ .value }} + {{- else -}} + {{ .value }} + {{- end -}} +
    + {{- end -}} +
    +
    +
    +
  • + {{- end }} +
+{{- end -}} \ No newline at end of file From 861da850bae85d946e3f2efb9493206cb8ec24f3 Mon Sep 17 00:00:00 2001 From: Allen Lee Date: Thu, 21 May 2026 23:57:59 -0700 Subject: [PATCH 4/6] refactor: sort by year descending + ui refinement --- .agent/working-memory/session.md | 15 ++++++++++++- content/en/resources/publications.md | 4 ++-- layouts/docs/awesome-list.html | 16 ++++--------- layouts/docs/publications.html | 2 +- layouts/partials/publications-list.html | 30 +++++++++++++++++-------- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/.agent/working-memory/session.md b/.agent/working-memory/session.md index aadcb4f1..087e11e7 100644 --- a/.agent/working-memory/session.md +++ b/.agent/working-memory/session.md @@ -5,10 +5,23 @@ - Publications pipeline is now BibTeX-driven from `assets/bibliographies/publications.bib`. - Publications rendering is shared via `layouts/partials/publications-list.html` and consumed by both publications and awesome pages. - Awesome page inserts publications in the `Papers` section and uses fallback rendering when remote README fetch fails. -- Next step on request: commit-ready QA and final content/link review. +- Publications are sorted by year descending and BibTeX brace/escape cleanup is applied for display text. +- Next step on request: finalize commit scope and commit message. ## Notes by date (newest first) +### 2026-05-22 (sync pass) + +- Rendering consistency refinements completed: + - Awesome fallback markup deduplicated in `layouts/docs/awesome-list.html`. + - Fallback section title aligned to `Papers` for content consistency. + - Empty metadata link rows removed when DOI/URL are absent. +- Bibliography output quality updates: + - Publications sorted by year descending in `layouts/partials/publications-list.html`. + - Curly brace artifacts removed from rendered BibTeX values and common escaped symbols normalized. +- Validation: + - Containerized production build path (`.github/scripts/build-site.sh`) passed after each update. + ### 2026-05-22 - Synced publications architecture: diff --git a/content/en/resources/publications.md b/content/en/resources/publications.md index e1a505c9..ea3666d4 100644 --- a/content/en/resources/publications.md +++ b/content/en/resources/publications.md @@ -1,8 +1,8 @@ --- title: "Publications" -description: "Published artifacts from OMF activities (reports, manuscripts, preprints, publications)." +description: "Published artifacts from OMF activities (reports, manuscripts, preprints, publications) and core references." layout: "publications" weight: 20 --- -The publications list is generated dynamically from the OMF bibliography database. \ No newline at end of file +This publications list is generated dynamically from the OMF bibliography database. \ No newline at end of file diff --git a/layouts/docs/awesome-list.html b/layouts/docs/awesome-list.html index 45930819..168a1a60 100644 --- a/layouts/docs/awesome-list.html +++ b/layouts/docs/awesome-list.html @@ -10,6 +10,7 @@ {{ $buildTimestamp = time . }} {{ end }} {{ $pubs := partial "publications-list.html" . }} + {{ $pubsFallback := printf "

Papers

%s
" $pubs | safeHTML }}

{{ .Title }}

@@ -33,10 +34,7 @@

{{ .Title }}

Live list unavailable. We could not load the latest list during this build. Please visit openmodelingfoundation/awesome-modeling-practices directly.
-
-

OMF Publications

- {{ $pubs }} -
+ {{ $pubsFallback }} {{ else with .Value }} {{ $content := string .Content }} {{ $content = replaceRE `(?m)^#\s+[^\n]+\n` "" $content }} @@ -115,20 +113,14 @@

OMF Publications

Live list unavailable. Please visit openmodelingfoundation/awesome-modeling-practices directly. -
-

OMF Publications

- {{ $pubs }} -
+ {{ $pubsFallback }} {{ end }} {{ else }} -
-

OMF Publications

- {{ $pubs }} -
+ {{ $pubsFallback }} {{ end }} {{ end }} \ No newline at end of file diff --git a/layouts/docs/publications.html b/layouts/docs/publications.html index 139dcf96..82cbbeb3 100644 --- a/layouts/docs/publications.html +++ b/layouts/docs/publications.html @@ -7,7 +7,7 @@

{{ .Title }}

{{ end }}

- Download the bibliography database as BibTeX: + Download all references in BibTeX: publications.bib

diff --git a/layouts/partials/publications-list.html b/layouts/partials/publications-list.html index 0e660b76..67f2c661 100644 --- a/layouts/partials/publications-list.html +++ b/layouts/partials/publications-list.html @@ -24,7 +24,13 @@ {{- $entry = dict "key" $entryKey "type" $entryType -}} {{- else if and $inEntry (eq $line "}") -}} - {{- $entry = merge $entry (dict "fields" $fields "fieldMap" $fieldMap) -}} + {{- $yearRaw := printf "%v" (index $fieldMap "year") -}} + {{- $yearDigits := replaceRE `[^0-9]` "" $yearRaw -}} + {{- $sortYear := 0 -}} + {{- if ne $yearDigits "" -}} + {{- $sortYear = int $yearDigits -}} + {{- end -}} + {{- $entry = merge $entry (dict "fields" $fields "fieldMap" $fieldMap "sortYear" $sortYear) -}} {{- $publications = $publications | append $entry -}} {{- $inEntry = false -}} @@ -41,11 +47,18 @@ {{- $fieldValue = strings.TrimSuffix "\"" $fieldValue -}} {{- end -}} + {{- /* BibTeX uses braces for case protection/grouping and backslash escapes for symbols. */ -}} + {{- $fieldValue = replace $fieldValue "{" "" -}} + {{- $fieldValue = replace $fieldValue "}" "" -}} + {{- $fieldValue = replaceRE `\\([&%_$#])` `$1` $fieldValue -}} + {{- $fields = $fields | append (dict "name" $fieldName "value" $fieldValue) -}} {{- $fieldMap = merge $fieldMap (dict $fieldName $fieldValue) -}} {{- end -}} {{- end -}} + {{- $publications = sort $publications "sortYear" "desc" -}} +
    {{- range $publications }} {{- $title := or (index .fieldMap "title") .key -}} @@ -71,14 +84,13 @@

    {{ $title }}

    {{ . }}

    {{- end -}} - + {{- if or $doi $url -}} + + {{- end -}}
    Full record From 388bebb43a59ca9537f6220d27a0752ae25583b2 Mon Sep 17 00:00:00 2001 From: Allen Lee Date: Fri, 22 May 2026 12:08:49 -0700 Subject: [PATCH 5/6] refactor: extract rewrite/sanitize logic to partial simplify awesome-list.html and extract hairy regex rewrites and sanitization into the `render-remote-readme` partial --- .agent/working-memory/session.md | 21 +++- AGENTS.md | 1 + Makefile | 15 ++- layouts/docs/awesome-list.html | 108 ++++----------------- layouts/partials/render-remote-readme.html | 101 +++++++++++++++++++ 5 files changed, 155 insertions(+), 91 deletions(-) create mode 100644 layouts/partials/render-remote-readme.html diff --git a/.agent/working-memory/session.md b/.agent/working-memory/session.md index 087e11e7..ea2fe6b7 100644 --- a/.agent/working-memory/session.md +++ b/.agent/working-memory/session.md @@ -6,10 +6,29 @@ - Publications rendering is shared via `layouts/partials/publications-list.html` and consumed by both publications and awesome pages. - Awesome page inserts publications in the `Papers` section and uses fallback rendering when remote README fetch fails. - Publications are sorted by year descending and BibTeX brace/escape cleanup is applied for display text. -- Next step on request: finalize commit scope and commit message. +- Remote README helper partial now uses a single return statement while preserving the warning/rendered payload contract. +- Isolated containerized build validation passed (`hugo build --gc --minify --cacheDir /tmp/.hugo_cache -d /tmp/public --noBuildLock`) in ~23s. +- Next step on request: finalize scoped commit prep. ## Notes by date (newest first) +### 2026-05-22 (cleanup + docs sync) + +- Cleanup pass: + - Scanned repository for common stale artifacts (`*.bak`, `*.orig`, `*.tmp`, `*.swp`, `*~`, `.DS_Store`, `Thumbs.db`). + - No unnecessary temporary/backup files found. +- Agent docs sync: + - Updated working-memory active task and status after single-return refactor in `layouts/partials/render-remote-readme.html`. + - Updated latest checkpoint scope to reflect current state. +- Validation status: + - Template diagnostics remain clean for: + - `layouts/partials/render-remote-readme.html` + - `layouts/docs/awesome-list.html` + - Isolated containerized build re-validation passed: + - Command: `docker run --rm --entrypoint sh -v "$PWD":/workspace:ro -w /tmp openmodelingfoundation/omf:latest -lc 'cp -a /workspace /tmp/src && git config --global --add safe.directory /tmp/src && cd /tmp/src && hugo build --gc --minify --cacheDir /tmp/.hugo_cache -d /tmp/public --noBuildLock'` + - Result: success (exit 0), total ~23s. + - Residual warnings: Hugo deprecations (`.Language.LanguageDirection`, `.Site.AllPages`) from theme/template code. + ### 2026-05-22 (sync pass) - Rendering consistency refinements completed: diff --git a/AGENTS.md b/AGENTS.md index 283ecb48..4b26c307 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,6 +34,7 @@ Agent-generated artifacts must be written under `.agent/`. - Use Docker Compose with the `hugo` service for build/test/update tasks (for example: `docker compose run --rm --no-deps --entrypoint sh hugo -c ''`). - Prefer the shared Hugo production build entrypoint `.github/scripts/build-site.sh` for render operations used by CI and local production-style checks. - Use `make render` for the local production-style render path and `make serve` for local hot-reload preview. +- Use `make render-site-isolated` when another local Hugo container/session is running or host lock/permission conflicts are present; this runs in a one-off isolated container workspace and reuses the host cache directory `.hugo_cache` for module/cache reuse. - If a command cannot run in the current container setup, document the limitation and propose a container-based alternative. ## Artifact guidance diff --git a/Makefile b/Makefile index 3eb9ac57..cee573b2 100644 --- a/Makefile +++ b/Makefile @@ -9,13 +9,16 @@ GID=$(shell id -g) DOCKER_COMPOSE=docker compose HUGO_SERVICE=hugo HUGO_RUN_SH=$(DOCKER_COMPOSE) run --rm --no-deps --entrypoint sh +HUGO_IMAGE=openmodelingfoundation/omf:latest HUGO_CACHE_CONTAINER_DIR ?= /src/.hugo_cache +HUGO_ISOLATED_CACHE_HOST_DIR ?= $(CURDIR)/.hugo_cache +HUGO_ISOLATED_CACHE_CONTAINER_DIR ?= /tmp/.hugo_cache RENDER_OUTPUT_DIR ?= /src/public RENDER_BASE_URL ?= HUGO_USER_ENV=--user "$(UID):$(GID)" -e HOME=/tmp -e npm_config_cache=/tmp/.npm # Controls -.PHONY : all commands build clean stop serve render render-site shell +.PHONY : all commands build clean stop serve render render-site render-site-isolated shell all : commands ## commands : show all commands. @@ -43,6 +46,16 @@ render-site : build -e BASE_URL="$(RENDER_BASE_URL)" \ $(HUGO_SERVICE) -c '.github/scripts/build-site.sh' +## render-site-isolated : run production-style render in isolated container workspace with persistent cache. +render-site-isolated : build + @mkdir -p "$(HUGO_ISOLATED_CACHE_HOST_DIR)" + docker run --rm --entrypoint sh \ + -v "$(CURDIR)":/workspace:ro \ + -v "$(HUGO_ISOLATED_CACHE_HOST_DIR)":"$(HUGO_ISOLATED_CACHE_CONTAINER_DIR)":rw \ + -w /tmp \ + $(HUGO_IMAGE) \ + -lc 'cp -a /workspace /tmp/src && git config --global --add safe.directory /tmp/src && cd /tmp/src && hugo build --gc --minify --cacheDir "$(HUGO_ISOLATED_CACHE_CONTAINER_DIR)" -d /tmp/public --noBuildLock' + ## shell : open a hugo shell shell : build $(DOCKER_COMPOSE) run --rm --no-deps $(HUGO_SERVICE) shell diff --git a/layouts/docs/awesome-list.html b/layouts/docs/awesome-list.html index 168a1a60..f7cbe3b9 100644 --- a/layouts/docs/awesome-list.html +++ b/layouts/docs/awesome-list.html @@ -28,98 +28,28 @@

    {{ .Title }}

    - {{ with try (resources.GetRemote $rawURL $opts) }} - {{ with .Err }} - - {{ $pubsFallback }} - {{ else with .Value }} - {{ $content := string .Content }} - {{ $content = replaceRE `(?m)^#\s+[^\n]+\n` "" $content }} - {{ $content = replaceRE `\]\((/openmodelingfoundation/awesome-modeling-practices[^)]*)\)` "](https://github.com$1)" $content }} - - {{ if in $content "Publications list generated dynamically on the OMF website" }} - {{ $content = replaceRE `(?m)^[\-\*]\s*Publications list generated dynamically on the OMF website\s*$` "OMF_PUBLICATIONS_LIST" $content }} - {{ end }} - - {{ if not (in $content "OMF_PUBLICATIONS_LIST") }} - {{ if in $content "## Papers" }} - {{ $content = replace $content "## Papers" "## Papers\n\nOMF_PUBLICATIONS_LIST" }} - {{ else }} - {{ $content = printf "%s\n\n## OMF Publications\n\nOMF_PUBLICATIONS_LIST" $content }} - {{ end }} - {{ end }} - - {{ $html := $content | markdownify }} - {{ $html = replace $html "

    OMF_PUBLICATIONS_LIST

    " $pubs }} - {{ $html = replace $html "OMF_PUBLICATIONS_LIST" $pubs }} - - - {{/* - Content handling policy (intentional lightweight processing): - - Rewritten: - - Repo-root href values like /openmodelingfoundation/awesome-modeling-practices... - to full github.com links. - - Relative href values (/, ./, ../, and bare relative paths) to $blobRoot. - - Relative src values (/, ./, ../, and bare relative paths) to $rawRoot. - - javascript: href/src URLs to safe no-op (#). - - Sanitized: - - Removes high-risk tag blocks: script, iframe, object, embed, form, style. - - Removes standalone interactive/metadata tags: input, button, textarea, - select, meta, link. - - Removes inline event handlers (onclick, onload, etc.). - - Left untouched: - - Absolute links (http:, https:, mailto:, tel:). - - Fragment-only links (#...). - - Markdown semantics/content structure not related to URL rewriting. - - Advanced HTML sanitization beyond these patterns (this is intentionally - trust-based because OMF controls the upstream repository). - */}} - {{/* Lightweight sanitization for remote HTML blocks and URL protocols. */}} - {{ $html = replaceRE `(?is)]*)?>.*?` "" $html }} - {{ $html = replaceRE `(?is)]*)?>.*?` "" $html }} - {{ $html = replaceRE `(?is)]*)?>.*?` "" $html }} - {{ $html = replaceRE `(?is)]*)?>.*?` "" $html }} - {{ $html = replaceRE `(?is)]*)?>.*?` "" $html }} - {{ $html = replaceRE `(?is)]*)?>.*?` "" $html }} - {{ $html = replaceRE `(?is)<(?:input|button|textarea|select|meta|link)(?:\s[^>]*)?/?>` "" $html }} - {{ $html = replaceRE `(?i)\s+on[a-z]+\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)` "" $html }} - {{ $html = replaceRE `(?i)\s+style\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)` "" $html }} - {{ $html = replaceRE `(?i)(href|src|xlink:href|formaction|poster)\s*=\s*"\s*(?:javascript|vbscript|data)\s*:[^"]*"` `$1="#"` $html }} - {{ $html = replaceRE `(?i)(href|src|xlink:href|formaction|poster)\s*=\s*'\s*(?:javascript|vbscript|data)\s*:[^']*'` `$1='#'` $html }} - {{ $html = replaceRE `(?i)(href|src|xlink:href|formaction|poster)\s*=\s*(?:javascript|vbscript|data)\s*:[^\s>]+` `$1="#"` $html }} - - {{/* Rewrite relative links after Markdown rendering for better GitHub parity. */}} - {{ $html = replaceRE `href="/openmodelingfoundation/awesome-modeling-practices([^"]*)"` `href="https://github.com/openmodelingfoundation/awesome-modeling-practices$1"` $html }} - {{ $html = replaceRE `href="/([^"][^"]*)"` `href="https://github.com/openmodelingfoundation/awesome-modeling-practices/blob/main/$1"` $html }} - {{ $html = replaceRE `href="\./([^"]+)"` (printf `href="%s$1"` $blobRoot) $html }} - {{ $html = replaceRE `href="\.\./([^"]+)"` (printf `href="%s../$1"` $blobRoot) $html }} - {{ $html = replaceRE `href="([A-Za-z0-9][^":#]*)"` (printf `href="%s$1"` $blobRoot) $html }} - {{ $html = replaceRE `src="/([^"]+)"` `src="https://raw.githubusercontent.com/openmodelingfoundation/awesome-modeling-practices/main/$1"` $html }} - {{ $html = replaceRE `src="\./([^"]+)"` (printf `src="%s$1"` $rawRoot) $html }} - {{ $html = replaceRE `src="\.\./([^"]+)"` (printf `src="%s../$1"` $rawRoot) $html }} - {{ $html = replaceRE `src="([A-Za-z0-9][^":#]*)"` (printf `src="%s$1"` $rawRoot) $html }} - -
    - {{ $html | safeHTML }} -
    - {{ else }} - - {{ $pubsFallback }} - {{ end }} - {{ else }} + {{ $remote := partial "render-remote-readme.html" (dict + "sourceRepo" $sourceRepo + "rawURL" $rawURL + "blobRoot" $blobRoot + "rawRoot" $rawRoot + "opts" $opts + "pubs" $pubs + )}} + {{ $warning := $remote.warning }} + {{ $rendered := $remote.rendered }} + {{ if ne $warning "" }} + {{ end }} + + {{ if ne $rendered "" }} +
    + {{ $rendered | safeHTML }} +
    + {{ else }} {{ $pubsFallback }} {{ end }} diff --git a/layouts/partials/render-remote-readme.html b/layouts/partials/render-remote-readme.html new file mode 100644 index 00000000..cc6f3c37 --- /dev/null +++ b/layouts/partials/render-remote-readme.html @@ -0,0 +1,101 @@ +{{- $sourceRepo := .sourceRepo -}} +{{- $rawURL := .rawURL -}} +{{- $blobRoot := .blobRoot -}} +{{- $rawRoot := .rawRoot -}} +{{- $opts := .opts -}} +{{- $pubs := .pubs -}} + +{{- $warningMsg := "Live list unavailable. Please visit the source repository directly." -}} +{{- $marker := "OMF_PUBLICATIONS_LIST" -}} +{{- $warning := $warningMsg -}} +{{- $rendered := "" -}} + + +{{- $remote := try (resources.GetRemote $rawURL $opts) -}} +{{- if and $remote (not $remote.Err) -}} + {{- with $remote.Value -}} + {{- $content := string .Content -}} + + {{- $content = replaceRE `(?m)^#\s+[^\n]+\n` "" $content -}} + {{- $content = replaceRE `\]\((/openmodelingfoundation/awesome-modeling-practices[^)]*)\)` "](https://github.com$1)" $content -}} + + {{- if in $content "Publications list generated dynamically on the OMF website" -}} + {{- $content = replaceRE `(?m)^[\-\*]\s*Publications list generated dynamically on the OMF website\s*$` $marker $content -}} + {{- end -}} + + {{- if not (in $content $marker) -}} + {{- if in $content "## Papers" -}} + {{- $content = replace $content "## Papers" (printf "## Papers\n\n%s" $marker) -}} + {{- else -}} + {{- $content = printf "%s\n\n## OMF Publications\n\n%s" $content $marker -}} + {{- end -}} + {{- end -}} + + {{- $html := $content | markdownify -}} + {{- $html = replace $html (printf "

    %s

    " $marker) $pubs -}} + {{- $html = replace $html $marker $pubs -}} + + {{/* + Sanitize potentially unsafe embedded HTML from the upstream README. + + Removes: + - Active content tags (` "replacement" "") + (dict "pattern" `(?is)]*)?>.*?` "replacement" "") + (dict "pattern" `(?is)]*)?>.*?` "replacement" "") + (dict "pattern" `(?is)]*)?>.*?` "replacement" "") + (dict "pattern" `(?is)]*)?>.*?` "replacement" "") + (dict "pattern" `(?is)]*)?>.*?` "replacement" "") + (dict "pattern" `(?is)<(?:input|button|textarea|select|meta|link)(?:\s[^>]*)?/?>` "replacement" "") + (dict "pattern" `(?i)\s+on[a-z]+\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)` "replacement" "") + (dict "pattern" `(?i)\s+style\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)` "replacement" "") + (dict "pattern" `(?i)(href|src|xlink:href|formaction|poster)\s*=\s*"\s*(?:javascript|vbscript|data)\s*:[^"]*"` "replacement" `$1="#"`) + (dict "pattern" `(?i)(href|src|xlink:href|formaction|poster)\s*=\s*'\s*(?:javascript|vbscript|data)\s*:[^']*'` "replacement" `$1='#'`) + (dict "pattern" `(?i)(href|src|xlink:href|formaction|poster)\s*=\s*(?:javascript|vbscript|data)\s*:[^\s>]+` "replacement" `$1="#"`) + -}} + {{- range $sanitizers -}} + {{- $html = replaceRE .pattern .replacement $html -}} + {{- end -}} + + {{/* + Rewrite relative GitHub-style links after markdown rendering. + + Converts: + - Repo-relative links (/path) -> GitHub blob/raw URLs + - Relative paths (./foo, ../foo, foo/bar) -> absolute URLs + - Image src paths -> raw.githubusercontent.com URLs + + Leaves untouched: + - Absolute URLs (https:, mailto:, tel:) + - Fragment links (#section) + */}} + + {{- $rewrites := slice + (dict "pattern" `href="/openmodelingfoundation/awesome-modeling-practices([^"]*)"` "replacement" (printf `href="%s$1"` $sourceRepo)) + (dict "pattern" `href="/([^"][^"]*)"` "replacement" (printf `href="%s/blob/main/$1"` $sourceRepo)) + (dict "pattern" `href="\./([^"]+)"` "replacement" (printf `href="%s$1"` $blobRoot)) + (dict "pattern" `href="\.\./([^"]+)"` "replacement" (printf `href="%s../$1"` $blobRoot)) + (dict "pattern" `href="([A-Za-z0-9][^":#]*)"` "replacement" (printf `href="%s$1"` $blobRoot)) + (dict "pattern" `src="/([^"]+)"` "replacement" (printf `src="%s$1"` $rawRoot)) + (dict "pattern" `src="\./([^"]+)"` "replacement" (printf `src="%s$1"` $rawRoot)) + (dict "pattern" `src="\.\./([^"]+)"` "replacement" (printf `src="%s../$1"` $rawRoot)) + (dict "pattern" `src="([A-Za-z0-9][^":#]*)"` "replacement" (printf `src="%s$1"` $rawRoot)) + -}} + {{- range $rewrites -}} + {{- $html = replaceRE .pattern .replacement $html -}} + {{- end -}} + {{- $rendered = $html -}} + {{- $warning = "" -}} + {{- end -}} +{{- end -}} + +{{- return (dict "warning" $warning "rendered" $rendered) -}} From b08692e815da7ccd67e96435f03c895a9f7edf50 Mon Sep 17 00:00:00 2001 From: Allen Lee Date: Fri, 22 May 2026 17:47:19 -0700 Subject: [PATCH 6/6] feat: refactor bibtex pipeline add minimalist Python script with bibtexparser to transform bibtex to json in `data/publications.json` for a more maintainable hugo partial --- .agent/working-memory/session.md | 18 ++- .dockerignore | 6 +- .github/scripts/bibtex_to_json.py | 207 ++++++++++++++++++++++++ .github/workflows/gh-pages.yml | 25 ++- .gitignore | 1 + AGENTS.md | 4 + Dockerfile | 58 +++++-- Makefile | 8 +- data/.gitignore | 0 layouts/partials/publications-list.html | 187 +++++++++------------ 10 files changed, 376 insertions(+), 138 deletions(-) create mode 100755 .github/scripts/bibtex_to_json.py create mode 100644 data/.gitignore diff --git a/.agent/working-memory/session.md b/.agent/working-memory/session.md index ea2fe6b7..715d6402 100644 --- a/.agent/working-memory/session.md +++ b/.agent/working-memory/session.md @@ -7,11 +7,25 @@ - Awesome page inserts publications in the `Papers` section and uses fallback rendering when remote README fetch fails. - Publications are sorted by year descending and BibTeX brace/escape cleanup is applied for display text. - Remote README helper partial now uses a single return statement while preserving the warning/rendered payload contract. -- Isolated containerized build validation passed (`hugo build --gc --minify --cacheDir /tmp/.hugo_cache -d /tmp/public --noBuildLock`) in ~23s. -- Next step on request: finalize scoped commit prep. +- Cleanup + formatting/linting pass completed with containerized validations. +- Shared production build entrypoint (`.github/scripts/build-site.sh`) passed with writable cache override. +- Next step on request: stage/commit the intended documentation and generated JSON updates. ## Notes by date (newest first) +### 2026-05-23 (cleanup + formatting/lint pass) + +- Cleanup pass: + - Scanned repository for common stale artifacts (`*.bak`, `*.orig`, `*.rej`, `*.tmp`, `*.swp`, `*~`, `.DS_Store`, `Thumbs.db`). + - No stale artifacts were found. +- Formatting/linting pass: + - Publications template was kept in formatted state (`layouts/partials/publications-list.html`). + - Regenerated bibliography data with `.github/scripts/bibtex_to_json.py` to ensure `data/publications.json` is current. + - Executed `.github/scripts/build-site.sh` in the Hugo container as a production-style lint gate. +- Validation status: + - Build completed successfully after setting writable cache/output env vars and clearing a stale lock file. + - Residual non-blocking Hugo deprecation warnings persist (`.Language.LanguageDirection`, `.Site.AllPages`, `.Site.Data`). + ### 2026-05-22 (cleanup + docs sync) - Cleanup pass: diff --git a/.dockerignore b/.dockerignore index fe4519dd..db514b4c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,10 +1,10 @@ ### JS ### -node_modules +node_modules/ ### Hugo ### # Generated files by hugo -/public/ -/resources/_gen/ +public/ +resources/ .hugo_build.lock ### git things diff --git a/.github/scripts/bibtex_to_json.py b/.github/scripts/bibtex_to_json.py new file mode 100755 index 00000000..2d0c97f7 --- /dev/null +++ b/.github/scripts/bibtex_to_json.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python3 +"""Convert a BibTeX bibliography into Hugo-friendly JSON. + +This script is intentionally small and deterministic: +- parse the input BibTeX file with bibtexparser +- normalize each entry into plain JSON data +- sort entries by year descending, then key ascending +- write the result to the requested output path + +The output structure is a JSON array of objects with keys: +- key +- type +- sortYear +- fields +- fieldMap +""" + +from __future__ import annotations + +import argparse +import json +import re +import sys +from dataclasses import dataclass +from pathlib import Path +from typing import Any, Iterable + +import bibtexparser + +_FIELD_CLEANUP_RE = re.compile(r"\\([&%_$#])") + + +@dataclass(frozen=True) +class NormalizedField: + name: str + value: str + + +@dataclass(frozen=True) +class NormalizedEntry: + key: str + entry_type: str + sort_year: int + fields: list[NormalizedField] + field_map: dict[str, str] + author_list: list[str] + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Convert a BibTeX bibliography into Hugo data JSON." + ) + parser.add_argument( + "--input", + required=True, + type=Path, + help="Path to the source .bib file.", + ) + parser.add_argument( + "--output", + required=True, + type=Path, + help="Path to the JSON file to write.", + ) + return parser.parse_args() + + +def normalize_author_name(name: str) -> str: + """Convert 'Family, Given' BibTeX names to 'Given Family'.""" + name = name.strip() + + if "," not in name: + return name + + parts = [part.strip() for part in name.split(",")] + + # BibTeX supports: + # Family, Given + # Family, Jr, Given + if len(parts) == 2: + family, given = parts + return f"{given} {family}" + + if len(parts) >= 3: + family, jr, given = parts[:3] + return f"{given} {family}, {jr}" + + return name + + +def split_author_list(value: str) -> list[str]: + """Split and normalize BibTeX author strings.""" + return [ + normalize_author_name(item) + for item in re.split(r"\s+and\s+", value) + if item.strip() + ] + + +def normalize_bibtex_value(value: Any) -> str: + """Convert a BibTeX field value to a display-friendly string.""" + text = str(value).strip() + if not text: + return "" + + # Remove one layer of balanced braces or quotes. + if len(text) >= 2: + if text.startswith("{") and text.endswith("}"): + text = text[1:-1].strip() + elif text.startswith('"') and text.endswith('"'): + text = text[1:-1].strip() + + # BibTeX often uses braces for grouping and backslashes for symbol escapes. + text = text.replace("{", "").replace("}", "") + text = _FIELD_CLEANUP_RE.sub(r"\1", text) + return text.strip() + + +def field_value(entry: Any, name: str) -> str: + field = entry.fields_dict.get(name) + if field is None: + return "" + return normalize_bibtex_value(field.value) + + +def infer_sort_year(entry: Any) -> int: + year_text = field_value(entry, "year") + match = re.search(r"\d{4}", year_text) + return int(match.group(0)) if match else 0 + + +def normalize_entry(entry: Any) -> NormalizedEntry: + fields: list[NormalizedField] = [] + field_map: dict[str, str] = {} + + # Preserve BibTeX field order for the details view. + for field in entry.fields: + value = normalize_bibtex_value(field.value) + fields.append(NormalizedField(name=str(field.key), value=value)) + field_map[str(field.key)] = value + + return NormalizedEntry( + key=str(entry.key), + entry_type=str(entry.entry_type).lower(), + sort_year=infer_sort_year(entry), + fields=fields, + field_map=field_map, + author_list=split_author_list(field_map.get("author", "")), + ) + + +def parse_bibtex(path: Path) -> list[NormalizedEntry]: + bibtex_text = path.read_text(encoding="utf-8") + library = bibtexparser.parse_string(bibtex_text) + + failed_blocks = getattr(library, "failed_blocks", []) + if failed_blocks: + print( + f"warning: {len(failed_blocks)} BibTeX block(s) failed to parse", + file=sys.stderr, + ) + + entries = [normalize_entry(entry) for entry in getattr(library, "entries", [])] + entries.sort(key=lambda item: (-item.sort_year, item.key.lower())) + return entries + + +def write_json(entries: Iterable[NormalizedEntry], path: Path) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + data = [ + { + "key": entry.key, + "type": entry.entry_type, + "sortYear": entry.sort_year, + "fields": [ + {"name": field.name, "value": field.value} for field in entry.fields + ], + "fieldMap": entry.field_map, + **({"authorList": entry.author_list} if entry.author_list else {}), + } + for entry in entries + ] + path.write_text( + json.dumps(data, indent=2, ensure_ascii=False) + "\n", + encoding="utf-8", + ) + + +def main() -> int: + args = parse_args() + + if not args.input.exists(): + print(f"error: input file not found: {args.input}", file=sys.stderr) + return 2 + + try: + entries = parse_bibtex(args.input) + write_json(entries, args.output) + except Exception as exc: # pragma: no cover - fail fast with context. + print(f"error: failed to convert BibTeX to JSON: {exc}", file=sys.stderr) + return 1 + + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 31bffa9c..844949d5 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -6,13 +6,11 @@ on: - develop workflow_dispatch: -# Required for GitHub Pages OIDC deployment permissions: contents: read pages: write id-token: write -# Allow only one concurrent deployment; queue the next, cancel any in-between concurrency: group: pages cancel-in-progress: false @@ -29,13 +27,26 @@ jobs: HUGO_CACHE_CONTAINER_DIR: /src/.hugo_cache steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: - fetch-depth: 0 # full history for Hugo .GitInfo / .Lastmod + fetch-depth: 0 - name: Setup Pages id: pages - uses: actions/configure-pages@v5 + uses: actions/configure-pages@v6 + + - name: Setup uv + uses: astral-sh/setup-uv@v8.1.0 + + - name: Install BibTeX parser + run: uv pip install --system bibtexparser + + - name: Generate Hugo data from BibTeX + run: | + mkdir -p data + python .github/scripts/bibtex_to_json.py \ + --input assets/bibliographies/publications.bib \ + --output data/publications.json - name: Restore build cache uses: actions/cache/restore@v4 @@ -67,7 +78,7 @@ jobs: key: hugo-${{ runner.os }}-${{ github.run_id }} - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v5 with: path: ./public @@ -80,4 +91,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@v5 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 10a14655..6d640f25 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ node_modules .hugo_build.lock /.hugo_cache/ /dist/ +data/publications.json # Executable may be added to repository hugo.exe diff --git a/AGENTS.md b/AGENTS.md index 4b26c307..40cf6ef7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -27,6 +27,7 @@ Agent-generated artifacts must be written under `.agent/`. 2. Record in-progress context in `.agent/working-memory/session.md`. 3. For long tasks, save progress snapshots in `.agent/checkpoints/`. 4. Before pausing or transferring work, create a handoff in `.agent/handoffs/`. +5. When a user requests a cleanup pass, review and update this file (`AGENTS.md`) as part of that pass, even if the update is only a brief synchronization note. ## Command execution environment @@ -34,6 +35,7 @@ Agent-generated artifacts must be written under `.agent/`. - Use Docker Compose with the `hugo` service for build/test/update tasks (for example: `docker compose run --rm --no-deps --entrypoint sh hugo -c ''`). - Prefer the shared Hugo production build entrypoint `.github/scripts/build-site.sh` for render operations used by CI and local production-style checks. - Use `make render` for the local production-style render path and `make serve` for local hot-reload preview. +- Use `make publications-json` to regenerate `data/publications.json` from `assets/bibliographies/publications.bib` when bibliography data changes. - Use `make render-site-isolated` when another local Hugo container/session is running or host lock/permission conflicts are present; this runs in a one-off isolated container workspace and reuses the host cache directory `.hugo_cache` for module/cache reuse. - If a command cannot run in the current container setup, document the limitation and propose a container-based alternative. @@ -47,6 +49,8 @@ Agent-generated artifacts must be written under `.agent/`. ## Important dependency versions - Hugo (Docker build arg): `0.161.1` (`Dockerfile`) +- UV (Docker build arg): `0.11.16` (`Dockerfile`) +- BibTeX parser floor (Docker build arg): `2.0.0b9` (`Dockerfile`) - Docsy module: `v0.14.3` (`go.mod` and `Dockerfile`) - Go toolchain declaration: `1.18` (`go.mod`) - npm package manifest version: `1.0.0` (`package.json`) diff --git a/Dockerfile b/Dockerfile index e7620680..9292bcf2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,28 +1,62 @@ +# syntax=docker/dockerfile:1.7 + ARG HUGO_VERSION=v0.161.1 -FROM ghcr.io/gohugoio/hugo:${HUGO_VERSION} +ARG UV_VERSION=0.11.16 +ARG BIBTEX_VERSION=2.0.0b9 + +# Stage 1: preprocess BibTeX into Hugo data. +FROM ghcr.io/astral-sh/uv:${UV_VERSION} AS uv + +FROM python:3.12-alpine AS bibtex-builder +COPY --from=uv /uv /uvx /bin/ +ARG BIBTEX_VERSION + +WORKDIR /work + +# Only copy what the preprocessing step needs. +COPY assets/bibliographies/publications.bib ./publications.bib +COPY .github/scripts/bibtex_to_json.py ./scripts/bibtex_to_json.py + +RUN --mount=type=cache,target=/root/.cache/uv \ + uv pip install --system --break-system-packages "bibtexparser>=${BIBTEX_VERSION}" -ARG DOCSY_VERSION=v0.14.3 +RUN mkdir -p ./data && \ + python ./scripts/bibtex_to_json.py \ + --input ./publications.bib \ + --output ./data/publications.json +# Stage 2: local dev Hugo server. +FROM ghcr.io/gohugoio/hugo:${HUGO_VERSION} +COPY --from=uv /uv /uvx /bin/ + +ARG BIBTEX_VERSION LABEL maintainer="CoMSES Net " USER root RUN git config --global --add safe.directory /src -# Install Node.js and npm for PostCSS (required by Docsy) -RUN apk add --no-cache nodejs npm go +# Install Node.js/npm for PostCSS, Go, and Python for repo maintenance scripts. +RUN apk add --no-cache nodejs npm go python3 + +# Install Python dependencies used by repository scripts. +RUN --mount=type=cache,target=/root/.cache/uv \ + uv pip install --system --break-system-packages "bibtexparser>=${BIBTEX_VERSION}" # Install front-end tooling. -# Layer is invalidated only when package.json or package-lock.json changes. -# The BuildKit cache mount keeps the npm download cache across rebuilds so -# packages are never re-fetched from the network unnecessarily. COPY package.json package-lock.json /tmp/ RUN --mount=type=cache,target=/root/.npm \ - cd /tmp && npm ci && \ - ln -sf /tmp/node_modules/.bin/postcss /usr/local/bin/postcss && \ - ln -sf /tmp/node_modules/.bin/autoprefixer /usr/local/bin/autoprefixer + cd /tmp && npm ci -ENV NODE_PATH="/tmp/node_modules" ENV PATH="/tmp/node_modules/.bin:${PATH}" -CMD ["server", "--bind", "0.0.0.0"] +WORKDIR /src + +# Copy the site source after dependency installation for better layer reuse. +COPY . . + +# Overwrite any checked-in data file with the generated one. +RUN mkdir -p /src/data +COPY --from=bibtex-builder /work/data/publications.json /src/data/publications.json + +CMD ["server", "--bind", "0.0.0.0"] \ No newline at end of file diff --git a/Makefile b/Makefile index cee573b2..9e34b539 100644 --- a/Makefile +++ b/Makefile @@ -16,9 +16,11 @@ HUGO_ISOLATED_CACHE_CONTAINER_DIR ?= /tmp/.hugo_cache RENDER_OUTPUT_DIR ?= /src/public RENDER_BASE_URL ?= HUGO_USER_ENV=--user "$(UID):$(GID)" -e HOME=/tmp -e npm_config_cache=/tmp/.npm +PUBLICATIONS_BIB_PATH ?= assets/bibliographies/publications.bib +PUBLICATIONS_JSON_PATH ?= data/publications.json # Controls -.PHONY : all commands build clean stop serve render render-site render-site-isolated shell +.PHONY : all commands build clean stop serve render render-site render-site-isolated shell publications-json all : commands ## commands : show all commands. @@ -56,6 +58,10 @@ render-site-isolated : build $(HUGO_IMAGE) \ -lc 'cp -a /workspace /tmp/src && git config --global --add safe.directory /tmp/src && cd /tmp/src && hugo build --gc --minify --cacheDir "$(HUGO_ISOLATED_CACHE_CONTAINER_DIR)" -d /tmp/public --noBuildLock' +## publications-json: generate Hugo data/publications.json from BibTeX. +publications-json : build + $(HUGO_RUN_SH) $(HUGO_USER_ENV) $(HUGO_SERVICE) -c 'python3 .github/scripts/bibtex_to_json.py --input "$(PUBLICATIONS_BIB_PATH)" --output "$(PUBLICATIONS_JSON_PATH)"' + ## shell : open a hugo shell shell : build $(DOCKER_COMPOSE) run --rm --no-deps $(HUGO_SERVICE) shell diff --git a/data/.gitignore b/data/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/layouts/partials/publications-list.html b/layouts/partials/publications-list.html index 67f2c661..16352d48 100644 --- a/layouts/partials/publications-list.html +++ b/layouts/partials/publications-list.html @@ -1,123 +1,84 @@ -{{- $bib := resources.Get "bibliographies/publications.bib" -}} +{{- $publications := .Site.Data.publications -}} -{{- if not $bib -}} +{{- if not $publications -}} {{- else -}} - {{- $lines := split (string $bib.Content) "\n" -}} - {{- $publications := slice -}} - {{- $inEntry := false -}} - {{- $entry := dict -}} - {{- $fields := slice -}} - {{- $fieldMap := dict -}} - - {{- range $lines -}} - {{- $line := trim . " \t\r" -}} - - {{- if and (not $inEntry) (hasPrefix $line "@") -}} - {{- $inEntry = true -}} - {{- $fields = slice -}} - {{- $fieldMap = dict -}} - {{- $entryKey := replaceRE `^@\w+\{([^,]+),\s*$` `$1` $line -}} - {{- $entryType := lower (replaceRE `^@(\w+)\{[^,]+,\s*$` `$1` $line) -}} - {{- $entry = dict "key" $entryKey "type" $entryType -}} - - {{- else if and $inEntry (eq $line "}") -}} - {{- $yearRaw := printf "%v" (index $fieldMap "year") -}} - {{- $yearDigits := replaceRE `[^0-9]` "" $yearRaw -}} - {{- $sortYear := 0 -}} - {{- if ne $yearDigits "" -}} - {{- $sortYear = int $yearDigits -}} - {{- end -}} - {{- $entry = merge $entry (dict "fields" $fields "fieldMap" $fieldMap "sortYear" $sortYear) -}} - {{- $publications = $publications | append $entry -}} - {{- $inEntry = false -}} - - {{- else if and $inEntry (in $line "=") -}} - {{- $fieldName := replaceRE `^([A-Za-z0-9_-]+)\s*=.*$` `$1` $line -}} - {{- $fieldValue := replaceRE `^[A-Za-z0-9_-]+\s*=\s*(.+?)\s*,?\s*$` `$1` $line -}} - {{- $fieldValue = trim $fieldValue " \t" -}} - - {{- if and (hasPrefix $fieldValue "{") (hasSuffix $fieldValue "}") -}} - {{- $fieldValue = strings.TrimPrefix "{" $fieldValue -}} - {{- $fieldValue = strings.TrimSuffix "}" $fieldValue -}} - {{- else if and (hasPrefix $fieldValue "\"") (hasSuffix $fieldValue "\"") -}} - {{- $fieldValue = strings.TrimPrefix "\"" $fieldValue -}} - {{- $fieldValue = strings.TrimSuffix "\"" $fieldValue -}} - {{- end -}} - - {{- /* BibTeX uses braces for case protection/grouping and backslash escapes for symbols. */ -}} - {{- $fieldValue = replace $fieldValue "{" "" -}} - {{- $fieldValue = replace $fieldValue "}" "" -}} - {{- $fieldValue = replaceRE `\\([&%_$#])` `$1` $fieldValue -}} - - {{- $fields = $fields | append (dict "name" $fieldName "value" $fieldValue) -}} - {{- $fieldMap = merge $fieldMap (dict $fieldName $fieldValue) -}} - {{- end -}} - {{- end -}} - - {{- $publications = sort $publications "sortYear" "desc" -}} -
      - {{- range $publications }} - {{- $title := or (index .fieldMap "title") .key -}} - {{- $year := index .fieldMap "year" -}} - {{- $journal := index .fieldMap "journal" -}} - {{- $volume := index .fieldMap "volume" -}} - {{- $pages := index .fieldMap "pages" -}} - {{- $doi := index .fieldMap "doi" -}} - {{- $url := index .fieldMap "url" -}} - {{- $annotation := index .fieldMap "annotation" -}} -
    • -
      -

      {{ $title }}

      - -

      - {{- with $year }}{{ . }}{{ end -}} - {{- with $journal }}{{ . }}{{ end -}} - {{- with $volume }}Vol. {{ . }}{{ end -}} - {{- with $pages }}pp. {{ . }}{{ end -}} -

      - - {{- with $annotation -}} -

      {{ . }}

      - {{- end -}} - - {{- if or $doi $url -}} -
    • +
      +

      {{ $title }}

      + {{- with .authorList -}} + {{- $authors := . -}} + {{- if gt (len .) 5 -}} + {{- $authors = first 5 . | append "et al." -}} + {{- end -}} +

      {{ delimit $authors ", " }}

      +{{- end -}} +

      + {{- with $year }}{{ . }}{{ end -}} + {{- with $journal }}{{ . }}{{ end -}} + {{- with $volume }}Vol. {{ . }}{{ end -}} + {{- with $pages }}pp. {{ replace . "--" "–" }}{{ end -}}

      - {{- end -}} - -
      - Full record -
      -
      key
      -
      {{ .key }}
      - -
      entrytype
      -
      {{ .type }}
      - {{- range .fields -}} -
      {{ .name }}
      -
      + {{- with $annotation }} +

      {{ . }}

      + {{- end }} + + {{- if $doi }} + + {{- else if $url }} + + {{- end }} + +
      + Full record +
      +
      key
      +
      {{ .key }}
      + +
      entry type
      +
      {{ .type }}
      + + {{- range .fields }} {{- $name := lower .name -}} - {{- if eq $name "doi" -}} - {{ .value }} - {{- else if eq $name "url" -}} - {{ .value }} - {{- else -}} - {{ .value }} - {{- end -}} -
      - {{- end -}} -
      -
      -
      -
    • - {{- end }} + {{- if not (in (slice "title" "year" "journal" "volume" "pages" "annotation") $name) }} +
      {{ .name }}
      +
      + {{- if eq $name "doi" -}} + {{ .value }} + {{- else if eq $name "url" -}} + {{ .value }} + {{- else -}} + {{ .value }} + {{- end -}} +
      + {{- end }} + {{- end }} + +
    + + + {{- end }}
{{- end -}} \ No newline at end of file