@sfgrp/taxonpages 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. package/README.markdown +432 -0
  2. package/bin/taxonpages.js +78 -0
  3. package/index.html +22 -0
  4. package/package.json +82 -0
  5. package/postcss.config.cjs +17 -0
  6. package/server.js +142 -0
  7. package/src/App.vue +31 -0
  8. package/src/assets/css/leaflet.css +24 -0
  9. package/src/assets/css/main.css +23 -0
  10. package/src/assets/css/tailwind.css +3 -0
  11. package/src/assets/css/vars.css +58 -0
  12. package/src/assets/css/webkit.css +19 -0
  13. package/src/assets/images/taxonworks_full_logo.svg +22 -0
  14. package/src/assets/images/taxonworks_logo.svg +7 -0
  15. package/src/cli/commands/build.js +60 -0
  16. package/src/cli/commands/dev.js +48 -0
  17. package/src/cli/commands/init.js +65 -0
  18. package/src/cli/commands/preview.js +27 -0
  19. package/src/cli/commands/serve.js +26 -0
  20. package/src/cli/utils/resolveConfig.js +112 -0
  21. package/src/components/AddressMaker.global.vue +67 -0
  22. package/src/components/Animation/AnimationOpacity.global.vue +12 -0
  23. package/src/components/Autocomplete/Autocomplete.global.vue +223 -0
  24. package/src/components/Autocomplete/AutocompleteOtu.global.vue +33 -0
  25. package/src/components/Autocomplete/AutocompleteSpinner.vue +36 -0
  26. package/src/components/Button/ButtonExpand.global.vue +40 -0
  27. package/src/components/Button/VButton.global.vue +39 -0
  28. package/src/components/Card/VCard.global.vue +18 -0
  29. package/src/components/Card/VCardContent.global.vue +5 -0
  30. package/src/components/Card/VCardHeader.global.vue +7 -0
  31. package/src/components/Clipboard/VClipboard.global.vue +50 -0
  32. package/src/components/Dropdown/Dropdown.global.vue +108 -0
  33. package/src/components/Footer/FooterAnalytics.vue +26 -0
  34. package/src/components/Footer/FooterCitation.vue +45 -0
  35. package/src/components/Footer/FooterCopyright.vue +20 -0
  36. package/src/components/Gallery/GalleryCarousel/GalleryCarousel.global.vue +138 -0
  37. package/src/components/Gallery/GalleryImage.global.vue +65 -0
  38. package/src/components/Gallery/GalleryMainImage.vue +63 -0
  39. package/src/components/Gallery/GalleryMosaic/GalleryMosaic.global.vue +75 -0
  40. package/src/components/Gallery/GalleryThumbnail.vue +26 -0
  41. package/src/components/Gallery/GalleryThumbnailList.vue +34 -0
  42. package/src/components/Gallery/useGallery.js +50 -0
  43. package/src/components/Icon/IconArrowDown.global.vue +19 -0
  44. package/src/components/Icon/IconArrowLeft.global.vue +20 -0
  45. package/src/components/Icon/IconArrowRight.global.vue +20 -0
  46. package/src/components/Icon/IconArrowUp.global.vue +16 -0
  47. package/src/components/Icon/IconCalendar.global.vue +25 -0
  48. package/src/components/Icon/IconCheck.global.vue +16 -0
  49. package/src/components/Icon/IconClipboard.global.vue +16 -0
  50. package/src/components/Icon/IconClose.global.vue +20 -0
  51. package/src/components/Icon/IconDocument.global.vue +20 -0
  52. package/src/components/Icon/IconDownload.global.vue +16 -0
  53. package/src/components/Icon/IconFiles.global.vue +23 -0
  54. package/src/components/Icon/IconGithub.global.vue +11 -0
  55. package/src/components/Icon/IconHamburger.global.vue +18 -0
  56. package/src/components/Icon/IconInformation.global.vue +16 -0
  57. package/src/components/Icon/IconJson.global.vue +14 -0
  58. package/src/components/Icon/IconMinusCircle.global.vue +19 -0
  59. package/src/components/Icon/IconPause.global.vue +16 -0
  60. package/src/components/Icon/IconPlay.global.vue +16 -0
  61. package/src/components/Icon/IconPlusCircle.global.vue +19 -0
  62. package/src/components/Icon/IconSearch.global.vue +19 -0
  63. package/src/components/Icon/IconSpeakerWave.global.vue +16 -0
  64. package/src/components/Icon/IconSpeakerX.global.vue +16 -0
  65. package/src/components/Icon/IconTrash.global.vue +16 -0
  66. package/src/components/Icon/IconWarning.global.vue +16 -0
  67. package/src/components/ImageViewer/ControlImageNext.vue +11 -0
  68. package/src/components/ImageViewer/ControlImagePrevious.vue +10 -0
  69. package/src/components/ImageViewer/ImageAttribution.vue +15 -0
  70. package/src/components/ImageViewer/ImageDepictions.vue +21 -0
  71. package/src/components/ImageViewer/ImageSource.vue +15 -0
  72. package/src/components/ImageViewer/ImageToolbar.vue +14 -0
  73. package/src/components/ImageViewer/ImageViewer.global.vue +197 -0
  74. package/src/components/ImageViewer/ImageViewerClose.vue +12 -0
  75. package/src/components/ImageViewer/ImageViewerCounter.vue +16 -0
  76. package/src/components/Input/InputText.global.vue +30 -0
  77. package/src/components/Input/SelectInput.global.vue +31 -0
  78. package/src/components/Layout/LayoutFooter.vue +67 -0
  79. package/src/components/Layout/LayoutHeader.vue +62 -0
  80. package/src/components/Map/VMap.client.vue +365 -0
  81. package/src/components/Map/constants/disableLayerOptions.js +7 -0
  82. package/src/components/Map/constants/index.js +1 -0
  83. package/src/components/Map/icons/AssertedDistribution.js +5 -0
  84. package/src/components/Map/icons/CollectionObject.js +5 -0
  85. package/src/components/Map/icons/FieldOccurrence.js +5 -0
  86. package/src/components/Map/icons/Georeference.js +5 -0
  87. package/src/components/Map/icons/TypeMaterial.js +5 -0
  88. package/src/components/Map/icons/index.js +5 -0
  89. package/src/components/Map/shapes/Absent.js +8 -0
  90. package/src/components/Map/shapes/Aggregate.js +7 -0
  91. package/src/components/Map/shapes/AssertedDistribution.js +7 -0
  92. package/src/components/Map/shapes/CollectionObject.js +5 -0
  93. package/src/components/Map/shapes/FieldOccurrence.js +5 -0
  94. package/src/components/Map/shapes/TypeMaterial.js +5 -0
  95. package/src/components/Map/shapes/index.js +6 -0
  96. package/src/components/Map/utils/addPatternToMap.js +45 -0
  97. package/src/components/Map/utils/geojsonOptions.js +62 -0
  98. package/src/components/Map/utils/makeTileFromConfiguration.js +31 -0
  99. package/src/components/Markdown/MarkdownLayout.global.vue +36 -0
  100. package/src/components/Modal/VModal.global.vue +107 -0
  101. package/src/components/Navbar/NavbarMenu.vue +36 -0
  102. package/src/components/Navbar/NavbarMobile.vue +93 -0
  103. package/src/components/Navbar/NavbarSubmenu.vue +112 -0
  104. package/src/components/Pagination/VPagination.global.vue +139 -0
  105. package/src/components/Pagination/VPaginationInfo.global.vue +36 -0
  106. package/src/components/ProjectStats.global.vue +69 -0
  107. package/src/components/Ssr/ClientOnly.global.vue +14 -0
  108. package/src/components/SwitchTheme.vue +86 -0
  109. package/src/components/Tab/TabItem.global.vue +20 -0
  110. package/src/components/Tab/TabMenu.global.vue +7 -0
  111. package/src/components/Table/VTable.global.vue +7 -0
  112. package/src/components/Table/VTableBody.global.vue +7 -0
  113. package/src/components/Table/VTableBodyCell.global.vue +7 -0
  114. package/src/components/Table/VTableBodyRow.global.vue +5 -0
  115. package/src/components/Table/VTableHeader.global.vue +7 -0
  116. package/src/components/Table/VTableHeaderCell.global.vue +7 -0
  117. package/src/components/Table/VTableHeaderRow.global.vue +5 -0
  118. package/src/components/TrackerReport.global.vue +92 -0
  119. package/src/components/VSkeleton.global.vue +48 -0
  120. package/src/components/VSpinner.global.vue +219 -0
  121. package/src/components/clientComponents.js +28 -0
  122. package/src/components/globalComponents.js +29 -0
  123. package/src/constants/configPaths.cjs +4 -0
  124. package/src/constants/defaultConfig.js +7 -0
  125. package/src/constants/objectTypes.js +8 -0
  126. package/src/entry-client.js +39 -0
  127. package/src/entry-server.js +114 -0
  128. package/src/layout/Application.vue +21 -0
  129. package/src/main.js +20 -0
  130. package/src/modules/DwCFilter/components/DropdownMenu.vue +79 -0
  131. package/src/modules/DwCFilter/components/Facet/FacetDistribution.vue +47 -0
  132. package/src/modules/DwCFilter/components/Facet/FacetInstitutionCode.vue +17 -0
  133. package/src/modules/DwCFilter/components/Facet/FacetOrder.vue +38 -0
  134. package/src/modules/DwCFilter/components/Facet/FacetTypeStatus.vue +35 -0
  135. package/src/modules/DwCFilter/components/FilterBar.vue +123 -0
  136. package/src/modules/DwCFilter/components/OtuModal/OtuModal.vue +177 -0
  137. package/src/modules/DwCFilter/components/OtuModal/RecordItems.vue +89 -0
  138. package/src/modules/DwCFilter/components/OtuModal/TabList.vue +32 -0
  139. package/src/modules/DwCFilter/router/index.js +7 -0
  140. package/src/modules/DwCFilter/utils/flattenParameters.js +20 -0
  141. package/src/modules/DwCFilter/views/index.vue +183 -0
  142. package/src/modules/ImageMatrix/components/ListImages.vue +54 -0
  143. package/src/modules/ImageMatrix/router/index.js +7 -0
  144. package/src/modules/ImageMatrix/services/Keys.js +9 -0
  145. package/src/modules/ImageMatrix/utils/makeImageObject.js +15 -0
  146. package/src/modules/ImageMatrix/views/id.vue +133 -0
  147. package/src/modules/bibliography/components/DropdownMenu.vue +53 -0
  148. package/src/modules/bibliography/components/Facet/FacetFullCitation.vue +0 -0
  149. package/src/modules/bibliography/components/OtuModal.vue +129 -0
  150. package/src/modules/bibliography/components/VSlider.vue +154 -0
  151. package/src/modules/bibliography/components/YearPicker.vue +40 -0
  152. package/src/modules/bibliography/router/index.js +7 -0
  153. package/src/modules/bibliography/utils/getPagination.js +7 -0
  154. package/src/modules/bibliography/views/index.vue +225 -0
  155. package/src/modules/home/router/index.js +8 -0
  156. package/src/modules/home/views/index.vue +11 -0
  157. package/src/modules/httpErrorPages/router/index.js +18 -0
  158. package/src/modules/httpErrorPages/view/404.vue +10 -0
  159. package/src/modules/httpErrorPages/view/500.vue +11 -0
  160. package/src/modules/interactiveKeys/router/index.js +7 -0
  161. package/src/modules/interactiveKeys/views/InteractiveKey.vue +108 -0
  162. package/src/modules/keys/components/MetadataModal.vue +53 -0
  163. package/src/modules/keys/router/index.js +7 -0
  164. package/src/modules/keys/views/keyId.vue +161 -0
  165. package/src/modules/news/adapters/makeNews.js +21 -0
  166. package/src/modules/news/components/NewsCard.vue +35 -0
  167. package/src/modules/news/components/NewsCategories.vue +31 -0
  168. package/src/modules/news/components/PinnedNews.vue +70 -0
  169. package/src/modules/news/components/WidgetNews.global.vue +53 -0
  170. package/src/modules/news/router/index.js +12 -0
  171. package/src/modules/news/services/News.js +11 -0
  172. package/src/modules/news/store/news.js +50 -0
  173. package/src/modules/news/utils/getPagination.js +7 -0
  174. package/src/modules/news/views/id.vue +77 -0
  175. package/src/modules/news/views/index.vue +69 -0
  176. package/src/modules/otus/components/Breadcrumb/Breadcrumb.vue +40 -0
  177. package/src/modules/otus/components/Breadcrumb/BreadcrumbDropdown.vue +57 -0
  178. package/src/modules/otus/components/CommonNames.vue +14 -0
  179. package/src/modules/otus/components/DWCDownload.vue +33 -0
  180. package/src/modules/otus/components/DataMap.vue +57 -0
  181. package/src/modules/otus/components/Export.vue +1 -0
  182. package/src/modules/otus/components/ExternalResources.vue +11 -0
  183. package/src/modules/otus/components/Panel/PanelBiologicalAssociations/PanelBiologicalAssociations.vue +184 -0
  184. package/src/modules/otus/components/Panel/PanelBiologicalAssociations/main.js +6 -0
  185. package/src/modules/otus/components/Panel/PanelBiologicalAssociations/utils/makeBiologicalAssociation.js +30 -0
  186. package/src/modules/otus/components/Panel/PanelContent/PanelContent.vue +58 -0
  187. package/src/modules/otus/components/Panel/PanelContent/PanelContentTopic.vue +42 -0
  188. package/src/modules/otus/components/Panel/PanelContent/main.js +6 -0
  189. package/src/modules/otus/components/Panel/PanelDescendants/DescendantsSynonymList.vue +21 -0
  190. package/src/modules/otus/components/Panel/PanelDescendants/DescendantsTree.vue +122 -0
  191. package/src/modules/otus/components/Panel/PanelDescendants/PanelDescendants.vue +82 -0
  192. package/src/modules/otus/components/Panel/PanelDescendants/main.js +6 -0
  193. package/src/modules/otus/components/Panel/PanelDropdown.vue +63 -0
  194. package/src/modules/otus/components/Panel/PanelGallery/PanelGallery.vue +42 -0
  195. package/src/modules/otus/components/Panel/PanelGallery/main.js +7 -0
  196. package/src/modules/otus/components/Panel/PanelKeys/PanelKeys.vue +103 -0
  197. package/src/modules/otus/components/Panel/PanelKeys/main.js +6 -0
  198. package/src/modules/otus/components/Panel/PanelMap/PanelMap.vue +124 -0
  199. package/src/modules/otus/components/Panel/PanelMap/clusters/Mixed.js +50 -0
  200. package/src/modules/otus/components/Panel/PanelMap/clusters/index.js +2 -0
  201. package/src/modules/otus/components/Panel/PanelMap/clusters/makeClusterIconFor.js +10 -0
  202. package/src/modules/otus/components/Panel/PanelMap/components/CachedMap.vue +118 -0
  203. package/src/modules/otus/components/Panel/PanelMap/components/DwcTable.vue +64 -0
  204. package/src/modules/otus/components/Panel/PanelMap/components/MapPopup.vue +34 -0
  205. package/src/modules/otus/components/Panel/PanelMap/components/Search/ListResults.vue +51 -0
  206. package/src/modules/otus/components/Panel/PanelMap/components/Search/OtuSearch.vue +167 -0
  207. package/src/modules/otus/components/Panel/PanelMap/components/Search/SearchBar.vue +27 -0
  208. package/src/modules/otus/components/Panel/PanelMap/composables/useGeojsonOptions.js +36 -0
  209. package/src/modules/otus/components/Panel/PanelMap/constants/index.js +1 -0
  210. package/src/modules/otus/components/Panel/PanelMap/constants/legend.js +30 -0
  211. package/src/modules/otus/components/Panel/PanelMap/main.js +6 -0
  212. package/src/modules/otus/components/Panel/PanelMap/store/useDistributionStore.js +130 -0
  213. package/src/modules/otus/components/Panel/PanelMap/utils/index.js +4 -0
  214. package/src/modules/otus/components/Panel/PanelMap/utils/isRankGroup.js +5 -0
  215. package/src/modules/otus/components/Panel/PanelMap/utils/makeGeoJSONFeature.js +13 -0
  216. package/src/modules/otus/components/Panel/PanelMap/utils/makeSegmentedCircle.js +37 -0
  217. package/src/modules/otus/components/Panel/PanelMap/utils/removeDuplicateShapes.js +40 -0
  218. package/src/modules/otus/components/Panel/PanelNomenclature/PanelCitationRow.vue +25 -0
  219. package/src/modules/otus/components/Panel/PanelNomenclature/PanelNomenclature.vue +97 -0
  220. package/src/modules/otus/components/Panel/PanelNomenclature/PanelNomenclatureShowMore.vue +22 -0
  221. package/src/modules/otus/components/Panel/PanelNomenclature/main.js +6 -0
  222. package/src/modules/otus/components/Panel/PanelNomenclature/splitList.js +14 -0
  223. package/src/modules/otus/components/Panel/PanelNomenclatureReferences/PanelNomenclatureReferences.vue +72 -0
  224. package/src/modules/otus/components/Panel/PanelNomenclatureReferences/PanelReferenceRow.vue +20 -0
  225. package/src/modules/otus/components/Panel/PanelNomenclatureReferences/main.js +6 -0
  226. package/src/modules/otus/components/Panel/PanelSounds/PanelSounds.vue +42 -0
  227. package/src/modules/otus/components/Panel/PanelSounds/components/AudioPlayer.vue +275 -0
  228. package/src/modules/otus/components/Panel/PanelSounds/components/PanelSoundRow.vue +21 -0
  229. package/src/modules/otus/components/Panel/PanelSounds/components/SoundObservations.vue +73 -0
  230. package/src/modules/otus/components/Panel/PanelSounds/components/TableObservations.vue +31 -0
  231. package/src/modules/otus/components/Panel/PanelSounds/constants/observationTypes.js +15 -0
  232. package/src/modules/otus/components/Panel/PanelSounds/main.js +7 -0
  233. package/src/modules/otus/components/Panel/PanelSounds/utils/index.js +5 -0
  234. package/src/modules/otus/components/Panel/PanelSounds/utils/makeContinuousObservation.js +5 -0
  235. package/src/modules/otus/components/Panel/PanelSounds/utils/makeMediaObservation.js +5 -0
  236. package/src/modules/otus/components/Panel/PanelSounds/utils/makeObservation.js +40 -0
  237. package/src/modules/otus/components/Panel/PanelSounds/utils/makePresenceAbsenceObservation.js +5 -0
  238. package/src/modules/otus/components/Panel/PanelSounds/utils/makeQualitativeObservation.js +5 -0
  239. package/src/modules/otus/components/Panel/PanelSounds/utils/makeSampleObservation.js +29 -0
  240. package/src/modules/otus/components/Panel/PanelSounds/utils/makeWorkingObservation.js +5 -0
  241. package/src/modules/otus/components/Panel/PanelStats/PanelStats.vue +160 -0
  242. package/src/modules/otus/components/Panel/PanelStats/main.js +6 -0
  243. package/src/modules/otus/components/Panel/PanelTypeDesignation/PanelTypeDesignation.vue +37 -0
  244. package/src/modules/otus/components/Panel/PanelTypeDesignation/main.js +8 -0
  245. package/src/modules/otus/components/Panel/PanelTypeSpecimen/PanelTypeSpecimen.vue +52 -0
  246. package/src/modules/otus/components/Panel/PanelTypeSpecimen/main.js +8 -0
  247. package/src/modules/otus/components/TaxaInfo.vue +38 -0
  248. package/src/modules/otus/composables/index.js +2 -0
  249. package/src/modules/otus/composables/useChildrenRoutes.js +32 -0
  250. package/src/modules/otus/composables/useUserLifeCycleHooks.js +24 -0
  251. package/src/modules/otus/constants/index.js +3 -0
  252. package/src/modules/otus/constants/layouts/index.js +1 -0
  253. package/src/modules/otus/constants/layouts/overview.js +23 -0
  254. package/src/modules/otus/constants/layouts.js +43 -0
  255. package/src/modules/otus/constants/rankGroups.js +5 -0
  256. package/src/modules/otus/constants/responseError.js +3 -0
  257. package/src/modules/otus/constants/typeOrder.js +11 -0
  258. package/src/modules/otus/helpers/useOtuPageRequest.js +19 -0
  259. package/src/modules/otus/router/index.js +28 -0
  260. package/src/modules/otus/services/TaxonWorks.js +77 -0
  261. package/src/modules/otus/store/request.js +34 -0
  262. package/src/modules/otus/store/store.js +92 -0
  263. package/src/modules/otus/store/useImageStore.js +57 -0
  264. package/src/modules/otus/utils/index.js +2 -0
  265. package/src/modules/otus/utils/isAvailableForRank.js +6 -0
  266. package/src/modules/otus/utils/stripHtml.js +5 -0
  267. package/src/modules/otus/views/Index.vue +218 -0
  268. package/src/modules/otus/views/PageLayout.vue +78 -0
  269. package/src/modules/setup/views/Index.vue +66 -0
  270. package/src/plugins/markdown/index.js +2 -0
  271. package/src/plugins/markdown/relativeToRouter.js +51 -0
  272. package/src/plugins/markdown/variableReplacement.js +14 -0
  273. package/src/plugins/schemaOrg/composables/index.js +28 -0
  274. package/src/plugins/schemaOrg/index.js +31 -0
  275. package/src/plugins/schemaOrg/loadResolver.js +10 -0
  276. package/src/plugins/schemaOrg/nodes/Taxon.js +82 -0
  277. package/src/plugins/schemaOrg/nodes/index.js +1 -0
  278. package/src/plugins/vite/index.js +2 -0
  279. package/src/plugins/vite/projectStyle.js +29 -0
  280. package/src/plugins/vite/restart.js +30 -0
  281. package/src/router/index.js +46 -0
  282. package/src/ssr/utils/generateConsoleMessage.js +16 -0
  283. package/src/ssr/utils/registerFakeClientComponents.js +20 -0
  284. package/src/ssr/utils/taxonPagesMark.txt +9 -0
  285. package/src/store/index.js +1 -0
  286. package/src/store/useFooterStore.js +13 -0
  287. package/src/utils/color.js +9 -0
  288. package/src/utils/files.js +21 -0
  289. package/src/utils/globalVars.js +7 -0
  290. package/src/utils/index.js +5 -0
  291. package/src/utils/loadConfiguration.js +34 -0
  292. package/src/utils/loadLayouts.js +21 -0
  293. package/src/utils/parseEnvConfig.js +0 -0
  294. package/src/utils/request.js +18 -0
  295. package/src/utils/strings.js +12 -0
  296. package/src/utils/url.js +8 -0
  297. package/tailwind.config.cjs +92 -0
  298. package/templates/config/analytics.yml.example +22 -0
  299. package/templates/config/api.yml +5 -0
  300. package/templates/config/copyright.yml +5 -0
  301. package/templates/config/header.yml +17 -0
  302. package/templates/config/maps.yml +16 -0
  303. package/templates/config/metadata.yml +10 -0
  304. package/templates/config/news.yml.example +15 -0
  305. package/templates/config/project.yml +6 -0
  306. package/templates/config/router.yml.example +4 -0
  307. package/templates/config/style/theme.css +48 -0
  308. package/templates/config/taxa_page.yml.example +22 -0
  309. package/templates/config/tracker.yml.example +8 -0
  310. package/templates/pages/about.md +44 -0
  311. package/templates/pages/home.md +26 -0
  312. package/vite.config.js +92 -0
