diff --git a/cms/README.md b/cms/README.md
index 32348a19e3..fd780648b8 100644
--- a/cms/README.md
+++ b/cms/README.md
@@ -177,11 +177,11 @@ frontmatter directives, then you can also import the template directly at any po
This is done by wrapping a template import directive in an HTML `
` tag (to prevent the markdown
interpreter from touching it). This is done as follows. Ensure that the import directive is formatted
-exactly as specified here. You should just change the path to the template file (`data/sponsors.html`)
+exactly as specified here. You should just change the path to the template file (`public/includes/_sponsors.html`)
to the appropriate path for the template you wish to include:
```
-
{% include "data/sponsors.html" %}
+
{% include "public/includes/_sponsors.html" %}
```
For example, to import a data template in the middle of some text:
@@ -189,7 +189,7 @@ For example, to import a data template in the middle of some text:
```
Here is some introductory text about the following data...
-
{% include "data/sponsors.html" %}
+
{% include "public/includes/_sponsors.html" %}
Wasn't that data interesting?
```
diff --git a/cms/assets/img/ambassadors/Adrian.png b/cms/assets/img/ambassadors/Adrian.png
deleted file mode 100644
index 7f1f638504..0000000000
Binary files a/cms/assets/img/ambassadors/Adrian.png and /dev/null differ
diff --git a/cms/assets/img/ambassadors/Melkamu_Beyene.JPG b/cms/assets/img/ambassadors/Melkamu_Beyene.JPG
deleted file mode 100644
index 23de7c912e..0000000000
Binary files a/cms/assets/img/ambassadors/Melkamu_Beyene.JPG and /dev/null differ
diff --git a/cms/assets/img/ambassadors/Nizameddin.jpg b/cms/assets/img/ambassadors/Nizameddin.jpg
deleted file mode 100644
index 4c499c84b9..0000000000
Binary files a/cms/assets/img/ambassadors/Nizameddin.jpg and /dev/null differ
diff --git a/cms/assets/img/ambassadors/Popova-1.jpeg b/cms/assets/img/ambassadors/Popova-1.jpeg
deleted file mode 100644
index a64630323a..0000000000
Binary files a/cms/assets/img/ambassadors/Popova-1.jpeg and /dev/null differ
diff --git a/cms/assets/img/ambassadors/foto dian ok.jpeg b/cms/assets/img/ambassadors/foto dian ok.jpeg
deleted file mode 100644
index 2d1ca22cce..0000000000
Binary files a/cms/assets/img/ambassadors/foto dian ok.jpeg and /dev/null differ
diff --git a/cms/assets/img/ambassadors/hea-lim-rhee.jpg b/cms/assets/img/ambassadors/hea-lim-rhee.jpg
deleted file mode 100644
index 41fa7f654a..0000000000
Binary files a/cms/assets/img/ambassadors/hea-lim-rhee.jpg and /dev/null differ
diff --git a/cms/assets/img/ambassadors/hyun-jung-yi.png b/cms/assets/img/ambassadors/hyun-jung-yi.png
deleted file mode 100644
index a475e9d199..0000000000
Binary files a/cms/assets/img/ambassadors/hyun-jung-yi.png and /dev/null differ
diff --git a/cms/assets/img/ambassadors/max.png b/cms/assets/img/ambassadors/max.png
deleted file mode 100644
index 87f2bf7d3b..0000000000
Binary files a/cms/assets/img/ambassadors/max.png and /dev/null differ
diff --git a/cms/assets/img/ambassadors/melkamu.JPG b/cms/assets/img/ambassadors/melkamu.JPG
new file mode 100644
index 0000000000..1dc98c0d76
Binary files /dev/null and b/cms/assets/img/ambassadors/melkamu.JPG differ
diff --git a/cms/assets/img/ambassadors/shitara.png b/cms/assets/img/ambassadors/shitara.png
deleted file mode 100644
index fcc776070a..0000000000
Binary files a/cms/assets/img/ambassadors/shitara.png and /dev/null differ
diff --git a/cms/assets/img/ambassadors/sun-huh.jpg b/cms/assets/img/ambassadors/sun-huh.jpg
deleted file mode 100644
index 28a713bc2a..0000000000
Binary files a/cms/assets/img/ambassadors/sun-huh.jpg and /dev/null differ
diff --git a/cms/assets/img/ambassadors/thomas_mboa.png b/cms/assets/img/ambassadors/thomas_mboa.png
deleted file mode 100644
index a31a41d5ad..0000000000
Binary files a/cms/assets/img/ambassadors/thomas_mboa.png and /dev/null differ
diff --git a/cms/assets/img/ambassadors/youngim-jung.jpg b/cms/assets/img/ambassadors/youngim-jung.jpg
deleted file mode 100644
index e92079f60f..0000000000
Binary files a/cms/assets/img/ambassadors/youngim-jung.jpg and /dev/null differ
diff --git a/cms/assets/img/team/lene.jpg b/cms/assets/img/team/lene.jpg
new file mode 100644
index 0000000000..f95866b74b
Binary files /dev/null and b/cms/assets/img/team/lene.jpg differ
diff --git a/cms/assets/img/volunteers/Ana Melisa Fernandes.jpg b/cms/assets/img/volunteers/Ana Melisa Fernandes.jpg
new file mode 100644
index 0000000000..b08b5e0ee7
Binary files /dev/null and b/cms/assets/img/volunteers/Ana Melisa Fernandes.jpg differ
diff --git a/cms/data/ambassadors.yml b/cms/data/ambassadors.yml
index a14afcc2b4..52c3cdc294 100644
--- a/cms/data/ambassadors.yml
+++ b/cms/data/ambassadors.yml
@@ -1,47 +1,21 @@
# List of DOAJ ambassadors
# ~~Ambassadors:Data~~
-- name: Adrian Stanley
- region: North America
- bio: "Adrian is past President of the Society for Scholarly Publishing (SSP). He has previously lived and worked in China and is well connected with the global publishing community, especially in places like Brazil (Scielo) and Japan (J-STAGE). He was also Managing Director, Publishers for Digital Science. Adrian serves on the OA Switchboard Client Advisor Group, and is the Chair of the Fully OA Publishers Group (a sub group formed out of OASPA working group), he is currently an Independent Contractor, and advisor for JMIR Publications, DataSeer.ai and Underline.io."
- photo: "Adrian.png"
- coi:
- 2022: https://drive.google.com/file/d/1CC6bqk_JF_kovY6Z-SVhv01epY7dcYWq/view?usp=sharing
- name: Amber Osman
region: Pakistan
- bio: "Amber is a passionate expert in open science and a research enthusiast. Over the last decade, she has been actively involved in different international academic, research & publishing organizations and with the Higher Education Commission (Govt. of Pakistan). She has been an award-winning journal editor for advancing the publishing process by adopting innovative research and publishing solutions. Amber advocates for best practices in open access scholarly content. She has Masters of Philosophy in marketing."
+ bio: "Amber is a passionate expert in open science and a research enthusiast. Over the last decade, she has been actively involved in different international academic, research & publishing organizations and with the Higher Education Commission (Govt. of Pakistan). She has been an award-winning journal editor for advancing the publishing process by adopting innovative research and publishing solutions. Amber advocates for best practices in open access scholarly content. She has a Masters of Philosophy in marketing."
photo: "amber.jpeg"
coi:
2022: https://drive.google.com/file/d/18KLtcd-F4q1XbVxh5o54k7feQUY-e-uv/view?usp=sharing
-- name: Eriko Amano
- region: Japan
- bio: ""
- photo: ""
- coi:
- 2022: https://drive.google.com/file/d/1HXvSXTbgK5n5H3a-P_SPTM_IubmaYJzd/view?usp=sharing
-
- name: Gimena del Rio Riande
region: Latin America
- bio: "Gimena is a researcher at IIBICRIT, the Institute for Bibliographic Research and Textual Criticism at CONICET, the main agency that fosters science and technology in Argentina. Most of her research projects are related to Open Science and Digital Humanities, with a focus on the Global South. She is also the president of the Asociación Argentina de Humanidades Digitales (AAHD), and a member of the Board of Directors of Force11, OpenMethods-DARIAH, Hypotheses, and Area (Open Education Network in Argentina)."
+ bio: "Gimena is a researcher at IIBICRIT, the Institute for Bibliographic Research and Textual Criticism at CONICET, the main agency that fosters science and technology in Argentina. Most of her research projects are related to Open Science and Digital Humanities, focusing on the Global South. She is also the president of the Asociación Argentina de Humanidades Digitales (AAHD), and a member of the Board of Directors of Force11, OpenMethods-DARIAH, Hypotheses, and Area (Open Education Network in Argentina)."
photo: "del-rio-riande-gimena.jpg"
coi:
2022: https://drive.google.com/file/d/1wwxuAH15I4k-mQ3NW03x3W12ExUKJ7f9/view?usp=sharing
-- name: Hea Lim Rhee
- region: South Korea
- bio: "Hea is a senior researcher at Korea Institute of Science and Technology Information (KISTI), and also the managing editor of KISTI’s Journal of Information Science Theory and Practice (JISTaP), the first English journal on computer science in Korea. Hea received her PhD from the University of Pittsburgh and her Master of Science in Information from the University of Michigan, where she specialised in archives and records management."
- photo: "hea-lim-rhee.jpg"
- coi:
- 2022: https://drive.google.com/file/d/1qBL2bfc9y1JufncY5bn1pn4zanD519Q_/view?usp=sharing
-
-- name: Hyun Jung Yi
- region: South Korea
- bio: "Hyun Jung Yi holds a PhD in Library and Information Science from Chung-Ang University and is a librarian at Hanyang University Guri Hospital. Currently, she also serves as a member of the Scholarly Committee at the Korean Medical Library Association and as a vice chair of the Committee of Information Management at the Korean Council of Science Editors (KCSE). Her interests include observing trends in the scholarly publishing market, disseminating open access journals, and enhancing the publishing environment for researchers."
- photo: "hyun-jung-yi.png"
- coi:
-
- name: Ikhwan Arief
region: Indonesia
bio: "Ikhwan is a faculty member in the Industrial Engineering Department at Universitas Andalas, Indonesia. He is an enthusiastic photography hobbyist. He joined DOAJ in 2018 as an ambassador and gradually became a volunteer editor. He used to manage the university's library information system, including establishing the online public access catalogue (OPAC) and the repository servers. He is keenly interested in data science, primarily in industrial and manufacturing systems research. He has been assisting Indonesian journal managers in their application to DOAJ."
@@ -58,7 +32,7 @@
- name: Ivonne Lujano
region: Latin America
- bio: "Ivonne Lujano Vilchis is a PhD student in Education Policy and Evaluation at Arizona State University. She holds a Master’s degree in Social Sciences with an emphasis on Education. She has worked in scholarly communication and open access since 2011. As DOAJ ambassador she has collaborated with several universities and government agencies on the adoption of best practice for scholarly publications, and open science policies. She serves as a section editor of Current Issues of Education, a journal produced by doctoral students at Mary Lou Fulton Teachers College of Arizona State University. Her research interests focus on higher education systems, research evaluation, science policy, open access, scholarly communication, and open science. Ivonne also has a background in dance, and she is currently an amateur tango dancer."
+ bio: "Ivonne Lujano Vilchis is a PhD student in Education Policy and Evaluation at Arizona State University. She holds a Master’s degree in Social Sciences with an emphasis on Education. She has worked in scholarly communication and open access since 2011. As DOAJ ambassador, she has collaborated with several universities and government agencies on the adoption of best practices for scholarly publications and open science policies. She is a section editor of Current Issues of Education, a journal produced by doctoral students at Mary Lou Fulton Teachers College of Arizona State University. Her research interests focus on higher education systems, research evaluation, science policy, open access, scholarly communication, and open science. Ivonne also has a background in dance, and she is currently an amateur tango dancer."
photo: "ivonne.jpg"
coi:
2022: https://drive.google.com/file/d/1HnGhYbvbzL34guWOmIqcthcwAN8NADX1/view?usp=sharing
@@ -69,20 +43,11 @@
photo: "mahmoud-new.jpg"
coi:
2022: https://drive.google.com/file/d/10s7B0WeTPqpaafhThv-i8q03uIFaAAue/view?usp=sharing
-
-- name: Maxim Mitrofanov
- region: Russian Federation
- bio: "Maxim was born in Moscow, graduated from the University of Foreign Relations and then worked for the Ministry of Foreign Affairs of Russia for nine years. After leaving the Ministry in 2007 he worked for the largest Russian exhibition company, Expocentre, and then joined NEICON in 2014. NEICON is the driving force to share open access ideas among the Russian journal and scholar community."
- photo: "max.png"
- coi:
- 2022: https://drive.google.com/file/d/1Dzb8QzS5V0KzjNnybkWFQpjBwk1Jy8il/view?usp=sharing
- name: Melkamu Beyene
region: East Africa
- bio: "Dr.Melkamu Beyene is Assistant professor in the school of information science. He received his Ph.D in Information Retrieval from Addis Ababa University in a joint program with the Institut national des sciences appliquées de Lyon, France by 2017. He is
-serving as a chief librarian of Addis Ababa University Library system and Chairperson of the Consortium of Ethiopian Academic and Research Libraries from March 08, 2018 up
-to now."
- photo: "Melkamu_Beyene.JPG"
+ bio: "Dr. Melkamu Beyene is an Assistant Professor in the School of Information Science at Addis Ababa University. He received his PhD in Information Retrieval from Addis Ababa University in a joint program with the Institut National des Sciences Appliquées de Lyon, France, in 2017. He is a Chief Librarian at Addis Ababa University Library system and Chairperson of the Consortium of Ethiopian Academic and Research Libraries from March 08, 2018."
+ photo: "melkamu.JPG"
coi:
- name: Muhammad Imtiaz Subhani
@@ -92,27 +57,6 @@ to now."
coi:
2022: https://drive.google.com/file/d/1nYQZ8h766UsNY_gWwCbRyVQ_yxdCyQN5/view?usp=sharing
-- name: Narumi Shitara
- region: Japan
- bio: "Narumi is the head of the Editorial Office, Center for Southeast Asian Studies (CSEAS), Kyoto University. She has been the managing editor of CSEAS’s academic journals and monograph series since 2011. Her research interest is in bulletin journals published by Japanese universities and research institutes."
- photo: "shitara.png"
- coi:
- 2022: https://drive.google.com/file/d/1f_Od4aor5r9e2idA1gUNnNnPM8naZCcV/view?usp=sharing
-
-- name: Natalia Popova
- region: Russian Federation
- bio: "Natalia has been conducting research into academic communication for over 25 years. Currently, her research interests embrace sociology of science and technology, in particular the problems of open access, transformation in the role
-of scientific journals in academic communication, and academic publishing under the influence of globalization trends. Natalia is an active member of the International Sociological Association (ISA), Assistant Editor of the journal Changing societies & personalities, editorial board member for Russian and international scientific journals, expert in the evaluation of the quality of scientific journals of the Association of Science Editors and Publishers (ASEP), and Deputy Chair of the Scopus Expert Content Selection and Advisory Board (ESCAB) in the Russian Federation."
- photo: "Popova-1.jpeg"
- coi:
- 2022: https://drive.google.com/file/d/1JHIibZcrJx6wPLXcn62SWS7R_tCRIJdv/view?usp=sharing
-
-- name: Olga Kirillova
- region: Russian Federation
- bio:
- photo:
- coi:
-
- name: Shuai Yan
region: China
bio: "Shuai Yan is an independent consultant since 2020. Since November 2021, Shuai has worked with STM as its China Consultant. From 2017 to 2020, he worked with Springer Nature Greater China as director of academic relationships (including government relations). From 2011 to 2017 he was at Tsinghua University Press (TUP) as an associate chief editor and was TUP's director of Journal Publishing. He was also the editor-in-chief of Journal of Tsinghua University (Science and Technology). He has served as the president of Society of China University Journals (CUJS) from 2004 to 2019, the vice president of China Periodicals Association (CPA) from 2012 to 2018, and the vice president of the China Editology Society for Scientific Periodicals (CESSP) from 2015 to 2021."
@@ -120,23 +64,9 @@ of scientific journals in academic communication, and academic publishing under
coi:
2022: https://drive.google.com/file/d/1Xy9OPuTQZp5AS3wBs0Ittd3t_n4onKCy/view?usp=sharing
-- name: Sun Huh
- region: South Korea
- bio: "Sun is a medical doctor and holds a PhD from Seoul National University in parasitology. He has been a Professor of Parasitology at College of Medicine, Hallym University, Korea since 1988. He has worked voluntarily as a board member of Korean Association of Medical Journal Editors (1996-2011), Korean Council of Science Editors (2011-present), and Council of Asian Science Editors (2014-present).
-He has been an editor of Journal of Educational Evaluation for Health Professions since 2005. His goal with DOAJ is to pursue the registration of all open access journals from Korea to DOAJ."
- photo: "sun-huh.jpg"
- coi:
-
- name: Vrushali Dandawate
region: India
bio: "Vrushali is Head Librarian at AISSMS College of Engineering College Pune, Maharashtra, India, and She holds a Ph.D. degree from Reva University Banglore, India. Her research topic is 'OPEN ACCESS E -RESOURCES DEVELOPMENT IN ASIA: A STUDY' Vrushali was the winner of the ALCTS Online Course Grant for Library Professionals from Developing Countries in 2014, and the INASP open access week competition in both 2015 and 2016. She was invited to OpenCon 2017 in Berlin, Germany, and subsequently worked as a member of the organizing committee for OpenCon 2018 in Toronto, Canada. She also served as an advisory committee member for Open Access Week 2018-2019. She is selected as an advisory committee member of OpenDOAR and conference committee member of the FORCE2021 Conference."
photo: vrushali.jpg
coi:
2022: https://drive.google.com/file/d/18Z2wZ9KMxuD0WD_b3pfxg4QJy9-7lUO6/view?usp=sharing
-
-- name: Youngim Jung
- region: South Korea
- bio: "Youngim holds a PhD from Pusan National University in Computer Science and Engineering. She is now a Senior Researcher at Korea Institute of Science and Technology Information, developing and managing scholarly publishing systems for supporting domestic societies. Previously, she worked for KESLI, the national library consortium in South Korea and helped to establish the Korea DOI Center. She is a committee member of the Korean Council of Science Editors (KCSE) and Council of Asian Science Editors (CASE). She has authored publications and communications in the fields of Scientometrics, Library Systems and Natural Language Processing."
- photo: "youngim-jung.jpg"
- coi:
- 2022: https://drive.google.com/file/d/1aXpu85OEFnxEl9YJsOF_QBRkG8brVSz4/view?usp=sharing
diff --git a/cms/data/nav.yml b/cms/data/nav.yml
index 62cbdece73..5250833b7c 100644
--- a/cms/data/nav.yml
+++ b/cms/data/nav.yml
@@ -46,7 +46,7 @@ entries:
route: doaj.ambassadors # ~~->Ambassadors:WebRoute~~
- label: Advisory Board & Council
route: doaj.abc # ~~->AdvisoryBoardCouncil:WebRoute~~
- - label: Editorial Policy and Advisory Group
+ - label: Editorial Policy Advisory Group
route: doaj.epag # ~~->EditorialPolicyAdvisoryGroup:WebRoute~~
- label: Volunteers
route: doaj.volunteers # ~~->Volunteers:WebRoute~~
@@ -106,7 +106,7 @@ entries:
url: '#'
modal:
id: wechat
- include: "includes/_wechat_modal.html"
+ include: "public/includes/_wechat_modal.html"
- label: Atom feed
feather: rss
route: atom.feed # ~~->Atom:WebRoute~~
diff --git a/cms/data/notifications.yml b/cms/data/notifications.yml
index cde76f922b..711d8f5027 100644
--- a/cms/data/notifications.yml
+++ b/cms/data/notifications.yml
@@ -84,11 +84,11 @@ application:publisher:inprogress:notify:
application:publisher:quickreject:notify:
long: |
- The application which you submitted for **{title}** on {date_applied} has been rejected as the journal does not meet our basic criteria ([{doaj_guide_url}]({doaj_guide_url})).
+ The application you submitted for **{title}** on {date_applied} has been rejected as the journal does not meet our criteria for inclusion.
{note}
- You may submit a new application 6 months after the date of this email unless advised otherwise by a member of the DOAJ Editorial Team. Before you apply again, make any necessary changes to ensure your journal adheres to our criteria: ([{doaj_guide_url}]({doaj_guide_url}))
+ You may submit a new application 6 months after the date of this email. Before you apply again, make the necessary changes to ensure your journal adheres to our criteria: ([{doaj_guide_url}]({doaj_guide_url}))
short:
Your application ({issns}) was rejected
diff --git a/cms/data/team.yml b/cms/data/team.yml
index 009803bf3d..b5dd574a51 100644
--- a/cms/data/team.yml
+++ b/cms/data/team.yml
@@ -31,9 +31,9 @@
2024: https://drive.google.com/file/d/1Gr7f_V5Of84_OmRr_4vYnJyAyOLMEySA/view?usp=drive_link
- name: Dominic Mitchell
- role: Operations Manager
+ role: Deputy Director, Platform Manager
photo: dominic.jpg
- bio: "Dominic has over 25 years of experience working with the publisher and library communities. He is responsible for operations, and the development of the DOAJ platform. He acts as Committee chair for the Think. Check. Submit. initiative, of which DOAJ is a founding organisation. He represents DOAJ in Project JASPER, a cross-industry project working to ensure that journals are preserved for the long term. He is also Chair of the OASPA Board of Directors. His spare time is divided between looking after his twin sons and his vinyl record collection."
+ bio: "Dominic has over 25 years of experience working with the publisher and library communities. He is responsible for managing and developing the DOAJ platform in association with DOAJ's technical partners. He acts as Committee chair for the Think. Check. Submit. initiative, of which DOAJ is a founding organisation. He is also Chair of the OASPA Board of Directors. His spare time is divided between looking after his twin sons and his vinyl record collection."
coi:
2018: https://drive.google.com/file/d/13XX_GUrw2xRmXARjRrTxegULPT8Redka/view?usp=sharing
2020: https://drive.google.com/file/d/1nxFOuAdXLb8A-LulhNpz9i5vSmr5DBwF/view?usp=sharing
@@ -132,6 +132,13 @@
2022: https://drive.google.com/file/d/19rw-naMJqHkI5T7aDIDPUkwPutBdDpDm/view?usp=sharing
2024: https://drive.google.com/file/d/1mE86YvfsmGtklIs4I_iwLI9iH5vefg0n/view?usp=drive_link
+- name: Lene Rasmussen
+ role: Operations Manager
+ photo: lene.jpg
+ bio: "Lene holds a master’s degree in mathematics and economics and spent 17 years in the financial industry before joining DOAJ. She has extensive leadership experience, including leading strategy and business development processes, managing key strategic projects and driving operational excellence while delivering senior management support and advice. Lene highly prioritizes time with close friends and family and loves to travel the world. Her spare time is spent coaching the local children’s soccer team and taking a run or bike ride in the nearby forest."
+ coi:
+ 2024: https://drive.google.com/file/d/1GK8gX_8_yoDWiidDweF9CHVlG0N7a-ot/view?usp=sharing
+
- name: Mahmoud Khalifa
role: Managing Editor and Ambassador
photo: mahmoud-new.jpg
diff --git a/cms/data/volunteers.yml b/cms/data/volunteers.yml
index 71589566e5..d526786e14 100644
--- a/cms/data/volunteers.yml
+++ b/cms/data/volunteers.yml
@@ -125,8 +125,16 @@ ass_ed:
city: Florence
country: Italy
language: Italian, English, Spanish
-
-- name: Amber Osman
+
+- name: Ana Melisa Fernandes
+ area: Bird behavior and ecology
+ year_since:
+ city: Bogotá
+ country: Colombia
+ language: Spanish, English, Portuguese
+ photo: "Ana Melisa Fernandes.jpg"
+
+- name: Amber Osman
area: Open Science, Publication Ethics, Scholarly communication
year_since:
city: Karachi
@@ -464,7 +472,15 @@ ass_ed:
country: Iraq
language: Arabic, English, Swedish
photo: "karima.jpg"
-
+
+- name: Kelly Anne Dumayne
+ area: Psychology, linguistics, creative writing
+ year_since:
+ city: Wales
+ country: United Kingdom
+ language: English
+ photo:
+
- name: Khoirul Fathoni
area: Humanities
year_since:
diff --git a/cms/pages/about/advisory-board-council.md b/cms/pages/about/advisory-board-council.md
index fb1fcb8ec2..46fa12ece0 100644
--- a/cms/pages/about/advisory-board-council.md
+++ b/cms/pages/about/advisory-board-council.md
@@ -1,6 +1,6 @@
---
layout: no-sidenav
-include: /data/advisory-board-council.html
+include: /public/includes/_advisory-board-council.html
title: Advisory Board & Council
section: About
toc: true
diff --git a/cms/pages/about/ambassadors.md b/cms/pages/about/ambassadors.md
index 5ee6f0376c..882596f771 100644
--- a/cms/pages/about/ambassadors.md
+++ b/cms/pages/about/ambassadors.md
@@ -1,12 +1,17 @@
---
layout: no-sidenav
-include: /data/ambassadors.html
+include: /public/includes/_ambassadors.html
title: Ambassadors
section: About
toc: true
+sticky_sidenav: true
highlight: true
featuremap: ~~Ambassadors:Fragment->AmbassadorsData:Template~~
---
-DOAJ has 21 active ambassadors, who work with communities around the world. Ambassadors help journal editors understand the importance of standards in open access publishing; they raise DOAJ's profile and help to make the journals a more attractive place to publish research.
+DOAJ has 13 active Ambassadors, who work with local communities around the world. Ambassadors work within Low- or Middle-Income Countries (LMIC) to raise DOAJ's profile through local outreach and engagment activities. Ambassadors advocate for good practice in open access and publishing, assist with information around applying to DOAJ, and conduct training and events on behalf of DOAJ.
+
+In 2024, we reveiwed the Ambassador Programme and have implemented a range of changes. In 2025, our Ambassador Programme will have a pilot year where our focus will be on projects led by Ambassadors, supported by DOAJ. If you are interested in becoming an Ambasador, please look out for calls and information that will be published on [our blog](https://blog.doaj.org/).
+
+#
diff --git a/cms/pages/about/editorial-policy-advisory-group.md b/cms/pages/about/editorial-policy-advisory-group.md
index edf22f70c2..3b5f36ab60 100644
--- a/cms/pages/about/editorial-policy-advisory-group.md
+++ b/cms/pages/about/editorial-policy-advisory-group.md
@@ -28,28 +28,42 @@ The Editorial Policy Advisory Group is:
### Budianto Hamuddin
-Budianto is a senior lecturer in the Faculty of Education and Vocational Studies at Universitas Lancang Kuning, Indonesia, where he also leads the Research Department at LPPM Unilak. An active member of RJI, he currently serves as the coordinator for Tim Panji RJI to support and develop scientific journals in Indonesia. Budianto earned his Master's degree from the Universiti Malaya in Malaysia and his Doctorate from Universitas Hasanuddin in Indonesia, specializing in Applied Linguistics with a focus on cyberbullying on online platforms. He serves on the editorial boards of several SINTA-accredited journals in Indonesia and is a reviewer for numerous international scientific journals.
+Budianto is a senior lecturer in the Faculty of Education and Vocational Studies at [Universitas Lancang Kuning](https://www.unilak.ac.id/), Indonesia, where he also leads the Research Department at LPPM Unilak. An active member of [RJI](https://relawanjurnal.id/), he currently serves as the coordinator for Tim Panji RJI to support and develop scientific journals in Indonesia. Budianto earned his Master's degree from the Universiti Malaya in Malaysia and his Doctorate from Universitas Hasanuddin in Indonesia, specializing in Applied Linguistics with a focus on cyberbullying on online platforms.
+
+He serves on the editorial boards of several SINTA-accredited journals in Indonesia and is a reviewer for numerous international scientific journals.
### José Florencio Fabella Lapeña, Jr.
-Joey is a retired Professor of Otolaryngology at U.P. College of Medicine, former Vice Chancellor at the University of the Philippines Manila and Attending Otolaryngologist at Philippine General Hospital. He has special interests in pediatric cleft and aero-digestive surgery, medical education, mentoring, writing and peer review. He is Secretary of the World Association of Medical Editors, Past President of the Asia-Pacific Association of Medical Journal Editors, and Charter President of the Philippine Association of Medical Journal Editors. He is Editor-in-Chief of the *Philippine Journal of Otolaryngology Head and Neck Surgery*, and chairs the Philippine National Journal Selection Committee for the Western Pacific Region Index Medicus of the World Health Organization.
+Joey is a retired Professor of Otolaryngology at U.P. College of Medicine, former Vice Chancellor at the University of the Philippines Manila and Attending Otolaryngologist at the Philippine General Hospital. He has special interests in pediatric cleft and aero-digestive surgery, medical education, mentoring, writing and peer review. He is Secretary of the [World Association of Medical Editors](https://wame.org/), Past President of the Asia-Pacific Association of Medical Journal Editors, and Charter President of the [Philippine Association of Medical Journal Editors](https://www.philippinemedicalassociation.org/).
+
+He is Editor-in-Chief of the *[Philippine Journal of Otolaryngology Head and Neck Surgery](https://doaj.org/toc/1908-4889)*, and chairs the Philippine National Journal Selection Committee for the Western Pacific Region Index Medicus of the World Health Organization.
### Jose Octavio Alonso Gamboa
-Octavio is a founding member of Latindex (www.latindex.org), an information system comprising 24 countries, of which he has been the general coordinator since 2005. He is a tenured academic at the General Directorate of Libraries of the National Autonomous University of Mexico (UNAM) and holds a Master's degree in Library and Information Studies. His experience includes topics such as the quality and visibility of scientific journals, as well as the transformation of academic journals to the digital culture. His professional career focuses on regional science communication and open access, reflecting his interest in the promotion of open science and the democratization of knowledge.
+Octavio is a founding member of [Latindex](https://www.latindex.org/latindex/), an information system comprising 24 countries, of which he has been the general coordinator since 2005. He is a tenured academic at the General Directorate of Libraries of the [National Autonomous University of Mexico](https://www.unaminternacional.unam.mx/) (UNAM) and holds a Master's degree in Library and Information Studies.
+
+His experience includes topics such as the quality and visibility of scientific journals and the transformation of academic journals to the digital culture. His professional career focuses on regional science communication and open access, reflecting his interest in the promotion of open science and the democratization of knowledge.
### Kazuki Ide
-Kazuki is a Specially-Appointed Associate Professor at Osaka University. His broad research interests include scholarly communication/publication ethics, public health/health informatics, and ELSI/RRI. He has performed peer reviews over 500 times and received the Top Peer Reviewer Award in 2019 for Cross-Field (Top 1% in the World, Web of Science). He also led the translation of the following educational materials into Japanese: Combatting Predatory Academic Journals and Conferences (IAP, 2023) and Think.Check.Submit. (2024).
+Kazuki is a Specially-Appointed Associate Professor at [Osaka University](https://www.osaka-u.ac.jp/). His broad research interests include scholarly communication/publication ethics, public health/health informatics, and ELSI/RRI. He has performed peer reviews over 500 times and received the Top Peer Reviewer Award in 2019 for Cross-Field (Top 1% in the World, Web of Science).
+
+He led the translation of the following educational materials into Japanese: [Combatting Predatory Academic Journals and Conferences](https://www.interacademies.org/project/predatorypublishing) (IAP, 2023) and [Think.Check.Submit.](https://thinkchecksubmit.org/journals/) (2024).
### Kylie van Zyl
-Kylie is one of the small, dedicated team at African Journals Online, a South Africa-based NPO dedicated to quality African-published scholarly journals, where she handles JPPS assessments of new applicant journals. She holds an MA and PhD in History from Rhodes University, specialising in the social history of health in South African contexts.
+Kylie is one of the small, dedicated team at [African Journals Online](https://www.ajol.info/index.php/ajol), a South Africa-based NPO dedicated to quality African-published scholarly journals, where she handles JPPS assessments of new applicant journals.
+
+She holds an MA and PhD in History from Rhodes University, specialising in the social history of health in South African contexts.
### Matt Hodgkinson
-Matt is a publishing and research integrity consultant based in Cambridge, UK. He volunteers as the co-chair of the membership subcommittee of the Committee on Publication Ethics (COPE) and Treasurer of the European Association of Science Editors (EASE). He has worked at three Open Access journal publishers: as a professional scientific editor at both BioMed Central (BMC) and the Public Library of Science (PLOS), then as Head of Research Integrity and Head of Editorial Policy and Ethics at Hindawi. He was also a Research Integrity Manager at the UK Research Integrity Office (UKRIO).
+Matt is a publishing and research integrity consultant based in Cambridge, UK. He volunteers as the co-chair of the membership subcommittee of the [Committee on Publication Ethics](https://publicationethics.org/) (COPE) and Treasurer of the [European Association of Science Editors](https://ease.org.uk/) (EASE).
+
+He has worked at three Open Access journal publishers: as a professional scientific editor at both BioMed Central (BMC) and the Public Library of Science (PLOS), then as Head of Research Integrity and Head of Editorial Policy and Ethics at Hindawi. He was also a Research Integrity Manager at the UK Research Integrity Office (UKRIO).
### Paulin Ribbe
-Paulin holds a master degree in digital publishing from ENSSIB (French National Library and Information Science School, Lyon, France). He has worked as a project manager for European projects in various research infrastructures in social sciences: Huma-Num, OPERAS (OpenEdition). He currently works in Sciences Po Lyon as Open Science Officer, and as a project manager for Mir@bel, a website and community aiming to facilitate access to online journals. He participates in various projects including major French publishing platforms and agencies working together to increase the visibility of French scientific journals.
+Paulin holds a Master's degree in digital publishing from [ENSSIB](https://www.enssib.fr/) (French National Library and Information Science School, Lyon, France). He has worked as a project manager for European projects in various research infrastructures in social sciences: Huma-Num, OPERAS (OpenEdition).
+
+He currently works at [Sciences Po Lyon](https://www.sciencespo-lyon.fr/) as an Open Science Officer and as a project manager for [Mir@bel](https://reseau-mirabel.info/), a website and community aiming to facilitate access to online journals. He participates in various projects, including major French publishing platforms and agencies working together to increase the visibility of French scientific journals.
diff --git a/cms/pages/about/team.md b/cms/pages/about/team.md
index 68a3200a48..549f1e50ae 100644
--- a/cms/pages/about/team.md
+++ b/cms/pages/about/team.md
@@ -1,6 +1,6 @@
---
layout: no-sidenav
-include: /data/team.html
+include: /public/includes/_team.html
title: DOAJ team
section: About
toc: true
diff --git a/cms/pages/about/volunteers.md b/cms/pages/about/volunteers.md
index b2dd6767c8..e2a040518e 100644
--- a/cms/pages/about/volunteers.md
+++ b/cms/pages/about/volunteers.md
@@ -4,7 +4,7 @@ title: Volunteers
section: About
toc: true
highlight: true
-include: /data/volunteers.html
+include: /public/includes/_volunteers.html
featuremap: ~~Volunteers:Fragment->VolunteersData:Template~~
---
diff --git a/cms/pages/apply/thank-you.md b/cms/pages/apply/thank-you.md
index ca18c98fe9..342aa05b61 100644
--- a/cms/pages/apply/thank-you.md
+++ b/cms/pages/apply/thank-you.md
@@ -2,7 +2,7 @@
layout: no-sidenav
title: Thank you for your application.
section: Apply
-aside: /includes/_aside_in_case_of_rejection.html
+aside: /public/includes/_aside_in_case_of_rejection.html
featuremap: ~~ApplicationThanks:Fragment->RejectionAside:Template~~
---
diff --git a/cms/pages/docs/openurl.md b/cms/pages/docs/openurl.md
index 538bcdac31..aadd435bba 100644
--- a/cms/pages/docs/openurl.md
+++ b/cms/pages/docs/openurl.md
@@ -20,7 +20,7 @@ Here is the mapping between OpenURL parameters and our Elasticsearch database fi
### Journal
-| Parameter | Elasticsearch field |
+| Parameter | DOAJ record field |
|-----------|---------------------------------|
| jtitle | index.title.exact |
| stitle | bibjson.alternative_title.exact |
@@ -30,7 +30,7 @@ Here is the mapping between OpenURL parameters and our Elasticsearch database fi
### Article
-| Parameter | Elasticsearch field |
+| Parameter | DOAJ record field |
|-----------|----------------------------------|
| aulast | bibjson.author.name.exact |
| aucorp | bibjson.author.affiliation.exact |
diff --git a/cms/pages/legal/accessibility.md b/cms/pages/legal/accessibility.md
index 1a9a784e4f..0d076ee3cd 100644
--- a/cms/pages/legal/accessibility.md
+++ b/cms/pages/legal/accessibility.md
@@ -81,6 +81,7 @@ The content listed below is non-accessible for the following reasons.
- Some images may not have a text alternative, so people using a screen reader cannot access the information. This fails WCAG 2.1 Success Criterion 1.1.1 (Non-text content).
- Some form fields may be missing a label identifying the purpose of its corresponding field. This fails WCAG Success Criterion 1.3.5 (Identify Input Purpose).
- We make users solve, recall, or transcribe something to log in. This fails WCAG Success Criterion Success 3.3.8 (Accessible Authentication)
+- We use ReCAPTCHA. This fails WCAG Success Criterion Success 3.3.8 (Accessible Authentication)
### Disproportionate burden
diff --git a/cms/pages/legal/contact.md b/cms/pages/legal/contact.md
index 28c976f61a..d4236e3371 100644
--- a/cms/pages/legal/contact.md
+++ b/cms/pages/legal/contact.md
@@ -7,9 +7,11 @@ featuremap: ~~ContactUs:Fragment~~
---
-Please [contact our Help Desk](mailto:helpdesk@doaj.org) if you want to send us feedback, have questions about our website or services, or have a complaint.
+Please don't submit articles to us for publication. You should [use our journal search](/search/journals) to find a journal that matches the area of your research and use the contact details on its website.
+
+There are online resources that provide answers to frequently asked questions. The [OA Journals Toolkit](https://www.oajournals-toolkit.org/) and [the PLACE discussion forum](https://theplace.discourse.group/) are two examples and DOAJ plays an active role in both.
-Please don't submit articles to us for publication. You should [use our journal search](/search/journals) to find a journal that matches the area of your research and contact them directly.
+Please [contact our Help Desk](mailto:helpdesk@doaj.org) if you want to send us feedback, have questions about our website or services, or have a complaint.
**Potential supporters**
@@ -18,8 +20,8 @@ Please don't submit articles to us for publication. You should [use our journal
**Providing us with information or updates about journals**
- If you want to provide confidential information about a journal we index, [contact our Help Desk](mailto:helpdesk@doaj.org). Please remember to include the journal title and ISSN.
-- If you find that the information we hold about a journal is out of date, please use the 'Update this journal' tab on each journal record.
-- If you are the publisher of the journal and have a DOAJ account, you can send an update request from the '[My journals](/publisher/journal)' tab on your Publisher dashboard.
+- If you find that the information we display about a journal is out of date, please use the 'Rate this page' button at the side of each journal record.
+- If you are the publisher of a journal that needs to be updated, use your DOAJ account to submit an update request from the '[My journals](/publisher/journal)' tab on your Publisher dashboard.
**Publishers or journal editors**
diff --git a/cms/pages/legal/media.md b/cms/pages/legal/media.md
index 7ef790b404..c19357b796 100644
--- a/cms/pages/legal/media.md
+++ b/cms/pages/legal/media.md
@@ -6,23 +6,25 @@ sticky_sidenav: true
featuremap: ~~Media:Fragment~~
---
-The Directory of Open Access Journals is the definitive place for anyone in the world to find peer-reviewed, open access journals. It is the only open access directory which is community-driven, not-for-profit and provides all of its main services, online, for free.
+The Directory of Open Access Journals is the definitive place for anyone in the world to find peer-reviewed, open-access journals. It is the only open-access directory that is community-driven, not-for-profit, and provides all its reviewing services and metadata for free.
On this page, you can find links, information and contacts specifically for journalists. Please contact us with any questions or requests for interviews.
- [Meet the team](/about/team/)
- [About DOAJ](/about/)
-- [News Service](https://blog.doaj.org)
+- [Blog](https://blog.doaj.org)
- [Logos](https://doaj-kit.netlify.app/building-blocks/logotype/)
## Contact
-Louise Stoddard, PR Officer
-[louise@doaj.org](mailto:louise@doaj.org?subject=Press Enquiry)
+Katrine Sundsbø [katrine@doaj.org](mailto:katrine@doaj.org?subject=Press Enquiry)
-## Social media
+## Social media and online
-- [Twitter](https://twitter.com/doajplus)
+- [ X ](https://twitter.com/doajplus)
- [Facebook](https://www.facebook.com/DirectoryofOpenAccessJournals/)
+- [Instagram](https://www.instagram.com/doajplus/)
+- [Bluesky](https://bsky.app/profile/doaj.bsky.social)
+- [Mastodon](https://masto.ai/@DOAJ)
- [Linkedin](https://www.linkedin.com/company/doaj/)
- [Github](https://github.com/DOAJ)
diff --git a/cms/pages/support/publisher-supporters.md b/cms/pages/support/publisher-supporters.md
index 5d0cf13f95..3a4e667d73 100644
--- a/cms/pages/support/publisher-supporters.md
+++ b/cms/pages/support/publisher-supporters.md
@@ -1,6 +1,6 @@
---
layout: sidenav
-include: /data/publisher-supporters.html
+include: /public/includes/_publisher-supporters.html
title: Publisher supporter model
section: Support
sticky_sidenav: true
@@ -10,48 +10,47 @@ featuremap:
- ~~->PublisherSupportersData:Template~~
---
-DOAJ relies on the support of publishers and [libraries](/support/) to ensure that its metadata and services remain free for all. The publishers on this page have chosen to show their commitment to quality, peer-reviewed open access by supporting DOAJ. We thank them, as our work would not be possible without them.
+We rely on the support of publishers and [libraries](/support/) so we can uphold our commitment to ensuring that our journal reviewing and metadata services remain free for all. The publishers on this page have chosen to show their commitment to quality, peer-reviewed open access by supporting DOAJ. We thank them, as our work would not be possible without them.
## Pricing
-We are introducing a revised and simplified model for publishers to support DOAJ for 2024 and publishing this openly in line with [our commitment to the Principles of Open Scholarly Infrastructure](https://blog.doaj.org/2022/10/06/doaj-commits-to-the-principles-of-open-scholarly-infrastructure-posi/). We are also relaunching the set of benefits for publishers choosing to support us.
+We always publish our simplified support prices openly, in line with [our commitment to the Principles of Open Scholarly Infrastructure](https://blog.doaj.org/2022/10/06/doaj-commits-to-the-principles-of-open-scholarly-infrastructure-posi/).
-We only accept support through our publisher supporter model from publishers with journals already indexed in DOAJ. Non-commercial/institutional rates are only available to community-led, smaller publishers with limited funding. [Contact us](/contact/) if you are unsure which category applies or if you want to discuss ways of further contributing to DOAJ’s operating costs.
+We only accept support through our publisher supporter model from publishers with journals already indexed in DOAJ. Non-commercial/institutional rates are only available to community-led, smaller publishers with limited funding. [Contact us](/contact/) if you are unsure which category applies or if you want to discuss ways of further contributing to DOAJ's operating costs.
### Commercial publishers
| Band | Number of journals in DOAJ | GBPs (£)* |
|------|----------------------------|-----------|
-| A | 600+ | 25,000 |
-| B | 400-599 | 20,000 |
-| C | 150-399 | 17,000 |
-| D | 100-149 | 14,000 |
-| E | 50-99 | 8000 |
-| F | 30-49 | 6000 |
-| G | 10-29 | 5000 |
-| H | 1-9 | 3500 |
+| A | 600+ | 26,000 |
+| B | 400-599 | 21,000 |
+| C | 150-399 | 18,000 |
+| D | 100-149 | 15,000 |
+| E | 50-99 | 8500 |
+| F | 30-49 | 6400 |
+| G | 10-29 | 5200 |
+| H | 1-9 | 3700 |
### Non-commercial / institutional publishers
| Band | Number of journals in DOAJ | GBPs (£)* |
|------|----------------------------|-----------|
-| C | 150-399 | 3500 |
-| D | 100-149 | 3000 |
-| E | 50-99 | 2500 |
-| F | 30-49 | 2000 |
-| G | 10-29 | 1500 |
-| H | 1-9 | 1000 |
+| C | 150-399 | 3600 |
+| D | 100-149 | 3100 |
+| E | 50-99 | 2600 |
+| F | 30-49 | 2100 |
+| G | 10-29 | 1550 |
+| H | 1-9 | 1050 |
*A 50% discount is available for supporters in Low- and Middle-Income Countries according to the World Bank classification.
## Benefits
1. Your logo on the DOAJ website
-2. A post from all our social media platforms (Twitter, Facebook, LinkedIn, Mastodon, Instagram) acknowledging your organisation as a Supporter
-3. A blog post at the start of the year introducing our new supporters
-4. A DOAJ Supporter logo that you can use on your website
-5. Access to our Public Data Dump
-6. For supporters from Bands A-E or those contributing over the suggested amounts, a personal DOAJ contact to whom all enquiries regarding your applications and updates can be directed
+2. A blog post during the year thanking all our supporters
+3. A DOAJ Supporter logo that you can use on your website
+4. Access to our Public Data Dump
+5. A personal DOAJ contact to whom all enquiries regarding your applications and updates can be directed
## Sponsorship opportunities
@@ -65,4 +64,4 @@ Please [contact us](/contact/) to discuss further.
## Supporting publishers, aggregators, and other organizations
-
{% include '/data/sponsors.html' %}
+
{% include 'public/includes/_sponsors.html' %}
diff --git a/doajtest/testdrive/publisher_with_journal.py b/doajtest/testdrive/publisher_with_journal.py
index bd4173a822..a03842b505 100644
--- a/doajtest/testdrive/publisher_with_journal.py
+++ b/doajtest/testdrive/publisher_with_journal.py
@@ -1,6 +1,7 @@
from portality import constants
from doajtest.testdrive.factory import TestDrive
from doajtest.fixtures.v2.journals import JournalFixtureFactory
+from doajtest.fixtures.v2.applications import ApplicationFixtureFactory
from portality import models
@@ -22,17 +23,32 @@ def setup(self) -> dict:
j.bibjson().pissn = "2222-2222"
j.save()
+ source = ApplicationFixtureFactory.make_application_source()
+ a = models.Application(**source)
+ a.remove_current_journal()
+ a.remove_related_journal()
+ a.application_type = constants.APPLICATION_TYPE_NEW_APPLICATION
+ a.set_id(a.makeid())
+ a.set_owner(acc.id)
+ a.bibjson().eissn = "3333-3333"
+ a.bibjson().pissn = "4444-4444"
+ a.set_application_status(constants.APPLICATION_STATUS_IN_PROGRESS)
+ a.save()
+
return {
"account": {
"username": acc.id,
"password": pw,
"api_key": acc.api_key
},
- "journals": [j.id]
+ "journals": [j.id],
+ "applications": [a.id],
}
def teardown(self, params) -> dict:
models.Account.remove_by_id(params["account"]["username"])
for jid in params["journals"]:
models.Journal.remove_by_id(jid)
+ for aid in params["applications"]:
+ models.Application.remove_by_id(aid)
return {"status": "success"}
\ No newline at end of file
diff --git a/doajtest/unit/application_processors/test_application_processor_emails.py b/doajtest/unit/application_processors/test_application_processor_emails.py
index 036c86c68a..cc106942e6 100644
--- a/doajtest/unit/application_processors/test_application_processor_emails.py
+++ b/doajtest/unit/application_processors/test_application_processor_emails.py
@@ -13,6 +13,7 @@
from portality.forms.application_forms import ApplicationFormFactory, JournalFormFactory
from portality.bll import DOAJ
from doajtest.mocks.bll_notification import InterceptNotifications
+from portality.ui import templates
from portality.events.consumers.application_assed_inprogress_notify import ApplicationAssedInprogressNotify
@@ -119,7 +120,7 @@ def test_01_public_application_email(self):
# We expect one email sent:
# * to the applicant, informing them the application was received
- public_template = re.escape('notification_email.jinja2')
+ public_template = re.escape(templates.EMAIL_NOTIFICATION)
public_to = re.escape(account.email)
public_subject = re.escape("Directory of Open Access Journals - Your application (" + ", ".join(issn for issn in processor.source.bibjson().issns()) + ") to DOAJ has been received")
public_email_matched = re.search(email_log_regex % (public_template, public_to, public_subject),
@@ -219,7 +220,7 @@ def test_01_maned_review_emails(self):
assert notification.action is not None
assert notification.classification == constants.NOTIFICATION_CLASSIFICATION_STATUS_CHANGE
- editor_template = re.escape('notification_email.jinja2')
+ editor_template = re.escape(templates.EMAIL_NOTIFICATION)
editor_to = re.escape('eddie@example.com')
editor_subject = re.escape("Application (" + ", ".join(issn for issn in processor.source.bibjson().issns()) + ") reverted to 'In Progress' by Managing Editor\n")
editor_email_matched = re.search(email_log_regex % (editor_template, editor_to, editor_subject),
@@ -235,7 +236,7 @@ def test_01_maned_review_emails(self):
assert notification.action is not None
assert notification.classification == constants.NOTIFICATION_CLASSIFICATION_STATUS_CHANGE
- assoc_editor_template = re.escape('email/notification_email.jinja2')
+ assoc_editor_template = re.escape(templates.EMAIL_NOTIFICATION)
assoc_editor_to = re.escape('associate@example.com')
assoc_editor_subject = re.escape(self.svc.short_notification(ApplicationAssedInprogressNotify.ID).replace("{issns}", ", ".join(issn for issn in processor.source.bibjson().issns())) + "\n")# "an application assigned to you has not passed review."
assoc_editor_email_matched = re.search(email_log_regex % (assoc_editor_template, assoc_editor_to, assoc_editor_subject),
@@ -287,7 +288,7 @@ def test_01_maned_review_emails(self):
assert notification.action is not None
assert notification.classification == constants.NOTIFICATION_CLASSIFICATION_STATUS_CHANGE
- editor_template = re.escape('email/notification_email.jinja2')
+ editor_template = re.escape(templates.EMAIL_NOTIFICATION)
editor_to = re.escape('eddie@example.com')
editor_subject = re.escape("Directory of Open Access Journals - Application ({}) reverted to 'In Progress' by Managing Editor".format(', '.join(issn for issn in processor.source.bibjson().issns())))
editor_email_matched = re.search(email_log_regex % (editor_template, editor_to, editor_subject),
@@ -303,7 +304,7 @@ def test_01_maned_review_emails(self):
assert notification.action is not None
assert notification.classification == constants.NOTIFICATION_CLASSIFICATION_STATUS_CHANGE
- assoc_editor_template = re.escape('email/notification_email.jinja2')
+ assoc_editor_template = re.escape(templates.EMAIL_NOTIFICATION)
assoc_editor_to = re.escape('associate@example.com')
assoc_editor_subject = re.escape(self.svc.short_notification(ApplicationAssedInprogressNotify.ID).replace("{issns}", ", ".join(issn for issn in processor.source.bibjson().issns())) + "\n") # "an application assigned to you has not passed review."
assoc_editor_email_matched = re.search(
@@ -344,16 +345,16 @@ def test_01_maned_review_emails(self):
# We expect 2 emails to be sent:
# * to the AssEd who's been assigned,
# * and to the publisher informing them there's an editor assigned.
- assEd_template = re.escape('email/notification_email.jinja2')
+ assEd_template = re.escape(templates.EMAIL_NOTIFICATION)
assEd_to = re.escape(models.Account.pull('associate_3').email)
assEd_subject = re.escape('Directory of Open Access Journals - New application ({}) assigned to you'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
assEd_email_matched = re.search(email_log_regex % (assEd_template, assEd_to, assEd_subject),
info_stream_contents,
re.DOTALL)
- assert bool(assEd_email_matched)
+ assert bool(assEd_email_matched), info_stream_contents.strip('\x00')
- publisher_template = re.escape('email/notification_email.jinja2')
+ publisher_template = re.escape(templates.EMAIL_NOTIFICATION)
publisher_to = re.escape(owner.email)
publisher_subject = re.escape('Directory of Open Access Journals - Your application ({}) has been assigned to an editor for review'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -385,7 +386,7 @@ def test_01_maned_review_emails(self):
# We expect 2 emails to be sent:
# * to the editor of the assigned group,
# * to the AssEd who's been assigned
- editor_template = re.escape('email/notification_email.jinja2')
+ editor_template = re.escape(templates.EMAIL_NOTIFICATION)
editor_to = re.escape('eddie@example.com')
editor_subject = re.escape('Directory of Open Access Journals - New application ({}) assigned to your group'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -394,13 +395,13 @@ def test_01_maned_review_emails(self):
re.DOTALL)
assert bool(editor_email_matched)
- assEd_template = re.escape('email/notification_email.jinja2')
+ assEd_template = re.escape(templates.EMAIL_NOTIFICATION)
assEd_to = re.escape(models.Account.pull('associate_3').email)
assEd_subject = re.escape('Directory of Open Access Journals - New application ({}) assigned to you'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
assEd_email_matched = re.search(email_log_regex % (assEd_template, assEd_to, assEd_subject),
info_stream_contents,
re.DOTALL)
- assert bool(assEd_email_matched)
+ assert bool(assEd_email_matched), info_stream_contents.strip('\x00')
assert len(re.findall(email_count_string, info_stream_contents)) == 2
# Clear the stream for the next part
@@ -433,7 +434,7 @@ def test_01_maned_review_emails(self):
# We expect one email to be sent here:
# * to the ManEd in charge of the assigned Editor Group, saying an application is ready
- manEd_template = re.escape('email/notification_email.jinja2')
+ manEd_template = re.escape(templates.EMAIL_NOTIFICATION)
manEd_to = re.escape(acc.email)
manEd_subject = re.escape('Directory of Open Access Journals - Application ({}) marked as ready'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -458,7 +459,7 @@ def test_01_maned_review_emails(self):
# We expect 1 email to be sent:
# * to the publisher, informing them of the journal's acceptance
- publisher_template = re.escape('email/notification_email.jinja2')
+ publisher_template = re.escape(templates.EMAIL_NOTIFICATION)
publisher_to = re.escape(owner.email)
publisher_subject = re.escape('Directory of Open Access Journals - Your journal ({}) has been accepted'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -509,7 +510,7 @@ def test_02_ed_review_emails(self):
# We expect one email to be sent here:
# * to the ManEds, saying an application is ready
- manEd_template = 'email/notification_email.jinja2'
+ manEd_template = templates.EMAIL_NOTIFICATION
manEd_to = re.escape("maned@example.com")
manEd_subject = re.escape('Application ({}) marked as ready'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -544,16 +545,16 @@ def test_02_ed_review_emails(self):
# We expect 2 emails to be sent:
# * to the AssEd who's been assigned,
# * and to the publisher informing them there's an editor assigned.
- assEd_template = 'email/notification_email.jinja2'
+ assEd_template = templates.EMAIL_NOTIFICATION
assEd_to = re.escape(models.Account.pull('associate_3').email)
assEd_subject = re.escape('New application ({}) assigned to you'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
assEd_email_matched = re.search(email_log_regex % (assEd_template, assEd_to, assEd_subject),
info_stream_contents,
re.DOTALL)
- assert bool(assEd_email_matched)
+ assert bool(assEd_email_matched), info_stream_contents.strip('\x00')
- publisher_template = 'email/notification_email.jinja2'
+ publisher_template = templates.EMAIL_NOTIFICATION
publisher_to = re.escape(owner.email)
publisher_subject = re.escape('Your update request ({}) has been assigned to an editor for review'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -582,14 +583,14 @@ def test_02_ed_review_emails(self):
# We expect 1 email to be sent:
# * to the AssEd who's been assigned,
- assEd_template = 'email/notification_email.jinja2'
+ assEd_template = templates.EMAIL_NOTIFICATION
assEd_to = re.escape(models.Account.pull('associate_2').email)
assEd_subject = re.escape('New application ({}) assigned to you'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
assEd_email_matched = re.search(email_log_regex % (assEd_template, assEd_to, assEd_subject),
info_stream_contents,
re.DOTALL)
- assert bool(assEd_email_matched)
+ assert bool(assEd_email_matched), info_stream_contents.strip('\x00')
assert len(re.findall(email_count_string, info_stream_contents)) == 1
# Clear the stream for the next part
@@ -624,7 +625,7 @@ def test_02_ed_review_emails(self):
# We expect two email to be sent:
# * to the associate editor, informing them the application has been bounced back to in progress.
# * to the editor telling them an application has reverted to in progress
- assoc_editor_template = re.escape('email/notification_email.jinja2')
+ assoc_editor_template = re.escape(templates.EMAIL_NOTIFICATION)
assoc_editor_to = re.escape('associate@example.com')
assoc_editor_subject = re.escape('One of your applications ({}) has not passed review'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
assoc_editor_email_matched = re.search(
@@ -666,7 +667,7 @@ def test_03_assoc_ed_review_emails(self):
# We expect one email to be sent here:
# * to the publisher, notifying that an editor is viewing their application
- publisher_template = re.escape('email/notification_email.jinja2')
+ publisher_template = re.escape(templates.EMAIL_NOTIFICATION)
publisher_to = re.escape(owner.email)
publisher_subject = re.escape('Directory of Open Access Journals - Your submission ({}) is under review'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -687,7 +688,7 @@ def test_03_assoc_ed_review_emails(self):
# We expect one email sent:
# * to the editor, informing them an application has been completed by an Associate Editor
- editor_template = re.escape('notification_email.jinja2')
+ editor_template = re.escape(templates.EMAIL_NOTIFICATION)
editor_to = re.escape('eddie@example.com')
editor_subject = re.escape('Directory of Open Access Journals - Application ({}) marked as completed'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
editor_email_matched = re.search(email_log_regex % (editor_template, editor_to, editor_subject),
@@ -803,7 +804,7 @@ def test_01_maned_review_emails(self):
assert notification.action is not None
assert notification.classification == constants.NOTIFICATION_CLASSIFICATION_STATUS_CHANGE
- editor_template = re.escape('email/notification_email.jinja2')
+ editor_template = re.escape(templates.EMAIL_NOTIFICATION)
editor_to = re.escape('eddie@example.com')
editor_subject = re.escape("Application ({}) reverted to 'In Progress' by Managing Editor".format(', '.join(issn for issn in processor.source.bibjson().issns())))
editor_email_matched = re.search(email_log_regex % (editor_template, editor_to, editor_subject),
@@ -820,7 +821,7 @@ def test_01_maned_review_emails(self):
assert notification.action is not None
assert notification.classification == constants.NOTIFICATION_CLASSIFICATION_STATUS_CHANGE
- assoc_editor_template = re.escape('email/notification_email.jinja2')
+ assoc_editor_template = re.escape(templates.EMAIL_NOTIFICATION)
assoc_editor_to = re.escape('associate@example.com')
assoc_editor_subject = re.escape(self.svc.short_notification(
ApplicationAssedInprogressNotify.ID).replace("{issns}", ", ".join(issn for issn in processor.target.bibjson().issns())) + "\n") # "an application assigned to you has not passed review."
@@ -874,7 +875,7 @@ def test_01_maned_review_emails(self):
assert notification.action is not None
assert notification.classification == constants.NOTIFICATION_CLASSIFICATION_STATUS_CHANGE
- editor_template = re.escape('email/notification_email.jinja2')
+ editor_template = re.escape(templates.EMAIL_NOTIFICATION)
editor_to = re.escape('eddie@example.com')
editor_subject = re.escape("Application ({}) reverted to 'In Progress' by Managing Editor".format(', '.join(issn for issn in processor.source.bibjson().issns())))
editor_email_matched = re.search(email_log_regex % (editor_template, editor_to, editor_subject),
@@ -891,7 +892,7 @@ def test_01_maned_review_emails(self):
assert notification.action is not None
assert notification.classification == constants.NOTIFICATION_CLASSIFICATION_STATUS_CHANGE
- assoc_editor_template = re.escape('email/notification_email.jinja2')
+ assoc_editor_template = re.escape(templates.EMAIL_NOTIFICATION)
assoc_editor_to = re.escape('associate@example.com')
assoc_editor_subject = re.escape(self.svc.short_notification(
ApplicationAssedInprogressNotify.ID).replace("{issns}", ", ".join(issn for issn in processor.source.bibjson().issns())) + "\n") # "an application assigned to you has not passed review."
@@ -927,16 +928,16 @@ def test_01_maned_review_emails(self):
# We expect 2 emails to be sent:
# * to the AssEd who's been assigned,
# * and to the publisher informing them there's an editor assigned.
- assEd_template = 'email/notification_email.jinja2'
+ assEd_template = templates.EMAIL_NOTIFICATION
assEd_to = re.escape(models.Account.pull('associate_3').email)
assEd_subject = re.escape('New application ({}) assigned to you'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
assEd_email_matched = re.search(email_log_regex % (assEd_template, assEd_to, assEd_subject),
info_stream_contents,
re.DOTALL)
- assert bool(assEd_email_matched)
+ assert bool(assEd_email_matched), info_stream_contents.strip('\x00')
- publisher_template = 'email/notification_email.jinja2'
+ publisher_template = templates.EMAIL_NOTIFICATION
publisher_to = re.escape(owner.email)
publisher_subject = re.escape('Your update request ({}) has been assigned to an editor for review'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -968,7 +969,7 @@ def test_01_maned_review_emails(self):
# We expect 2 emails to be sent:
# * to the editor of the assigned group,
# * to the AssEd who's been assigned
- editor_template = re.escape('email/notification_email.jinja2')
+ editor_template = re.escape(templates.EMAIL_NOTIFICATION)
editor_to = re.escape('eddie@example.com')
editor_subject = re.escape('New application ({}) assigned to your group'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -977,14 +978,14 @@ def test_01_maned_review_emails(self):
re.DOTALL)
assert bool(editor_email_matched)
- assEd_template = 'email/notification_email.jinja2'
+ assEd_template = templates.EMAIL_NOTIFICATION
assEd_to = re.escape(models.Account.pull('associate_3').email)
assEd_subject = re.escape('New application ({}) assigned to you'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
assEd_email_matched = re.search(email_log_regex % (assEd_template, assEd_to, assEd_subject),
info_stream_contents,
re.DOTALL)
- assert bool(assEd_email_matched)
+ assert bool(assEd_email_matched), info_stream_contents.strip('\x00')
assert len(re.findall(email_count_string, info_stream_contents)) == 2
# Clear the stream for the next part
@@ -1005,7 +1006,7 @@ def test_01_maned_review_emails(self):
# We expect one email to be sent here:
# * to the ManEds, saying an application is ready
- manEd_template = 'email/notification_email.jinja2'
+ manEd_template = templates.EMAIL_NOTIFICATION
manEd_to = re.escape("maned@example.com")
manEd_subject = re.escape('Application ({}) marked as ready'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -1032,7 +1033,7 @@ def test_01_maned_review_emails(self):
# We expect 1 email to be sent:
# * to the publisher, informing them of the journal's acceptance
# * to the journal contact, informing them of the journal's acceptance
- publisher_template = 'email/notification_email.jinja2'
+ publisher_template = templates.EMAIL_NOTIFICATION
publisher_to = re.escape(owner.email)
publisher_subject = re.escape('Update request ({}) accepted'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -1082,7 +1083,7 @@ def test_02_ed_review_emails(self):
# We expect one email to be sent here:
# * to the ManEds, saying an application is ready
- manEd_template = 'email/notification_email.jinja2'
+ manEd_template = templates.EMAIL_NOTIFICATION
manEd_to = re.escape("maned@example.com")
manEd_subject = re.escape('Application ({}) marked as ready'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -1116,16 +1117,16 @@ def test_02_ed_review_emails(self):
# We expect 2 emails to be sent:
# * to the AssEd who's been assigned,
# * and to the publisher informing them there's an editor assigned.
- assEd_template = 'email/notification_email.jinja2'
+ assEd_template = templates.EMAIL_NOTIFICATION
assEd_to = re.escape(models.Account.pull('associate_3').email)
assEd_subject = re.escape('New application ({}) assigned to you'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
assEd_email_matched = re.search(email_log_regex % (assEd_template, assEd_to, assEd_subject),
info_stream_contents,
re.DOTALL)
- assert bool(assEd_email_matched)
+ assert bool(assEd_email_matched), info_stream_contents.strip('\x00')
- publisher_template = 'email/notification_email.jinja2'
+ publisher_template = templates.EMAIL_NOTIFICATION
publisher_to = re.escape(owner.email)
publisher_subject = re.escape('Your update request ({}) has been assigned to an editor for review'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -1154,14 +1155,14 @@ def test_02_ed_review_emails(self):
# We expect 1 email to be sent:
# * to the AssEd who's been assigned,
- assEd_template = 'email/notification_email.jinja2'
+ assEd_template = templates.EMAIL_NOTIFICATION
assEd_to = re.escape(models.Account.pull('associate_2').email)
assEd_subject = re.escape('New application ({}) assigned to you'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
assEd_email_matched = re.search(email_log_regex % (assEd_template, assEd_to, assEd_subject),
info_stream_contents,
re.DOTALL)
- assert bool(assEd_email_matched)
+ assert bool(assEd_email_matched), info_stream_contents.strip('\x00')
assert len(re.findall(email_count_string, info_stream_contents)) == 1
# Clear the stream for the next part
@@ -1195,7 +1196,7 @@ def test_02_ed_review_emails(self):
# We expect one email to be sent:
# * to the associate editor, informing them the application has been bounced back to in progress.
- assoc_editor_template = re.escape('email/notification_email.jinja2')
+ assoc_editor_template = re.escape(templates.EMAIL_NOTIFICATION)
assoc_editor_to = re.escape('associate@example.com')
assoc_editor_subject = re.escape('One of your applications ({}) has not passed review'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
assoc_editor_email_matched = re.search(
@@ -1241,7 +1242,7 @@ def test_03_assoc_ed_review_emails(self):
# We expect one email to be sent here:
# * to the publisher, notifying that an editor is viewing their application
- publisher_template = re.escape('email/notification_email.jinja2')
+ publisher_template = re.escape(templates.EMAIL_NOTIFICATION)
publisher_to = re.escape(owner.email)
publisher_subject = re.escape('Your submission ({}) is under review'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -1262,7 +1263,7 @@ def test_03_assoc_ed_review_emails(self):
# We expect one email sent:
# * to the editor, informing them an application has been completed by an Associate Editor
- editor_template = re.escape('email/notification_email.jinja2')
+ editor_template = re.escape(templates.EMAIL_NOTIFICATION)
editor_to = re.escape('eddie@example.com')
editor_subject = re.escape("Application ({}) marked as completed".format(', '.join(issn for issn in processor.source.bibjson().issns())))
editor_email_matched = re.search(email_log_regex % (editor_template, editor_to, editor_subject),
@@ -1330,7 +1331,7 @@ def test_01_maned_review_emails(self):
# We expect 2 emails to be sent:
# * to the editor of the assigned group,
# * to the AssEd who's been assigned,
- editor_template = re.escape('email/notification_email.jinja2')
+ editor_template = re.escape(templates.EMAIL_NOTIFICATION)
editor_to = re.escape('eddie@example.com')
editor_subject = re.escape('Directory of Open Access Journals - New journal ({}) assigned to your group'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
@@ -1339,14 +1340,14 @@ def test_01_maned_review_emails(self):
re.DOTALL)
assert bool(editor_email_matched)
- assEd_template = re.escape('email/notification_email.jinja2')
+ assEd_template = re.escape(templates.EMAIL_NOTIFICATION)
assEd_to = re.escape(models.Account.pull('associate_3').email)
assEd_subject = re.escape('Directory of Open Access Journals - New journal ({}) assigned to you'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
assEd_email_matched = re.search(email_log_regex % (assEd_template, assEd_to, assEd_subject),
info_stream_contents,
re.DOTALL)
- assert bool(assEd_email_matched)
+ assert bool(assEd_email_matched), info_stream_contents.strip('\x00')
assert len(re.findall(email_count_string, info_stream_contents)) == 2
ctx.pop()
@@ -1370,14 +1371,14 @@ def test_02_ed_review_emails(self):
# We expect 1 email to be sent:
# * to the AssEd who's been assigned
- assEd_template = re.escape('email/notification_email.jinja2')
+ assEd_template = re.escape(templates.EMAIL_NOTIFICATION)
assEd_to = re.escape(models.Account.pull('associate_2').email)
assEd_subject = re.escape('Directory of Open Access Journals - New journal ({}) assigned to you'.format(', '.join(issn for issn in processor.source.bibjson().issns())))
assEd_email_matched = re.search(email_log_regex % (assEd_template, assEd_to, assEd_subject),
info_stream_contents,
re.DOTALL)
- assert bool(assEd_email_matched)
+ assert bool(assEd_email_matched), info_stream_contents.strip('\x00')
assert len(re.findall(email_count_string, info_stream_contents)) == 1
ctx.pop()
diff --git a/doajtest/unit/application_processors/test_readonly_journal.py b/doajtest/unit/application_processors/test_readonly_journal.py
index 9e4bc4c42a..3a98d69805 100644
--- a/doajtest/unit/application_processors/test_readonly_journal.py
+++ b/doajtest/unit/application_processors/test_readonly_journal.py
@@ -39,14 +39,63 @@ def tearDown(self):
super(TestReadOnlyJournal, self).tearDown()
lcc.lookup_code = self.old_lookup_code
- ###########################################################
- # Tests on the publisher's re-journal form
- ###########################################################
- def test_01_readonly_journal_success(self):
- """Give the read-only journal form a full workout"""
+ def test_01_unknown_context(self):
+ """ Pulling the wrong context gives an exception """
+
+ with self.assertRaises(AttributeError):
+ formulaic_context = JournalFormFactory.context("readonly")
+ fc = formulaic_context.processor(source=models.Journal(**JOURNAL_SOURCE))
+
+ def test_02_editor_readonly_journal(self):
+ """ Tests on the editor's read-only journal form """
+
+ # we start by constructing it from source
+ formulaic_context = JournalFormFactory.context("editor_readonly")
+ fc = formulaic_context.processor(source=models.Journal(**JOURNAL_SOURCE))
+ assert isinstance(fc, ReadOnlyJournal)
+ assert fc.form is not None
+ assert fc.source is not None
+ assert fc.form_data is None
+
+ # now construct it from form data (with a known source)
+ journal_obj = models.Journal(**JOURNAL_SOURCE)
+ journal_bibjson_obj = journal_obj.bibjson()
+ fc = formulaic_context.processor(
+ formdata=JOURNAL_FORM,
+ source=journal_obj
+ )
+
+ assert isinstance(fc, ReadOnlyJournal)
+ assert fc.form is not None
+ assert fc.source is not None
+ assert fc.form_data is not None
+
+ # see that form has the correct info from an object (after all, that's the only point of having the form)
+ assert fc.form.title.data == journal_bibjson_obj.title
+ assert fc.form.pissn.data == journal_bibjson_obj.pissn
+ assert fc.form.eissn.data == journal_bibjson_obj.eissn
+
+ # test each of the workflow components individually ...
+
+ # run the validation
+ assert fc.validate(), fc.form.errors
+
+ # run the crosswalk (no need to look in detail, xwalks are tested elsewhere)
+ fc.form2target()
+ assert fc.target is None # can't edit data using this form
+
+ # patch the target with data from the source
+ fc.patch_target()
+ assert fc.target is None # can't edit data using this form
+
+ # shouldn't be able to finalise, can't edit data using this form
+ self.assertRaises(Exception, fc.finalise)
+
+ def test_03_maned_readonly_journal(self):
+ """ Tests on the managing editor's read-only journal form """
# we start by constructing it from source
- formulaic_context = JournalFormFactory.context("readonly")
+ formulaic_context = JournalFormFactory.context("admin_readonly")
fc = formulaic_context.processor(source=models.Journal(**JOURNAL_SOURCE))
assert isinstance(fc, ReadOnlyJournal)
assert fc.form is not None
diff --git a/doajtest/unit/event_consumers/test_account_created_email.py b/doajtest/unit/event_consumers/test_account_created_email.py
index d360eb673e..7e5af568a8 100644
--- a/doajtest/unit/event_consumers/test_account_created_email.py
+++ b/doajtest/unit/event_consumers/test_account_created_email.py
@@ -8,6 +8,7 @@
from io import StringIO
import logging
import re
+from portality.ui import templates
# A regex string for searching the log entries
email_log_regex = 'template.*%s.*to:\[u{0,1}\'%s.*subject:.*%s'
@@ -65,7 +66,7 @@ def test_consume_success(self):
# We expect one email sent:
# * to the applicant, informing them the application was received
- template = re.escape('account_created.jinja2')
+ template = re.escape(templates.EMAIL_ACCOUNT_CREATED)
to = re.escape(acc.email)
subject = "Directory of Open Access Journals - account created, please verify your email address"
email_matched = re.search(email_log_regex % (template, to, subject),
diff --git a/doajtest/unit/event_consumers/test_account_passwordreset_email.py b/doajtest/unit/event_consumers/test_account_passwordreset_email.py
index 43119416cd..a400f7358d 100644
--- a/doajtest/unit/event_consumers/test_account_passwordreset_email.py
+++ b/doajtest/unit/event_consumers/test_account_passwordreset_email.py
@@ -8,6 +8,7 @@
from io import StringIO
import logging
import re
+from portality.ui import templates
# A regex string for searching the log entries
email_log_regex = 'template.*%s.*to:\[u{0,1}\'%s.*subject:.*%s'
@@ -65,7 +66,7 @@ def test_consume_success(self):
# We expect one email sent:
# * to the applicant, informing them the application was received
- template = re.escape('account_password_reset.jinja2')
+ template = re.escape(templates.EMAIL_PASSWORD_RESET)
to = re.escape(acc.email)
subject = "Directory of Open Access Journals - password reset"
email_matched = re.search(email_log_regex % (template, to, subject),
diff --git a/doajtest/unit/event_consumers/test_journal_assed_assigned_notify.py b/doajtest/unit/event_consumers/test_journal_assed_assigned_notify.py
index 2882e51ea7..f24a9c894a 100644
--- a/doajtest/unit/event_consumers/test_journal_assed_assigned_notify.py
+++ b/doajtest/unit/event_consumers/test_journal_assed_assigned_notify.py
@@ -49,7 +49,7 @@ def test_consume_success(self):
assert n.classification == constants.NOTIFICATION_CLASSIFICATION_ASSIGN
assert n.long is not None
assert n.short is not None
- assert n.action is not None
+ assert n.action is None # view.editor.journal_page has been removed
assert not n.is_seen()
def test_consume_fail(self):
diff --git a/doajtest/unit/event_consumers/test_journal_editor_group_assigned_notify.py b/doajtest/unit/event_consumers/test_journal_editor_group_assigned_notify.py
index ed0b46d775..e55d0ea082 100644
--- a/doajtest/unit/event_consumers/test_journal_editor_group_assigned_notify.py
+++ b/doajtest/unit/event_consumers/test_journal_editor_group_assigned_notify.py
@@ -41,7 +41,7 @@ def test_consume_success(self):
eg.set_editor("editor")
eg.save(blocking=True)
- event = models.Event(constants.EVENT_JOURNAL_EDITOR_GROUP_ASSIGNED, context={"journal" : app.data})
+ event = models.Event(constants.EVENT_JOURNAL_EDITOR_GROUP_ASSIGNED, context={"journal": app.data})
JournalEditorGroupAssignedNotify.consume(event)
time.sleep(1)
@@ -54,7 +54,7 @@ def test_consume_success(self):
assert n.classification == constants.NOTIFICATION_CLASSIFICATION_ASSIGN
assert n.long is not None
assert n.short is not None
- assert n.action is not None
+ assert n.action is None # view.editor.journal_page has been removed
assert not n.is_seen()
def test_consume_fail(self):
diff --git a/doajtest/unit/test_application_forms.py b/doajtest/unit/test_application_forms.py
index 94e17ab761..7e0fd9e47e 100644
--- a/doajtest/unit/test_application_forms.py
+++ b/doajtest/unit/test_application_forms.py
@@ -1,3 +1,7 @@
+"""
+NOTE: This test has been disabled due to the removal of the /editor/journal route (see portality.view.editor#51)
+"""
+
import pytest
from doajtest import helpers
@@ -38,6 +42,7 @@ def test_disable_edit_note_except_editing_user(user_id, expected_result):
class TestEditableNote(DoajTestCase):
+ @pytest.mark.skip(reason="Untestable: we don't have the editor.journal_page route enabled") # FIXME: permanently?
def test_note_textarea_disabled_correctly(self):
pwd = 'password123'
acc = models.Account(**AccountFixtureFactory.make_editor_source())
diff --git a/doajtest/unit/test_bll_notifications_notify.py b/doajtest/unit/test_bll_notifications_notify.py
index 1720ac6add..15244f6ec1 100644
--- a/doajtest/unit/test_bll_notifications_notify.py
+++ b/doajtest/unit/test_bll_notifications_notify.py
@@ -5,6 +5,7 @@
from portality import models
from portality.bll import DOAJ
from portality.ui.messages import Messages
+from portality.ui import templates
from portality.bll.exceptions import NoSuchObjectException, NoSuchPropertyException
# A regex string for searching the log entries
@@ -60,7 +61,7 @@ def test_01_notify(self):
info_stream_contents = self.info_stream.getvalue()
# check an email is sent
- template = re.escape('email/notification_email.jinja2')
+ template = re.escape(templates.EMAIL_NOTIFICATION)
to = re.escape('test@example.com')
subject = n2.short
email_matched = re.search(
diff --git a/docs/redhead/config.json b/docs/redhead/config.json
new file mode 100644
index 0000000000..1202c4641a
--- /dev/null
+++ b/docs/redhead/config.json
@@ -0,0 +1,12 @@
+[
+ {
+ "template_dir": "/home/richard/Dropbox/Code/doaj3/portality/templates",
+ "template_filters": [".*\\.html$", ".*\\.jinja2$", ".*_frag$"],
+ "out_dir": "/home/richard/Dropbox/Code/doaj3/docs/redhead/templates"
+ },
+ {
+ "template_dir": "/home/richard/Dropbox/Code/doaj3/portality/templates-v2",
+ "template_filters": [".*\\.html$", ".*\\.jinja2$", ".*_frag$"],
+ "out_dir": "/home/richard/Dropbox/Code/doaj3/docs/redhead/templates-v2"
+ }
+]
\ No newline at end of file
diff --git a/docs/redhead/templates-v2/redhead_blocks.html b/docs/redhead/templates-v2/redhead_blocks.html
new file mode 100644
index 0000000000..a3fb516a7c
--- /dev/null
+++ b/docs/redhead/templates-v2/redhead_blocks.html
@@ -0,0 +1,1910 @@
+
+
+
+
+ Redhead: Jinja2 template structure browser
+
+
+
+
+
+
+
+
+
+
+
+File Inheritance | Block Inheritance |
+ Records JSON | Tree JSON | Blocks JSON
List of Application JSON objects that you would like to create. Each element of the list should comply with the schema displayed in the GET (Retrieve) an application route.
",
+ "description": "
List of Application JSON objects that you would like to create. Each element of the list should comply with the schema displayed in the 'GET (Retrieve) an application route' below.
A list/array of article JSON objects that you would like to create or update. The contents should be a list, and each object in the list should comply with the schema displayed in the GET (Retrieve) an article route. Partial updates are not allowed; you have to supply the full JSON.
",
+ "description": "
A list/array of article JSON objects that you would like to create or update. The contents should be a list, and each object in the list should comply with the schema displayed in the 'GET (Retrieve) an article route' below. Partial updates are not allowed; you have to supply the full JSON.
A list/array of article JSON objects that you would like to create or update. The contents should be a list, and each object in the list should comply with the schema displayed in the GET (Retrieve) an article route. Partial updates are not allowed; you have to supply the full JSON.
This request is asynchronous; the response will contain an upload_id. You can use this id to query the task status.
",
+ "description": "
A list/array of article JSON objects that you would like to create or update. The contents should be a list, and each object in the list should comply with the schema displayed in the 'GET (Retrieve) an article route' below. Partial updates are not allowed; you have to supply the full JSON.
This request is asynchronous; the response will contain an upload_id. You can use this id to query the task status.
",
"required": True,
"schema": {"type": "string"},
"name": "article_json",
diff --git a/portality/api/current/crud/applications.py b/portality/api/current/crud/applications.py
index 064e099b5a..f9bfcd6df0 100644
--- a/portality/api/current/crud/applications.py
+++ b/portality/api/current/crud/applications.py
@@ -13,6 +13,7 @@
from portality import lock
from portality.crosswalks.application_form import ApplicationFormXWalk
from portality.forms.application_forms import ApplicationFormFactory
+from portality.ui import templates
from copy import deepcopy
@@ -78,7 +79,7 @@ def create(cls, data, account, dry_run=False):
app_email.send_mail(to=to,
fro=fro,
subject=subject,
- template_name="email/script_tag_detected.jinja2",
+ template_name=templates.EMAIL_SCRIPT_TAG_DETECTED,
es_type=es_type,
data=jdata)
except app_email.EmailException:
diff --git a/portality/api/current/crud/articles.py b/portality/api/current/crud/articles.py
index cb8e0d9e5a..c416f5c1f0 100644
--- a/portality/api/current/crud/articles.py
+++ b/portality/api/current/crud/articles.py
@@ -15,6 +15,7 @@
IngestException
from portality.dao import ElasticSearchWriteException, DAOSaveExceptionMaxRetriesReached
from copy import deepcopy
+from portality.ui import templates
class ArticlesCrudApi(CrudApi):
@@ -137,7 +138,7 @@ def prep_article(cls, data: Dict, account: models.Account) -> models.Article:
app_email.send_mail(to=to,
fro=fro,
subject=subject,
- template_name="email/script_tag_detected.jinja2",
+ template_name=templates.EMAIL_SCRIPT_TAG_DETECTED,
es_type=es_type,
data=jdata)
except app_email.EmailException:
diff --git a/portality/app.py b/portality/app.py
index 2b6e5115a2..0ad6e4f609 100644
--- a/portality/app.py
+++ b/portality/app.py
@@ -26,6 +26,7 @@
from portality import settings
from portality.lib import edges, dates
from portality.lib.dates import FMT_DATETIME_STD, FMT_YEAR
+from portality.ui import templates
from portality.view.account import blueprint as account
from portality.view.admin import blueprint as admin
@@ -422,22 +423,22 @@ def get_site_key():
@app.errorhandler(400)
def page_not_found(e):
- return render_template('400.html'), 400
+ return render_template(templates.ERROR_400), 400
@app.errorhandler(401)
def page_not_found(e):
- return render_template('401.html'), 401
+ return render_template(templates.ERROR_401), 401
@app.errorhandler(404)
def page_not_found(e):
- return render_template('404.html'), 404
+ return render_template(templates.ERROR_404), 404
@app.errorhandler(500)
def page_not_found(e):
- return render_template('500.html'), 500
+ return render_template(templates.ERROR_500), 500
@app.errorhandler(elasticsearch.exceptions.RequestError)
diff --git a/portality/bll/services/notifications.py b/portality/bll/services/notifications.py
index 50574d8fca..3dcd2a6a1f 100644
--- a/portality/bll/services/notifications.py
+++ b/portality/bll/services/notifications.py
@@ -6,7 +6,7 @@
from portality.bll.exceptions import NoSuchObjectException, NoSuchPropertyException
from datetime import datetime
from portality.lib import dates
-
+from portality.ui import templates
class NotificationsService(object):
def notify(self, notification: models.Notification):
@@ -29,8 +29,8 @@ def notify(self, notification: models.Notification):
app_email.send_markdown_mail(to=to,
fro=fro,
subject=subject,
- template_name="email/notification_email.jinja2",
- markdown_template_name="email/notification_email.jinja2", # for the moment the markdown and plaintext templates are the same
+ template_name=templates.EMAIL_NOTIFICATION,
+ markdown_template_name=templates.EMAIL_NOTIFICATION, # for the moment the markdown and plaintext templates are the same
user=acc,
message=notification.long,
action=notification.action,
diff --git a/portality/constants.py b/portality/constants.py
index 2fec308772..4372aa503c 100644
--- a/portality/constants.py
+++ b/portality/constants.py
@@ -60,10 +60,6 @@
TODO_ASSOCIATE_START_PENDING = "todo_associate_start_pending"
TODO_ASSOCIATE_ALL_APPLICATIONS = "todo_associate_all_applications"
-# Roles
-ROLE_ASSOCIATE_EDITOR = 'associate_editor'
-ROLE_API = "api"
-
EVENT_ACCOUNT_CREATED = "account:created"
EVENT_ACCOUNT_PASSWORD_RESET = "account:password_reset"
EVENT_APPLICATION_STATUS = "application:status"
@@ -88,9 +84,9 @@
# Role
ROLE_ADMIN = "admin"
ROLE_PUBLISHER = "publisher"
+ROLE_EDITOR = "editor"
ROLE_ASSOCIATE_EDITOR = 'associate_editor'
ROLE_PUBLIC_DATA_DUMP = "public_data_dump"
-ROLE_PUBLISHER = "publisher"
ROLE_PUBLISHER_JOURNAL_CSV = "journal_csv"
ROLE_PUBLISHER_PRESERVATION = "preservation"
ROLE_API = "api"
diff --git a/portality/core.py b/portality/core.py
index 8280edc620..d1146d1224 100644
--- a/portality/core.py
+++ b/portality/core.py
@@ -13,6 +13,7 @@
from portality.error_handler import setup_error_logging
from portality.lib import es_data_mapping, dates, paths
from portality.ui.debug_toolbar import DoajDebugToolbar
+from portality.ui import templates
import esprit
import elasticsearch
@@ -283,6 +284,7 @@ def setup_jinja(app):
app.jinja_env.globals['type'] = type
#~~->Constants:Config~~
app.jinja_env.globals['constants'] = constants
+ app.jinja_env.globals['templates'] = templates
#~~-> Dates:Library~~
app.jinja_env.globals['dates'] = dates
#~~->Datasets:Data~~
@@ -291,7 +293,8 @@ def setup_jinja(app):
app.jinja_env.globals['services'] = DOAJ
_load_data(app)
#~~->CMS:DataStore~~
- app.jinja_env.loader = FileSystemLoader([app.config['BASE_FILE_PATH'] + '/templates',
+ app.jinja_env.loader = FileSystemLoader([app.config['BASE_FILE_PATH'] + '/templates-v2',
+ app.config['BASE_FILE_PATH'] + '/templates',
os.path.dirname(app.config['BASE_FILE_PATH']) + '/cms/fragments'])
# a jinja filter that prints to the Flask log
diff --git a/portality/decorators.py b/portality/decorators.py
index 9779a7d806..ccaffacf6c 100644
--- a/portality/decorators.py
+++ b/portality/decorators.py
@@ -8,7 +8,7 @@
from portality.lib import dates
from portality.models import Account
from portality.models.harvester import HarvesterProgressReport as Report
-
+from portality.ui import templates
def swag(swag_summary, swag_spec):
"""
@@ -119,7 +119,8 @@ def decorated_view(*args, **kwargs):
resp.mimetype = "application/json"
return resp
else:
- return render_template("doaj/readonly.html")
+ # FIXME: ideally, this would show a different page for each different user class
+ return render_template(templates.PUBLIC_READ_ONLY_MODE)
return fn(*args, **kwargs)
diff --git a/portality/events/consumers/account_created_email.py b/portality/events/consumers/account_created_email.py
index 6f1f2ca171..b9012f3f9a 100644
--- a/portality/events/consumers/account_created_email.py
+++ b/portality/events/consumers/account_created_email.py
@@ -6,6 +6,7 @@
from portality import models
from portality.core import app
from portality.bll.exceptions import NoSuchPropertyException
+from portality.ui import templates
class AccountCreatedEmail(EventConsumer):
@@ -44,7 +45,7 @@ def _send_account_created_email(cls, account: models.Account):
app_email.send_mail(to=to,
fro=fro,
subject=subject,
- template_name="email/account_created.jinja2",
+ template_name=templates.EMAIL_ACCOUNT_CREATED,
reset_url=reset_url,
email=account.email,
timeout_days=password_create_timeout_days,
diff --git a/portality/events/consumers/account_passwordreset_email.py b/portality/events/consumers/account_passwordreset_email.py
index 92c00824e8..3c118137b8 100644
--- a/portality/events/consumers/account_passwordreset_email.py
+++ b/portality/events/consumers/account_passwordreset_email.py
@@ -6,6 +6,7 @@
from portality import models
from portality.core import app
from portality.bll.exceptions import NoSuchPropertyException
+from portality.ui import templates
class AccountPasswordResetEmail(EventConsumer):
@@ -35,7 +36,7 @@ def _send_password_reset_email(cls, account: models.Account):
app_email.send_mail(to=to,
fro=fro,
subject=subject,
- template_name="email/account_password_reset.jinja2",
+ template_name=templates.EMAIL_PASSWORD_RESET,
email=account.email,
reset_url=reset_url,
forgot_pw_url=app.config.get('BASE_URL', "https://doaj.org") + url_for('account.forgot')
diff --git a/portality/events/consumers/journal_assed_assigned_notify.py b/portality/events/consumers/journal_assed_assigned_notify.py
index 5788334e44..3fa2030d8a 100644
--- a/portality/events/consumers/journal_assed_assigned_notify.py
+++ b/portality/events/consumers/journal_assed_assigned_notify.py
@@ -43,6 +43,8 @@ def consume(cls, event):
notification.short = svc.short_notification(cls.ID).format(
issns=journal.bibjson().issns_as_text()
)
- notification.action = url_for("editor.journal_page", journal_id=journal.id)
+
+ # No action possible due to page removed (see portality.view.editor.journal_page(journal_id))
+ # notification.action = url_for("editor.journal_page", journal_id=journal.id)
svc.notify(notification)
diff --git a/portality/events/consumers/journal_editor_group_assigned_notify.py b/portality/events/consumers/journal_editor_group_assigned_notify.py
index 6f1637d019..0119bcaeb3 100644
--- a/portality/events/consumers/journal_editor_group_assigned_notify.py
+++ b/portality/events/consumers/journal_editor_group_assigned_notify.py
@@ -48,6 +48,8 @@ def consume(cls, event):
notification.short = svc.short_notification(cls.ID).format(
issns=journal.bibjson().issns_as_text()
)
- notification.action = url_for("editor.journal_page", journal_id=journal.id)
+
+ # No action possible due to page removed (see portality.view.editor.journal_page(journal_id))
+ # notification.action = url_for("editor.journal_page", journal_id=journal.id)
svc.notify(notification)
diff --git a/portality/forms/application_forms.py b/portality/forms/application_forms.py
index ff86584b7b..8d4adcd85d 100644
--- a/portality/forms/application_forms.py
+++ b/portality/forms/application_forms.py
@@ -46,6 +46,7 @@
from portality.models import EditorGroup
from portality.regex import ISSN, ISSN_COMPILED
from portality.ui.messages import Messages
+from portality.ui import templates
# Stop words used in the keywords field
STOP_WORDS = [
@@ -1143,8 +1144,8 @@ class FieldDefinitions:
"apc_currency",
"apc_max"
],
- "template": "application_form/_list.html",
- "entry_template": "application_form/_entry_group_horizontal.html",
+ "template": templates.AF_LIST,
+ "entry_template": templates.AF_ENTRY_GROUP_HORIZONTAL,
"widgets": [
"multiple_field"
]
@@ -1972,8 +1973,8 @@ class FieldDefinitions:
"note_id",
"note_author_id",
],
- "template": "application_form/_list.html",
- "entry_template": "application_form/_entry_group.html",
+ "template": templates.AF_LIST,
+ "entry_template": templates.AF_ENTRY_GOUP,
"widgets": [
{"infinite_repeat": {"enable_on_repeat": ["textarea"]}},
"note_modal"
@@ -2367,9 +2368,9 @@ class ApplicationContextDefinitions:
FieldSetDefinitions.UNIQUE_IDENTIFIERS["name"]
],
"templates": {
- "form": "application_form/public_application.html",
- "default_field": "application_form/_field.html",
- "default_group": "application_form/_group.html"
+ "form": templates.PUBLIC_APPLICATION_FORM,
+ "default_field": templates.AF_FIELD,
+ "default_group": templates.AF_GROUP
},
"crosswalks": {
"obj2form": ApplicationFormXWalk.obj2form,
@@ -2384,14 +2385,14 @@ class ApplicationContextDefinitions:
UPDATE = deepcopy(PUBLIC)
UPDATE["name"] = "update_request"
UPDATE["processor"] = application_processors.PublisherUpdateRequest
- UPDATE["templates"]["form"] = "application_form/publisher_update_request.html"
+ UPDATE["templates"]["form"] = templates.PUBLISHER_UPDATE_REQUEST_FORM
# ~~->$ ReadOnlyApplication:FormContext~~
# ~~^-> NewApplication:FormContext~~
READ_ONLY = deepcopy(PUBLIC)
READ_ONLY["name"] = "application_read_only"
READ_ONLY["processor"] = application_processors.NewApplication # FIXME: enter the real processor
- READ_ONLY["templates"]["form"] = "application_form/readonly_application.html"
+ READ_ONLY["templates"]["form"] = templates.PUBLISHER_READ_ONLY_APPLICATION
# ~~->$ AssociateEditorApplication:FormContext~~
# ~~^-> NewApplication:FormContext~~
@@ -2404,7 +2405,7 @@ class ApplicationContextDefinitions:
FieldSetDefinitions.NOTES["name"]
]
ASSOCIATE["processor"] = application_processors.AssociateApplication
- ASSOCIATE["templates"]["form"] = "application_form/assed_application.html"
+ ASSOCIATE["templates"]["form"] = templates.ASSED_APPLICATION_FORM
# ~~->$ EditorApplication:FormContext~~
# ~~^-> NewApplication:FormContext~~
@@ -2418,7 +2419,7 @@ class ApplicationContextDefinitions:
FieldSetDefinitions.NOTES["name"]
]
EDITOR["processor"] = application_processors.EditorApplication
- EDITOR["templates"]["form"] = "application_form/editor_application.html"
+ EDITOR["templates"]["form"] = templates.EDITOR_APPLICATION_FORM
# ~~->$ ManEdApplication:FormContext~~
# ~~^-> NewApplication:FormContext~~
@@ -2436,15 +2437,15 @@ class ApplicationContextDefinitions:
FieldSetDefinitions.NOTES["name"]
]
MANED["processor"] = application_processors.AdminApplication
- MANED["templates"]["form"] = "application_form/maned_application.html"
+ MANED["templates"]["form"] = templates.MANED_APPLICATION_FORM
class JournalContextDefinitions:
# ~~->$ ReadOnlyJournal:FormContext~~
# ~~^-> JournalForm:Crosswalk~~
# ~~^-> ReadOnlyJournal:FormProcessor~~
- READ_ONLY = {
- "name": "readonly",
+ ADMIN_READ_ONLY = {
+ "name": "admin_readonly",
"fieldsets": [
FieldSetDefinitions.BASIC_COMPLIANCE["name"],
FieldSetDefinitions.ABOUT_THE_JOURNAL["name"],
@@ -2464,9 +2465,9 @@ class JournalContextDefinitions:
FieldSetDefinitions.UNIQUE_IDENTIFIERS["name"]
],
"templates": {
- "form": "application_form/readonly_journal.html",
- "default_field": "application_form/_field.html",
- "default_group": "application_form/_group.html"
+ "form": templates.MANED_READ_ONLY_JOURNAL,
+ "default_field": templates.AF_FIELD,
+ "default_group": templates.AF_GROUP
},
"crosswalks": {
"obj2form": JournalFormXWalk.obj2form,
@@ -2475,17 +2476,22 @@ class JournalContextDefinitions:
"processor": application_processors.ReadOnlyJournal
}
+ # identical context for editors, mostly to support the different view contexts
+ EDITOR_READ_ONLY = deepcopy(ADMIN_READ_ONLY)
+ EDITOR_READ_ONLY["name"] = "editor_readonly"
+ EDITOR_READ_ONLY["templates"]["form"] = templates.EDITOR_READ_ONLY_JOURNAL
+
# ~~->$ AssEditorJournal:FormContext~~
# ~~^-> ReadOnlyJournal:FormContext~~
# ~~^-> AssEdJournal:FormProcessor~~
- ASSOCIATE = deepcopy(READ_ONLY)
+ ASSOCIATE = deepcopy(ADMIN_READ_ONLY)
ASSOCIATE["fieldsets"] += [
FieldSetDefinitions.SUBJECT["name"],
FieldSetDefinitions.NOTES["name"]
]
ASSOCIATE["name"] = "associate_editor"
ASSOCIATE["processor"] = application_processors.AssEdJournalReview
- ASSOCIATE["templates"]["form"] = "application_form/assed_journal.html"
+ ASSOCIATE["templates"]["form"] = templates.ASSED_JOURNAL_FORM
# ~~->$ EditorJournal:FormContext~~
# ~~^-> AssEdJournal:FormContext~~
@@ -2496,7 +2502,7 @@ class JournalContextDefinitions:
FieldSetDefinitions.REVIEWERS["name"]
]
EDITOR["processor"] = application_processors.EditorJournalReview
- EDITOR["templates"]["form"] = "application_form/editor_journal.html"
+ EDITOR["templates"]["form"] = templates.EDITOR_JOURNAL_FORM
# ~~->$ ManEdJournal:FormContext~~
# ~~^-> EditorJournal:FormContext~~
@@ -2510,7 +2516,7 @@ class JournalContextDefinitions:
FieldSetDefinitions.CONTINUATIONS["name"]
]
MANED["processor"] = application_processors.ManEdJournalReview
- MANED["templates"]["form"] = "application_form/maned_journal.html"
+ MANED["templates"]["form"] = templates.MANED_JOURNAL_FORM
# ~~->$ BulkEditJournal:FormContext~~
# ~~^-> JournalForm:Crosswalk~~
@@ -2521,9 +2527,9 @@ class JournalContextDefinitions:
FieldSetDefinitions.BULK_EDIT["name"]
],
"templates": {
- "form": "application_form/maned_journal_bulk_edit.html",
- "default_field": "application_form/_field.html",
- "default_group": "application_form/_group.html"
+ "form": templates.MANED_JOURNAL_BULK_EDIT,
+ "default_field": templates.AF_FIELD,
+ "default_group": templates.AF_GROUP
},
"crosswalks": {
"obj2form": JournalFormXWalk.obj2form,
@@ -2552,7 +2558,8 @@ class JournalContextDefinitions:
JOURNAL_FORMS = {
"contexts": {
- JournalContextDefinitions.READ_ONLY["name"]: JournalContextDefinitions.READ_ONLY,
+ JournalContextDefinitions.ADMIN_READ_ONLY["name"]: JournalContextDefinitions.ADMIN_READ_ONLY,
+ JournalContextDefinitions.EDITOR_READ_ONLY["name"]: JournalContextDefinitions.EDITOR_READ_ONLY,
JournalContextDefinitions.BULK_EDIT["name"]: JournalContextDefinitions.BULK_EDIT,
JournalContextDefinitions.ASSOCIATE["name"]: JournalContextDefinitions.ASSOCIATE,
JournalContextDefinitions.EDITOR["name"]: JournalContextDefinitions.EDITOR,
diff --git a/portality/forms/article_forms.py b/portality/forms/article_forms.py
index 92bfc44968..28a84a6c62 100644
--- a/portality/forms/article_forms.py
+++ b/portality/forms/article_forms.py
@@ -15,6 +15,7 @@
from portality.forms.validate import OptionalIf, ThisOrThat, NoScriptTag, DifferentTo
from portality.lib import dates
from portality.ui.messages import Messages
+from portality.ui import templates
#########################################
@@ -715,7 +716,7 @@ def __init__(self, source, form_data, user):
super(PublisherMetadataForm, self).__init__(source=source, form_data=form_data, user=user)
def set_template(self):
- self.template = "publisher/metadata.html"
+ self.template = templates.PUBLISHER_ARTICLE_METADATA
def render_template(self, **kwargs):
self._check_for_author_errors(**kwargs)
@@ -732,7 +733,7 @@ def __init__(self, source, form_data, user):
super(AdminMetadataArticleForm, self).__init__(source=source, form_data=form_data, user=user)
def set_template(self):
- self.template = "admin/article_metadata.html"
+ self.template = templates.ADMIN_ARTICLE_FORM
def render_template(self, **kwargs):
self._check_for_author_errors(**kwargs)
diff --git a/portality/notifications/application_emails.py b/portality/notifications/application_emails.py
index c0c65d92dd..2df06ae8b1 100644
--- a/portality/notifications/application_emails.py
+++ b/portality/notifications/application_emails.py
@@ -7,6 +7,7 @@
from portality.dao import Facetview2
from portality.ui.messages import Messages
from portality.lib import dates
+from portality.ui import templates
def send_editor_completed_email(application):
@@ -34,7 +35,7 @@ def send_editor_completed_email(application):
app_email.send_mail(to=to,
fro=fro,
subject=subject,
- template_name="email/editor_application_completed.jinja2",
+ template_name=templates.EMAIL_EDITOR_APPLICATION_COMPLETED,
editor=editor_id,
associate_editor=assoc_id,
application_title=journal_name,
@@ -56,7 +57,7 @@ def send_account_created_email(account):
app_email.send_mail(to=to,
fro=fro,
subject=subject,
- template_name="email/account_created.jinja2",
+ template_name=templates.EMAIL_ACCOUNT_CREATED,
reset_url=reset_url,
email=account.email,
timeout_days=password_create_timeout_days,
@@ -74,7 +75,7 @@ def send_account_password_reset_email(account):
app_email.send_mail(to=to,
fro=fro,
subject=subject,
- template_name="email/account_password_reset.jinja2",
+ template_name=templates.EMAIL_PASSWORD_RESET,
email=account.email,
reset_url=reset_url,
forgot_pw_url=url_for('account.forgot', _external=True)
diff --git a/portality/scripts/journals_last_manual_update_between.py b/portality/scripts/journals_last_manual_update_between.py
index 16977a5816..c68d785651 100644
--- a/portality/scripts/journals_last_manual_update_between.py
+++ b/portality/scripts/journals_last_manual_update_between.py
@@ -1,22 +1,24 @@
""" Create a CSV of journals last updated before a given date. Headings are:
Journal title
Journal URL
-Journal ISSN (print version)
Journal EISSN (online version)
+Journal ISSN (print version)
+DOAJ Form URL
Created date
Owner
Owner's email address
Country
Publisher
+Editor Group
"""
import csv
from portality.lib.dates import DEFAULT_TIMESTAMP_VAL
from portality.models import Journal, Account
-from portality.core import es_connection
+from portality.core import es_connection, app
from portality.lib import dates
-
+from portality.util import url_for
LAST_MANUAL_UPDATE_BETWEEN = {
"query": {
@@ -72,11 +74,13 @@
"Journal URL",
"E-ISSN",
"P-ISSN",
+ "DOAJ Form URL",
"Created Date",
"Owner",
"Owner's email address",
"Country",
- "Publisher"])
+ "Publisher",
+ "Editor Group"])
for journal in Journal.iterate(q=LAST_MANUAL_UPDATE_BETWEEN, keepalive='5m', wrap=True):
bibjson = journal.bibjson()
@@ -89,9 +93,11 @@
bibjson.get_single_url(urltype="homepage"),
bibjson.get_one_identifier(bibjson.E_ISSN),
bibjson.get_one_identifier(bibjson.P_ISSN),
+ app.config.get("BASE_URL") + url_for("admin.journal_page", journal_id=journal.id),
journal.created_date,
owner,
account.email if account else "Not Found",
index["country"],
- bibjson.publisher
+ bibjson.publisher,
+ journal.editor_group
])
diff --git a/portality/scripts/priorities.csv b/portality/scripts/priorities.csv
index f5e5cdcc59..bae43cd738 100644
--- a/portality/scripts/priorities.csv
+++ b/portality/scripts/priorities.csv
@@ -10,7 +10,7 @@ HP/PfT,"Priority: High, Workflow: Pending for Test",Review
HP/rev,Priority: High,Review
PfT,Workflow: Pending for Test,Review
PfL,Workflow: Pending for Live,Review
-Inv,Workflow: Initial Investigation,"Review, In Progress, To Do"
+Inv,Workflow: Initial Investigation,"Review, In progress, To Do"
Rev,,Review
Near,Scale: Nearly Finished,
Sch,Priority: Scheduled,
diff --git a/portality/scripts/redhead.py b/portality/scripts/redhead.py
new file mode 100644
index 0000000000..a2045c5834
--- /dev/null
+++ b/portality/scripts/redhead.py
@@ -0,0 +1,571 @@
+import re, json, os
+from flask import render_template
+from portality.app import app
+from copy import deepcopy
+
+
+BLOCK_RE = "{%[-]{0,1} block (.*?) (.*?)%}"
+ENDBLOCK_RE = "{%[-]{0,1} endblock (.*?)%}"
+EXTENDS_RE = "{% extends [\"'](.*?)[\"'] %}"
+INCLUDES_RE = "{% include [\"'](.*?)[\"'].*?%}"
+IMPORTS_RE = "{% from [\"'](.*?)[\"'].*?%}"
+DYNAMIC_INCLUDES_RE = "{% include ([^\"'].*?) %}"
+
+
+def analyse_template(template, template_dir, file_prefix):
+ with open(template, "r") as f:
+ lines = f.readlines()
+
+ structure = destructure(lines)
+ records = analyse(structure, template, template_dir, file_prefix)
+ return records
+
+
+def destructure(lines):
+ structure = {"content": []}
+
+ while len(lines) > 0:
+ block_until = -1
+ post_end_block_line_content = ""
+ for i, line in enumerate(lines):
+ bm = re.search(BLOCK_RE, line)
+ if bm:
+ current_block = bm.group(1)
+ is_scoped = "scoped" in bm.group(2)
+ idx0 = line.index(bm.group(0))
+ idx1 = idx0 + len(bm.group(0))
+ before = line[:idx0]
+ after = line[idx1:]
+
+ structure["content"].append(before)
+
+ if "blocks" not in structure:
+ structure["blocks"] = {}
+ structure["blocks"][current_block] = {"content": [], "scoped": is_scoped}
+
+ l, pos1, pos2 = _find_block_end([after] + lines[i+1:])
+
+ if l is None:
+ structure["blocks"][current_block] = {"content": [after]}
+ structure["blocks"][current_block]["content"] += lines[i+1:]
+ elif l == 0:
+ structure["blocks"][current_block] = {"content": [after[:pos1]]}
+ post_end_block_line_content = after[pos2:]
+ block_until = l + i
+ else:
+ block_until = l + i
+ structure["blocks"][current_block]["content"] += lines[i+1:block_until]
+ pre_end_block_line_content = lines[block_until][:pos1]
+ post_end_block_line_content = lines[block_until][pos2:]
+ structure["blocks"][current_block]["content"].append(pre_end_block_line_content)
+
+ break
+
+ else:
+ structure["content"].append(line)
+
+ remaining = []
+ if post_end_block_line_content != "" and post_end_block_line_content is not None:
+ remaining.append(post_end_block_line_content)
+ if block_until != -1:
+ remaining += lines[block_until+1:]
+ lines = remaining
+
+ for k, v in structure.get("blocks", {}).items():
+ structure["blocks"][k]["structure"] = destructure(v["content"])
+
+ return structure
+
+
+def _find_block_end(lines):
+ blockcount = 0
+
+ for i, line in enumerate(lines):
+ block_commands = []
+ for bsm in re.finditer(BLOCK_RE, line):
+ block_commands.append((bsm.start(), 1, bsm))
+ for bem in re.finditer(ENDBLOCK_RE, line):
+ block_commands.append((bem.start(), -1, bem))
+ block_commands.sort()
+ for bc in block_commands:
+ blockcount += bc[1]
+ if blockcount < 0:
+ return i, bc[0], bc[0] + len(bc[2].group(0))
+
+ return None, None, None
+
+
+def analyse(structure, template_name, template_dir, file_prefix):
+ records = []
+ tr = {
+ "type": "template",
+ "file": file_prefix + template_name[len(template_dir):]
+ }
+
+ if structure.get("blocks"):
+ tr["blocks"] = list(structure.get("blocks", {}).keys())
+
+ for i, line in enumerate(structure["content"]):
+ ems = re.finditer(EXTENDS_RE, line)
+ for em in ems:
+ if "extends" not in tr:
+ tr["extends"] = []
+ tr["extends"].append(em.group(1))
+
+ im = re.search(INCLUDES_RE, line)
+ if im:
+ if "includes" not in tr:
+ tr["includes"] = []
+ tr["includes"].append(im.group(1))
+
+ dim = re.search(DYNAMIC_INCLUDES_RE, line)
+ if dim:
+ if "dynamic_includes" not in tr:
+ tr["dynamic_includes"] = []
+ tr["dynamic_includes"].append(dim.group(1))
+
+ records.append(tr)
+
+ for k, v in structure.get("blocks", {}).items():
+ records += _analyse_block(v["structure"], k, template_name, template_dir, file_prefix, scoped=v.get("scoped", False))
+
+ return records
+
+
+def _analyse_block(block, block_name, template_name, template_dir, file_prefix, parent_block=None, scoped=False):
+ records = []
+ br = {
+ "type": "block",
+ "name": block_name,
+ "file": file_prefix + template_name[len(template_dir):],
+ "parent_block": parent_block,
+ "content": False,
+ "scoped": scoped
+ }
+
+ if block.get("blocks"):
+ br["blocks"] = list(block.get("blocks", {}).keys())
+
+ if len([l for l in block.get("content", []) if l.strip() != ""]) > 0:
+ br["content"] = True
+
+ for i, line in enumerate(block["content"]):
+ im = re.search(INCLUDES_RE, line)
+ if im:
+ if "includes" not in br:
+ br["includes"] = []
+ br["includes"].append(im.group(1))
+
+ dim = re.search(DYNAMIC_INCLUDES_RE, line)
+ if dim:
+ if "dynamic_includes" not in br:
+ br["dynamic_includes"] = []
+ br["dynamic_includes"].append(dim.group(1))
+
+ ip = re.search(IMPORTS_RE, line)
+ if ip:
+ if "includes" not in br:
+ br["includes"] = []
+ br["includes"].append(ip.group(1))
+
+ records.append(br)
+
+ for k, v in block.get("blocks", {}).items():
+ substructure = v["structure"]
+ if substructure:
+ records += _analyse_block(substructure, k, template_name, template_dir, file_prefix, parent_block=block_name)
+
+ return records
+
+
+def treeify(records):
+ base = _get_base_templates(records)
+ base.sort(key=lambda x: x["file"])
+
+ tree = []
+ for b in base:
+ tree.append(_expand_file_node(b, records))
+
+ return tree
+
+
+def _expand_file_node(record, records):
+ b = record
+
+ node = {
+ "name": b["file"],
+ "blocks": [],
+ "includes": [],
+ "extensions": []
+ }
+
+ blockset = []
+ for block in b.get("blocks", []):
+ for r in records:
+ if r["type"] == "block" and r["file"] == b["file"] and r["name"] == block:
+ blockset.append(r)
+
+ blockset.sort(key=lambda x: x["name"])
+ for bs in blockset:
+ br = _expand_block_node(bs, records)
+ node["blocks"].append(br)
+
+ extensions = []
+ for r in records:
+ if r["type"] == "template" and b["file"] in r.get("extends", []):
+ extensions.append(r)
+
+ extensions.sort(key=lambda x: x["file"])
+ for ex in extensions:
+ exr = _expand_file_node(ex, records)
+ node["extensions"].append(exr)
+
+ includes = []
+ if "includes" in b:
+ for r in records:
+ if r["type"] == "template" and r["file"] in b["includes"]:
+ includes.append(r)
+
+ includes.sort(key=lambda x: x["file"])
+ for inc in includes:
+ incn = _expand_file_node(inc, records)
+ node["includes"].append(incn)
+
+ if "dynamic_includes" in b:
+ node["dynamic_includes"] = b["dynamic_includes"]
+ node["dynamic_includes"].sort()
+
+ return node
+
+
+def _expand_block_node(record, records):
+ b = record
+
+ node = {
+ "name": b["name"],
+ "blocks": [],
+ "includes": [],
+ "content": b["content"],
+ "overridden_by": [],
+ "overrides": [],
+ "scoped": b.get("scoped", False)
+ }
+
+ blockset = []
+ for block in b.get("blocks", []):
+ for r in records:
+ if r["type"] == "block" and r["file"] == b["file"] and r["name"] == block:
+ blockset.append(r)
+
+ blockset.sort(key=lambda x: x["name"])
+ for bs in blockset:
+ br = _expand_block_node(bs, records)
+ node["blocks"].append(br)
+
+ includes = []
+ if "includes" in b:
+ resolved = []
+ for r in records:
+ if r["type"] == "template" and r["file"] in b["includes"]:
+ includes.append(r)
+ resolved.append(r["file"])
+ for inc in b["includes"]:
+ if inc not in resolved:
+ includes.append({
+ "name": inc,
+ "file": inc,
+ "unresolved": True
+ })
+
+ includes.sort(key=lambda x: x["file"])
+ for inc in includes:
+ if inc.get("unresolved"):
+ incn = {"name": inc["name"], "unresolved": True}
+ else:
+ incn = _expand_file_node(inc, records)
+ node["includes"].append(incn)
+
+ if "dynamic_includes" in b:
+ node["dynamic_includes"] = b["dynamic_includes"]
+ node["dynamic_includes"].sort()
+
+ overridden_by = []
+ for r in records:
+ if r["type"] == "block" and r["name"] == b["name"] and r["file"] != b["file"]:
+ paths = _extension_paths(r["file"], b["file"], records)
+ if len(paths) > 0:
+ overridden_by.append((r, paths))
+
+ overridden_by.sort(key=lambda x: x[0]["file"])
+ for ov, paths in overridden_by:
+ node["overridden_by"].append({
+ "file": ov["file"],
+ "content": ov["content"],
+ "paths": paths
+ })
+
+ overrides = []
+ for r in records:
+ if r["type"] == "block" and r["name"] == b["name"] and r["file"] != b["file"]:
+ paths = _extension_paths(b["file"], r["file"], records)
+ if len(paths) > 0:
+ overrides.append((r, paths))
+
+ overrides.sort(key=lambda x: x[0]["file"])
+ for ov, paths in overrides:
+ node["overrides"].append({
+ "file": ov["file"],
+ "content": ov["content"],
+ "paths": paths
+ })
+
+ return node
+
+
+def _extension_paths(child, parent, records):
+ paths = [[child]]
+
+ def get_record(file):
+ for r in records:
+ if r["type"] == "template" and r["file"] == file:
+ return r
+ return None
+
+ def navigate(node, path):
+ paths = []
+ current_record = get_record(node)
+ extends = current_record.get("extends", [])
+ if len(extends) == 0:
+ return [path]
+ for ex in extends:
+ local_path = deepcopy(path)
+ local_path.append(ex)
+ paths.append(local_path)
+ return paths
+
+ while True:
+ all_new_paths = []
+ for p in paths:
+ new_paths = navigate(p[-1], p)
+ all_new_paths += new_paths
+
+ if all_new_paths != paths:
+ paths = all_new_paths
+ else:
+ paths = all_new_paths
+ break
+
+ parent_paths = []
+ for p in paths:
+ p.reverse()
+ if parent in p:
+ idx = p.index(parent)
+ parent_paths.append(p[idx:])
+ return parent_paths
+
+
+def serialise(tree):
+ ctx = app.test_request_context("/")
+ ctx.push()
+ return render_template("dev/redhead/tree.html", tree=tree)
+
+def serialise_blocks(tree):
+ ctx = app.test_request_context("/")
+ ctx.push()
+ return render_template("dev/redhead/blocks.html", tree=tree)
+
+def _get_base_templates(records):
+ base = []
+ includes = set()
+ for r in records:
+ if r["type"] == "template" and r.get("extends") is None:
+ base.append(r)
+ if "includes" in r:
+ includes.update(r["includes"])
+
+ base_index = [r.get("file") for r in base]
+
+ removes = []
+ for inc in includes:
+ if inc in base_index:
+ idx = base_index.index(inc)
+ removes.append(idx)
+
+ removes.sort(reverse=True)
+ for r in removes:
+ del base[r]
+
+ return base
+
+
+def _expand_block_tree_node(record, records):
+ b = record
+
+ node = {
+ "name": b["name"],
+ "blocks": [],
+ # "includes": [],
+ # "content": b["content"],
+ # "overridden_by": [],
+ # "overrides": [],
+ # "scoped": b.get("scoped", False),
+ "files": []
+ }
+
+ all_block_definitions = [b]
+ for r in records:
+ if r["type"] == "block" and r["name"] == b["name"] and r["file"] != b["file"]:
+ all_block_definitions.append(r)
+
+ node["files"] += [x["file"] for x in all_block_definitions]
+
+ blocklist = []
+ for entry in all_block_definitions:
+ for block in entry.get("blocks", []):
+ for r in records:
+ if r["type"] == "block" and r["file"] == entry["file"] and r["name"] == block:
+ isnew = True
+ for b in blocklist:
+ if b["name"] == r["name"] and b["file"] == r["file"]:
+ isnew = False
+ if isnew:
+ blocklist.append(r)
+
+ blocklist.sort(key=lambda x: x["name"])
+ for bs in blocklist:
+ br = _expand_block_tree_node(bs, records)
+ node["blocks"].append(br)
+
+ # includes = []
+ # if "includes" in b:
+ # for r in records:
+ # if r["type"] == "template" and r["file"] in b["includes"]:
+ # includes.append(r)
+ #
+ # includes.sort(key=lambda x: x["file"])
+ # for inc in includes:
+ # incn = _expand_file_node(inc, records)
+ # node["includes"].append(incn)
+ #
+ # overridden_by = []
+ # for r in records:
+ # if r["type"] == "block" and r["name"] == b["name"] and r["file"] != b["file"]:
+ # paths = _extension_paths(r["file"], b["file"], records)
+ # if len(paths) > 0:
+ # overridden_by.append((r, paths))
+ #
+ # overridden_by.sort(key=lambda x: x[0]["file"])
+ # for ov, paths in overridden_by:
+ # node["overridden_by"].append({
+ # "file": ov["file"],
+ # "content": ov["content"],
+ # "paths": paths
+ # })
+ #
+ # overrides = []
+ # for r in records:
+ # if r["type"] == "block" and r["name"] == b["name"] and r["file"] != b["file"]:
+ # paths = _extension_paths(b["file"], r["file"], records)
+ # if len(paths) > 0:
+ # overrides.append((r, paths))
+ #
+ # overrides.sort(key=lambda x: x[0]["file"])
+ # for ov, paths in overrides:
+ # node["overrides"].append({
+ # "file": ov["file"],
+ # "content": ov["content"],
+ # "paths": paths
+ # })
+
+ return node
+
+def block_treeify(records):
+ base = _get_base_templates(records)
+
+ tree = []
+ for b in base:
+ blockset = []
+ for block in b.get("blocks", []):
+ for r in records:
+ if r["type"] == "block" and r["file"] == b["file"] and r["name"] == block:
+ blockset.append(r)
+
+ blockset.sort(key=lambda x: x["name"])
+ for bs in blockset:
+ tree.append(_expand_block_tree_node(bs, records))
+
+ return tree
+
+
+def redhead(out_dir, template_dir, template_root=None, template_filters=None):
+ file_prefix = ""
+
+ if not template_dir.endswith("/"):
+ template_dir += "/"
+
+ if template_root is None:
+ template_root = template_dir
+
+ if not template_root.endswith("/"):
+ template_root += "/"
+
+ if not template_root == template_dir:
+ file_prefix = template_dir[len(template_root):]
+
+ if not os.path.exists(out_dir):
+ os.makedirs(out_dir, exist_ok=True)
+
+ records = []
+
+ for (root, dirs, files) in os.walk(template_dir, topdown=True):
+ for f in files:
+ passed_filter = False
+ if template_filters is not None:
+ for tf in template_filters:
+ if re.match(tf, f):
+ passed_filter = True
+ break
+ else:
+ passed_filter = True
+ if passed_filter:
+ template = os.path.join(root, f)
+ print("Analysing", template)
+ records += analyse_template(template, template_dir, file_prefix)
+ else:
+ print("Skipping", f)
+
+ with open(os.path.join(out_dir, "redhead_records.json"), "w") as f:
+ f.write(json.dumps(records, indent=2))
+
+ tree = treeify(records)
+
+ with open(os.path.join(out_dir, "redhead_tree.json"), "w") as f:
+ f.write(json.dumps(tree, indent=2))
+
+ html = serialise(tree)
+ with open(os.path.join(out_dir, "redhead_tree.html"), "w") as f:
+ f.write(html)
+
+ block_tree = block_treeify(records)
+
+ with open(os.path.join(out_dir, "redhead_blocks.json"), "w") as f:
+ f.write(json.dumps(block_tree, indent=2))
+
+ block_html = serialise_blocks(block_tree)
+ with open(os.path.join(out_dir, "redhead_blocks.html"), "w") as f:
+ f.write(block_html)
+
+
+if __name__ == "__main__":
+ import argparse
+ import json
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument("config", help="The config file of run configurations")
+ args = parser.parse_args()
+
+ with open(args.config, "r") as f:
+ config = json.load(f)
+
+ for c in config:
+ redhead(c["out_dir"], c["template_dir"], template_root=c.get("template_root"), template_filters=c.get("template_filters"))
diff --git a/portality/settings.py b/portality/settings.py
index 1ad46e8720..9d6e313e6b 100644
--- a/portality/settings.py
+++ b/portality/settings.py
@@ -9,7 +9,7 @@
# Application Version information
# ~~->API:Feature~~
-DOAJ_VERSION = "6.8.5"
+DOAJ_VERSION = "7.0.0"
API_VERSION = "4.0.0"
######################################
@@ -39,7 +39,7 @@
DEBUG_PYCHARM_SERVER = 'localhost'
DEBUG_PYCHARM_PORT = 6000
-#~~->DebugToolbar:Framework~~
+# ~~->DebugToolbar:Framework~~
DEBUG_TB_TEMPLATE_EDITOR_ENABLED = True
DEBUG_TB_INTERCEPT_REDIRECTS = False
@@ -48,7 +48,7 @@
#######################################
# Elasticsearch configuration
-#~~->Elasticsearch:Technology
+# ~~->Elasticsearch:Technology
# elasticsearch settings # TODO: changing from single host / esprit to multi host on ES & correct the default
ELASTIC_SEARCH_HOST = os.getenv('ELASTIC_SEARCH_HOST', 'http://localhost:9200') # remember the http:// or https://
@@ -66,7 +66,7 @@
ELASTIC_SEARCH_DB_PREFIX = "doaj-" # note: include the separator
ELASTIC_SEARCH_TEST_DB_PREFIX = "doajtest-"
-INITIALISE_INDEX = True # whether or not to try creating the index and required index types on startup
+INITIALISE_INDEX = True # whether or not to try creating the index and required index types on startup
ELASTIC_SEARCH_VERSION = "7.10.2"
ELASTIC_SEARCH_SNAPSHOT_REPOSITORY = None
ELASTIC_SEARCH_SNAPSHOT_TTL = 366
@@ -233,7 +233,7 @@
]
# GitHub base url where static content can be edited by the DOAJ team (you can leave out the trailing slash)
-#~~->GitHub:ExternalService~~
+# ~~->GitHub:ExternalService~~
CMS_EDIT_BASE_URL = "https://github.com/DOAJ/doaj/edit/static_pages/cms"
# Where static files are served from - in case we need to serve a file
@@ -267,7 +267,6 @@
SITE_NOTE_KEY = "doaj-site-note"
SITE_NOTE_SLEEP = 259200 # every 3 days
SITE_NOTE_COOKIE_VALUE = "You have seen our most recent site wide announcement"
-SITE_NOTE_TEMPLATE = "doaj/site_note.html"
####################################
# Authorisation settings
@@ -285,7 +284,7 @@
# amount of time a reset token for a new account is valid for
PASSWORD_CREATE_TIMEOUT = PASSWORD_RESET_TIMEOUT * 14
-#"api" top-level role is added to all acounts on creation; it can be revoked per account by removal of the role.
+# "api" top-level role is added to all accounts on creation; it can be revoked per account by removal of the role.
TOP_LEVEL_ROLES = [
"admin",
"publisher",
@@ -437,7 +436,7 @@
"request_es_backup": {"month": "*", "day": "*", "day_of_week": "*", "hour": "6", "minute": "0"},
"check_latest_es_backup": {"month": "*", "day": "*", "day_of_week": "*", "hour": "9", "minute": "0"},
"prune_es_backups": {"month": "*", "day": "*", "day_of_week": "*", "hour": "9", "minute": "15"},
- "public_data_dump": {"month": "*", "day": "*", "day_of_week": "*", "hour": "10", "minute": "0"},
+ "public_data_dump": {"month": "*", "day": "*/6", "day_of_week": "*", "hour": "10", "minute": "0"},
"harvest": {"month": "*", "day": "*", "day_of_week": "*", "hour": "5", "minute": "30"},
"anon_export": {"month": "*", "day": "10", "day_of_week": "*", "hour": "6", "minute": "30"},
"old_data_cleanup": {"month": "*", "day": "12", "day_of_week": "*", "hour": "6", "minute": "30"},
@@ -447,9 +446,6 @@
"article_bulk_create": {"month": "*", "day": "*", "day_of_week": "*", "hour": "*", "minute": "20"},
}
-# Standard schedule for PDD (#3970)
-# "public_data_dump": {"month": "*", "day": "*/6", "day_of_week": "*", "hour": "10", "minute": "0"},
-
HUEY_TASKS = {
"ingest_articles": {"retries": 10, "retry_delay": 15},
@@ -690,15 +686,6 @@
'settings': DEFAULT_INDEX_SETTINGS
}
}
-# MAPPINGS['article'] = {'article': DEFAULT_DYNAMIC_MAPPING} #~~->Article:Model~~
-# MAPPINGS['upload'] = {'upload': DEFAULT_DYNAMIC_MAPPING} #~~->Upload:Model~~
-# MAPPINGS['cache'] = {'cache': DEFAULT_DYNAMIC_MAPPING} #~~->Cache:Model~~
-# MAPPINGS['lcc'] = {'lcc': DEFAULT_DYNAMIC_MAPPING} #~~->LCC:Model~~
-# MAPPINGS['editor_group'] = {'editor_group': DEFAULT_DYNAMIC_MAPPING} #~~->EditorGroup:Model~~
-# MAPPINGS['news'] = {'news': DEFAULT_DYNAMIC_MAPPING} #~~->News:Model~~
-# MAPPINGS['lock'] = {'lock': DEFAULT_DYNAMIC_MAPPING} #~~->Lock:Model~~
-# MAPPINGS['provenance'] = {'provenance': DEFAULT_DYNAMIC_MAPPING} #~~->Provenance:Model~~
-# MAPPINGS['preserve'] = {'preserve': DEFAULT_DYNAMIC_MAPPING} #~~->Preservation:Model~~
MAPPINGS['article'] = MAPPINGS["account"] #~~->Article:Model~~
MAPPINGS['upload'] = MAPPINGS["account"] #~~->Upload:Model~~
@@ -717,222 +704,223 @@
# ~~->Query:WebRoute~~
QUERY_ROUTE = {
- "query" : {
+ "query": {
# ~~->PublicJournalQuery:Endpoint~~
- "journal" : {
- "auth" : False,
- "role" : None,
- "query_validators" : ["non_public_fields_validator", "public_query_validator"],
- "query_filters" : ["only_in_doaj", "last_update_fallback", "search_all_meta"],
- "result_filters" : ["public_result_filter"],
- "dao" : "portality.models.Journal", # ~~->Journal:Model~~
- "required_parameters" : {"ref" : ["ssw", "public_journal", "subject_page"]}
+ "journal": {
+ "auth": False,
+ "role": None,
+ "query_validators": ["non_public_fields_validator", "public_query_validator"],
+ "query_filters": ["only_in_doaj", "last_update_fallback", "search_all_meta"],
+ "result_filters": ["public_result_filter"],
+ "dao": "portality.models.Journal", # ~~->Journal:Model~~
+ "required_parameters": {"ref": ["ssw", "public_journal", "subject_page"]}
},
# ~~->PublicArticleQuery:Endpoint~~
- "article" : {
- "auth" : False,
- "role" : None,
- "query_validators" : ["non_public_fields_validator", "public_query_validator"],
- "query_filters" : ["only_in_doaj"],
- "result_filters" : ["public_result_filter"],
- "dao" : "portality.models.Article", # ~~->Article:Model~~
- "required_parameters" : {"ref" : ["public_article", "toc", "subject_page"]}
+ "article": {
+ "auth": False,
+ "role": None,
+ "query_validators": ["non_public_fields_validator", "public_query_validator"],
+ "query_filters": ["only_in_doaj"],
+ "result_filters": ["public_result_filter"],
+ "dao": "portality.models.Article", # ~~->Article:Model~~
+ "required_parameters": {"ref": ["public_article", "toc", "subject_page"]}
},
# back-compat for fixed query widget
# ~~->PublicJournalArticleQuery:Endpoint~~
- "journal,article" : {
- "auth" : False,
- "role" : None,
- "query_validators" : ["non_public_fields_validator", "public_query_validator"],
- "query_filters" : ["only_in_doaj", "strip_facets", "es_type_fix", "journal_article_filter"],
- "result_filters" : ["public_result_filter", "add_fqw_facets", "fqw_back_compat"],
- "dao" : "portality.models.JournalArticle", # ~~->JournalArticle:Model~~
- "required_parameters" : {"ref" : ["fqw"]}
+ "journal,article": {
+ "auth": False,
+ "role": None,
+ "query_validators": ["non_public_fields_validator", "public_query_validator"],
+ "query_filters": ["only_in_doaj", "strip_facets", "es_type_fix", "journal_article_filter"],
+ "result_filters": ["public_result_filter", "add_fqw_facets", "fqw_back_compat"],
+ "dao": "portality.models.JournalArticle", # ~~->JournalArticle:Model~~
+ "required_parameters": {"ref": ["fqw"]}
}
},
- "publisher_query" : {
+ "publisher_query": {
# ~~->PublisherJournalQuery:Endpoint~~
- "journal" : {
- "auth" : True,
- "role" : "publisher",
- "query_validators" : ["non_public_fields_validator"],
- "query_filters" : ["owner", "only_in_doaj", "search_all_meta"],
- "result_filters" : ["publisher_result_filter"],
- "dao" : "portality.models.Journal" # ~~->Journal:Model~~
+ "journal": {
+ "auth": True,
+ "role": "publisher",
+ "query_validators": ["non_public_fields_validator"],
+ "query_filters": ["owner", "only_in_doaj", "search_all_meta"],
+ "result_filters": ["publisher_result_filter"],
+ "dao": "portality.models.Journal" # ~~->Journal:Model~~
},
# ~~->PublisherApplicationQuery:Endpoint~~
- "applications" : {
- "auth" : True,
- "role" : "publisher",
- "query_validators" : ["non_public_fields_validator"],
- "query_filters" : ["owner", "not_update_request", "search_all_meta"],
- "result_filters" : ["publisher_result_filter"],
- "dao" : "portality.models.AllPublisherApplications" # ~~->AllPublisherApplications:Model~~
+ "applications": {
+ "auth": True,
+ "role": "publisher",
+ "query_validators": ["non_public_fields_validator"],
+ "query_filters": ["owner", "not_update_request", "search_all_meta"],
+ "result_filters": ["publisher_result_filter"],
+ "dao": "portality.models.AllPublisherApplications" # ~~->AllPublisherApplications:Model~~
},
# ~~->PublisherUpdateRequestsQuery:Endpoint~~
- "update_requests" : {
- "auth" : True,
- "role" : "publisher",
- "query_validators" : ["non_public_fields_validator"],
- "query_filters" : ["owner", "update_request", "search_all_meta"],
- "result_filters" : ["publisher_result_filter"],
- "dao" : "portality.models.Application" # ~~->Application:Model~~
+ "update_requests": {
+ "auth": True,
+ "role": "publisher",
+ "query_validators": ["non_public_fields_validator"],
+ "query_filters": ["owner", "update_request", "search_all_meta"],
+ "result_filters": ["publisher_result_filter"],
+ "dao": "portality.models.Application" # ~~->Application:Model~~
}
},
- "admin_query" : {
+ "admin_query": {
# ~~->AdminJournalQuery:Endpoint~~
- "journal" : {
- "auth" : True,
- "role" : "admin",
- "dao" : "portality.models.Journal" # ~~->Journal:Model~~
+ "journal": {
+ "auth": True,
+ "role": "admin",
+ "dao": "portality.models.Journal" # ~~->Journal:Model~~
},
# ~~->AdminApplicationQuery:Endpoint~~
- "suggestion" : {
- "auth" : True,
- "role" : "admin",
- "query_filters" : ["not_update_request"],
- "dao" : "portality.models.Application" # ~~->Application:Model~~
+ "suggestion": {
+ "auth": True,
+ "role": "admin",
+ "query_filters": ["not_update_request"],
+ "dao": "portality.models.Application" # ~~->Application:Model~~
},
# ~~->AdminUpdateRequestQuery:Endpoint~~
"update_requests": {
"auth": True,
"role": "admin",
- "query_filters" : ["update_request"],
+ "query_filters": ["update_request"],
"dao": "portality.models.Application" # ~~->Application:Model~~
},
# ~~->AdminEditorGroupQuery:Endpoint~~
- "editor,group" : {
- "auth" : True,
- "role" : "admin",
- "dao" : "portality.models.EditorGroup" # ~~->EditorGroup:Model~~
+ "editor,group": {
+ "auth": True,
+ "role": "admin",
+ "dao": "portality.models.EditorGroup" # ~~->EditorGroup:Model~~
},
# ~~->AdminAccountQuery:Endpoint~~
- "account" : {
- "auth" : True,
- "role" : "admin",
- "dao" : "portality.models.Account" # ~~->Account:Model~~
+ "account": {
+ "auth": True,
+ "role": "admin",
+ "dao": "portality.models.Account" # ~~->Account:Model~~
},
# ~~->AdminJournalArticleQuery:Endpoint~~
- "journal,article" : {
- "auth" : True,
- "role" : "admin",
- "dao" : "portality.models.search.JournalArticle" # ~~->JournalArticle:Model~~
+ "journal,article": {
+ "auth": True,
+ "role": "admin",
+ "dao": "portality.models.search.JournalArticle" # ~~->JournalArticle:Model~~
},
# ~~->AdminBackgroundJobQuery:Endpoint~~
- "background,job" : {
- "auth" : True,
- "role" : "admin",
- "dao" : "portality.models.BackgroundJob" # ~~->BackgroundJob:Model~~
+ "background,job": {
+ "auth": True,
+ "role": "admin",
+ "dao": "portality.models.BackgroundJob" # ~~->BackgroundJob:Model~~
},
# ~~->APINotificationQuery:Endpoint~~
- "notifications" : {
- "auth" : False,
- "role" : "admin",
- "dao" : "portality.models.Notification", # ~~->Notification:Model~~
- "required_parameters" : None
+ "notifications": {
+ "auth": False,
+ "role": "admin",
+ "dao": "portality.models.Notification", # ~~->Notification:Model~~
+ "required_parameters": None
}
},
- "associate_query" : {
+ "associate_query": {
# ~~->AssEdJournalQuery:Endpoint~~
- "journal" : {
- "auth" : True,
- "role" : "associate_editor",
- "query_validators" : ["non_public_fields_validator"],
- "query_filters" : ["associate", "search_all_meta"],
- "dao" : "portality.models.Journal" # ~~->Journal:Model~~
+ "journal": {
+ "auth": True,
+ "role": "associate_editor",
+ "query_validators": ["non_public_fields_validator"],
+ "query_filters": ["associate", "search_all_meta"],
+ "dao": "portality.models.Journal" # ~~->Journal:Model~~
},
# ~~->AssEdApplicationQuery:Endpoint~~
- "suggestion" : {
- "auth" : True,
- "role" : "associate_editor",
- "query_validators" : ["non_public_fields_validator"],
- "query_filters" : ["associate", "search_all_meta"],
- "dao" : "portality.models.Application" # ~~->Application:Model~~
+ "suggestion": {
+ "auth": True,
+ "role": "associate_editor",
+ "query_validators": ["non_public_fields_validator"],
+ "query_filters": ["associate", "search_all_meta"],
+ "dao": "portality.models.Application" # ~~->Application:Model~~
}
},
- "editor_query" : {
+ "editor_query": {
# ~~->EditorJournalQuery:Endpoint~~
- "journal" : {
- "auth" : True,
- "role" : "editor",
- "query_validators" : ["non_public_fields_validator"],
- "query_filters" : ["editor", "search_all_meta"],
- "dao" : "portality.models.Journal" # ~~->Journal:Model~~
+ "journal": {
+ "auth": True,
+ "role": "editor",
+ "query_validators": ["non_public_fields_validator"],
+ "query_filters": ["editor", "search_all_meta"],
+ "dao": "portality.models.Journal" # ~~->Journal:Model~~
},
# ~~->EditorApplicationQuery:Endpoint~~
- "suggestion" : {
- "auth" : True,
- "role" : "editor",
- "query_validators" : ["non_public_fields_validator"],
- "query_filters" : ["editor", "search_all_meta"],
- "dao" : "portality.models.Application" # ~~->Application:Model~~
+ "suggestion": {
+ "auth": True,
+ "role": "editor",
+ "query_validators": ["non_public_fields_validator"],
+ "query_filters": ["editor", "search_all_meta"],
+ "dao": "portality.models.Application" # ~~->Application:Model~~
}
},
- "api_query" : {
+ "api_query": {
# ~~->APIArticleQuery:Endpoint~~
- "article" : {
- "auth" : False,
- "role" : None,
- "query_filters" : ["only_in_doaj", "public_source"],
- "dao" : "portality.models.Article", # ~~->Article:Model~~
- "required_parameters" : None,
- "keepalive" : "10m"
+ "article": {
+ "auth": False,
+ "role": None,
+ "query_filters": ["only_in_doaj", "public_source"],
+ "dao": "portality.models.Article", # ~~->Article:Model~~
+ "required_parameters": None,
+ "keepalive": "10m"
},
# ~~->APIJournalQuery:Endpoint~~
- "journal" : {
- "auth" : False,
- "role" : None,
+ "journal": {
+ "auth": False,
+ "role": None,
"query_validators": ["non_public_fields_validator"],
- "query_filters" : ["only_in_doaj", "public_source", "search_all_meta"],
- "dao" : "portality.models.Journal", # ~~->Journal:Model~~
- "required_parameters" : None
+ "query_filters": ["only_in_doaj", "public_source", "search_all_meta"],
+ "dao": "portality.models.Journal", # ~~->Journal:Model~~
+ "required_parameters": None
},
# ~~->APIApplicationQuery:Endpoint~~
- "application" : {
- "auth" : True,
- "role" : None,
+ "application": {
+ "auth": True,
+ "role": None,
"query_validators": ["non_public_fields_validator"],
- "query_filters" : ["owner", "private_source", "search_all_meta"],
- "dao" : "portality.models.Suggestion", # ~~->Application:Model~~
- "required_parameters" : None
+ "query_filters": ["owner", "private_source", "search_all_meta"],
+ "dao": "portality.models.Suggestion", # ~~->Application:Model~~
+ "required_parameters": None
}
},
"dashboard_query": {
# ~~->APINotificationQuery:Endpoint~~
- "notifications" : {
- "auth" : False,
- "role" : "read_notifications",
- "query_filters" : ["who_current_user"], # ~~-> WhoCurrentUser:Query
- "dao" : "portality.models.Notification", # ~~->Notification:Model~~
- "required_parameters" : None
+ "notifications": {
+ "auth": False,
+ "role": "read_notifications",
+ "query_filters": ["who_current_user"], # ~~-> WhoCurrentUser:Query
+ "dao": "portality.models.Notification", # ~~->Notification:Model~~
+ "required_parameters": None
}
}
}
QUERY_FILTERS = {
# sanitisers
- "public_query_validator" : "portality.lib.query_filters.public_query_validator",
- "non_public_fields_validator" : "portality.lib.query_filters.non_public_fields_validator",
+ "public_query_validator": "portality.lib.query_filters.public_query_validator",
+ "non_public_fields_validator": "portality.lib.query_filters.non_public_fields_validator",
# query filters
- "only_in_doaj" : "portality.lib.query_filters.only_in_doaj",
- "owner" : "portality.lib.query_filters.owner",
- "update_request" : "portality.lib.query_filters.update_request",
- "associate" : "portality.lib.query_filters.associate",
- "editor" : "portality.lib.query_filters.editor",
- "strip_facets" : "portality.lib.query_filters.strip_facets",
- "es_type_fix" : "portality.lib.query_filters.es_type_fix",
- "last_update_fallback" : "portality.lib.query_filters.last_update_fallback",
- "not_update_request" : "portality.lib.query_filters.not_update_request",
- "who_current_user" : "portality.lib.query_filters.who_current_user", # ~~-> WhoCurrentUser:Query ~~
- "search_all_meta" : "portality.lib.query_filters.search_all_meta", # ~~-> SearchAllMeta:Query ~~
- "journal_article_filter" : "portality.lib.query_filters.journal_article_filter", # ~~-> JournalArticleFilter:Query ~~
+ "only_in_doaj": "portality.lib.query_filters.only_in_doaj",
+ "owner": "portality.lib.query_filters.owner",
+ "update_request": "portality.lib.query_filters.update_request",
+ "associate": "portality.lib.query_filters.associate",
+ "editor": "portality.lib.query_filters.editor",
+ "strip_facets": "portality.lib.query_filters.strip_facets",
+ "es_type_fix": "portality.lib.query_filters.es_type_fix",
+ "last_update_fallback": "portality.lib.query_filters.last_update_fallback",
+ "not_update_request": "portality.lib.query_filters.not_update_request",
+ "who_current_user": "portality.lib.query_filters.who_current_user", # ~~-> WhoCurrentUser:Query ~~
+ "search_all_meta": "portality.lib.query_filters.search_all_meta", # ~~-> SearchAllMeta:Query ~~
+ "journal_article_filter": "portality.lib.query_filters.journal_article_filter",
+ # ~~-> JournalArticleFilter:Query ~~
# result filters
"public_result_filter": "portality.lib.query_filters.public_result_filter",
"publisher_result_filter": "portality.lib.query_filters.publisher_result_filter",
- "add_fqw_facets" : "portality.lib.query_filters.add_fqw_facets",
- "fqw_back_compat" : "portality.lib.query_filters.fqw_back_compat",
+ "add_fqw_facets": "portality.lib.query_filters.add_fqw_facets",
+ "fqw_back_compat": "portality.lib.query_filters.fqw_back_compat",
# source filters
"private_source": "portality.lib.query_filters.private_source",
@@ -947,7 +935,7 @@
]
ADMIN_NOTES_INDEX_ONLY_FIELDS = {
- "all_meta" : {
+ "all_meta": {
"type": "text",
"fields": {
"exact": {
@@ -993,8 +981,8 @@
# ~~->BibJSON:Model~~
AUTOCOMPLETE_ADVANCED_FIELD_MAPS = {
- "bibjson.publisher.name" : "index.publisher_ac",
- "bibjson.institution.name" : "index.institution_ac"
+ "bibjson.publisher.name": "index.publisher_ac",
+ "bibjson.institution.name": "index.institution_ac"
}
####################################################
@@ -1020,7 +1008,7 @@
# Licensing terms for feed content
# ~~->SiteLicence:Content~~
-FEED_LICENCE = "(c) DOAJ 2013. CC BY-SA."
+FEED_LICENCE = "(c) DOAJ 2024. CC BY-SA."
# name of the feed generator (goes in the atom:generator element)
FEED_GENERATOR = "CottageLabs feed generator"
@@ -1123,7 +1111,6 @@
TOC_CHANGEFREQ = "monthly"
-
##################################################
# News feed settings
# ~~->News:Feature~~
@@ -1159,9 +1146,6 @@
# ENTER YOUR OWN TOKEN IN APPROPRIATE .cfg FILE
#BITLY_OAUTH_TOKEN = ""
-###############################################
-# Date handling
-# See portality.lib.dates - moved to prevent circular import
#################################################
# API configuration
@@ -1176,42 +1160,42 @@
# ~~->ArticleBibJSON:Model~~
DISCOVERY_ARTICLE_SEARCH_SUBS = {
- "title" : "bibjson.title",
- "doi" : "bibjson.identifier.id.exact",
- "issn" : "index.issn.exact",
- "publisher" : "bibjson.journal.publisher",
- "journal" : "bibjson.journal.title",
- "abstract" : "bibjson.abstract"
+ "title": "bibjson.title",
+ "doi": "bibjson.identifier.id.exact",
+ "issn": "index.issn.exact",
+ "publisher": "bibjson.journal.publisher",
+ "journal": "bibjson.journal.title",
+ "abstract": "bibjson.abstract"
}
DISCOVERY_ARTICLE_SORT_SUBS = {
- "title" : "index.unpunctitle.exact"
+ "title": "index.unpunctitle.exact"
}
# ~~->JournalBibJSON:Model~~
DISCOVERY_JOURNAL_SEARCH_SUBS = {
- "title" : "index.title",
- "issn" : "index.issn.exact",
- "publisher" : "bibjson.publisher",
- "license" : "index.license.exact",
- "username" : "admin.owner.exact"
+ "title": "index.title",
+ "issn": "index.issn.exact",
+ "publisher": "bibjson.publisher",
+ "license": "index.license.exact",
+ "username": "admin.owner.exact"
}
DISCOVERY_JOURNAL_SORT_SUBS = {
- "title" : "index.unpunctitle.exact",
- "issn" : "index.issn.exact"
+ "title": "index.unpunctitle.exact",
+ "issn": "index.issn.exact"
}
DISCOVERY_APPLICATION_SEARCH_SUBS = {
- "title" : "index.title",
- "issn" : "index.issn.exact",
- "publisher" : "bibjson.publisher",
- "license" : "index.license.exact"
+ "title": "index.title",
+ "issn": "index.issn.exact",
+ "publisher": "bibjson.publisher",
+ "license": "index.license.exact"
}
DISCOVERY_APPLICATION_SORT_SUBS = {
- "title" : "index.unpunctitle.exact",
- "issn" : "index.issn.exact"
+ "title": "index.unpunctitle.exact",
+ "issn": "index.issn.exact"
}
# API data dump settings
@@ -1332,12 +1316,12 @@
#############################################
-## Harvester Configuration
+# Harvester Configuration
# ~~->Harvester:Feature~~
-## Configuration options for the DOAJ API Client
+# Configuration options for the DOAJ API Client
-## EPMC Client configuration
+# EPMC Client configuration
# ~~-> EPMC:ExternalService~~
EPMC_REST_API = "https://www.ebi.ac.uk/europepmc/webservices/rest/"
EPMC_TARGET_VERSION = "6.9" # doc here: https://europepmc.org/docs/Europe_PMC_RESTful_Release_Notes.pdf
@@ -1467,7 +1451,7 @@
}
##################################################
-## Public data dump settings
+# Public data dump settings
# how long should the temporary URL for public data dumps last
PUBLIC_DATA_DUMP_URL_TIMEOUT = 3600
@@ -1545,7 +1529,7 @@
# Datalog
# ~~->Datalog:Feature~~
-### Datalog for Journal Added
+# Datalog for Journal Added
# google sheet filename for datalog ja
DATALOG_JA_FILENAME = 'DOAJ: journals added and withdrawn'
diff --git a/portality/static/js/application_form.js b/portality/static/js/application_form.js
index b3c646dfac..e7959a2db3 100644
--- a/portality/static/js/application_form.js
+++ b/portality/static/js/application_form.js
@@ -35,7 +35,9 @@ doaj.af.journalFormFactory = (params) => {
return doaj.af.newEditorJournalForm(params);
case "associate_editor":
return doaj.af.newAssociateJournalForm(params);
- case "readonly":
+ case "admin_readonly":
+ return doaj.af.newReadOnlyJournalForm(params);
+ case "editor_readonly":
return doaj.af.newReadOnlyJournalForm(params);
default:
throw "Could not extract a context from the form";
diff --git a/portality/tasks/async_workflow_notifications.py b/portality/tasks/async_workflow_notifications.py
index b0236af7ec..70de3eb70e 100644
--- a/portality/tasks/async_workflow_notifications.py
+++ b/portality/tasks/async_workflow_notifications.py
@@ -11,6 +11,7 @@
from portality.lib.dates import FMT_DATETIME_STD
from portality.tasks.helpers import background_helper
from portality.tasks.redis_huey import main_queue, schedule
+from portality.ui import templates
class AgeQuery(object):
@@ -200,7 +201,7 @@ def managing_editor_notifications(emails_dict):
idle_res = models.Suggestion.query(q=age_query.query())
num_idle = idle_res.get('hits', {}).get('total', {}).get('value', 0)
- text = render_template('email/workflow_reminder_fragments/admin_age_frag', num_idle=num_idle, x_weeks=X_WEEKS)
+ text = render_template(templates.EMAIL_WF_ADMIN_AGE, num_idle=num_idle, x_weeks=X_WEEKS)
_add_email_paragraph(emails_dict, MAN_ED_EMAIL, 'Managing Editors', text)
# The second notification - the number of ready records
@@ -214,7 +215,7 @@ def managing_editor_notifications(emails_dict):
ready_res = models.Suggestion.query(q=ready_query.query())
num_ready = ready_res.get('hits').get('total', {}).get('value', 0)
- text = render_template('email/workflow_reminder_fragments/admin_ready_frag', num=num_ready, url=ready_url)
+ text = render_template(templates.EMAIL_WF_ADMIN_READY, num=num_ready, url=ready_url)
_add_email_paragraph(emails_dict, MAN_ED_EMAIL, 'Managing Editors', text)
@@ -255,7 +256,7 @@ def editor_notifications(emails_dict, limit=None):
editor = eg.get_editor_account()
ed_email = editor.email
- text = render_template('email/workflow_reminder_fragments/editor_groupcount_frag', num=group_count, ed_group=group_name, url=ed_url)
+ text = render_template(templates.EMAIL_WF_EDITOR_GROUPCOUNT, num=group_count, ed_group=group_name, url=ed_url)
_add_email_paragraph(emails_dict, ed_email, eg.editor, text)
# Second note - records within editor group not touched for so long
@@ -286,7 +287,7 @@ def editor_notifications(emails_dict, limit=None):
editor = eg.get_editor_account()
ed_email = editor.email
- text = render_template('email/workflow_reminder_fragments/editor_age_frag', num=group_count, ed_group=group_name, url=ed_age_url, x_weeks=X_WEEKS)
+ text = render_template(templates.EMAIL_WF_EDITOR_AGE, num=group_count, ed_group=group_name, url=ed_age_url, x_weeks=X_WEEKS)
_add_email_paragraph(emails_dict, ed_email, eg.editor, text)
@@ -336,7 +337,7 @@ def associate_editor_notifications(emails_dict, limit=None):
app.logger.warning("No account found for ID {0}".format(assoc_id))
continue
- text = render_template('email/workflow_reminder_fragments/assoc_ed_age_frag', num_idle=idle, x_days=X_DAYS, num_very_idle=very_idle, y_weeks=Y_WEEKS, url=url)
+ text = render_template(templates.EMAIL_WF_ASSED_AGE, num_idle=idle, x_days=X_DAYS, num_very_idle=very_idle, y_weeks=Y_WEEKS, url=url)
_add_email_paragraph(emails_dict, assoc_email, assoc_id, text)
diff --git a/portality/templates-v2/README.md b/portality/templates-v2/README.md
new file mode 100644
index 0000000000..096ea35409
--- /dev/null
+++ b/portality/templates-v2/README.md
@@ -0,0 +1,42 @@
+# Template directory structure
+
+Every level of the template directory structure can look like this:
+
+```
+├── base.html => the base file for all templates in this level or below. It must inherit from the template in the level above
+├── [sub level] => All template files associated with the next level down in the hierarcy. For example, the `management` directory under the base
+├── _[common infrastructure] => application forms, email templates, anything else that is used in many places at this level or below
+├── includes => Any files that are included generally at this level or below
+├── layouts => any layouts that are used generally at this level or below
+```
+
+For example
+
+```
+├── base.html
+├── management
+ ├── base.html => extends ../base.html
+ ├── maned
+ ├── editor
+ ├── assed
+├──public
+ ├── layouts
+ ├── static-pages.html
+ ├── publisher
+├── _application_forms
+├── _emails
+├── includes
+ ├── _cookie-consent.html
+├── layouts
+ ├── sidenav.html
+```
+
+Files should be named according to these rules:
+
+* If a file is called directly by a view, it should be named with `-` providing any spaces in the name. For example `static-pages.html`
+* If a file is included or imported within a template, it should be named with a `_` prefix and `-` providing any spaces in the name. For example: `_edges-common-css.html`
+* If a file has a close relationship with another template file, it may be prefixed with an `_` that template's name, and separated with a `_`. For example: `_static-pages_no-sidenav.html`
+
+
+# Block hierarchy
+
diff --git a/portality/templates-v2/_account/includes/_api-access.html b/portality/templates-v2/_account/includes/_api-access.html
new file mode 100644
index 0000000000..0353448f1d
--- /dev/null
+++ b/portality/templates-v2/_account/includes/_api-access.html
@@ -0,0 +1,22 @@
+{% if account.has_role("api") %}
+
+{% endif %}
\ No newline at end of file
diff --git a/portality/templates-v2/_account/includes/_edit_form_js.html b/portality/templates-v2/_account/includes/_edit_form_js.html
new file mode 100644
index 0000000000..bb6cf3ebfe
--- /dev/null
+++ b/portality/templates-v2/_account/includes/_edit_form_js.html
@@ -0,0 +1,38 @@
+
+
+
diff --git a/portality/templates-v2/_account/includes/_edit_user_form.html b/portality/templates-v2/_account/includes/_edit_user_form.html
new file mode 100644
index 0000000000..bca8acce8a
--- /dev/null
+++ b/portality/templates-v2/_account/includes/_edit_user_form.html
@@ -0,0 +1,54 @@
+{% from "includes/_formhelpers.html" import render_field %}
+
+
Edit your details
+
+
diff --git a/portality/templates-v2/_account/includes/_login_form.html b/portality/templates-v2/_account/includes/_login_form.html
new file mode 100644
index 0000000000..8582f5ed3f
--- /dev/null
+++ b/portality/templates-v2/_account/includes/_login_form.html
@@ -0,0 +1,12 @@
+{% from "includes/_formhelpers.html" import render_field %}
+
+
diff --git a/portality/templates-v2/_account/includes/_marketing-consent.html b/portality/templates-v2/_account/includes/_marketing-consent.html
new file mode 100644
index 0000000000..8ef8b8a009
--- /dev/null
+++ b/portality/templates-v2/_account/includes/_marketing-consent.html
@@ -0,0 +1,23 @@
+
\ No newline at end of file
diff --git a/portality/templates-v2/_account/includes/_register_form.html b/portality/templates-v2/_account/includes/_register_form.html
new file mode 100644
index 0000000000..718fee8793
--- /dev/null
+++ b/portality/templates-v2/_account/includes/_register_form.html
@@ -0,0 +1,30 @@
+{% from "includes/_formhelpers.html" import render_field %}
+
+
diff --git a/portality/templates-v2/_account/includes/_reset_form.html b/portality/templates-v2/_account/includes/_reset_form.html
new file mode 100644
index 0000000000..373ecb6491
--- /dev/null
+++ b/portality/templates-v2/_account/includes/_reset_form.html
@@ -0,0 +1,10 @@
+{% from "includes/_formhelpers.html" import render_field %}
+
+
\ No newline at end of file
diff --git a/portality/templates/application_form/_application_warning_msg.html b/portality/templates-v2/_application-form/includes/_application_warning_msg.html
similarity index 99%
rename from portality/templates/application_form/_application_warning_msg.html
rename to portality/templates-v2/_application-form/includes/_application_warning_msg.html
index 85c706816e..f693240700 100644
--- a/portality/templates/application_form/_application_warning_msg.html
+++ b/portality/templates-v2/_application-form/includes/_application_warning_msg.html
@@ -1,4 +1,3 @@
-
{% macro build_journal_withdrawn_deleted_msg(obj) -%}
{% if obj["es_type"] == "application"
and obj.application_type == "update_request"
diff --git a/portality/templates-v2/_application-form/includes/_backend_validation.html b/portality/templates-v2/_application-form/includes/_backend_validation.html
new file mode 100644
index 0000000000..294b0f9785
--- /dev/null
+++ b/portality/templates-v2/_application-form/includes/_backend_validation.html
@@ -0,0 +1,11 @@
+{% if formulaic_context.wtform_inst.errors %}
+
+ This form has errors which prevented its submission. The following fields are invalid:
+
+ {% for field, errors in formulaic_context.wtform_inst.errors.items() %}
+ {% set field_def = formulaic_context.get(field) %}
+
+{% endif %}
diff --git a/portality/templates/application_form/_entry_group.html b/portality/templates-v2/_application-form/includes/_entry_group.html
similarity index 100%
rename from portality/templates/application_form/_entry_group.html
rename to portality/templates-v2/_application-form/includes/_entry_group.html
diff --git a/portality/templates/application_form/_entry_group_horizontal.html b/portality/templates-v2/_application-form/includes/_entry_group_horizontal.html
similarity index 100%
rename from portality/templates/application_form/_entry_group_horizontal.html
rename to portality/templates-v2/_application-form/includes/_entry_group_horizontal.html
diff --git a/portality/templates/application_form/_field.html b/portality/templates-v2/_application-form/includes/_field.html
similarity index 95%
rename from portality/templates/application_form/_field.html
rename to portality/templates-v2/_application-form/includes/_field.html
index 0e1d37e1d5..a7ee3ec44e 100644
--- a/portality/templates/application_form/_field.html
+++ b/portality/templates-v2/_application-form/includes/_field.html
@@ -1,4 +1,4 @@
-{% from "application_form/_value.html" import value %}
+{% from "_application-form/includes/_value.html" import value %}
@@ -71,4 +71,4 @@
-{% include "application_form/modal.html" %}
+{% include "_application-form/includes/_modal.html" %}
diff --git a/portality/templates/application_form/02-about/index.html b/portality/templates-v2/_application-form/includes/_fieldset_about.html
similarity index 100%
rename from portality/templates/application_form/02-about/index.html
rename to portality/templates-v2/_application-form/includes/_fieldset_about.html
diff --git a/portality/templates/application_form/06-best-practice/index.html b/portality/templates-v2/_application-form/includes/_fieldset_best-practice.html
similarity index 100%
rename from portality/templates/application_form/06-best-practice/index.html
rename to portality/templates-v2/_application-form/includes/_fieldset_best-practice.html
diff --git a/portality/templates/application_form/05-business-model/index.html b/portality/templates-v2/_application-form/includes/_fieldset_business-model.html
similarity index 100%
rename from portality/templates/application_form/05-business-model/index.html
rename to portality/templates-v2/_application-form/includes/_fieldset_business-model.html
diff --git a/portality/templates/application_form/03-copyright-licensing/index.html b/portality/templates-v2/_application-form/includes/_fieldset_copyright-licensing.html
similarity index 100%
rename from portality/templates/application_form/03-copyright-licensing/index.html
rename to portality/templates-v2/_application-form/includes/_fieldset_copyright-licensing.html
diff --git a/portality/templates/application_form/04-editorial/index.html b/portality/templates-v2/_application-form/includes/_fieldset_editorial.html
similarity index 100%
rename from portality/templates/application_form/04-editorial/index.html
rename to portality/templates-v2/_application-form/includes/_fieldset_editorial.html
diff --git a/portality/templates/application_form/01-oa-compliance/index.html b/portality/templates-v2/_application-form/includes/_fieldset_oa_compliance.html
similarity index 100%
rename from portality/templates/application_form/01-oa-compliance/index.html
rename to portality/templates-v2/_application-form/includes/_fieldset_oa_compliance.html
diff --git a/portality/templates/application_form/js/_form_js.html b/portality/templates-v2/_application-form/includes/_form_js.html
similarity index 91%
rename from portality/templates/application_form/js/_form_js.html
rename to portality/templates-v2/_application-form/includes/_form_js.html
index 323b90b656..1329ce8f53 100644
--- a/portality/templates/application_form/js/_form_js.html
+++ b/portality/templates-v2/_application-form/includes/_form_js.html
@@ -1,8 +1,5 @@
-
-
-{# #}
diff --git a/portality/templates/application_form/_group.html b/portality/templates-v2/_application-form/includes/_group.html
similarity index 95%
rename from portality/templates/application_form/_group.html
rename to portality/templates-v2/_application-form/includes/_group.html
index cb0d98f64c..2d20c25cb8 100644
--- a/portality/templates/application_form/_group.html
+++ b/portality/templates-v2/_application-form/includes/_group.html
@@ -27,4 +27,4 @@
{% endif %}
-{% include "application_form/modal.html" %}
+{% include "_application-form/includes/_modal.html" %}
diff --git a/portality/templates/application_form/_list.html b/portality/templates-v2/_application-form/includes/_list.html
similarity index 95%
rename from portality/templates/application_form/_list.html
rename to portality/templates-v2/_application-form/includes/_list.html
index 02567676cc..656c3d118d 100644
--- a/portality/templates/application_form/_list.html
+++ b/portality/templates-v2/_application-form/includes/_list.html
@@ -1,4 +1,4 @@
-{% from "application_form/_value.html" import value %}
+{% from "_application-form/includes/_value.html" import value %}
@@ -59,5 +59,5 @@
{{ f.help("short_help") | safe }}
{% endif %}
- {% include "application_form/modal.html" %}
+ {% include "_application-form/includes/_modal.html" %}
diff --git a/portality/templates/application_form/modal.html b/portality/templates-v2/_application-form/includes/_modal.html
similarity index 100%
rename from portality/templates/application_form/modal.html
rename to portality/templates-v2/_application-form/includes/_modal.html
diff --git a/portality/templates-v2/_application-form/includes/_public_fieldsets.html b/portality/templates-v2/_application-form/includes/_public_fieldsets.html
new file mode 100644
index 0000000000..04c3a1a025
--- /dev/null
+++ b/portality/templates-v2/_application-form/includes/_public_fieldsets.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/portality/templates/application_form/_value.html b/portality/templates-v2/_application-form/includes/_value.html
similarity index 100%
rename from portality/templates/application_form/_value.html
rename to portality/templates-v2/_application-form/includes/_value.html
diff --git a/portality/templates-v2/_articles/includes/_article_metadata_form.html b/portality/templates-v2/_articles/includes/_article_metadata_form.html
new file mode 100644
index 0000000000..09ec2c9f13
--- /dev/null
+++ b/portality/templates-v2/_articles/includes/_article_metadata_form.html
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/portality/templates/includes/_tourist.html b/portality/templates-v2/_tourist/includes/_tourist.html
similarity index 100%
rename from portality/templates/includes/_tourist.html
rename to portality/templates-v2/_tourist/includes/_tourist.html
diff --git a/portality/templates/includes/_tourist_nav.html b/portality/templates-v2/_tourist/includes/_tourist_nav.html
similarity index 100%
rename from portality/templates/includes/_tourist_nav.html
rename to portality/templates-v2/_tourist/includes/_tourist_nav.html
diff --git a/portality/templates-v2/base.html b/portality/templates-v2/base.html
new file mode 100644
index 0000000000..1fe3553814
--- /dev/null
+++ b/portality/templates-v2/base.html
@@ -0,0 +1,75 @@
+
+
+
+
+
+ {% block page_title %}Directory of Open Access Journals{% endblock %} – DOAJ
+
+
+
+
+
+
+
+
+
+
+
+
+ {% block base_meta %}{% endblock %}
+
+
+
+
+
+
+
+
+
+
+ {# FIXME: probably just on the application form? #}
+
+
+ {# Page-specific styles todo: select2 could possibly go here #}
+ {% block base_stylesheets %}{% endblock %}
+
+
+
+
+
+
+
+
+{% if not request.cookies.get(config.get("CONSENT_COOKIE_KEY")) %}
+ {% include "includes/_cookie_consent.html" %}
+{% endif %}
+
+{% block base_content %}{% endblock %}
+
+{% include 'includes/_js_includes.html' %}
+
+{% if not request.cookies.get("doaj-consent") %}
+
+{% endif %}
+
+{% block base_js %}{% endblock %}
+
+
+
+
diff --git a/portality/templates-v2/dev/redhead/blocks.html b/portality/templates-v2/dev/redhead/blocks.html
new file mode 100644
index 0000000000..7679c0db0e
--- /dev/null
+++ b/portality/templates-v2/dev/redhead/blocks.html
@@ -0,0 +1,164 @@
+
+
+
+
+ Redhead: Jinja2 template structure browser
+
+
+
+
+
+
+
+{% macro render_block_node(node, display) %}
+
+ {{ node.name }}
+{# #}
+{# {% if not node.content %}[Empty]{% else %}[Has Content]{% endif %}#}
+{# {% if node.overrides|length == 0 %}[New Definition]{% endif %}#}
+{# {% if node.scoped %}[Scoped]{% endif %}#}
+{# {% if node.overridden_by|length == 0 and not node.content %}[WARNING: Unused block]{% endif %}#}
+{# {% for over in node.overrides %}#}
+{# {% if not loop.first %} {% endif %}#}
+{# {% for p in over.paths %}#}
+{# [{{ p|join(" < ") }}]#}
+{# {% endfor %}#}
+{# {% endfor %}#}
+{# #}
+ {% if node.blocks|length > 0 or node.files|length > 0 %}
+
+ {% for node in tree %}
+ {{ render_file_node(node, true) }}
+ {% endfor %}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/portality/templates/testdrive/testdrive.html b/portality/templates-v2/dev/testdrive/testdrive.html
similarity index 100%
rename from portality/templates/testdrive/testdrive.html
rename to portality/templates-v2/dev/testdrive/testdrive.html
diff --git a/portality/templates/email/account_created.jinja2 b/portality/templates-v2/email/account_created.jinja2
similarity index 100%
rename from portality/templates/email/account_created.jinja2
rename to portality/templates-v2/email/account_created.jinja2
diff --git a/portality/templates/email/account_password_reset.jinja2 b/portality/templates-v2/email/account_password_reset.jinja2
similarity index 100%
rename from portality/templates/email/account_password_reset.jinja2
rename to portality/templates-v2/email/account_password_reset.jinja2
diff --git a/portality/templates/email/editor_application_completed.jinja2 b/portality/templates-v2/email/editor_application_completed.jinja2
similarity index 100%
rename from portality/templates/email/editor_application_completed.jinja2
rename to portality/templates-v2/email/editor_application_completed.jinja2
diff --git a/portality/templates/email/notification_email.jinja2 b/portality/templates-v2/email/notification_email.jinja2
similarity index 100%
rename from portality/templates/email/notification_email.jinja2
rename to portality/templates-v2/email/notification_email.jinja2
diff --git a/portality/templates/email/script_tag_detected.jinja2 b/portality/templates-v2/email/script_tag_detected.jinja2
similarity index 100%
rename from portality/templates/email/script_tag_detected.jinja2
rename to portality/templates-v2/email/script_tag_detected.jinja2
diff --git a/portality/templates/email/workflow_reminder_fragments/admin_age_frag b/portality/templates-v2/email/workflow_reminder_fragments/admin_age_frag.jinja2
similarity index 100%
rename from portality/templates/email/workflow_reminder_fragments/admin_age_frag
rename to portality/templates-v2/email/workflow_reminder_fragments/admin_age_frag.jinja2
diff --git a/portality/templates/email/workflow_reminder_fragments/admin_ready_frag b/portality/templates-v2/email/workflow_reminder_fragments/admin_ready_frag.jinja2
similarity index 100%
rename from portality/templates/email/workflow_reminder_fragments/admin_ready_frag
rename to portality/templates-v2/email/workflow_reminder_fragments/admin_ready_frag.jinja2
diff --git a/portality/templates/email/workflow_reminder_fragments/assoc_ed_age_frag b/portality/templates-v2/email/workflow_reminder_fragments/assoc_ed_age_frag.jinja2
similarity index 100%
rename from portality/templates/email/workflow_reminder_fragments/assoc_ed_age_frag
rename to portality/templates-v2/email/workflow_reminder_fragments/assoc_ed_age_frag.jinja2
diff --git a/portality/templates/email/workflow_reminder_fragments/editor_age_frag b/portality/templates-v2/email/workflow_reminder_fragments/editor_age_frag.jinja2
similarity index 100%
rename from portality/templates/email/workflow_reminder_fragments/editor_age_frag
rename to portality/templates-v2/email/workflow_reminder_fragments/editor_age_frag.jinja2
diff --git a/portality/templates/email/workflow_reminder_fragments/editor_groupcount_frag b/portality/templates-v2/email/workflow_reminder_fragments/editor_groupcount_frag.jinja2
similarity index 100%
rename from portality/templates/email/workflow_reminder_fragments/editor_groupcount_frag
rename to portality/templates-v2/email/workflow_reminder_fragments/editor_groupcount_frag.jinja2
diff --git a/portality/templates-v2/includes/_back-to-top.html b/portality/templates-v2/includes/_back-to-top.html
new file mode 100644
index 0000000000..62fd115147
--- /dev/null
+++ b/portality/templates-v2/includes/_back-to-top.html
@@ -0,0 +1,4 @@
+
+
+ Back to top
+
diff --git a/portality/templates/doaj/cookie_consent.html b/portality/templates-v2/includes/_cookie_consent.html
similarity index 100%
rename from portality/templates/doaj/cookie_consent.html
rename to portality/templates-v2/includes/_cookie_consent.html
diff --git a/portality/templates/_edges_common_js.html b/portality/templates-v2/includes/_edges_common_js.html
similarity index 100%
rename from portality/templates/_edges_common_js.html
rename to portality/templates-v2/includes/_edges_common_js.html
diff --git a/portality/templates-v2/includes/_error_header.html b/portality/templates-v2/includes/_error_header.html
new file mode 100644
index 0000000000..fc2c21c4ea
--- /dev/null
+++ b/portality/templates-v2/includes/_error_header.html
@@ -0,0 +1,3 @@
+{% if there_were_errors %}
+
There is a problem with the submitted form.
+{% endif %}
\ No newline at end of file
diff --git a/portality/templates/includes/_flash_notification.html b/portality/templates-v2/includes/_flash_notification.html
similarity index 100%
rename from portality/templates/includes/_flash_notification.html
rename to portality/templates-v2/includes/_flash_notification.html
diff --git a/portality/templates/_formhelpers.html b/portality/templates-v2/includes/_formhelpers.html
similarity index 100%
rename from portality/templates/_formhelpers.html
rename to portality/templates-v2/includes/_formhelpers.html
diff --git a/portality/templates/includes/_hotjar.html b/portality/templates-v2/includes/_hotjar.html
similarity index 100%
rename from portality/templates/includes/_hotjar.html
rename to portality/templates-v2/includes/_hotjar.html
diff --git a/portality/templates/_js_includes.html b/portality/templates-v2/includes/_js_includes.html
similarity index 100%
rename from portality/templates/_js_includes.html
rename to portality/templates-v2/includes/_js_includes.html
diff --git a/portality/templates-v2/includes/_site_note.html b/portality/templates-v2/includes/_site_note.html
new file mode 100644
index 0000000000..76daabd42b
--- /dev/null
+++ b/portality/templates-v2/includes/_site_note.html
@@ -0,0 +1,4 @@
+
diff --git a/portality/templates/includes/svg/20yrs-stacked.svg b/portality/templates-v2/includes/svg/20yrs-stacked.svg
similarity index 100%
rename from portality/templates/includes/svg/20yrs-stacked.svg
rename to portality/templates-v2/includes/svg/20yrs-stacked.svg
diff --git a/portality/templates/includes/svg/20yrs.svg b/portality/templates-v2/includes/svg/20yrs.svg
similarity index 100%
rename from portality/templates/includes/svg/20yrs.svg
rename to portality/templates-v2/includes/svg/20yrs.svg
diff --git a/portality/templates/includes/svg/at-20/theme_global.svg b/portality/templates-v2/includes/svg/at-20/theme_global.svg
similarity index 100%
rename from portality/templates/includes/svg/at-20/theme_global.svg
rename to portality/templates-v2/includes/svg/at-20/theme_global.svg
diff --git a/portality/templates/includes/svg/at-20/theme_open.svg b/portality/templates-v2/includes/svg/at-20/theme_open.svg
similarity index 100%
rename from portality/templates/includes/svg/at-20/theme_open.svg
rename to portality/templates-v2/includes/svg/at-20/theme_open.svg
diff --git a/portality/templates/includes/svg/at-20/theme_trusted.svg b/portality/templates-v2/includes/svg/at-20/theme_trusted.svg
similarity index 100%
rename from portality/templates/includes/svg/at-20/theme_trusted.svg
rename to portality/templates-v2/includes/svg/at-20/theme_trusted.svg
diff --git a/portality/templates/includes/svg/by.svg b/portality/templates-v2/includes/svg/by.svg
similarity index 100%
rename from portality/templates/includes/svg/by.svg
rename to portality/templates-v2/includes/svg/by.svg
diff --git a/portality/templates/includes/svg/cc.svg b/portality/templates-v2/includes/svg/cc.svg
similarity index 100%
rename from portality/templates/includes/svg/cc.svg
rename to portality/templates-v2/includes/svg/cc.svg
diff --git a/portality/templates/includes/svg/copyright.svg b/portality/templates-v2/includes/svg/copyright.svg
similarity index 100%
rename from portality/templates/includes/svg/copyright.svg
rename to portality/templates-v2/includes/svg/copyright.svg
diff --git a/portality/templates/includes/svg/doaj-icon.svg b/portality/templates-v2/includes/svg/doaj-icon.svg
similarity index 100%
rename from portality/templates/includes/svg/doaj-icon.svg
rename to portality/templates-v2/includes/svg/doaj-icon.svg
diff --git a/portality/templates/includes/svg/logo.svg b/portality/templates-v2/includes/svg/logo.svg
similarity index 100%
rename from portality/templates/includes/svg/logo.svg
rename to portality/templates-v2/includes/svg/logo.svg
diff --git a/portality/templates/includes/svg/nc.svg b/portality/templates-v2/includes/svg/nc.svg
similarity index 100%
rename from portality/templates/includes/svg/nc.svg
rename to portality/templates-v2/includes/svg/nc.svg
diff --git a/portality/templates/includes/svg/nd.svg b/portality/templates-v2/includes/svg/nd.svg
similarity index 100%
rename from portality/templates/includes/svg/nd.svg
rename to portality/templates-v2/includes/svg/nd.svg
diff --git a/portality/templates/includes/svg/sa.svg b/portality/templates-v2/includes/svg/sa.svg
similarity index 100%
rename from portality/templates/includes/svg/sa.svg
rename to portality/templates-v2/includes/svg/sa.svg
diff --git a/portality/templates/includes/svg/seal.svg b/portality/templates-v2/includes/svg/seal.svg
similarity index 100%
rename from portality/templates/includes/svg/seal.svg
rename to portality/templates-v2/includes/svg/seal.svg
diff --git a/portality/templates/includes/svg/wechat.svg b/portality/templates-v2/includes/svg/wechat.svg
similarity index 100%
rename from portality/templates/includes/svg/wechat.svg
rename to portality/templates-v2/includes/svg/wechat.svg
diff --git a/portality/templates/includes/svg/zero.svg b/portality/templates-v2/includes/svg/zero.svg
similarity index 100%
rename from portality/templates/includes/svg/zero.svg
rename to portality/templates-v2/includes/svg/zero.svg
diff --git a/portality/templates-v2/management/_application-form/includes/_application_diff.html b/portality/templates-v2/management/_application-form/includes/_application_diff.html
new file mode 100644
index 0000000000..4e9f514750
--- /dev/null
+++ b/portality/templates-v2/management/_application-form/includes/_application_diff.html
@@ -0,0 +1,40 @@
+{% from "_application-form/includes/_value.html" import value %}
+
+{% if current_journal %}
+
+
+ The following fields have changed:
+
+
+
+
+
+
+
Previous
+
New
+
+
+
+ {% for f in formulaic_context.list_fields_in_order() %}
+ {% if f.name in form_diff %}
+ {% set previous = form_diff[f.name]['a'] %}
+ {% set new = form_diff[f.name]['b'] %}
+
+{% endif %}
diff --git a/portality/templates/application_form/_autochecks.html b/portality/templates-v2/management/_application-form/includes/_autochecks.html
similarity index 100%
rename from portality/templates/application_form/_autochecks.html
rename to portality/templates-v2/management/_application-form/includes/_autochecks.html
diff --git a/portality/templates/application_form/_contact.html b/portality/templates-v2/management/_application-form/includes/_contact.html
similarity index 100%
rename from portality/templates/application_form/_contact.html
rename to portality/templates-v2/management/_application-form/includes/_contact.html
diff --git a/portality/templates/application_form/_edit_status.html b/portality/templates-v2/management/_application-form/includes/_edit_status.html
similarity index 100%
rename from portality/templates/application_form/_edit_status.html
rename to portality/templates-v2/management/_application-form/includes/_edit_status.html
diff --git a/portality/templates/application_form/editorial_form_body.html b/portality/templates-v2/management/_application-form/includes/_editorial_form_body.html
similarity index 54%
rename from portality/templates/application_form/editorial_form_body.html
rename to portality/templates-v2/management/_application-form/includes/_editorial_form_body.html
index 9750c1ceff..5e4d1d07b2 100644
--- a/portality/templates/application_form/editorial_form_body.html
+++ b/portality/templates-v2/management/_application-form/includes/_editorial_form_body.html
@@ -1,8 +1,8 @@
-{% include "application_form/_edit_status.html" %}
-{% include "application_form/_backend_validation.html" %}
-{% include "application_form/_autochecks.html" %}
+{% include "management/_application-form/includes/_edit_status.html" %}
+{% include "_application-form/includes/_backend_validation.html" %}
+{% include "management/_application-form/includes/_autochecks.html" %}
+{% import "_application-form/includes/_application_warning_msg.html" as _msg %}
-{% import "application_form/_application_warning_msg.html" as _msg %}
{% if obj and (obj.es_type == 'journal' and obj.is_in_doaj()) %}
{{ _msg.build_journal_withdrawn_deleted_msg(obj) }}
See this journal in DOAJ
@@ -21,15 +21,13 @@
{% if diff_table %}
- {% include 'application_form/_application_diff.html' %}
+ {% include 'management/_application-form/includes/_application_diff.html' %}
{% endif %}
- {% include 'application_form/editorial_form_fields.html' %}
- {% include "application_form/_fieldsets.html" %}
+ {% include 'management/_application-form/includes/_editorial_form_fields.html' %}
+ {% include "_application-form/includes/_public_fieldsets.html" %}
- {% include "application_form/editorial_side_panel.html" %}
+ {% include "management/_application-form/includes/_editorial_side_panel.html" %}
-
-{% include "includes/_hotjar.html" %}
diff --git a/portality/templates/application_form/editorial_form_fields.html b/portality/templates-v2/management/_application-form/includes/_editorial_form_fields.html
similarity index 100%
rename from portality/templates/application_form/editorial_form_fields.html
rename to portality/templates-v2/management/_application-form/includes/_editorial_form_fields.html
diff --git a/portality/templates/application_form/editorial_side_panel.html b/portality/templates-v2/management/_application-form/includes/_editorial_side_panel.html
similarity index 95%
rename from portality/templates/application_form/editorial_side_panel.html
rename to portality/templates-v2/management/_application-form/includes/_editorial_side_panel.html
index 9ddf55698f..f7047bd426 100644
--- a/portality/templates/application_form/editorial_side_panel.html
+++ b/portality/templates-v2/management/_application-form/includes/_editorial_side_panel.html
@@ -1,5 +1,5 @@
- {% include "application_form/_contact.html" %}
+ {% include "management/_application-form/includes/_contact.html" %}
{% if obj %}
Locked for editing until {{ lock.expire_formatted() }}
@@ -56,7 +56,5 @@
Locked for editing until
-
- {# #}
diff --git a/portality/templates-v2/management/admin/_application-form/layouts/maned_journal_bulk_edit.html b/portality/templates-v2/management/admin/_application-form/layouts/maned_journal_bulk_edit.html
new file mode 100644
index 0000000000..e1ece1d205
--- /dev/null
+++ b/portality/templates-v2/management/admin/_application-form/layouts/maned_journal_bulk_edit.html
@@ -0,0 +1,15 @@
+{% if formulaic_context.errors %}
+
There is a problem with the form.
+{% endif %}
+
+
+
+
+ {% set fs = formulaic_context.fieldset("bulk_edit") %}
+ {% for f in fs.fields() %}
+ {% set field_template = f.template %}
+ {% include field_template %}
+ {% endfor %}
+
+
+
\ No newline at end of file
diff --git a/portality/templates-v2/management/admin/account/create.html b/portality/templates-v2/management/admin/account/create.html
new file mode 100644
index 0000000000..105deb99c6
--- /dev/null
+++ b/portality/templates-v2/management/admin/account/create.html
@@ -0,0 +1,41 @@
+{% extends "management/admin/base.html" %}
+
+{% block page_title %}Create User{% endblock %}
+
+{% block admin_stylesheets %}
+
+{% endblock %}
+
+{% block admin_content %}
+
+
+
+
+ {% include "_account/includes/_register_form.html" %}
+
+ Please provide the Journal Title and ISSN(s) for the journal that is continued by {{ current.bibjson().title }}.
+
+
+ This will create a record in DOAJ so do not use this option if the journal
+ already exists. Once you submit this form, a new journal record will be created and
+ you may edit the other associated metadata fields.
+
+ Please provide the new Journal Title and new ISSN(s) that
+ continue {{ current.bibjson().title }}. Once you submit this form, a new journal record will
+ be created and you may edit the other associated metadata fields.
+
+ {% endif %}
+
+
+
+ {% from "includes/_formhelpers.html" import render_field_horizontal %}
+ {% from "includes/_formhelpers.html" import render_field %}
+
+
+
+
+
+ {# TODO: there’s a bit of a11y work to be done here; we need to indicate which tabs are hidden and which
+ aren’t using ARIA attributes. #}
+ {# TODO: the first tab content needs to be shown by default, without a "click to see" message. #}
+
+ {% endif %}
+{% endmacro %}
+
+{% set form_id = "maned_form" %}
+{% set formulaic_after = url_for("admin.journal_page", journal_id=obj.id) %}
+{% set form_action = url_for("admin.journal_page", journal_id=obj.id) %}
+
+{% set js_validation = True %}
+{% set auto_save = 0 %}
+{% set notabs = true %}
+{% set diff_table = false %}
+{% set quick_reject = false %}
+{% set withdrawable = true %}
+
+{% block page_title %}Journal: {{ obj.bibjson().title }}{% endblock %}
+{% block body_id %}apply{% endblock %}
+
+{% block admin_content scoped %}
+ {% include "management/_application-form/includes/_editorial_form_body.html" %}
+
+
+
+ {% set action_label = "Withdraw" if obj.is_in_doaj() else "Reinstate" %}
+ {% set message = "Are you sure you want to " + action_label + " " + obj.id %}
+
+ {% if job %}
+ {% set action_label = "Withdrawing" if obj.is_in_doaj() else "Reinstating" %}
+ {% set job_url = "/admin/background_jobs?source=%7B%22query%22%3A%7B%22query_string%22%3A%7B%22query%22%3A%22" + job.id + "%22%2C%22default_operator%22%3A%22AND%22%7D%7D%2C%22sort%22%3A%5B%7B%22created_date%22%3A%7B%22order%22%3A%22desc%22%7D%7D%5D%2C%22from%22%3A0%2C%22size%22%3A25%7D" %}
+ {% set message = "There is currently a background job " + action_label + " " + obj.id + ". You can view the progress of this job here (opens in new tab). You will get an email when your request has been processed; this could take anything from a few minutes to a few hours." %}
+ {% endif %}
+
+ {{ action_label }}
+
+
{% autoescape off %}{{ message }}{% endautoescape %}
+
+ {% if not job %}
+
+ {# withdraw or reinstate only this journal #}
+ {% set url_name = "admin.journal_deactivate" if obj.is_in_doaj() else "admin.journal_activate" %}
+ {% set action = url_for(url_name, journal_id=obj.id) %}
+
+
+
+ {# withdraw or reinstate all continuations #}
+ {% if obj.is_in_doaj() and (
+ obj.bibjson().replaces or obj.bibjson().is_replaced_by
+ ) %}
+
+
+ {% autoescape off %}
+ This journal is connected to another/others by a continuation.
+ Please remember to withdraw all affected records.
+ {% endautoescape %}
+
-
- {% include "application_form/editorial_form_body.html" %}
-
-
-{% include "includes/_hotjar.html" %}
+
{{ obj.bibjson().title }}
+ {% include "management/_application-form/includes/_editorial_form_body.html" %}
{% endblock %}
-{% block extra_js_bottom scoped %}
- {% include "application_form/js/_form_js.html" %}
+{% block editor_js scoped %}
+ {% include "_application-form/includes/_form_js.html" %}
{% endblock %}
diff --git a/portality/templates/application_form/assed_journal.html b/portality/templates-v2/management/editor/assed_journal.html
similarity index 59%
rename from portality/templates/application_form/assed_journal.html
rename to portality/templates-v2/management/editor/assed_journal.html
index 11fa25edf2..a6ec92f9bf 100644
--- a/portality/templates/application_form/assed_journal.html
+++ b/portality/templates-v2/management/editor/assed_journal.html
@@ -1,4 +1,6 @@
-{% extends "editor/editor_base.html" %}
+{% extends "management/editor/base.html" %}
+{# NOTE: this file is not currently used, as editors are not assigned journals,
+but we are leaving it in place in case that changes #}
{% set form_id = "assed_form" %}
{% set formulaic_after = url_for("editor.journal_page", journal_id=obj.id) %}
@@ -15,13 +17,11 @@
{% block body_id %}apply{% endblock %}
{% block editor_content scoped %}
-
{{ obj.bibjson().title }}
-
- {% include "application_form/editorial_form_body.html" %}
-
+
+ {% include "management/includes/_todo.html" %}
+
+ {# ~~->$GroupStatus:Feature~~ #}
+ {% if editor_of_groups | length != 0 %}
+
Activity
+
+
+ {% endif %}
+
+ {# TODO: there’s a bit of a11y work to be done here; we need to indicate which tabs are hidden and which
+ aren’t using ARIA attributes. #}
+ {# TODO: the first tab content needs to be shown by default, without a "click to see" message. #}
+
+
+
+
+
+
+{% endblock %}
+
+{% block editor_js %}
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/portality/templates/application_form/editor_application.html b/portality/templates-v2/management/editor/editor_application.html
similarity index 67%
rename from portality/templates/application_form/editor_application.html
rename to portality/templates-v2/management/editor/editor_application.html
index 6f30c0ffdb..01b1dad841 100644
--- a/portality/templates/application_form/editor_application.html
+++ b/portality/templates-v2/management/editor/editor_application.html
@@ -1,4 +1,4 @@
-{% extends "editor/editor_base.html" %}
+{% extends "management/editor/base.html" %}
{% set form_id = "ed_form" %}
{% set formulaic_after = url_for("editor.application", application_id=obj.id) %}
@@ -14,14 +14,10 @@
{% block body_id %}apply{% endblock %}
{% block editor_content scoped %}
-
{{ obj.bibjson().title }}
-
- {% include "application_form/editorial_form_body.html" %}
-
-
-{% include "includes/_hotjar.html" %}
+
{{ obj.bibjson().title }}
+ {% include "management/_application-form/includes/_editorial_form_body.html" %}
{% endblock %}
-{% block extra_js_bottom scoped %}
- {% include "application_form/js/_form_js.html" %}
+{% block editor_js scoped %}
+ {% include "_application-form/includes/_form_js.html" %}
{% endblock %}
diff --git a/portality/templates/application_form/editor_journal.html b/portality/templates-v2/management/editor/editor_journal.html
similarity index 58%
rename from portality/templates/application_form/editor_journal.html
rename to portality/templates-v2/management/editor/editor_journal.html
index 0c2c04c72d..42c03d72df 100644
--- a/portality/templates/application_form/editor_journal.html
+++ b/portality/templates-v2/management/editor/editor_journal.html
@@ -1,5 +1,6 @@
-{% extends "editor/editor_base.html" %}
-
+{% extends "management/editor/base.html" %}
+{# NOTE: this file is not currently used, as editors are not assigned journals,
+but we are leaving it in place in case that changes #}
{% set form_id = "ed_form" %}
{% set formulaic_after = url_for("editor.journal_page", journal_id=obj.id) %}
{% set form_action = url_for("editor.journal_page", journal_id=obj.id) %}
@@ -15,13 +16,11 @@
{% block body_id %}apply{% endblock %}
{% block editor_content scoped %}
-
{{ obj.bibjson().title }}
-
- {% include "application_form/editorial_form_body.html" %}
-
+
{{ obj.bibjson().title }}
+ {% include "management/_application-form/includes/_editorial_form_body.html" %}
{% endblock %}
-{% block extra_js_bottom scoped %}
+{% block editor_js scoped %}
{% set factory = "journal" %}
- {% include "application_form/js/_form_js.html" %}
+ {% include "_application-form/includes/_form_js.html" %}
{% endblock %}
diff --git a/portality/templates/editor/group_applications.html b/portality/templates-v2/management/editor/group_applications.html
similarity index 52%
rename from portality/templates/editor/group_applications.html
rename to portality/templates-v2/management/editor/group_applications.html
index bb0bd2053e..73023a28d2 100644
--- a/portality/templates/editor/group_applications.html
+++ b/portality/templates-v2/management/editor/group_applications.html
@@ -1,24 +1,28 @@
-{% extends "editor/editor_base.html" %}
+{% extends "management/editor/base.html" %}
-{% include "_edges_common_css.html" %}
+{% block editor_stylesheets %}
+ {% include "management/includes/_edges_common_css.html" %}
+ {# FIXME: for some reason this is not in edges common, why is that? #}
+
+{% endblock %}
{% block page_title %}Your group’s applications{% endblock %}
{% block editor_content %}
-
+
{% endblock %}
-{% block extra_js_bottom %}
+{% block editor_js %}
- {% include "_edges_common_js.html" %}
+ {% include "includes/_edges_common_js.html" %}
{% endblock %}
diff --git a/portality/templates/editor/nav.html b/portality/templates-v2/management/editor/includes/_nav.html
similarity index 76%
rename from portality/templates/editor/nav.html
rename to portality/templates-v2/management/editor/includes/_nav.html
index 2ab38010b1..2aa7b1e41b 100644
--- a/portality/templates/editor/nav.html
+++ b/portality/templates-v2/management/editor/includes/_nav.html
@@ -1,15 +1,6 @@
{% set index = url_for("editor.index") %}
{% set group_apps = url_for('editor.group_suggestions') %}
-{% set group_journals = url_for('editor.group_journals') %}
{% set ass_apps = url_for('editor.associate_suggestions') %}
-{% set ass_journals = url_for('editor.associate_journals') %}
-
-
-{#
-Tabs removed for https://github.com/DOAJ/doajPM/issues/3422
-(ass_journals, "Journals assigned to you", None, "book-open")
-(group_journals, "Your group’s journals", "list_group_journals", "book")
-#}
{% set tabs = [
(index, "Dashboard", None, "list"),
diff --git a/portality/templates-v2/management/editor/journal_locked.html b/portality/templates-v2/management/editor/journal_locked.html
new file mode 100644
index 0000000000..f362fa636f
--- /dev/null
+++ b/portality/templates-v2/management/editor/journal_locked.html
@@ -0,0 +1,27 @@
+{% extends "management/editor/base.html" %}
+
+{# NOTE: this file is not currently in use, and the code that calls it is commented out #}
+
+{% block page_title %}(Locked) {{ journal.bibjson().title }}{% endblock %}
+
+{% block editor_content %}
+
+
+
+ Journal —
+ {{journal.bibjson().title}}
+
+ {% if journal.last_updated %}
+
Last updated: {{journal.last_updated}}
+ {% endif %}
+
+
+
+
You cannot currently edit this journal
+
+
The user {{lock.username}} is currently editing this record, and has an edit-lock until {{lock.expire_formatted()}}
+{% endblock %}
+
+{% block editor_js scoped %}
+ {% set factory = "journal" %}
+ {% include "_application-form/includes/_form_js.html" %}
+{% endblock %}
diff --git a/portality/templates-v2/management/editor/unlocked.html b/portality/templates-v2/management/editor/unlocked.html
new file mode 100644
index 0000000000..ac1c9902c3
--- /dev/null
+++ b/portality/templates-v2/management/editor/unlocked.html
@@ -0,0 +1,8 @@
+{% extends "management/editor/base.html" %}
+
+{% block page_title %}Unlocked record{% endblock %}
+{% block title %}This record is now unlocked{% endblock %}
+
+{% block editor_content %}
+
You may close this tab safely.
+{% endblock %}
diff --git a/portality/templates/editor/associate_applications.html b/portality/templates-v2/management/editor/your_applications.html
similarity index 51%
rename from portality/templates/editor/associate_applications.html
rename to portality/templates-v2/management/editor/your_applications.html
index 4b12ca16a1..fc3ea6bfaf 100644
--- a/portality/templates/editor/associate_applications.html
+++ b/portality/templates-v2/management/editor/your_applications.html
@@ -1,24 +1,28 @@
-{% extends "editor/editor_base.html" %}
+{% extends "management/editor/base.html" %}
-{% include "_edges_common_css.html" %}
+{% block editor_stylesheets %}
+ {% include "management/includes/_edges_common_css.html" %}
+ {# FIXME: for some reason this is not in edges common, why is that? #}
+
+{% endblock %}
{% block page_title %}Applications assigned to you{% endblock %}
{% block editor_content %}
-
+
{% endblock %}
-{% block extra_js_bottom %}
+{% block editor_js %}
- {% include "_edges_common_js.html" %}
+ {% include "includes/_edges_common_js.html" %}
{% endblock %}
diff --git a/portality/templates/_edges_common_css.html b/portality/templates-v2/management/includes/_edges_common_css.html
similarity index 100%
rename from portality/templates/_edges_common_css.html
rename to portality/templates-v2/management/includes/_edges_common_css.html
diff --git a/portality/templates/dashboard/_todo.html b/portality/templates-v2/management/includes/_todo.html
similarity index 65%
rename from portality/templates/dashboard/_todo.html
rename to portality/templates-v2/management/includes/_todo.html
index 069ba89633..14d29431b2 100644
--- a/portality/templates/dashboard/_todo.html
+++ b/portality/templates-v2/management/includes/_todo.html
@@ -97,25 +97,25 @@
"link" : url_for('editor.associate_suggestions')
}
}
-%}
+ %}
{% if todos|length == 0 %}
-
-
+
+
{% if current_user.has_role("admin") %}
- {% set source = search_query_source(
+ {% set source = search_query_source(
term=[
{"admin.editor.exact" : current_user.id},
{"index.application_type.exact" : "new application"}
],
sort=[{"admin.date_applied": {"order": "asc"}}]
)
- %}
- All priority tasks have been done. Check your queue for more open applications
+ %}
+ All priority tasks have been done. Check your queue for more open applications
{% elif current_user.has_role("editor") %}
{% set source = search_query_source(
term=[
@@ -123,7 +123,7 @@
],
sort=[{"admin.date_applied": {"order": "asc"}}]
)
- %}
+ %}
All priority tasks have been done. Check your queue for more open applications. If you need more applications to be assigned to your group, contact your Managing Editor.
{% elif current_user.has_role("associate_editor") %}
{% set source = search_query_source(
@@ -132,71 +132,62 @@
],
sort=[{"admin.date_applied": {"order": "asc"}}]
)
- %}
+ %}
All priority tasks have been done. Check your queue for more open applications. If you need more to be assigned to you, contact your Editor or Managing Editor.
{% endif %}
-
+
{% endif %}
- {% for todo in todos %}
- {# TODO only show tasks for this user’s groups #}
- {# TODO integrated priority in list display
- {{ todo.boost }}
- #}
- {% set action = TODOS[todo.action_id[0]] %}
- {% set app_route = "admin.application" if current_user.has_role("admin") else "editor.application" %}
- {% set app_url = url_for(app_route, application_id=todo.object_id) %}
- {% set app_date = todo.object.date_applied_timestamp %}
-
+ {% for todo in todos %}
+ {% set action = TODOS[todo.action_id[0]] %}
+ {% set app_route = "admin.application" if current_user.has_role("admin") else "editor.application" %}
+ {% set app_url = url_for(app_route, application_id=todo.object_id) %}
+ {% set app_date = todo.object.date_applied_timestamp %}
+
+ {% endfor %}
- {# TODO to be displayed once we implement page listing out all tasks
-
- #}
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/portality/templates-v2/public/400.html b/portality/templates-v2/public/400.html
new file mode 100644
index 0000000000..10857594b5
--- /dev/null
+++ b/portality/templates-v2/public/400.html
@@ -0,0 +1,17 @@
+{% extends "public/layouts/single_col_page.html" %}
+
+{% block body_class %}error-page{% endblock %}
+{% block page_title %}400: Bad request{% endblock %}
+
+{% block single_col_content %}
+
400 — Bad request!
+
Uh-oh! An error has occured. It looks like something has gone wrong.
+
+ If you are trying to reset your password, the link may have expired.
- {% include "account/_reset_form.html" %}
+ {% include "_account/includes/_reset_form.html" %}
If you have any difficulties with your account, please contact us.
diff --git a/portality/templates/api/includes/swagger_description.html b/portality/templates-v2/public/api/includes/_swagger_description.html
similarity index 100%
rename from portality/templates/api/includes/swagger_description.html
rename to portality/templates-v2/public/api/includes/_swagger_description.html
diff --git a/portality/templates/api/includes/_version-history.html b/portality/templates-v2/public/api/includes/_version-history.html
similarity index 100%
rename from portality/templates/api/includes/_version-history.html
rename to portality/templates-v2/public/api/includes/_version-history.html
diff --git a/portality/templates/api/v3/api_docs.html b/portality/templates-v2/public/api/v3/api_docs.html
similarity index 86%
rename from portality/templates/api/v3/api_docs.html
rename to portality/templates-v2/public/api/v3/api_docs.html
index fc95ca6569..363d54c0b3 100644
--- a/portality/templates/api/v3/api_docs.html
+++ b/portality/templates-v2/public/api/v3/api_docs.html
@@ -1,15 +1,15 @@
-{% extends "layouts/public_base.html" %}
+{% extends "public/base.html" %}
{% block page_title %}API{% endblock %}
-{% block extra_stylesheets %}
+{% block public_stylesheets %}
{% endblock %}
-{% block content %}
+{% block public_content %}
@@ -21,23 +21,23 @@
API
A new version of the API is available here.
You should review the release notes and migration instructions as soon as possible.
- {% include "api/includes/swagger_description.html" %}
+ {% include "public/api/includes/_swagger_description.html" %}
Full API reference
- {% include "api/v3/extra_docs.html" %}
- {% include "api/includes/_version-history.html" %}
+ {% include "public/api/v3/includes/_extra_docs.html" %}
+ {% include "public/api/includes/_version-history.html" %}
- {% include "api/v3/sidenav.html" %}
+ {% include "public/api/v3/includes/_sidenav.html" %}
{% endblock %}
-{% block extra_js_bottom %}
+{% block public_js %}
diff --git a/portality/templates/api/v3/extra_docs.html b/portality/templates-v2/public/api/v3/includes/_extra_docs.html
similarity index 100%
rename from portality/templates/api/v3/extra_docs.html
rename to portality/templates-v2/public/api/v3/includes/_extra_docs.html
diff --git a/portality/templates/api/v3/sidenav.html b/portality/templates-v2/public/api/v3/includes/_sidenav.html
similarity index 100%
rename from portality/templates/api/v3/sidenav.html
rename to portality/templates-v2/public/api/v3/includes/_sidenav.html
diff --git a/portality/templates/api/v4/api_docs.html b/portality/templates-v2/public/api/v4/api_docs.html
similarity index 92%
rename from portality/templates/api/v4/api_docs.html
rename to portality/templates-v2/public/api/v4/api_docs.html
index a90016d56d..1e0a453bb9 100644
--- a/portality/templates/api/v4/api_docs.html
+++ b/portality/templates-v2/public/api/v4/api_docs.html
@@ -1,15 +1,15 @@
-{% extends "layouts/public_base.html" %}
+{% extends "public/base.html" %}
{% block page_title %}API{% endblock %}
-{% block extra_stylesheets %}
+{% block public_stylesheets %}
{% endblock %}
-{% block content %}
+{% block public_content %}
@@ -46,23 +46,23 @@
Timeline
Please get in touch if you have any questions.
- {% include "api/includes/swagger_description.html" %}
+ {% include "public/api/includes/_swagger_description.html" %}
Full API reference
- {% include "api/v4/extra_docs.html" %}
- {% include "api/includes/_version-history.html" %}
+ {% include "public/api/v4/includes/_extra_docs.html" %}
+ {% include "public/api/includes/_version-history.html" %}
- {% include "api/v4/sidenav.html" %}
+ {% include "public/api/v4/includes/_sidenav.html" %}
{% endblock %}
-{% block extra_js_bottom %}
+{% block public_js %}
diff --git a/portality/templates/api/v4/extra_docs.html b/portality/templates-v2/public/api/v4/includes/_extra_docs.html
similarity index 100%
rename from portality/templates/api/v4/extra_docs.html
rename to portality/templates-v2/public/api/v4/includes/_extra_docs.html
diff --git a/portality/templates/api/v4/sidenav.html b/portality/templates-v2/public/api/v4/includes/_sidenav.html
similarity index 100%
rename from portality/templates/api/v4/sidenav.html
rename to portality/templates-v2/public/api/v4/includes/_sidenav.html
diff --git a/portality/templates/doaj/article.html b/portality/templates-v2/public/article.html
similarity index 93%
rename from portality/templates/doaj/article.html
rename to portality/templates-v2/public/article.html
index b1fc9caf4a..e853224192 100644
--- a/portality/templates/doaj/article.html
+++ b/portality/templates-v2/public/article.html
@@ -1,15 +1,15 @@
-{% extends "layouts/public_base.html" %}
+{% extends "public/base.html" %}
-{% block body_class %}article-details{% endblock %}
+{% block page_title %}{% include "public/includes/_article_meta_title.html" %}{% endblock %}
+
+{% block meta_og_title %}{% include "public/includes/_article_meta_title.html" %}{% endblock %}
+{% block meta_twitter_title %}{% include "public/includes/_article_meta_title.html" %}{% endblock %}
-{% block page_title %}{% include "doaj/includes/_article_meta_title.html" %}{% endblock %}
-{% block meta_og_title %}{% include "doaj/includes/_article_meta_title.html" %}{% endblock %}
-{% block meta_twitter_title %}{% include "doaj/includes/_article_meta_title.html" %}{% endblock %}
-{%- block meta_description -%}{% include "doaj/includes/_article_meta_description.html" %}{%- endblock -%}
-{%- block meta_og_description -%}{% include "doaj/includes/_article_meta_description.html" %}{%- endblock -%}
-{%- block meta_twitter_description -%}{% include "doaj/includes/_article_meta_description.html" %}{%- endblock -%}
+{%- block meta_description -%}{% include "public/includes/_article_meta_description.html" %}{%- endblock -%}
+{%- block meta_og_description -%}{% include "public/includes/_article_meta_description.html" %}{%- endblock -%}
+{%- block meta_twitter_description -%}{% include "public/includes/_article_meta_description.html" %}{%- endblock -%}
-{% block extra_meta_tags %}
+{% block public_meta %}
{% set bibjson = article.bibjson() %}
{% set jbib = journal.bibjson() %}
{% set jtitle, cite = bibjson.vancouver_citation() %}
@@ -51,7 +51,9 @@
{% endfor %}
{% endblock %}
-{% block content %}
+{% block body_class %}article-details{% endblock %}
+
+{% block public_content %}
{%
set TYN = {
diff --git a/portality/templates/doaj/articles_search.html b/portality/templates-v2/public/articles_search.html
similarity index 77%
rename from portality/templates/doaj/articles_search.html
rename to portality/templates-v2/public/articles_search.html
index 4a518fb3ae..393cadff52 100644
--- a/portality/templates/doaj/articles_search.html
+++ b/portality/templates-v2/public/articles_search.html
@@ -1,6 +1,4 @@
-{% extends "layouts/public_base.html" %}
-
-{% block body_attrs %}class="search"{% endblock %}
+{% extends "public/base.html" %}
{% block page_title %}Articles{% endblock %}
{% block meta_og_title %}Articles{% endblock %}
@@ -9,14 +7,14 @@
{%- block meta_og_description -%}Find open access articles in DOAJ.{%- endblock -%}
{%- block meta_twitter_description -%}Find open access articles in DOAJ.{%- endblock -%}
-{% block content %}
+{% block public_content %}
- {% include "includes/search-help-modal.html" %}
+ {% include "public/includes/_search-help-modal.html" %}
+ {% block extra_header %}{% endblock %}
+
+
+ {% include "public/includes/_quick_search_modal.html" %}
+
+ {# global site note #}
+ {% if config.get("SITE_NOTE_ACTIVE", False) and not request.cookies.get(config.get("SITE_NOTE_KEY")) %}
+
+
+
+ {% include templates.SITE_NOTE %}
+
+
+
+ {% endif %}
+
+
+ {% block public_content %}{% endblock %}
+
+
+ {% include "public/includes/_footer.html" %}
+
+{% endblock %}
+
+{% block base_js %}
+ {% block public_js %}{% endblock %}
+{% endblock %}
+
diff --git a/portality/templates/data/advisory-board-council.html b/portality/templates-v2/public/includes/_advisory-board-council.html
similarity index 100%
rename from portality/templates/data/advisory-board-council.html
rename to portality/templates-v2/public/includes/_advisory-board-council.html
diff --git a/portality/templates/data/ambassadors.html b/portality/templates-v2/public/includes/_ambassadors.html
similarity index 100%
rename from portality/templates/data/ambassadors.html
rename to portality/templates-v2/public/includes/_ambassadors.html
diff --git a/portality/templates/doaj/includes/_article_meta_description.html b/portality/templates-v2/public/includes/_article_meta_description.html
similarity index 100%
rename from portality/templates/doaj/includes/_article_meta_description.html
rename to portality/templates-v2/public/includes/_article_meta_description.html
diff --git a/portality/templates/doaj/includes/_article_meta_title.html b/portality/templates-v2/public/includes/_article_meta_title.html
similarity index 100%
rename from portality/templates/doaj/includes/_article_meta_title.html
rename to portality/templates-v2/public/includes/_article_meta_title.html
diff --git a/portality/templates/includes/_aside_in_case_of_rejection.html b/portality/templates-v2/public/includes/_aside_in_case_of_rejection.html
similarity index 100%
rename from portality/templates/includes/_aside_in_case_of_rejection.html
rename to portality/templates-v2/public/includes/_aside_in_case_of_rejection.html
diff --git a/portality/templates/includes/footer-column.html b/portality/templates-v2/public/includes/_footer-column.html
similarity index 77%
rename from portality/templates/includes/footer-column.html
rename to portality/templates-v2/public/includes/_footer-column.html
index 1ef4307c82..06f07f0cd0 100644
--- a/portality/templates/includes/footer-column.html
+++ b/portality/templates-v2/public/includes/_footer-column.html
@@ -4,6 +4,6 @@
{{ entry.label }}
- {% include "includes/menu-items.html" %}
+ {% include "public/includes/_menu-items.html" %}
\ No newline at end of file
diff --git a/portality/templates/includes/footer.html b/portality/templates-v2/public/includes/_footer.html
similarity index 92%
rename from portality/templates/includes/footer.html
rename to portality/templates-v2/public/includes/_footer.html
index 82a08817a7..086dd047e4 100644
--- a/portality/templates/includes/footer.html
+++ b/portality/templates-v2/public/includes/_footer.html
@@ -1,4 +1,4 @@
-{% include "includes/_nav_modals.html" %}
+{% include "public/includes/_nav_modals.html" %}
diff --git a/portality/templates/doaj/includes/_journal_meta_description.html b/portality/templates-v2/public/includes/_journal_meta_description.html
similarity index 100%
rename from portality/templates/doaj/includes/_journal_meta_description.html
rename to portality/templates-v2/public/includes/_journal_meta_description.html
diff --git a/portality/templates/doaj/includes/_journal_meta_title.html b/portality/templates-v2/public/includes/_journal_meta_title.html
similarity index 100%
rename from portality/templates/doaj/includes/_journal_meta_title.html
rename to portality/templates-v2/public/includes/_journal_meta_title.html
diff --git a/portality/templates/includes/menu-items.html b/portality/templates-v2/public/includes/_menu-items.html
similarity index 100%
rename from portality/templates/includes/menu-items.html
rename to portality/templates-v2/public/includes/_menu-items.html
diff --git a/portality/templates/includes/_nav_modals.html b/portality/templates-v2/public/includes/_nav_modals.html
similarity index 100%
rename from portality/templates/includes/_nav_modals.html
rename to portality/templates-v2/public/includes/_nav_modals.html
diff --git a/portality/templates/data/publisher-supporters.html b/portality/templates-v2/public/includes/_publisher-supporters.html
similarity index 100%
rename from portality/templates/data/publisher-supporters.html
rename to portality/templates-v2/public/includes/_publisher-supporters.html
diff --git a/portality/templates/includes/_quick_search_modal.html b/portality/templates-v2/public/includes/_quick_search_modal.html
similarity index 100%
rename from portality/templates/includes/_quick_search_modal.html
rename to portality/templates-v2/public/includes/_quick_search_modal.html
diff --git a/portality/templates/includes/search-help-modal.html b/portality/templates-v2/public/includes/_search-help-modal.html
similarity index 100%
rename from portality/templates/includes/search-help-modal.html
rename to portality/templates-v2/public/includes/_search-help-modal.html
diff --git a/portality/templates/includes/_sidenav_toc.html b/portality/templates-v2/public/includes/_sidenav_toc.html
similarity index 100%
rename from portality/templates/includes/_sidenav_toc.html
rename to portality/templates-v2/public/includes/_sidenav_toc.html
diff --git a/portality/templates/data/sponsors.html b/portality/templates-v2/public/includes/_sponsors.html
similarity index 100%
rename from portality/templates/data/sponsors.html
rename to portality/templates-v2/public/includes/_sponsors.html
diff --git a/portality/templates/data/team.html b/portality/templates-v2/public/includes/_team.html
similarity index 100%
rename from portality/templates/data/team.html
rename to portality/templates-v2/public/includes/_team.html
diff --git a/portality/templates/data/volunteers.html b/portality/templates-v2/public/includes/_volunteers.html
similarity index 100%
rename from portality/templates/data/volunteers.html
rename to portality/templates-v2/public/includes/_volunteers.html
diff --git a/portality/templates-v2/public/includes/_wechat_modal.html b/portality/templates-v2/public/includes/_wechat_modal.html
new file mode 100644
index 0000000000..2e4ed6ec01
--- /dev/null
+++ b/portality/templates-v2/public/includes/_wechat_modal.html
@@ -0,0 +1,12 @@
+{# WeChat QR code modal #}
+
DOAJ is a unique and extensive index of diverse open access journals from around the world, driven by a growing community, and is committed to ensuring quality content is freely available online for everyone.
+
DOAJ is committed to keeping its services free of charge, including being indexed, and its data freely available.
DOAJ’s team of managing editors, editors, and volunteers work with publishers to index new journals. As soon as they’re accepted, these journals are displayed on our website freely accessible to everyone.
{% if not current_user.is_anonymous and current_user.has_role("admin") %}
- Edit this journal
+ Edit
+ this journal
{% endif %}
{% if journal.last_manually_updated_since(days=30) %}
-
- Updated recently
-
+
+ Updated recently
+
{% endif %}
+
-
- {{ bibjson.title }}
- {% if bibjson.alternative_title %}
- {{ bibjson.alternative_title }}
- {% endif %}
-
+
+ {{ bibjson.title }}
+ {% if bibjson.alternative_title %}
+ {{ bibjson.alternative_title }}
+ {% endif %}
+
{%- set seal = journal.has_seal() -%}
{%- if seal -%}
@@ -42,12 +41,13 @@
{%- endif %}
+
-
- {# this next bit has to be all on one line so that the spacing is correct #}
- {% if bibjson.pissn %}{{ bibjson.pissn }} (Print){% endif %}{% if bibjson.eissn %}
- {% if bibjson.pissn %} / {% endif %}{{ bibjson.eissn }} (Online){% endif %}
+
+ {# this next bit has to be all on one line so that the spacing is correct #}
+ {% if bibjson.pissn %}{{ bibjson.pissn }} (Print){% endif %}{% if bibjson.eissn %}
+ {% if bibjson.pissn %} / {% endif %}{{ bibjson.eissn }} (Online){% endif %}