@@ -0,0 +1,432 @@
1
+ # TaxonPages
2
+
3
+ TaxonPages is a tool to serve taxon pages. At present it draws data from TaxonWorks' API, however we seek to keep the TaxonPages platform agnostic therefor facilitating the modular addition of functionality that may reference data from any biodiversity data-serving API.
4
+
5
+ ## Status Warning
6
+
7
+ TaxonPages software is in active development and changes are expected that will cause the early first-adopters' instances to require rebuilding by refreshing one's forked branch using `git pull`. A first _stable version_ is expected by Spring 2023.
8
+
9
+ ## Usage
10
+
11
+ 1. Click on "Fork" button to create your own repository from this.
12
+ 2. Uncheck `Copy the setup branch only` and press `Save`
13
+ 3. After create your repo, go to `Settings > Pages`, on "Build and deployment - Source" select `GitHub Actions`.
14
+ 4. Go to `Actions` tab and press `I understand my workflows, go ahead and enable them` button
15
+ 5. Open `router.yml` file and change `base_url` to the name of your repository.
16
+ 6. After a couple of minutes, your public page should be available at `https://<your_user_name>.github.io/<your_repo_name>`
17
+
18
+ ### Setup
19
+
20
+ 1. Switch to `setup` branch in your TaxonPages repository.
21
+ 2. We provide some settings by default to setup your public pages, but API parameters are required and must be configured to get the data from your TaxonWorks project.
22
+
23
+ ```yaml
24
+ # config/api.yml
25
+ ---
26
+ url: https://<your.taxonworks.server>/api/v1
27
+ project_token: yourprojecttoken
28
+ ```
29
+
30
+ 3. Push the changes after update the configuration files inside `setup` branch
31
+ 4. GitHub actions will build TaxonPages with the current configuration in `setup` branch and publish it to the `gh-pages` branch
32
+
33
+ # Install
34
+
35
+ Follow this steps to run TaxonPages in your local machine.
36
+
37
+ 1. Install [NodeJS](https://nodejs.org/en/download/)
38
+ 2. We recommend you to fork this repository to keep getting updates. Use [GIT](https://git-scm.com/) to clone the repo.
39
+
40
+ ```
41
+ git clone https://github.com/<your_username>/<your_repository_name>.git
42
+ ```
43
+
44
+ But if you don't want to fork it, you can clone directly from this
45
+
46
+ ```
47
+ git clone https://github.com/SpeciesFileGroup/taxonpages.git
48
+ ```
49
+
50
+ 3. Go to `taxonpages` folder and enter the following commands to copy the software to your `setup` branch
51
+
52
+ ```
53
+ git checkout main
54
+ git checkout setup
55
+ git checkout main .
56
+ git reset
57
+ git checkout .
58
+ ```
59
+
60
+ 5. Setup `config/api.yml` with the API server configuration
61
+
62
+ 6. Install node dependencies
63
+
64
+ ```
65
+ npm install
66
+ ```
67
+
68
+ ## Start TaxonPages
69
+
70
+ ```
71
+ npm run dev
72
+ ```
73
+
74
+ TaxonPages will be running at http://localhost:5173/
75
+
76
+ # NPM Installation (CLI)
77
+
78
+ As an alternative to cloning the repository, you can use the TaxonPages CLI to scaffold and manage your project.
79
+
80
+ ### Requirements
81
+
82
+ - [Node.js](https://nodejs.org/en/download/) >= 18.0.0
83
+
84
+ ### Quick start
85
+
86
+ Create a new project using `npx` (no global install needed):
87
+
88
+ ```
89
+ npx @sfgrp/taxonpages init my-project
90
+ cd my-project
91
+ npm install
92
+ ```
93
+
94
+ Edit `config/api.yml` with your TaxonWorks API URL and project token, then start the development server:
95
+
96
+ ```
97
+ npm run dev
98
+ ```
99
+
100
+ Your site will be running at http://localhost:5173/
101
+
102
+ ### Global installation
103
+
104
+ If you prefer to have the CLI available globally:
105
+
106
+ ```
107
+ npm install -g @sfgrp/taxonpages
108
+ ```
109
+
110
+ Then you can use it directly:
111
+
112
+ ```
113
+ taxonpages init my-project
114
+ ```
115
+
116
+ ### CLI Commands
117
+
118
+ All commands are available through `npm run` scripts in your project or directly via the `taxonpages` CLI:
119
+
120
+ | Command | npm script | Description |
121
+ | ----------------------------- | ------------------- | ---------------------------------------------- |
122
+ | `taxonpages init [directory]` | — | Scaffold a new TaxonPages project |
123
+ | `taxonpages dev` | `npm run dev` | Start development server (SPA mode, port 5173) |
124
+ | `taxonpages dev:ssr` | `npm run dev:ssr` | Start SSR development server (port 6173) |
125
+ | `taxonpages build` | `npm run build` | Build for production (SPA mode) |
126
+ | `taxonpages build:ssr` | `npm run build:ssr` | Build for production (SSR mode) |
127
+ | `taxonpages serve` | `npm run serve` | Start production SSR server (port 6173) |
128
+ | `taxonpages preview` | `npm run preview` | Preview production build locally (port 4173) |
129
+
130
+ ### Example workflow
131
+
132
+ ```
133
+ npx @sfgrp/taxonpages init my-project
134
+ cd my-project
135
+ npm install
136
+ # Edit config/api.yml with your API settings
137
+ npm run dev
138
+ ```
139
+
140
+ # Customization
141
+
142
+ ## Pages
143
+
144
+ TaxonPages out of the box support markdown and vue for content sites. Add your content pages inside `pages` folder. By default, TaxonPages use the file name to create the route.
145
+ For example, if the filename is "contributors.md" the route to access it will be http://yourtaxonpagessite/contributors
146
+
147
+ ### Markdown pages
148
+
149
+ This software use [vite-plugin-md](https://github.com/antfu/vite-plugin-md) to render pages in Markdown format, the engine of this plugin is [markdown-it](https://github.com/markdown-it/markdown-it). For plugins and other configuration you can refer to this section https://github.com/antfu/vite-plugin-md#configuration--options
150
+
151
+ Example: `welcome.md` file
152
+
153
+ ```
154
+ ---
155
+ name: 'Charles Darwin'
156
+ ---
157
+
158
+ # Welcome, {{ name }}!
159
+ ```
160
+
161
+ To use TaxonPage internal variables in `config/*.yml`, you can either do so by adding the prefix {{ app:var_name }} or use the script tag in your markdown page and get them from the global object `__APP_ENV__`
162
+
163
+ #### Prefix
164
+
165
+ ```markdown
166
+ # Welcome to {{ app:project_name }}!
167
+ ```
168
+
169
+ #### Script tag
170
+
171
+ ```javascript
172
+ # Welcome to {{ project_name }}!
173
+
174
+ <script setup>
175
+ const { project_name } = __APP_ENV__
176
+ </script>
177
+ ```
178
+
179
+ #### Components
180
+
181
+ TaxonPages global components are enable in your markdown pages, by default we provide a set of global components that you don't need to import them to use it. You can see the list of this global components [here](#global-components)
182
+
183
+ ### Style
184
+
185
+ If you want to change the color palette, you can edit `/config/style/theme.css` file, colors must be in RGB format.
186
+ TaxonPages use [TailwindCSS](https://tailwindcss.com/docs/configuration) framework for the style. We already provide default settings for colors and markdown. If you want to make any change to your configuration, you must do so in the `config/vendor/tailwind.config.js` file. This file uses the TaxonPages configuration as a default. It is possible to overwrite it as long as you use it as a preset.
187
+
188
+ ## Analytics
189
+
190
+ TaxonPages has out-of-the-box support for the following list of analytics services:
191
+
192
+ ```yaml
193
+ analytics_services:
194
+ enableDev: false # Set true to work in development mode
195
+ analytics: # Google Analytics
196
+ - id: 'G-XXXXX'
197
+ gtm: # Google Tag Manager
198
+ - id: 'GTM-XXXXX'
199
+ pixel: # Facebook Pixel
200
+ - id: 'XXXXXXX'
201
+ retargeting: # VK Retargeting
202
+ - id: 'VK-RTRG-XXXXXX-XXXXX',
203
+ linkedin: # Linkedin Insight
204
+ - id: 'XXXXXXX'
205
+ tongji: # Baidu Tongji
206
+ - id: 'XXXXXXX',
207
+ metrica: # Yendex Metrica
208
+ - id: 'XXXXXXX',
209
+ microsoft: # Microsoft Analytics
210
+ id: 'XXXXXXX'
211
+ hotjar: # Hotjar Analytics
212
+ id: 'XXXXXXX',
213
+ fullStory: # Full story Analytics
214
+ org: 'X-XXXXXX-XXX'
215
+ tiktok: # TikTok Pixel Analytics
216
+ id: 'XXXXXXX'
217
+ ```
218
+
219
+ # Deep dive into TaxonPages
220
+
221
+ ## Access internal configuration vars
222
+
223
+ To access the configuration in \*.yml files, we provide a global object that contains all the configuration values. This variable can be used in either JavaScript, Vue, or Markdown files. To access these values you must use the `__APP_ENV__` variable:
224
+
225
+ ```javascript
226
+ const { project_name } = __APP_ENV__
227
+ // or
228
+ const projectName = __APP_ENV__.project_name
229
+ ```
230
+
231
+ ## Taxa Page
232
+
233
+ ### Layout
234
+
235
+ To modify the position of the panels in the layout of the Taxa page, edit the `taxa_page.yml` file. There you can add/move/remove panels from the layout, also you can add new tabs and include new panels there. If you want to make some tabs visible or not depending the rank group, you can include `rankGroup`
236
+
237
+ ```yaml
238
+ taxa_page:
239
+ overview:
240
+ panels:
241
+ - - - panel:gallery
242
+ - panel:type
243
+ - panel:type-specimen
244
+ - panel:nomenclature
245
+ - panel:nomenclature-references
246
+
247
+ - - panel:map
248
+ - panel:descendants
249
+ - panel:content
250
+ - panel:statistics
251
+ #
252
+ # An example of a new tab:
253
+ #
254
+ # type_specimens:
255
+ # rank_group: ['SpeciesGroup']
256
+ # panels:
257
+ # - - - panel:specimen-records
258
+ ```
259
+
260
+ ### Lifecycle hooks (Experimental feature)
261
+
262
+ The `onCreatePage` and `onSSRPageCreate` functions allow you to execute code at the time the taxa page is created. `onSSRPageCreate` will be executed only on the server side in SSR mode. To make use of them it is necessary to include them in a file object called `pages/otus.config.js`. Both functions accept `otu`, `taxon`, `route` and `router` objects as parameters. Since `onCreatePage` runs on Taxa page component, it is possible to use hooks like `onMounted` or `onBeforeMount` inside it
263
+
264
+ ```javascript
265
+ export default {
266
+ onSSRCreatePage: async ({ otu, taxon, route, router }) => {
267
+ // Your code here
268
+ },
269
+
270
+ onCreatePage: ({ otu, taxon, route, router }) => {
271
+ // Your code here
272
+ }
273
+ }
274
+ ```
275
+
276
+ ### Customizing the Layout
277
+
278
+ The application comes with a default layout that includes a header and a footer. If you'd like to replace this layout with your own, you can do so by creating a custom layout file.
279
+
280
+ Steps to replace the default layout
281
+
282
+ 1. In the root folder of your project, create a new folder called `layouts` (if it doesn't already exist).
283
+ 2. Inside this folder, create a file named default.vue.
284
+ 3. Define your custom layout structure inside this file as needed.
285
+
286
+ Example of layouts/default.vue
287
+
288
+ ```vuejs
289
+ <template>
290
+ <div>
291
+ <slot />
292
+ </div>
293
+ </template>
294
+ ```
295
+
296
+ This custom layout will replace the default one and be applied throughout the application. You can include your own elements, such as a navigation bar or footer, as needed.
297
+
298
+ #### Using Multiple Layouts
299
+
300
+ In addition to replacing the default layout, you can create multiple layouts by adding more .vue files inside the layout folder. You can then specify which layout to use for a specific page by setting the layout name in the meta property of the `<route>` tag in your Single File Component (SFC).
301
+
302
+ JSON5:
303
+
304
+ ```js
305
+ <route>
306
+ {
307
+ meta: {
308
+ layout: 'custom'
309
+ }
310
+ }
311
+ </route>
312
+ ```
313
+
314
+ YAML:
315
+
316
+ ```yaml
317
+ <route lang="yaml">
318
+ meta:
319
+ layout: custom
320
+ </route>
321
+ ```
322
+
323
+ ### External panels
324
+
325
+ To add panels in Taxa pages, create a folder called `panels` in your `setup` branch, and inside it create another folder for your panel. For example: `panels/PanelTest`
326
+
327
+ In `PanelTest` folder, create a `main.js` file, with the following structure:
328
+
329
+ ```javascript
330
+ import MyPanelComponent from './MyPanelComponent.vue'
331
+
332
+ export default {
333
+ id: 'panel:test', // ID to identify this panel
334
+ component: MyPanelComponent, // Vue component for your panel
335
+ rankGroup: [
336
+ 'HigherClassificationGroup',
337
+ 'FamilyGroup',
338
+ 'GenusGroup',
339
+ 'SpeciesGroup'
340
+ ] // <-- OPTIONAL: This will define for which rank group will be available, remove it if your panel will be available for all.
341
+ }
342
+ ```
343
+
344
+ This file is used to load your panel component in taxa page. Use the `id` to include and define the position in the layout in `taxa_page.yml`
345
+
346
+ ```yaml
347
+ taxa_page_overview:
348
+ panels:
349
+ - - - panel:gallery
350
+ - panel:test # <--- Your new panel
351
+ - panel:type
352
+ - panel:type-specimen
353
+ - panel:nomenclature
354
+ - panel:nomenclature-references
355
+
356
+ - - panel:map
357
+ - panel:descendants
358
+ - panel:scrutiny
359
+ - panel:content
360
+ - panel:keys
361
+ - panel:etymology
362
+ - panel:gbif
363
+ - panel:statistics
364
+ - panel:sounds
365
+ ```
366
+
367
+ ## Defining global components
368
+
369
+ TaxonPages provides an auto-import component from `src/components` and `/components` folders using special extensions for it. Some objects and functions are only present in the browser and not in the NodeJs server environment. When you run code that is not supported by the server, it ends up crashing. Some JavaScript libraries like `Leaflet` use the `document` or `window` object, which do not exist in the node environment. To handle this problem, TaxonPages provides 2 ways to import the components.
370
+
371
+ ### Client Side only (CSR):
372
+
373
+ This auto import method will only load the component on the client side, while on the server it will create a fake empty component, which will be used later on the client side to be replaced by the original one when the hydration process occurs. To define this type of import, the component name must contain the word `.client.` before `.vue` extension.
374
+
375
+ Example: `MyAmazingComponent.client.vue`
376
+
377
+ ### Global (CSR & SSR)
378
+
379
+ This auto-import method will load the component both client and server side. To define this type of import, the component must contain the word `.client.` before the `.vue` extension.
380
+
381
+ Example: `MyAmazingComponent.global.vue`
382
+
383
+ ### Global components
384
+
385
+ TaxonPages provides a set of global components that could be used to create your own panels or pages. Here is the complete list:
386
+
387
+ | Component | Description | Props |
388
+ | --------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
389
+ | `<AnimationOpacity/>` | Add an opacity animation for a child component | |
390
+ | `<Autocomplete/>` | Used to perform searches in TaxonWorks | [Link](https://github.com/SpeciesFileGroup/taxonpages/blob/main/src/components/Autocomplete/Autocomplete.global.vue#L42) |
391
+ | `<AutocompleteOtu/>` | A specific autocomplete for OTU search | |
392
+ | `<ClientOnly/>` | Render child components only from client side | |
393
+ | `<VButton/>` | Button component | |
394
+ | `<VCard/>` | Card component style | |
395
+ | `<VCardContent/>` | Card content body | |
396
+ | `<VCardHeader/>` | Card Header | |
397
+ | `<VClipboard/>` | Copy a text to clipboard | |
398
+ | `<Dropdown/>` | Dropdown menu | |
399
+ | `<GalleryImage/>` | | [Link](https://github.com/SpeciesFileGroup/taxonpages/blob/main/src/components/Gallery/GalleryImage.global.vue#L40) |
400
+ | `<ImageViewer/>` | | |
401
+ | `<TrackerReport/>` | Show trackers to report issues | [Link](https://github.com/SpeciesFileGroup/taxonpages/blob/main/src/components/TrackerReport.global.vue#L47) |
402
+ | `<TabMenu/>` | | |
403
+ | `<TabItem/>` | | |
404
+ | `<VMap/>` | Interactive map that use Leaflet library | |
405
+ | `<VModal/>` | Create lightboxes | |
406
+ | `<VSkeleton/>` | Content loading placeholder | |
407
+ | `<VSpinner/>` | Loading spinner | |
408
+ | `<VTable/>` | | |
409
+ | `<VTableBody/>` | | |
410
+ | `<VTableBodyCell/>` | | |
411
+ | `<VTableBodyRow/>` | | |
412
+ | `<VTableHeader/>` | | |
413
+ | `<VTableHeaderCell/>` | | |
414
+ | `<VTableHeaderRow/>` | | |
415
+
416
+ | Icons |
417
+ | -------------------- |
418
+ | `<IconArrowDown/>` |
419
+ | `<IconArrowLeft/>` |
420
+ | `<IconArrowRight/>` |
421
+ | `<IconCheck/>` |
422
+ | `<IconClipboard/>` |
423
+ | `<IconClose/>` |
424
+ | `<IconDocument/>` |
425
+ | `<IconDownload/>` |
426
+ | `<IconHamburger/>` |
427
+ | `<IconJson/>` |
428
+ | `<IconMinusCircle/>` |
429
+ | `<IconPlusCircle/>` |
430
+ | `<IconSearch/>` |
431
+ | `<IconTrash/>` |
432
+ | `<IconWarning/>` |
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { createRequire } from 'node:module'
4
+ import { resolve, dirname } from 'node:path'
5
+ import { fileURLToPath } from 'node:url'
6
+ import { Command } from 'commander'
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url))
9
+ const packageRoot = resolve(__dirname, '..')
10
+ const require = createRequire(import.meta.url)
11
+ const { version, description } = require('../package.json')
12
+
13
+ const program = new Command()
14
+
15
+ program.name('taxonpages').description(description).version(version)
16
+
17
+ program
18
+ .command('dev')
19
+ .description('Start Vite development server with HMR (SPA mode)')
20
+ .option('-p, --port <number>', 'port number', '5173')
21
+ .option('--host [host]', 'expose to network')
22
+ .action(async (options) => {
23
+ const { startDev } = await import('../src/cli/commands/dev.js')
24
+ await startDev({ packageRoot, projectRoot: process.cwd(), ...options })
25
+ })
26
+
27
+ program
28
+ .command('dev:ssr')
29
+ .description('Start SSR development server')
30
+ .option('-p, --port <number>', 'port number', '6173')
31
+ .action(async (options) => {
32
+ const { startDevSSR } = await import('../src/cli/commands/dev.js')
33
+ await startDevSSR({ packageRoot, projectRoot: process.cwd(), ...options })
34
+ })
35
+
36
+ program
37
+ .command('build')
38
+ .description('Build for production (SPA mode)')
39
+ .action(async () => {
40
+ const { runBuild } = await import('../src/cli/commands/build.js')
41
+ await runBuild({ packageRoot, projectRoot: process.cwd(), mode: 'spa' })
42
+ })
43
+
44
+ program
45
+ .command('build:ssr')
46
+ .description('Build for production (SSR mode)')
47
+ .action(async () => {
48
+ const { runBuild } = await import('../src/cli/commands/build.js')
49
+ await runBuild({ packageRoot, projectRoot: process.cwd(), mode: 'ssr' })
50
+ })
51
+
52
+ program
53
+ .command('serve')
54
+ .description('Start production SSR server')
55
+ .option('-p, --port <number>', 'port number', '6173')
56
+ .action(async (options) => {
57
+ const { serve } = await import('../src/cli/commands/serve.js')
58
+ await serve({ packageRoot, projectRoot: process.cwd(), ...options })
59
+ })
60
+
61
+ program
62
+ .command('preview')
63
+ .description('Preview production build locally')
64
+ .option('-p, --port <number>', 'port number', '4173')
65
+ .action(async (options) => {
66
+ const { preview } = await import('../src/cli/commands/preview.js')
67
+ await preview({ packageRoot, projectRoot: process.cwd(), ...options })
68
+ })
69
+
70
+ program
71
+ .command('init [directory]')
72
+ .description('Scaffold a new TaxonPages project')
73
+ .action(async (directory) => {
74
+ const { init } = await import('../src/cli/commands/init.js')
75
+ await init({ packageRoot, directory: directory || '.' })
76
+ })
77
+
78
+ program.parse()
package/index.html ADDED
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta
6
+ name="viewport"
7
+ content="width=device-width, initial-scale=1.0"
8
+ />
9
+ <!--head-tags-->
10
+ <!--preload-links-->
11
+ <!--app-state-->
12
+ </head>
13
+ <body>
14
+ <!--body-tags-open-->
15
+ <div id="app"></div>
16
+ <script
17
+ type="module"
18
+ src="/src/entry-client.js"
19
+ ></script>
20
+ <!--body-tags-->
21
+ </body>
22
+ </html>
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@sfgrp/taxonpages",
3
+ "version": "0.1.0",
4
+ "description": "CLI tool for building taxon pages powered by SpeciesFileGroup",
5
+ "type": "module",
6
+ "private": false,
7
+ "bin": {
8
+ "taxonpages": "./bin/taxonpages.js"
9
+ },
10
+ "files": [
11
+ "bin/",
12
+ "src/",
13
+ "templates/",
14
+ "server.js",
15
+ "vite.config.js",
16
+ "index.html",
17
+ "tailwind.config.cjs",
18
+ "postcss.config.cjs"
19
+ ],
20
+ "engines": {
21
+ "node": ">=18.0.0"
22
+ },
23
+ "scripts": {
24
+ "dev": "node bin/taxonpages.js dev",
25
+ "dev:ssr": "node bin/taxonpages.js dev:ssr",
26
+ "build": "node bin/taxonpages.js build",
27
+ "build:ssr": "node bin/taxonpages.js build:ssr",
28
+ "serve": "node bin/taxonpages.js serve",
29
+ "debug": "node --inspect-brk server",
30
+ "preview": "node bin/taxonpages.js preview",
31
+ "lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src"
32
+ },
33
+ "dependencies": {
34
+ "@geoman-io/leaflet-geoman-free": "^2.19.2",
35
+ "@nuxt/devalue": "^2.0.2",
36
+ "@sfgrp/distinguish": "^0.4.2",
37
+ "@sfgrp/pinpoint": "^0.0.12",
38
+ "@tailwindcss/typography": "^0.5.19",
39
+ "@unhead/ssr": "^2.1.4",
40
+ "@unhead/vue": "^2.1.4",
41
+ "@vitejs/plugin-vue": "^6.0.4",
42
+ "autoprefixer": "^10.4.24",
43
+ "axios": "^1.13.5",
44
+ "commander": "^14.0.3",
45
+ "compression": "^1.8.1",
46
+ "express": "^5.2.1",
47
+ "glob": "^13.0.3",
48
+ "js-yaml": "^4.1.1",
49
+ "leaflet": "^1.9.4",
50
+ "leaflet.markercluster": "^1.5.3",
51
+ "markdown-it-anchor": "^9.2.0",
52
+ "minimist": "^1.2.8",
53
+ "pinia": "^3.0.4",
54
+ "postcss": "^8.5.6",
55
+ "sass": "^1.97.3",
56
+ "serve-static": "^2.2.1",
57
+ "tailwindcss": "^3.4.17",
58
+ "unplugin-vue-markdown": "^29.2.0",
59
+ "vite": "^7.3.1",
60
+ "vite-plugin-pages": "^0.33.3",
61
+ "vite-plugin-radar": "^0.10.1",
62
+ "vue": "^3.5.28",
63
+ "vue-router": "^5.0.2"
64
+ },
65
+ "devDependencies": {
66
+ "eslint": "^9.39.2",
67
+ "eslint-plugin-vue": "^10.7.0"
68
+ },
69
+ "keywords": [
70
+ "taxonworks",
71
+ "biodiversity",
72
+ "taxonomy",
73
+ "vue",
74
+ "ssr",
75
+ "cli"
76
+ ],
77
+ "license": "MIT",
78
+ "repository": {
79
+ "type": "git",
80
+ "url": "https://github.com/SpeciesFileGroup/taxonpages.git"
81
+ }
82
+ }
@@ -0,0 +1,17 @@
1
+ const fs = require('fs')
2
+ const {
3
+ userTailwindConfigPath,
4
+ defaultTailwindConfigPath
5
+ } = require('./src/constants/configPaths.cjs')
6
+
7
+ module.exports = {
8
+ plugins: {
9
+ 'tailwindcss/nesting': {},
10
+ tailwindcss: {
11
+ config: fs.existsSync(userTailwindConfigPath)
12
+ ? userTailwindConfigPath
13
+ : defaultTailwindConfigPath
14
+ },
15
+ autoprefixer: {}
16
+ }
17
+ }