diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6f1cfbaf1d..10b2dfe5b8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - php-versions: ['7.4', '8.0', '8.1', '8.2'] + php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3'] fail-fast: false steps: - name: Checkout @@ -36,7 +36,7 @@ jobs: tools: composer:v1 env: COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} - + - name: Set up Node uses: actions/setup-node@v3 with: @@ -53,23 +53,23 @@ jobs: path: ${{ env.CI_COMPOSER_CACHE_DIR }} key: composer-${{ hashFiles('**/composer.lock') }} restore-keys: composer- - + - name: Cache build caches uses: actions/cache@v3 with: path: ./build/cache key: build-cache-${{ github.sha }} restore-keys: build-cache- - + - name: Start MySQL run: sudo systemctl start mysql.service - + - name: Install Node dependencies run: npm install - + - name: Gulp init run: npx gulp init - + - name: Set up database run: | mysql -e "create database IF NOT EXISTS omeka_test;" -uroot -proot @@ -77,7 +77,7 @@ jobs: sed -i 's/^user.*/user = "root"/' application/test/config/database.ini sed -i 's/^dbname.*/dbname = "omeka_test"/' application/test/config/database.ini sed -i 's/^password.*/password = "root"/' application/test/config/database.ini - + - name: Run tests run: npx gulp test --continue env: diff --git a/.htaccess.dist b/.htaccess.dist index e3ddcd16f5..c9e80a7f6d 100644 --- a/.htaccess.dist +++ b/.htaccess.dist @@ -5,7 +5,7 @@ RewriteEngine On # The following rule tells Apache that if the requested filename # exists, simply serve it. RewriteCond %{REQUEST_FILENAME} -f -RewriteRule !\.(php[0-9]?|phtml|phps)$ - [NC,C] +RewriteRule !\.(php[0-9]?|phtml|phps|phar|hphp)$ - [NC,C] RewriteRule !(?:^|/)\.(?!well-known(?:/.*)?$) - [C] RewriteRule .* - [L] diff --git a/README.md b/README.md index d4d9b30732..7b0ca9cd59 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ See the [user manual](https://omeka.org/s/docs/user-manual) for more information ### Requirements * Linux * [Apache](https://www.apache.org/) (with [AllowOverride](https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride) set to "All" and [mod_rewrite](http://httpd.apache.org/docs/current/mod/mod_rewrite.html) enabled) -* [MySQL](https://www.mysql.com/) 5.6.4+ (or [MariaDB](https://mariadb.org/) 10.0.5+) +* [MySQL](https://www.mysql.com/) 5.7.9+ (or [MariaDB](https://mariadb.org/) 10.2.6+) * [PHP](https://www.php.net/) 7.4+ (latest stable version preferred, with [PDO](http://php.net/manual/en/intro.pdo.php), [pdo_mysql](http://php.net/manual/en/ref.pdo-mysql.php), and [xml](http://php.net/manual/en/intro.xml.php) extensions installed) ### Generating thumbnails diff --git a/application/Module.php b/application/Module.php index af71d4d574..7ff309bcae 100644 --- a/application/Module.php +++ b/application/Module.php @@ -1,13 +1,17 @@ attach( 'Omeka\Entity\Media', - 'entity.persist.post', - [$this, 'saveFulltextOnMediaSave'] - ); - - $sharedEventManager->attach( - 'Omeka\Entity\Media', - 'entity.update.post', - [$this, 'saveFulltextOnMediaSave'] + 'entity.remove.pre', + [$this, 'deleteFulltextMedia'] ); $sharedEventManager->attach( 'Omeka\Api\Adapter\SitePageAdapter', 'api.delete.pre', - [$this, 'deleteFulltextPre'] + [$this, 'deleteFulltextPreSitePage'] ); $sharedEventManager->attach( @@ -178,6 +176,44 @@ public function attachListeners(SharedEventManagerInterface $sharedEventManager) [$this, 'noindexItemSet'] ); + // Add favicon to layouts. + $sharedEventManager->attach( + '*', + 'view.layout', + function (ZendEvent $event) { + $view = $event->getTarget(); + // Get the favicon asset ID. + if ($view->status()->isSiteRequest()) { + $faviconAssetId = $view->siteSetting('favicon'); + if (!is_numeric($faviconAssetId)) { + $faviconAssetId = $view->setting('favicon'); + } + } else { + $faviconAssetId = $view->setting('favicon'); + } + // Get the favicon href. + if (is_numeric($faviconAssetId)) { + $faviconAsset = $view->api()->searchOne('assets', ['id' => $faviconAssetId])->getContent(); + $href = $faviconAsset ? $faviconAsset->assetUrl() : null; + } else { + $href = null; // Passing null clears the favicon. + } + $view->headLink(['rel' => 'icon', 'href' => $href], 'PREPEND'); + } + ); + + $sharedEventManager->attach( + '*', + 'api.output.serialize', + [$this, 'serializeApiOutputJsonLd'] + ); + + $sharedEventManager->attach( + '*', + 'api.output.serialize', + [$this, 'serializeApiOutputRdf'] + ); + $sharedEventManager->attach( '*', 'sql_filter.resource_visibility', @@ -564,34 +600,42 @@ public function saveFulltext(ZendEvent $event) { $adapter = $event->getTarget(); $entity = $event->getParam('response')->getContent(); + $fulltextSearch = $this->getServiceLocator()->get('Omeka\FulltextSearch'); + $fulltextSearch->save($entity, $adapter); + + // Item create needs special handling. We must save media fulltext here + // because media is created via cascade persist (during item create/update), + // which is invisible to normal API events. + if ($entity instanceof Item) { + $mediaAdapter = $adapter->getAdapter('media'); + foreach ($entity->getMedia() as $mediaEntity) { + $fulltextSearch->save($mediaEntity, $mediaAdapter); + } + } + // Item media needs special handling. We must update the item's fulltext + // to append updated media data. if ($entity instanceof Media) { - // Media get special handling during entity.persist.post and - // entity.update.post in self::saveFulltextOnMediaSave(). There's no - // need to process them here. - return; + $itemEntity = $entity->getItem(); + $itemAdapter = $adapter->getAdapter('items'); + $fulltextSearch->save($itemEntity, $itemAdapter); } - $fulltext = $this->getServiceLocator()->get('Omeka\FulltextSearch'); - $fulltext->save($entity, $adapter); } /** - * Save fulltext on media save. + * Delete the fulltext of a media. * - * This method does two things. First, it updates the parent item's fulltext - * to contain any new text introduced by this media. Second it ensures that - * the fulltext of newly created media is saved. Otherwise, media created - * in the item context (via cascade persist) will not have fulltext. + * We must delete media fulltext here because media may be deleted via cascade + * remove (during item update), which is invisible to normal API events. * * @param ZendEvent $event */ - public function saveFulltextOnMediaSave(ZendEvent $event) + public function deleteFulltextMedia(ZendEvent $event) { $fulltextSearch = $this->getServiceLocator()->get('Omeka\FulltextSearch'); $adapterManager = $this->getServiceLocator()->get('Omeka\ApiAdapterManager'); $mediaEntity = $event->getTarget(); - $itemEntity = $mediaEntity->getItem(); - $fulltextSearch->save($mediaEntity, $adapterManager->get('media')); - $fulltextSearch->save($itemEntity, $adapterManager->get('items')); + $mediaAdapter = $adapterManager->get('media'); + $fulltextSearch->delete($mediaEntity->getId(), $mediaAdapter); } /** @@ -603,7 +647,7 @@ public function saveFulltextOnMediaSave(ZendEvent $event) * * @param ZendEvent $event */ - public function deleteFulltextPre(ZendEvent $event) + public function deleteFulltextPreSitePage(ZendEvent $event) { $request = $event->getParam('request'); $em = $this->getServiceLocator()->get('Omeka\EntityManager'); @@ -624,10 +668,24 @@ public function deleteFulltextPre(ZendEvent $event) */ public function deleteFulltext(ZendEvent $event) { - $fulltext = $this->getServiceLocator()->get('Omeka\FulltextSearch'); + $adapter = $event->getTarget(); + $entity = $event->getParam('response')->getContent(); $request = $event->getParam('request'); - $fulltext->delete( - // Note that the resource may not have an ID after being deleted. + $fulltextSearch = $this->getServiceLocator()->get('Omeka\FulltextSearch'); + + // Media delete needs special handling. We must update the item's fulltext + // to remove the appended media data. We return here because deleting media + // fulltext is handled by self::deleteFulltextMedia(). + if ($entity instanceof Media) { + $itemEntity = $entity->getItem(); + $itemAdapter = $adapter->getAdapter('items'); + $fulltextSearch->save($itemEntity, $itemAdapter); + return; + } + + // Note that the resource may not have an ID after being deleted. This + // is why we must use $request->getId() rather than $entity->getId(). + $fulltextSearch->delete( $request->getOption('deleted_entity_id') ?? $request->getId(), $event->getTarget() ); @@ -743,6 +801,99 @@ public function noindexItemSet(ZendEvent $event) $this->noindexResourceShow($view, $view->itemSet); } + /** + * Serialize the API output to JSON-LD. + */ + public function serializeApiOutputJsonLd(ZendEvent $event) + { + $renderer = $event->getTarget(); + $model = $event->getParam('model'); + $format = $event->getParam('format'); + $payload = $event->getParam('payload'); + $output = $event->getParam('output'); + + if ('jsonld' !== $format) { + return; + } + + $eventManager = $this->getServiceLocator()->get('EventManager'); + + if ($payload instanceof RepresentationInterface) { + $args = $eventManager->prepareArgs(['jsonLd' => $output]); + $eventManager->trigger('rep.resource.json_output', $payload, $args); + $output = $args['jsonLd']; + } + + if (null !== $model->getOption('pretty_print')) { + // Pretty print the JSON. + $output = Json::prettyPrint($output); + } + + $jsonpCallback = (string) $model->getOption('callback'); + if (!empty($jsonpCallback)) { + // Wrap the JSON in a JSONP callback. Normally this would be done + // via `$this->setJsonpCallback()` but we don't want to pass the + // wrapped string to `rep.resource.json_output` handlers. + $output = sprintf('%s(%s);', $jsonpCallback, $output); + $renderer->setHasJsonpCallback(true); + } + + $event->setParam('output', $output); + } + + /** + * Serialize the API output to RDF formats (rdfxml, n3, turtle, ntriples). + */ + public function serializeApiOutputRdf(ZendEvent $event) + { + $renderer = $event->getTarget(); + $model = $event->getParam('model'); + $format = $event->getParam('format'); + $payload = $event->getParam('payload'); + $output = $event->getParam('output'); + + if (!in_array($format, ['rdfxml', 'n3', 'turtle', 'ntriples'])) { + return; + } + + $eventManager = $this->getServiceLocator()->get('EventManager'); + + $serializeRdf = function ($jsonLd) use ($format) { + $graph = new Graph; + $graph->parse(Json::encode($jsonLd), 'jsonld'); + return $graph->serialise($format); + }; + + $getJsonLdWithContext = function (RepresentationInterface $representation) use ($eventManager) { + // Add the @context by encoding the output as JSON, then decoding to an array. + static $context; + if (!$context) { + // Get the JSON-LD @context + $args = $eventManager->prepareArgs(['context' => []]); + $eventManager->trigger('api.context', null, $args); + $context = $args['context']; + } + $jsonLd = Json::decode(Json::encode($representation), true); + $jsonLd['@context'] = $context; + return $jsonLd; + }; + + // Render a single representation (get). + if ($payload instanceof RepresentationInterface) { + $jsonLd = $getJsonLdWithContext($payload); + $output = $serializeRdf($jsonLd); + // Render multiple representations (getList); + } elseif (is_array($payload) && array_filter($payload, fn ($object) => ($object instanceof RepresentationInterface))) { + $jsonLd = []; + foreach ($payload as $representation) { + $jsonLd[] = $getJsonLdWithContext($representation); + } + $output = $serializeRdf($jsonLd); + } + + $event->setParam('output', $output); + } + /** * Add a robots "noindex" metatag to the current view if the resource * being viewed does not belong to the current site. diff --git a/application/asset/css/jstree.css b/application/asset/css/jstree.css index 290516bde6..8099fc44db 100755 --- a/application/asset/css/jstree.css +++ b/application/asset/css/jstree.css @@ -1 +1 @@ -.jstree-container-ul{margin:0}.jstree-container-ul,.jstree-container-ul ul{list-style-type:none}.jstree-children{padding-left:36px}.jstree-container-ul,.jstree-container-ul>li{padding-left:0}.jstree-node{position:relative}.jstree-anchor{width:100%;background-color:rgba(0,0,0,.04);padding:6px;position:relative;margin-bottom:6px;display:block;margin:6px 0 0}.jstree-editlink-container{display:none;padding:11px;border:1px solid rgba(0,0,0,.04);overflow:hidden;line-height:36px;font-weight:bold}.jstree-editlink-container>label>input,.jstree-editlink-container>label>textarea,.jstree-editlink-container>label>select,.jstree-editlink-container .query-form-element{float:right;width:70%;font-weight:normal}.jstree-editlink-container .query-form-element input{width:100%}.jstree-editlink-container label{display:block}.jstree-editlink-container label:not(:last-child){margin-bottom:6px}.jstree-hovered,.jstree-clicked{background-color:rgba(0,0,0,.12)}i.jstree-icon{font-style:normal;position:absolute;right:12px;top:0}.jstree-icon:before{font-family:"Font Awesome 5 Free";font-weight:900}.jstree-open,.jstree-closed{position:relative}.jstree-open>.jstree-ocl,.jstree-closed>.jstree-ocl,.jstree-removenode-remove,.jstree-removenode-undo,.jstree-editlink-edit,.jstree-displaylink,.jstree-private{width:24px;height:36px;line-height:36px;background-color:rgba(0,0,0,.2);text-align:right;cursor:pointer;z-index:1}.jstree-open>.jstree-ocl,.jstree-closed>.jstree-ocl{width:36px;right:0;text-align:center}i.jstree-icon.jstree-ok,i.jstree-icon.jstree-er{left:100%;width:36px;height:36px;line-height:36px;background-color:rgba(0,0,0,.12);text-align:center}.jstree-removenode-remove,.jstree-removenode-undo,.jstree-editlink-edit,.jstree-displaylink,.jstree-private{background-color:transparent;opacity:.5}.jstree-removenode-remove:hover,.jstree-removenode-undo:hover,.jstree-editlink-edit:hover,.jstree-displaylink:hover,.jstree-private:hover{opacity:1}.jstree-private{color:#676767}.jstree-private:hover{opacity:.5}.jstree-open>.jstree-anchor .jstree-removenode-remove,.jstree-closed>.jstree-anchor .jstree-removenode-remove,.jstree-open>.jstree-anchor .jstree-removenode-undo,.jstree-closed>.jstree-anchor .jstree-removenode-undo{right:48px}.jstree-open>.jstree-anchor .jstree-editlink-edit,.jstree-closed>.jstree-anchor .jstree-editlink-edit{right:72px}i.jstree-editlink-edit{right:36px}i.jstree-private{background-color:transparent;position:static;display:inline-block;margin-right:6px;height:16px;line-height:1}.jstree-open>.jstree-anchor .jstree-displaylink,.jstree-closed>.jstree-anchor .jstree-displaylink{right:96px}i.jstree-displaylink{right:60px}.block-pagelist-tree .jstree-open>.jstree-anchor .jstree-displaylink,.block-pagelist-tree .jstree-closed>.jstree-anchor .jstree-displaylink{right:72px}.block-pagelist-tree i.jstree-displaylink{right:36px}.jstree-anchor:hover>.jstree-removenode-remove{display:block}.jstree-open>.jstree-ocl:before{content:""}.jstree-closed>.jstree-ocl:before{content:""}.jstree-ok:before{content:""}.jstree-er:before{content:""}.jstree-removenode-remove:before{content:""}.jstree-removenode-undo:before{content:""}.jstree-editlink-edit:before{content:""}.jstree-displaylink:before{content:""}.jstree-private:before{content:""}.jstree-removenode-removed .jstree-anchor{background-color:#fcc}.jstree-removenode-removed .jstree-children .jstree-removenode-remove,.jstree-removenode-removed .jstree-children .jstree-removenode-undo{display:none}.jstree-removenode-removed.jstree-open>.jstree-ocl,.jstree-removenode-removed.jstree-closed>.jstree-ocl{background-color:rgba(255,0,0,.24)}.jstree-editlink-editmode>.jstree-anchor .jstree-editlink-edit{opacity:.35}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid rgba(0,0,0,0);border-bottom:5px solid rgba(0,0,0,0);border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{z-index:1;padding:6px 12px;background-color:rgba(0,0,0,.04);line-height:24px} \ No newline at end of file +.jstree-container-ul{margin:0}.jstree-container-ul,.jstree-container-ul ul{list-style-type:none}.jstree-children{padding-left:36px}.jstree-container-ul,.jstree-container-ul>li{padding-left:0}.jstree-node{position:relative}.jstree-anchor{width:100%;background-color:rgba(0,0,0,.04);padding:6px;position:relative;margin-bottom:6px;display:block;margin:6px 0 0}.jstree-editlink-container{display:none;padding:11px;border:1px solid rgba(0,0,0,.04);overflow:hidden;line-height:36px;font-weight:bold}.jstree-editlink-container>label>input,.jstree-editlink-container>label>textarea,.jstree-editlink-container>label>select,.jstree-editlink-container .query-form-element{float:right;width:70%;font-weight:normal}.jstree-editlink-container .query-form-element input{width:100%}.jstree-editlink-container label{display:block}.jstree-editlink-container label:not(:last-child){margin-bottom:6px}.value .jstree-editlink-container label{line-height:36px}.jstree-hovered,.jstree-clicked{background-color:rgba(0,0,0,.12)}i.jstree-icon{font-style:normal;position:absolute;right:12px;top:0}.jstree-icon:before{font-family:"Font Awesome 5 Free";font-weight:900}.jstree-open,.jstree-closed{position:relative}.jstree-open>.jstree-ocl,.jstree-closed>.jstree-ocl,.jstree-removenode-remove,.jstree-removenode-undo,.jstree-editlink-edit,.jstree-displaylink,.jstree-private{width:24px;height:36px;line-height:36px;background-color:rgba(0,0,0,.2);text-align:right;cursor:pointer;z-index:1}.jstree-open>.jstree-ocl,.jstree-closed>.jstree-ocl{width:36px;right:0;text-align:center}i.jstree-icon.jstree-ok,i.jstree-icon.jstree-er{left:100%;width:36px;height:36px;line-height:36px;background-color:rgba(0,0,0,.12);text-align:center}.jstree-removenode-remove,.jstree-removenode-undo,.jstree-editlink-edit,.jstree-displaylink,.jstree-private{background-color:transparent;opacity:.5}.jstree-removenode-remove:hover,.jstree-removenode-undo:hover,.jstree-editlink-edit:hover,.jstree-displaylink:hover,.jstree-private:hover{opacity:1}.jstree-private{color:#676767}.jstree-private:hover{opacity:.5}.jstree-open>.jstree-anchor .jstree-removenode-remove,.jstree-closed>.jstree-anchor .jstree-removenode-remove,.jstree-open>.jstree-anchor .jstree-removenode-undo,.jstree-closed>.jstree-anchor .jstree-removenode-undo{right:48px}.jstree-open>.jstree-anchor .jstree-editlink-edit,.jstree-closed>.jstree-anchor .jstree-editlink-edit{right:72px}i.jstree-editlink-edit{right:36px}i.jstree-private{background-color:transparent;position:static;display:inline-block;margin-right:6px;height:16px;line-height:1}.jstree-open>.jstree-anchor .jstree-displaylink,.jstree-closed>.jstree-anchor .jstree-displaylink{right:96px}i.jstree-displaylink{right:60px}.block-pagelist-tree .jstree-open>.jstree-anchor .jstree-displaylink,.block-pagelist-tree .jstree-closed>.jstree-anchor .jstree-displaylink{right:72px}.block-pagelist-tree i.jstree-displaylink{right:36px}.jstree-anchor:hover>.jstree-removenode-remove{display:block}.jstree-open>.jstree-ocl:before{content:""}.jstree-closed>.jstree-ocl:before{content:""}.jstree-ok:before{content:""}.jstree-er:before{content:""}.jstree-removenode-remove:before{content:""}.jstree-removenode-undo:before{content:""}.jstree-editlink-edit:before{content:""}.jstree-displaylink:before{content:""}.jstree-private:before{content:""}.jstree-removenode-removed .jstree-anchor{background-color:#fcc}.jstree-removenode-removed .jstree-children .jstree-removenode-remove,.jstree-removenode-removed .jstree-children .jstree-removenode-undo{display:none}.jstree-removenode-removed.jstree-open>.jstree-ocl,.jstree-removenode-removed.jstree-closed>.jstree-ocl{background-color:rgba(255,0,0,.24)}.jstree-editlink-editmode>.jstree-anchor .jstree-editlink-edit{opacity:.35}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid rgba(0,0,0,0);border-bottom:5px solid rgba(0,0,0,0);border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{z-index:1;padding:6px 12px;background-color:rgba(0,0,0,.04);line-height:24px} \ No newline at end of file diff --git a/application/asset/css/page-blocks.css b/application/asset/css/page-blocks.css index 327bb7be72..db300d6456 100644 --- a/application/asset/css/page-blocks.css +++ b/application/asset/css/page-blocks.css @@ -1 +1 @@ -.item-showcase{margin:1rem 0;border-top:1px solid #dfdfdf;border-bottom:1px solid #dfdfdf;padding:calc(1rem - 1px) 0 0;overflow:hidden;text-align:center;clear:both;display:flex;flex-wrap:wrap;justify-content:center}.item.resource .caption{font-size:.875rem;line-height:1.5rem}.item.resource .caption *{margin:0 0 1rem 0}.item.resource .caption>*:last-child{margin-bottom:0}.item-showcase .resource.item{vertical-align:top;margin-bottom:1rem}.item-showcase .resource.item img{margin-right:.5rem;max-width:100%}.item-showcase .resource.item:only-child img{margin:0 auto}.item-showcase .resource.item:not(:only-child){width:25%;clear:none;padding:0 .5rem}.item-showcase .resource.item:not(:only-child) h3{clear:left;font-size:1rem;line-height:1.5rem;margin:.5rem 0 0}.item-showcase .resource.item:not(:only-child) img{max-height:7rem;width:auto;float:none;margin-right:0;vertical-align:top}.right,.left{overflow:hidden;max-width:33.33%}.left .item.resource,.right .item.resource{margin:0 0 1rem 0}.left .item.resource:first-of-type,.right .item.resource:first-of-type{padding-top:calc(1rem - 1px);margin-top:0}.left .item.resource:last-of-type,.right .item.resource:last-of-type{padding-bottom:-1px}.left .item.resource .media-render a,.right .item.resource .media-render a{display:block}.left .item.resource audio,.left .item.resource canvas,.left .item.resource video,.left .item.resource progress,.left .item.resource img,.right .item.resource audio,.right .item.resource canvas,.right .item.resource video,.right .item.resource progress,.right .item.resource img{max-width:100%;vertical-align:bottom;margin-bottom:.5rem}.file{border-top:1px solid #dfdfdf;border-bottom:1px solid #dfdfdf;margin-top:1rem;margin-bottom:1rem}.left.file,.left.assets{float:left;clear:left;margin:0 1rem 1rem 0}.right.file,.right.assets{float:right;clear:right;margin:0 0 1rem 1rem}.center.file,.center.assets{display:flex;justify-content:center;flex-wrap:wrap;text-align:center}.center.file .item,.center.assets .item{width:100%}.left .item.resource>a:first-child,.right .item.resource>a:first-child{vertical-align:top}.medium .item.resource>h3,.square .item.resource>h3{font-size:16px;line-height:1.5rem}.left .item.resource>h3,.right .item.resource>h3{margin:0}.left .item.resource+p,.right .item.resource+p{margin-top:0}.break{width:100%;clear:both;border-bottom:1px solid #dfdfdf;padding-bottom:-1px;margin:1rem 0}.break.transparent{border-color:transparent}.break.opaque{border-color:#dfdfdf}.preview-block{margin:1rem 0;overflow:hidden;width:100%;clear:both}.toc-block>ul{margin:1rem 0;list-style-type:none;border-left:5px solid #dfdfdf}.toc-block>ul>li{margin-bottom:.5rem}.toc-block>ul>li>a{font-weight:bold}.toc-block ul ul{list-style-type:none;padding-left:0}.toc-block ul ul ul{padding-left:1.25em}.toc-block ul ul li:before{content:"—";color:#dfdfdf}.item-with-metadata{width:100%;overflow:hidden;margin:1rem 0}.item-with-metadata .show.resource{margin:2rem 0}.list-of-sites .site-list .site{margin-bottom:.5rem;overflow:auto}.list-of-sites .site-list .site-link{display:inline-block;font-size:1.25rem;margin-bottom:.25rem}.list-of-sites .site-list .site-summary{margin:0 0 .25rem 0;line-height:20px}.list-of-sites .site-list .site-thumbnail-image{max-width:25%;float:left;margin-right:1rem}.assets .asset,.assets .asset img{max-width:100%;height:auto}.assets .asset{margin-bottom:1rem}.assets .link-title{display:block;font-size:1.25rem;font-weight:bold}.page-date-time{margin:1rem 0}.page-date-time .property{font-weight:bold}.page-date-time .property:after{content:": "}.page-date-time>div,.page-date-time .property,.page-date-time .value{display:inline-block;margin:0} \ No newline at end of file +.block-layout-background-position-y-top{background-position-y:top}.block-layout-background-position-y-center{background-position-y:center}.block-layout-background-position-y-bottom{background-position-y:bottom}.block-layout-background-position-x-left{background-position-x:left}.block-layout-background-position-x-center{background-position-x:center}.block-layout-background-position-x-right{background-position-x:right}.page-layout-normal .block-layout-alignment-right,.page-layout-normal .block-layout-alignment-left{overflow:hidden;max-width:33.33%}.block-layout-alignment-left .item.resource,.block-layout-alignment-right .item.resource{margin:0 0 1rem 0}.block-layout-alignment-left .item.resource:first-of-type,.block-layout-alignment-right .item.resource:first-of-type{padding-top:calc(1rem - 1px);margin-top:0}.block-layout-alignment-left .item.resource:last-of-type,.block-layout-alignment-right .item.resource:last-of-type{padding-bottom:-1px}.block-layout-alignment-left .item.resource .media-render a,.block-layout-alignment-right .item.resource .media-render a{display:block}.block-layout-alignment-left .item.resource audio,.block-layout-alignment-left .item.resource canvas,.block-layout-alignment-left .item.resource video,.block-layout-alignment-left .item.resource progress,.block-layout-alignment-left .item.resource img,.block-layout-alignment-right .item.resource audio,.block-layout-alignment-right .item.resource canvas,.block-layout-alignment-right .item.resource video,.block-layout-alignment-right .item.resource progress,.block-layout-alignment-right .item.resource img{max-width:100%;vertical-align:bottom;margin-bottom:.5rem}.block-layout-alignment-left{float:left;clear:left;margin:0 1rem 1rem 0}.block-layout-alignment-right{float:right;clear:right;margin:0 0 1rem 1rem}.block-layout-alignment-center{display:flex;justify-content:center;flex-wrap:wrap;text-align:center}.block-layout-alignment-center .item{width:100%}.block-layout-alignment-left .item.resource>a:first-child,.block-layout-alignment-right .item.resource>a:first-child{vertical-align:top}.block-layout-alignment-left .item.resource>h3,.block-layout-alignment-right .item.resource>h3{margin:0}.block-layout-alignment-left .item.resource+p,.block-layout-alignment-right .item.resource+p{margin-top:0}.block-layout-background-size-cover,.block-layout-background-size-contain{background-repeat:no-repeat}.block-layout-background-size-cover{background-size:cover}.block-layout-background-size-contain{background-size:contain}.item-showcase{margin:1rem 0;border-top:1px solid #dfdfdf;border-bottom:1px solid #dfdfdf;padding:calc(1rem - 1px) 0 0;overflow:hidden;text-align:center;clear:both;display:flex;flex-wrap:wrap;justify-content:center}.item.resource .caption{font-size:.875rem;line-height:1.5rem}.item.resource .caption *{margin:0 0 1rem 0}.item.resource .caption>*:last-child{margin-bottom:0}.item-showcase .resource.item{vertical-align:top;margin-bottom:1rem}.item-showcase .resource.item img{margin-right:.5rem;max-width:100%}.item-showcase .resource.item:only-child img{margin:0 auto}.item-showcase .resource.item:not(:only-child){width:25%;clear:none;padding:0 .5rem}.item-showcase .resource.item:not(:only-child) h3{clear:left;font-size:1rem;line-height:1.5rem;margin:.5rem 0 0}.item-showcase .resource.item:not(:only-child) img{max-height:7rem;width:auto;float:none;margin-right:0;vertical-align:top}.file{border-top:1px solid #dfdfdf;border-bottom:1px solid #dfdfdf;margin-top:1rem;margin-bottom:1rem}.medium .item.resource>h3,.square .item.resource>h3{font-size:16px;line-height:1.5rem}.break{width:100%;clear:both;border-bottom:1px solid #dfdfdf;padding-bottom:-1px;margin:1rem 0}.break.transparent{border-color:transparent}.break.opaque{border-color:#dfdfdf}.preview-block{margin:1rem 0;overflow:hidden;width:100%;clear:both}.toc-block>ul{margin:1rem 0;list-style-type:none;border-left:5px solid #dfdfdf}.toc-block>ul>li{margin-bottom:.5rem}.toc-block>ul>li>a{font-weight:bold}.toc-block ul ul{list-style-type:none;padding-left:0}.toc-block ul ul ul{padding-left:1.25em}.toc-block ul ul li:before{content:"—";color:#dfdfdf}.item-with-metadata{width:100%;overflow:hidden;margin:1rem 0}.item-with-metadata .show.resource{margin:2rem 0}.list-of-sites .site-list .site{margin-bottom:.5rem;overflow:auto}.list-of-sites .site-list .site-link{display:inline-block;font-size:1.25rem;margin-bottom:.25rem}.list-of-sites .site-list .site-summary{margin:0 0 .25rem 0;line-height:20px}.list-of-sites .site-list .site-thumbnail-image{max-width:25%;float:left;margin-right:1rem}.assets .asset,.assets .asset img{max-width:100%;height:auto}.assets .asset{margin-bottom:1rem}.assets .link-title{display:block;font-size:1.25rem;font-weight:bold}.page-date-time{margin:1rem 0}.page-date-time .property{font-weight:bold}.page-date-time .property:after{content:": "}.page-date-time>div,.page-date-time .property,.page-date-time .value{display:inline-block;margin:0} \ No newline at end of file diff --git a/application/asset/css/page-grid.css b/application/asset/css/page-grid.css new file mode 100644 index 0000000000..6e8d8a1729 --- /dev/null +++ b/application/asset/css/page-grid.css @@ -0,0 +1 @@ +.page-layout-grid{display:grid}.page-layout-grid>div{min-height:50px}@media screen and (max-width: 896px){.page-layout-grid{display:block}} \ No newline at end of file diff --git a/application/asset/css/style.css b/application/asset/css/style.css index 15ef100b51..7b1b84dd89 100644 --- a/application/asset/css/style.css +++ b/application/asset/css/style.css @@ -1 +1 @@ -/*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}@media screen{*{box-sizing:border-box}em,i{font-style:italic}strong,b{font-weight:bold}a{text-decoration:none}a:link,a:visited{color:#a91919}a:active,a:hover{color:#e34545}h1,h2,h3,h4,h5,h6{margin:0}h3,h4,h5,h6{font-weight:bold}h1{font-size:32px;line-height:48px;margin-bottom:24px}h2{font-size:30px;line-height:36px;margin-bottom:24px}h3{font-size:24px;margin-bottom:24px}h5{font-size:14px}p{margin:24px 0}ul{padding-left:24px;list-style:disc}pre{max-width:100%;overflow-x:auto}html,body{height:100%}body{font-family:"Lato",sans-serif;font-size:16px;line-height:24px;color:#676767;overflow-x:hidden}table{width:100%;border-spacing:0;table-layout:fixed}th,table.tablesaw th{font-weight:bold;text-align:left;padding:6px .5em}table,table.tablesaw{margin-bottom:12px;border:1px solid #dfdfdf;border-radius:3px;border-collapse:separate}.tablesaw tr:not(:last-child) td{border-bottom:1px solid #dfdfdf}tr.delete{background-color:#fcc}td,table.tablesaw td{padding:6px .5em 5px;position:relative;vertical-align:middle}table.tablesaw td:first-child a{word-wrap:break-word}table.tablesaw thead tr:first-child th{padding-top:6px;padding-bottom:5px;border-bottom:1px solid #dfdfdf}legend{font-size:20px;padding:12px 0;font-weight:bold}[contenteditable=true],textarea{clear:both;padding:6px;border:1px solid rgba(0,0,0,.15);display:block;background-color:#fff;min-height:72px;overflow-y:auto}[contenteditable=true] p{margin:12px 0}.cke_dialog_body textarea{max-height:none}input,[contenteditable=true],textarea,button,select{font-family:"Lato",sans-serif;font-size:16px;line-height:24px;margin:0;color:#676767}input[type=text],input[type=password],input[type=email],input[type=url],input[type=number],input[type=date],input[type=datetime-local]{-webkit-appearance:none;appearance:none;border-radius:0;height:36px;border:1px solid rgba(0,0,0,.15);padding:6px;margin:0}:disabled{background-color:rgba(0,0,0,.04);box-shadow:0 0 0 1px rgba(0,0,0,.15) inset;color:#a7a7a7;-webkit-text-fill-color:#a7a7a7;cursor:default}:disabled:hover{box-shadow:0 0 0 1px rgba(0,0,0,.15) inset !important}::placeholder{font-style:italic}[contenteditable=true]>*:first-child{margin-top:0}[contenteditable=true]>*:last-child{margin-bottom:0}input[type=submit],button,a.button,.button{min-height:36px;background-color:rgba(0,0,0,.08);color:#676767;border-radius:3px;border:0;box-shadow:0 0 0 1px rgba(0,0,0,.15) inset;padding:6px 10px;display:inline-block;text-align:center;cursor:pointer;margin:0 0 12px 0}input[type=submit]:hover:not(.inactive),button:hover:not(.inactive),a.button:hover:not(.inactive),.button:hover:not(.inactive){box-shadow:0 0 0 1px rgba(0,0,0,.3) inset}input[type=submit].inactive,button.inactive,a.button.inactive,.button.inactive{box-shadow:none;background-color:#d2d2d2;cursor:default;border:0}.red.button{background-color:#fdefef;box-shadow:0 0 0 1px #e0c3c3 inset;color:#a91919}.red.button:hover{box-shadow:0 0 0 1px #da8b8b inset}.green.button{background-color:#cdffcd;color:green;box-shadow:0 0 0 1px #addead inset}.green.button:hover{box-shadow:0 0 0 1px #63c363 inset}.required .field-meta{position:relative;padding-right:36px}.required .field-meta:after{font-family:"Font Awesome 5 Free";font-weight:900;content:"";font-size:12px;position:absolute;right:12px;color:#a91919;top:6px}label input[type=checkbox]{display:inline-block;width:auto}label.required:after{font-family:"Font Awesome 5 Free";font-weight:900;content:"";font-size:12px;color:#a91919;float:right;padding-right:12px}.touched:invalid{box-shadow:0 0 2px 2px #a91919}.field{width:100%;background-color:rgba(0,0,0,.04);padding:6px;position:relative;margin-bottom:6px;display:flex;flex-wrap:wrap}.field:first-child{border-color:transparent}.media-field-wrapper{width:100%;padding:12px 6px;margin-bottom:6px;background-color:rgba(0,0,0,.04);position:relative}.media-field-wrapper .field{width:100%;margin:0 0 6px;padding:0;background-color:transparent}.media-field-wrapper .field:last-of-type{margin-bottom:0}.media-field-wrapper .field:last-of-type .field-meta,.media-field-wrapper .field:last-of-type .inputs{margin-bottom:-6px}.media-field-wrapper .actions{font-size:16px;padding:6px 0}select{background:#fff url("../img/select-arrow.svg") no-repeat;background-position:right 6px center;background-size:8px;border:1px solid #dfdfdf;height:36px;line-height:36px;font-size:16px;margin:0;padding:0 24px 0 6px;border-radius:3px;vertical-align:top;-webkit-appearance:none;appearance:none}select::-ms-expand{display:none}label input{margin-right:.5em}fieldset{margin:0 0 24px;border:0;padding:0;min-width:100%}.selector input[type=text],.selector>ul{width:100%}.selector>ul{margin:0}.chosen-container{max-width:100%}.chosen-container-single .chosen-single,.chosen-container-multi .chosen-choices{background-image:none;background-color:#fff;box-shadow:none;font-size:16px;line-height:24px;padding:6px;height:auto;border-radius:3px;border-collapse:#dfdfdf;color:#676767;border-color:#dfdfdf}.chosen-container-multi.chosen-container-active .chosen-choices{border-color:#aaa;border-radius:3px 3px 0 0}.chosen-container-multi.chosen-container.chosen-drop-up .chosen-choices{border-radius:0 0 3px 3px}.chosen-container-multi.chosen-container .chosen-drop{top:calc(100% - 1px);border-top:1px solid #aaa}.chosen-container-multi.chosen-container.chosen-drop-up .chosen-drop{bottom:calc(100% - 1px)}.chosen-container-multi .chosen-choices{padding:3px}.chosen-container-multi .chosen-choices li.search-field input[type=text]{font-family:"Lato",sans-serif;margin:0}.chosen-container-multi .chosen-choices li.search-choice{background:#f0f0f0;font-size:14px;line-height:24px;border:0;padding:0 27px 0 0}.chosen-container-multi .chosen-choices li.search-choice span{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;display:block}.chosen-container .search-choice .group-name{color:#676767;position:relative;background-color:rgba(0,0,0,.04);margin-right:6px;padding:0 6px;display:inline-block;vertical-align:top}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close{top:50%;right:6px;transform:translateY(-50%)}.chosen-container .search-choice .group-name:after{content:""}.chosen-container-multi .chosen-choices li.search-field input[type=text]{min-height:0;margin:3px;height:auto;line-height:24px}.chosen-container-active.chosen-with-drop .chosen-single{background-image:none}.chosen-container-single .chosen-single abbr{top:12px}.chosen-container-single .chosen-single div b{background:none !important}.chosen-container-single .chosen-single div b:after{font-family:"Font Awesome 5 Free";font-weight:900;content:"";line-height:24px;padding:6px 0;display:inline-block}.chosen-container-active.chosen-with-drop .chosen-single div b:after{content:""}.chosen-container-single .chosen-search input[type=text]{background:none !important}.chosen-search{position:relative}.chosen-search:after{font-family:"Font Awesome 5 Free";font-weight:900;content:"";line-height:24px;padding:6px 0;display:block;position:absolute;top:3px;right:12px}.chosen-container .chosen-results li.highlighted{background-color:#676767;background-image:none}.chosen-container.chosen-drop-up .chosen-drop{top:auto;bottom:100%;border-radius:3px 3px 0 0;box-shadow:0 -1px 2px rgba(0,0,0,.15);border-top:1px solid #aaa}.chosen-container-active.chosen-drop-up.chosen-with-drop .chosen-single{border-radius:0 0 3px 3px}.flex{display:flex}.mobile-only{display:none}.sr-only{left:-9999px}div[role=main]>.messages{margin-bottom:12px}div[role=main]>.messages li{margin:0 0 6px}div[role=main]>.messages .error{background-color:#f4b4b4}div[role=main]>.messages .success{background-color:#cdffcd}div[role=main]>.messages .warning{background-color:#fff6e6}div[role=main]>.messages a{text-decoration:underline}.messages{padding:0;margin:0;clear:both}.messages li{background-color:rgba(255,255,255,.5);border-radius:3px;padding:6px 10px;margin-top:6px;display:block;width:100%}.field .messages{width:70%;color:#a91919;margin-left:auto}.field .messages li{box-shadow:0 0 0 1px inset}.error,.error a{color:#a91919}.success,.success a{color:green}.warning,.warning a{color:orange}.version-notification{background-color:#cdffcd;color:green;border-radius:3px;padding:6px 10px;margin-top:6px;display:block;width:100%}.version-notification a{color:green;text-decoration:underline}table .icon-sortable{opacity:.4;font-size:12px;line-height:100%}.row{width:100%;background-color:rgba(0,0,0,.04);padding:6px;position:relative;margin-bottom:6px}.row.delete{background-color:#fcc;overflow:hidden}.jstree-themeicon,.sortable-handle{cursor:move;margin-right:12px;width:18px}.jstree-themeicon:before,.sortable-handle:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900;opacity:.35;font-size:20px;line-height:24px}.jstree i.jstree-themeicon{color:#676767;position:static;top:auto;right:auto}.o-description{margin-bottom:0}a.expand,a.collapse{color:#676767}.expand:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;margin-left:3px}.collapse:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;margin-left:3px}.selector-table{display:table}.selector-table.empty,.selector-table+.no-resources{display:none}.selector-table.empty+.no-resources{display:block}.selector .resources-available.empty,.selector .resources-available+.resources-unavailable{display:none}.selector .resources-available.empty+.resources-unavailable{display:block}.selector .selector-child.filter-hidden,.selector .selector-child.added{display:none}header{background-color:#404e61;width:18.75%;min-height:100vh;text-align:left;padding:0 1.0416666667% 24px;color:#bdcde3}.skip{position:absolute;left:-9999px}.skip:focus{position:absolute;top:0;left:45%;width:10%;z-index:1002;text-align:center;background-color:#fff;border-radius:0 0 3px 3px;border:1px solid #dfdfdf;padding:5px}.logo a,#user a{color:#bdcde3}#user{color:#fff;padding-top:12px;margin-bottom:-6px;display:flex;flex-wrap:wrap}#user p{margin:0 0 6px;display:inline-flex;vertical-align:top}#user .user-id{text-transform:uppercase;font-size:12px;margin-right:auto}#user .user-id a.button{display:inline-block;font-size:12px;text-transform:none;margin-bottom:0;background-color:#222933;padding:0 6px;min-height:0;border:0}#user .user-show{border-radius:3px 0 0 3px;margin-right:1px;display:inline-flex;max-width:85%;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}#user .user-show:before{margin-right:6px}#user .user-settings{border-radius:0 3px 3px 0;border-left:0}#user .user-settings:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900}#user .logout{font-size:12px;padding:0 6px;background-color:#222933;border-radius:3px;display:inline-block;min-width:25%;text-align:center}.logo{padding:6px 6.25%;margin:0 -6.25%;background-color:#222933}#search{width:100%;display:inline-block;vertical-align:top;margin:24px 0}#search input[type=text]{width:calc(100% - 72px);float:left}#search button{width:36px;text-indent:-9999px;background-color:#222933;color:#bdcde3;border:0;float:left;margin:0;border-radius:0;position:relative;height:36px;box-shadow:none}#search button:last-of-type{border-left:1px solid rgba(255,255,255,.2);border-radius:0 3px 3px 0}#search button:last-of-type:after{content:""}#search button:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;text-indent:0;position:absolute;top:0;left:0;width:36px;line-height:36px;text-align:center}#advanced-options{display:none}div[role=main]>h1:first-of-type{background-color:#fff;font-size:24px;position:fixed;padding:3px 30% 3px 1.0416666667%;z-index:3;top:0;right:0;width:81.25%;height:48px;border-bottom:1px solid #dfdfdf;overflow:hidden;line-height:36px}div[role=main]>h1:first-of-type .title{text-overflow:ellipsis;white-space:nowrap;max-width:65%;display:inline-block;overflow:hidden;vertical-align:middle}.subhead{text-transform:uppercase;font-size:14px;padding:0 6px;background-color:#eee;line-height:36px;vertical-align:middle;margin:0 12px 0 0;font-weight:normal;display:inline-block}.subhead:before{font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;margin-right:6px;font-size:16px;vertical-align:top}.action{display:inline-block;vertical-align:middle}.action:before{content:"·";margin:0 12px}.sidebar-open footer{margin-right:25%}footer{font-size:12px;position:relative;margin-top:-27px;margin-left:18.75%;padding-right:1.0416666667%;text-align:right}footer .site-version{margin:0;display:inline-block}footer .version-number{display:inline-block;margin:0 12px;line-height:1}body.transitions-enabled footer{transition:margin-right .5s}footer>a:not(:last-child){margin-right:12px}nav ul{padding:0;list-style:none;margin:0}nav.pagination{margin-bottom:12px;overflow:hidden}nav.pagination form,nav.pagination .button,nav.pagination .row-count{float:left}nav.pagination form{margin-right:12px}nav.pagination form *{display:inline-block;padding:0;text-align:center}nav.pagination .button{border-radius:0;margin:0;padding:0 10px}nav.pagination .button,nav.pagination input[type=text],.sorting button,.sorting select{font-size:13.08px;min-height:0;height:24px;line-height:24px;vertical-align:top;background-size:6.5408px}nav.pagination .button{box-shadow:0 0 0 1px #c8c8c8 inset;position:relative}nav.pagination .button:hover{z-index:1}nav.pagination .button:before{vertical-align:top;line-height:24px}nav.pagination .previous.button{border-radius:3px 0 0 3px}nav.pagination .next.button{border-radius:0 3px 3px 0;margin-left:-1px}nav.pagination form input[type=text]{margin-right:.25em;width:48px;border:1px solid #dfdfdf;padding:5px}nav.pagination+*:not(.sorting){clear:left}#mobile-nav{display:none}.mobile-container{position:relative}button .o-icon-private{margin:0 6px;color:#dfdfdf}header nav h4{padding-bottom:5px;border-bottom:1px solid #364252;margin-bottom:6px}header nav h4:not(:first-of-type){margin-top:24px}header nav ul.navigation>li:not(:first-of-type){margin-top:6px}header nav ul.navigation>li:not(:last-of-type){border-color:#dfdfdf}header nav ul.navigation li li{display:none}header nav ul.navigation li.active li{display:block;margin-left:24px}header nav ul.navigation li.active>a{color:#fff}header nav a:link,header nav a:visited{color:#bdcde3}header nav li>a:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;width:24px}header nav .items:before,.items .subhead:before{content:""}header nav .media:before,.media .subhead:before{content:""}header nav .item-sets:before,.item-sets .subhead:before{content:""}header nav .vocabularies:before,.vocabularies .subhead:before{content:""}header nav .resource-templates:before,.resource-templates .subhead:before{content:""}header nav .users:before,.users .subhead:before{content:""}header nav .modules:before,.modules .subhead:before{content:""}header nav .jobs:before,.jobs .subhead:before{content:""}header nav .sites:before,.sites .subhead:before{content:""}header nav .settings:before,.settings .subhead:before{content:""}header nav .assets:before,.assets .subhead:before{content:""}header nav li li a:before{content:""}header ul.navigation{margin-bottom:6px}#menu{position:relative}#menu h5{text-transform:uppercase;border-top:1px solid #364252;padding-top:5px;margin-bottom:0}#menu .expand,#menu .collapse{width:100%;z-index:1;padding-bottom:6px;margin-bottom:6px}#site-nav{background-color:#364252;padding:6px;margin-bottom:12px;border-radius:3px}#site-nav h5{border-top:0;border-bottom:1px solid #2c3542;padding:0 24px 5px 0;margin-bottom:6px}header nav#site-nav h5 a:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900;width:24px;display:inline-block;font-size:16px}#menu .pages:before,.site-pages .subhead:before{content:""}#menu a.navigation:before{content:""}#menu a.public{float:right;text-align:right;font-size:16px;line-height:30px;margin-top:-39px}#menu a.resources:before{content:""}#menu a.site-info:before{content:""}#menu a.theme:before,.theme-settings .subhead:before{content:""}div[role=main]{width:81.25%;padding:60px 1.0416666667% 36px;background-color:#fff;min-height:100%;overflow:hidden}body.transitions-enabled div[role=main]{transition:width .5s}#dashboard>p{width:100%;margin-top:12px}#manage-resources .add.button:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900}.panel{width:48.9583333333%;float:left;padding-left:1.0416666667%;padding-right:1.0416666667%;border:1px solid #dfdfdf;padding:5px;margin:0 1.0416666667% 0 0;float:left;overflow:hidden}.panel .row{width:100%;background-color:rgba(0,0,0,.04);padding:6px;position:relative;margin-bottom:6px}.panel>.row:last-child{margin-bottom:0}.panel .button{float:right;margin:0}.panel .row a.button{box-shadow:none;padding:0;color:#a91919;background-color:transparent}.panel h2{font-size:18px;line-height:24px;margin-bottom:6px}.browse .add.button,.browse .batch-edit.button{float:left;margin-right:.25em}.browse td:first-child,.browse th:first-child{width:50%}.browse td,.browse th{padding:12px 6px;overflow:hidden}.browse .browse-controls{display:flex;justify-content:space-between;flex-wrap:wrap;font-size:13.08px}.sites.pages.browse .browse-controls{justify-content:flex-end}.browse .browse-controls .advanced-search:before{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;font-style:normal;font-variant:normal;font-weight:normal;line-height:1;font-family:"Font Awesome 5 Free";font-weight:900;content:"";padding:.25em}.browse-controls select,.browse-controls input,.browse-controls button,.browse-controls .button{font-size:13.08px;min-height:0;height:24px;line-height:24px;vertical-align:top;background-size:6.5408px}.browse-controls .sorting:not(:last-child){margin-left:auto}.browse-controls button,.browse-controls .button{padding:0 10px}.browse-controls .filtering{margin-left:24px}.browse .select-all{width:12px;margin-right:12px}.browse .tablesaw-cell-content,#properties .tablesaw-cell-content{display:flex;align-items:center;justify-content:flex-start;word-wrap:break-word}.browse .tablesaw-cell-content>.actions,#properties .tablesaw-cell-content>.actions{white-space:nowrap}.browse .batch-edit .tablesaw-cell-content>input[type=checkbox]{margin-right:12px;flex-shrink:0}.browse .tablesaw-cell-content>span.indent{display:inline-block;vertical-align:top;flex:0;min-width:1em}.actions{margin:0 0 0 auto;display:flex;padding:0}.actions li{list-style-type:none}.actions a,.actions a:before,.actions button,.actions button:before{width:24px;height:24px;line-height:24px;vertical-align:top;border:0;box-shadow:none;display:inline-block}.actions .button:hover,.actions button:hover{box-shadow:none !important}.actions a,.actions button{opacity:.5}.actions a:before,.actions button:before{text-align:right}.actions a:hover,.actions a:active,.actions button:hover{opacity:1}.actions .inactive{display:none}.actions button{background-color:transparent;color:#a91919;margin:0;text-indent:-9999px;position:relative;padding:0;min-height:0}.actions button:before{text-indent:0;position:absolute;top:0;left:0}.row-count{margin:0 6px}.no-resources{text-align:center;position:relative;margin-top:96px}.no-resources:before{font-family:"Font Awesome 5 Free";font-weight:900;font-size:96px;position:absolute;top:0;left:0;width:100%;opacity:.08;content:""}.no-resources p{font-size:24px;line-height:48px;margin-top:48px}td .o-icon-private,td .o-icon-user-inactive{display:inline-block;vertical-align:bottom;margin-left:.5em;opacity:.5}.items .no-resources:before{content:""}.item-sets .no-resources:before{content:""}.media .no-resources:before,#media-list .no-resources:before{content:""}.modules .no-resources:before{content:""}.vocabs .no-resources:before{content:""}.resource-templates .no-resources:before,.resources-templates{content:""}.users .no-resources:before{content:""}.jobs .no-resources:before{content:""}.sites .no-resources:before{content:""}.sidebar .no-resources{display:block}.browse.assets td:first-child,.browse.assets th:first-child{width:75%}.asset-inline{max-width:100%}#batch-form{border:1px solid #dfdfdf;border-bottom:0;border-radius:3px;margin-bottom:12px}#batch-form table.tablesaw{border-width:1px 0;border-radius:0 0 3px 3px;margin-bottom:0}#batch-form .batch-actions{display:inline-block}#batch-form .batch-inputs{display:flex;align-items:center;padding:6px;background-color:rgba(0,0,0,.04)}#batch-form .batch-actions>a.button,#batch-form .batch-actions>button,#batch-form .batch-actions>input[type=submit]{display:none;margin:0 12px 0 0;font-size:14px;line-height:24px;min-height:0;padding:0 6px}#batch-form .batch-actions>a.button.active,#batch-form .batch-actions>button.active,#batch-form .batch-actions>input[type=submit].active{display:inline-block}#batch-form select{font-size:14px;min-height:0;height:auto;line-height:24px;padding:0 24px 0 6px;margin-right:6px;border:0;box-shadow:0 0 0 1px #dfdfdf inset}.batch-selected{padding-left:0;list-style:none}.batch-selected li{padding:12px 0 11px;border-bottom:1px solid #dfdfdf}.batch-selected li:first-child{padding-top:0}.batch-selected li:last-child{border-color:transparent}#advanced-options{background-color:#fff;padding:6px 12px calc(6px - 1px);clear:both;border:1px solid rgba(0,0,0,.15);border-top:0;color:#676767}#advanced-options legend{float:left;width:calc(100% + 24px);font-weight:bold;padding:6px 12px;margin:-6px -12px 12px;background-color:rgba(0,0,0,.04);max-width:none}#advanced-options input{float:left;clear:left;margin-right:.5em;height:24px;margin-bottom:6px}#advanced-options label{float:left;margin-bottom:6px}.search-filters{margin-bottom:6px;display:inline-block}.filter{display:inline-block;font-size:13.08px;margin:0 6px 6px 0;border-radius:3px;background-color:#f0f0f0;padding:0;vertical-align:top}.filter-label{display:inline-block;background-color:rgba(0,0,0,.04);border-radius:3px 0 0 3px}.filter-label,.filter-value{padding:0 6px}.filter-value:not(:last-child):after{content:","}.multi-value .value{display:flex}.multi-value .add-value,.multi-value.field .remove-value{background-color:transparent;color:#a91919;display:inline-block;text-indent:-9999px;position:relative;min-width:36px;width:36px;text-align:center;box-shadow:none}.multi-value .add-value:before,.multi-value.field .remove-value:before{position:absolute;top:0;left:0;width:36px;line-height:36px;text-indent:0}.multi-value .add-value:hover,.multi-value.field .remove-value:hover{box-shadow:none;color:#a91919}.multi-value .add-value{position:absolute;top:0;right:0}.multi-value .field-meta{padding-right:36px}.item-set-select-type{max-width:25%}fieldset.section>legend{position:absolute;left:-9999px}.section-nav{border-top:1px solid #fff;height:42px;position:relative;margin-bottom:12px;clear:both}.section-nav:before{content:"";height:3px;position:absolute;bottom:1px;left:0;right:0;z-index:0;background:#fff;border:1px solid #dfdfdf;border-width:1px 0}.section-nav a{display:block;float:left;height:36px;line-height:30px;padding:3px 1em;position:relative;z-index:1;background-color:#fff;border-color:#dfdfdf;border:1px solid #dfdfdf;margin-left:.25em;color:#676767}.section-nav .active a{font-weight:bold;border-bottom-color:#fff}.section:not(a){display:none}.section.active{display:block;clear:both}#page-actions{position:fixed;padding:6px 1.0416666667%;z-index:4;top:0;height:36px;right:0;text-align:right;margin-bottom:0}#page-actions input[type=submit],#page-actions button,#page-actions .button{display:inline-block;height:36px;padding:6px 1em;min-height:0;vertical-align:top}#page-actions .delete.button{background-color:#fdefef;box-shadow:0 0 0 1px #e0c3c3 inset;color:#a91919}#page-actions .delete.button:hover{box-shadow:0 0 0 1px #da8b8b inset}.page-action-menu{display:inline-block;position:relative}.page-action-menu ul{display:none;list-style:none;border:1px solid #dfdfdf;background-color:#fff;border-radius:3px;text-align:left;padding:0;position:relative;box-shadow:0 0 5px #dfdfdf;position:absolute;right:0;width:auto;white-space:nowrap;margin:12px 0}.page-action-menu ul:before{content:"";position:absolute;bottom:calc(100% - 1px);right:12px;width:0;height:0;border-bottom:12px solid #fff;border-left:6px solid transparent;border-right:6px solid transparent}.page-action-menu ul:after{content:"";position:absolute;bottom:calc(100% - 1px);right:11px;width:0;height:0;border-bottom:14px solid #dfdfdf;border-left:7px solid transparent;border-right:7px solid transparent;z-index:-1}.page-action-menu ul a,.page-action-menu ul .inactive{padding:6px 12px 5px;display:block;position:relative}.page-action-menu ul .inactive{color:#dfdfdf}.page-action-menu ul li{position:relative}.page-action-menu ul li:hover:before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background-color:#dfdfdf}.page-action-menu ul li:not(:last-child) a,.page-action-menu ul li:not(:last-child) span,.page-action-menu ul li:not(:last-child) [type=submit]{border-bottom:1px solid #dfdfdf}.page-action-menu [type=submit]{background:none;box-shadow:none;width:100%;margin-bottom:0;text-align:left}.page-action-menu li label{display:inline-block;height:36px;padding:6px 1em;min-height:0;vertical-align:top;width:100%}.page-action-menu li label input{margin-left:.25em}.page-action-menu li:not(:last-child) label{border-bottom:1px solid #dfdfdf}.page-action-menu .expand:after{content:""}.page-action-menu .expand:after,.page-action-menu .collapse:after{margin-left:6px}.page-action-menu .collapse+.collapsible{overflow:visible;display:block}.add-property.button{margin-top:24px}.field-term{display:inline-block;font-family:"Source Code Pro",monospace;font-size:12px}.value .input-body a.value-language{margin-right:0;vertical-align:top;position:absolute;top:0;right:0;height:36px;width:36px;line-height:36px;border:1px solid #dfdfdf;border-width:0 0 1px 1px;overflow:hidden;text-align:center;color:#f19d9d;z-index:1}.value .input-body a.value-language~textarea{padding-right:42px}.value .input-body .language-wrapper.active a.value-language{border-color:transparent;color:#a91919}.value .language-wrapper:not(.active)~textarea{padding-right:48px}.value .actions a.o-icon-more{display:block;height:36px}.more-actions.active a.o-icon-more{border-bottom:1px solid #dfdfdf}.language-wrapper input[type=text].value-language{line-height:24px;background-color:transparent;border:0;min-height:0;padding:6px 42px 6px 6px;display:block;background-color:#fff}.language-wrapper.active input[type=text].value-language~textarea{padding-left:6px;border-top:0}.input-body .language-wrapper:not(.active) .language-label{display:none}.sidebar .language-label{font-weight:inherit}.language-wrapper .language-label,.value[data-data-type=uri] .input-body label{display:flex;align-items:flex-start;background-color:#fff;margin:0;padding:0 42px 0 6px;box-shadow:0 0 0 1px #dfdfdf}.value-label-text{background-color:rgba(0,0,0,.04);border-radius:2px;font-size:14px;margin:6px;padding:0 6px}.sidebar .value-annotation .value{padding-bottom:0}.sidebar .value-annotation label:after{content:none}.sidebar .value-annotation p.selected-resource{border-bottom:1px solid #dfdfdf}.sidebar .value-annotation-resource-select{margin:6px !important}.sidebar [data-data-type^=resource] .o-title:not(:empty){padding:0;border-bottom:0}.sidebar [data-data-type^=resource] .o-title:not(:empty) a:empty{display:none}.sidebar [data-data-type^=resource] .o-title:not(:empty) img{margin:6px}.sidebar [data-data-type^=resource] .o-title:not(:empty) a{padding:6px;width:100%}.non-properties{margin-bottom:12px}.resource-form .values .sortable-handle{width:12px;background-color:rgba(0,0,0,.04);border:1px solid #dfdfdf;border-radius:2px 0 0 2px;align-self:stretch;border-right:0;margin:0;display:flex;align-items:center;justify-content:center}.resource-form .values .sortable-handle:before{font-size:10px}.visibility{display:inline-block;padding:6px;margin-right:12px}.add .visibility:before,.edit .visibility:before{margin-right:.25em}.add .visibility [type=checkbox],.edit .visibility [type=checkbox]{margin-left:.5em}#add-item .remove.field{background-color:#ea7171;opacity:.6}.resource.input-option span{display:block;background-color:rgba(255,255,255,.5);padding:6px 10px 0;width:100%;float:left}.field-meta{width:30%;padding-right:6px;position:relative}.field-meta legend,.field-meta label,.field-meta .label{max-width:80%;padding:6px 0;display:inline-block}.field-meta legend{position:static;float:left}.field-meta .error{float:left}.field-meta ul{margin:0}.field-label-text{display:block}.template{display:none}.selector ul{list-style:none;padding-left:0}.selector>ul{margin-top:6px}.selector li{position:relative}.selector li.total-count-heading{background-color:#404e61;color:#fff;border-radius:3px;text-transform:uppercase;font-size:12px;padding:6px 10px}.selector li.total-count-heading>ul{margin:6px -10px -6px;border-radius:0 0 3px 3px}.selector li.selector-parent.empty{display:none}.selector li.show>ul{position:relative;top:0;left:0;overflow:visible}.selector .selectable-list{background-color:#fff;color:#676767;overflow:visible;border-radius:3px;font-weight:bold;position:relative;border:1px solid #dfdfdf;margin:6px 0 0;text-transform:uppercase;font-size:12px}.selector .selectable-list li{padding:6px 12px}.selector .selectable-list .selector-parent{cursor:pointer;padding-right:24px;margin-bottom:0}.selector .selectable-list .selector-parent:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;position:absolute;right:0;top:6px;width:18px}.selector .selectable-list .selector-parent.show:after{content:""}.selector .selectable-list .selector-parent:hover:before{content:"";position:absolute;top:0;bottom:0;left:0;width:5px;background-color:#dfdfdf}.selector .selectable-list .selector-parent:not(:last-of-type){border-bottom:1px solid #dfdfdf;padding-bottom:5px;border-color:#dfdfdf}.selector-parent ul{position:absolute;top:-9999px;left:-9999px}.selector-child{border-radius:0;font-weight:normal;padding:6px 10px;margin:0 -12px;font-size:16px;text-transform:none;width:calc(100% + 36px)}.selector-child:hover{background-color:rgba(0,0,0,.04)}.selector-child:last-of-type{margin-bottom:-6px}.selector .description{display:inline-block;vertical-align:top}.selector .description.no-comment{opacity:0}.selector .description .o-icon-info{display:inline-block;margin:0 6px 0 0;opacity:.75;width:1em}.selector .description .o-icon-info:hover+.field-comment{left:5px;right:0;top:36px;padding:3px 10px 3px 36px;line-height:18px;background-color:#fff;z-index:1;margin:0;border-bottom:1px solid #dfdfdf;font-size:12px}.selector .description .o-icon-info:hover+.field-comment:before{content:"";position:absolute;left:7px;top:-6px;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff}.selector .description .o-icon-info:hover+.field-comment.above{bottom:100%;top:auto}.selector .description .o-icon-info:hover+.field-comment.above:before{top:calc(100% - 6px);transform:rotate(180deg)}.selector .description .o-icon-info+.field-comment{position:absolute;top:-9999px;left:-9999px;width:calc(100% - 5px)}.selector .selectable{display:inline-block;width:calc(100% - 36px);word-wrap:break-word}.field-actions{width:60%;display:inline-block;margin:24px 0 0 30%}.field .field-label{display:inline-block}.field .field-description,.field .docs-link{font-size:14px;line-height:18px;position:static;text-align:left;height:auto}.field .field-description:not(:only-child){margin-bottom:6px}.field-description{display:block;margin-right:10px;line-height:36px;height:36px;position:absolute;top:0;right:0;text-align:right;left:0}.field-description .o-icon-info{margin:0;cursor:pointer}.field-description .field-comment.open{left:inherit;right:0px;top:36px;background-color:#333;color:#fff;border-radius:3px;z-index:1;max-width:100%;font-size:14px;padding:6px 5px;margin:12px 0}.field-description .field-comment.open.above{top:auto;bottom:30px}.field-description .field-comment.open:before{content:"";display:block;height:0;width:0;position:absolute;top:-6px;bottom:0;right:3px;font-size:16px;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:12px solid #333}.field-description .field-comment.open.above:before{top:auto;bottom:-12px;transform:rotate(180deg)}.field .docs-link:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;margin-right:6px;font-size:14px;line-height:18px}.field-meta .expand,.field-meta .collapse{display:inline-block !important;margin-left:.5em !important;padding:0 !important;border:0 !important;width:auto !important}.field-meta .expand:after,.field-meta .collapse:after{float:none !important;margin-right:0 !important}.collapsible{display:none}.collapse+.collapsible{display:block;clear:both;overflow:hidden}.field-description .field-comment{position:absolute;top:-9999px;left:-9999px}.resource-property .field-term{display:block}.inputs{line-height:36px;width:70%}.inputs:only-child{width:100%}.inputs p:only-child{margin:0}.inputs label,.inputs select,.inputs textarea,.inputs input[type=text],.inputs input[type=password],.inputs input[type=email],.inputs input[type=url],.inputs input[type=date],.inputs input[type=datetime-local]{width:100%;min-height:36px;margin:6px 0}.inputs label:only-child,.inputs select:only-child,.inputs textarea:only-child,.inputs input[type=text]:only-child,.inputs input[type=password]:only-child,.inputs input[type=email]:only-child,.inputs input[type=url]:only-child,.inputs input[type=date]:only-child,.inputs input[type=datetime-local]:only-child{margin:0}.inputs textarea{resize:vertical;line-height:1.5;background-color:#fff;min-width:0}.inputs label{padding:6px 0;margin:0 24px 0 0}.inputs .button,.inputs button,.inputs input[type=submit]{margin:6px 0;line-height:24px}.inputs input:focus,.inputs textarea:focus{position:relative;z-index:100}#resource-values div.value{display:flex;align-items:stretch}#resource-values div.value:only-of-type .sortable-handle{display:none}.value{margin-bottom:6px}.value:last-of-type{margin-bottom:0}.value:last-of-type .remove-value{margin-bottom:0;box-shadow:none}.value.template{display:none}.inputs p.no-values{padding:12px;border-radius:3px;background-color:rgba(0,0,0,.04);line-height:24px}.inputs p.no-values:not(:only-child){display:none}.add-values{margin:6px 0 -3px}.add-values *{display:inline-block;min-width:36px;height:36px;border-radius:2px;text-align:center;margin:0}.inputs .add-values a.button{margin:0 0 3px}.inputs .add-values a.button:before{margin-right:.25em}.add-values label{background-color:rgba(0,0,0,.04);line-height:36px;margin-right:0;overflow:hidden;width:12px;vertical-align:top}.input-footer{display:flex;width:30px}.input-footer .actions{margin-left:6px;flex-direction:column}.input-footer .actions a:before{line-height:36px;height:36px;text-align:center}.more-actions ul{padding:0;display:none}.more-actions.active{box-shadow:0 0 0 1px #dfdfdf;background-color:#fff;border-radius:2px}.more-actions.active ul{display:block}.value.delete{background-color:#fcc;overflow:hidden}.value .restore-value,.value.delete a.tab,.value.delete [class*=o-icon-]:not(.restore-value){display:none}.value.delete .input-footer{background-color:transparent;width:100%}.value.delete .restore-value{display:inline-block}.value [class*=o-icon-].label{position:absolute;top:0;left:0;height:36px;width:36px;background-color:rgba(0,0,0,.04);text-align:center;line-height:36px;overflow:hidden}.value label,.add-values label{margin:0;min-height:0;line-height:24px}.block.value .inputs label{margin-right:24px}.add-values button,.add-values .button{line-height:24px}.inputs .value textarea,.inputs .value input[type=text]{width:100%;margin:0}.inputs .value textarea{min-height:72px;border:0;box-shadow:0 0 0 1px #dfdfdf}.inputs .value .input-body>textarea{padding:6px 12px}[data-data-type^=resource] .default,[data-data-type^=resource] .o-title:not(:empty){padding:6px;border-bottom:1px solid #dfdfdf;word-wrap:break-word;line-height:24px;display:flex}[data-data-type^=resource].delete .o-icon-undo:before{padding-right:0}.input-body{clear:both;background-color:#fff;flex:1;position:relative;box-shadow:0 0 0 1px inset #dfdfdf;max-width:calc(100% - 30px)}.value:not(:only-of-type) .input-body{max-width:calc(100% - 48px)}.inputs .input-body input[type=text]{margin:0;background-color:transparent}.inputs .input-body input[type=text]:focus,.inputs .input-body textarea:focus{z-index:10}.inputs .input-body .chosen-container{max-width:calc(100% - 12px);margin:6px}[data-data-type^=resource] .button{font-size:14px;padding:0 6px;line-height:24px;min-height:0;margin-right:3px}[data-data-type^=resource] .button:before{margin-right:6px}.value.delete span.restore-value{display:inline-block;padding:0 6px;width:calc(100% - 36px)}.value.delete>*:not(.input-footer){display:none}.sortable-handle~.input-body{background-color:transparent}.resource-inputs{background-color:#fff;box-shadow:0 0 0 1px #dfdfdf}p.selected-resource{position:relative;width:100%;margin:0}.selected-resource a{width:calc(100% - 72px)}.selected-resource+a.button{margin-left:6px}.selected-resource img{height:24px;margin-right:6px}.selected-resource .o-title a:after{font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;margin:0 6px}.selected-resource .items a:after{content:""}.selected-resource .item_sets a:after{content:""}.selected-resource .media a:after{content:""}[data-data-type=literal] .sortable-handle~.input-body{background-color:#fff}.inputs [data-data-type=literal] textarea.input-value{background-color:transparent;padding-right:42px}[data-data-type=uri] .input{position:relative;clear:both;background-color:#fff;box-shadow:0 0 0 1px #dfdfdf}[data-data-type=uri] .input:first-child{border-bottom:1px solid #dfdfdf}.value[data-data-type=uri] .input-body label{padding-right:0}.sidebar [data-data-type=uri] label{font-weight:inherit}[data-data-type=uri] .input-body input.uri-value,[data-data-type=uri] textarea.value-label{height:36px;border:0;box-shadow:none;padding:6px 42px 6px 6px;font-weight:normal;background:transparent;min-height:36px}[data-data-type=uri] textarea.value-label{border-top-width:0}.annotation-form{padding-bottom:12px}.annotation-form>div,.annotation-form>select{margin-bottom:6px}.value-annotation:not(:last-child){border-bottom:1px solid #dfdfdf;padding-bottom:12px;margin-bottom:12px}.value-annotation .restore-value{line-height:36px}#resource-files button{margin:24px 0 0}#add-media-field{margin-bottom:0}.media.row{padding:6px;margin-bottom:6px;display:flex;align-items:center;word-wrap:break-word}.media.row img{width:36px;height:auto;margin-right:12px}.media.row .resource-name{margin-right:12px;min-width:0}.media.row .primary-media{text-transform:uppercase;font-size:12px;font-weight:bold;margin:0 0 0 auto}.media.row .primary-media input{margin-left:6px}.media.row .actions{margin-left:24px}.media.value.delete span.restore-value{padding:0}.media.value.delete>*:not(.restore-value),.media.value.delete .actions a:not(.o-icon-undo){display:none}.media.value.delete>.actions{display:block;top:18px}.media-header{font-size:16px;margin:6px -6px;margin-top:-12px;background-color:rgba(0,0,0,.04);padding:0 6px;display:flex;align-items:center}.value.delete>.actions{display:inline-block}.media-render{margin-bottom:24px}.media-render>*{max-width:100%}.media-render img{max-width:100%;height:auto}#item-media .sidebar button{width:100%;text-align:left}#item-item-sets+.no-resources:before,#site-item-sets+.no-resources:before{content:""}#item-item-sets tr.delete{background-color:#fcc}#page-actions [class*=o-icon-].button{background-color:transparent;width:auto;padding:6px 6px;box-shadow:none}.o-icon-private.button,.o-icon-public.button{margin-right:6px;box-shadow:none}#item-sites.empty+.no-resources:before{content:""}.media.edit #media .cke_contents{min-height:500px}.search-nav{width:100%}.search-nav .resource-search{width:100%;position:relative;margin-bottom:6px;display:flex;flex-wrap:wrap}.search-nav .chosen-container{margin-bottom:6px}.search-nav button.o-icon-search{height:36px;width:36px;line-height:24px;padding:0 10px;border-radius:0 3px 3px 0;min-height:0;position:relative;text-indent:-9999px;margin:0}.search-nav button.o-icon-search:before{text-indent:0px;position:absolute;left:0;top:6px;line-height:24px;width:100%}.search-nav .resource-search>input[type=text]{width:calc(100% - 36px);border-right:0;margin-bottom:6px}.resource-search-filters{padding-bottom:5px;border-bottom:1px solid #dfdfdf;margin-bottom:6px;width:100%}.resource-search-filters a.expand:after,.resource-search-filters a.collapse:after{float:right}.resource-search-filters .collapsible{margin-top:6px;overflow:visible}.sidebar .pagination{font-size:13.08px;border-bottom:1px solid rgba(0,0,0,.08);padding-bottom:11px;margin-bottom:0;overflow:hidden;width:100%}.sidebar .pagination li{float:left}.sidebar .pagination li:first-of-type{padding-right:10px}.sidebar .pagination input{width:3em;text-align:center;color:#333;margin:0 3px}.sidebar .pagination .next.button{margin-right:5px}.sidebar .pagination input[type=text]{float:left;line-height:19.62px;height:24px;border:1px solid #dfdfdf;margin-left:0}.sidebar .pagination .page-count{float:left;margin-right:12px}.sidebar .pagination .inactive{background-color:#e6e6e6;color:#b9b9b9}.sidebar textarea{resize:vertical}#item-results+.confirm-panel,#item-results .select-resource-checkbox-wrapper{display:none}#item-results.active{padding-bottom:72px}#item-results.active+.confirm-panel{display:block}#item-results.active .select-resource-checkbox-wrapper{display:inline-flex;align-items:center}.sidebar button.select-all,.sidebar button.quick-select-toggle{background-color:transparent;color:#676767;box-shadow:none;margin:12px;padding:0;line-height:1;min-height:0}.success-statuses{position:absolute}.success-statuses .status,.sidebar button .sr-only{display:none}.sidebar button:not(.active) .sr-only.off,.sidebar button.active .sr-only.on,.success-statuses:not(.active) .sr-only.off,.success-statuses.active .sr-only.on{display:block}.sidebar button.select-all:before,.sidebar button.quick-select-toggle:before{font-family:"Font Awesome 5 Free";font-weight:900;content:"";display:inline-block;margin-right:6px}.sidebar button.quick-select-toggle.active:before{content:""}.sidebar button.select-all:before{content:"";font-weight:400}.sidebar button.select-all.active:before{content:""}.sidebar button.quick-select-toggle+.resource-list{border-top:1px solid #dfdfdf}.resource-link{display:inline-flex;align-items:center;max-width:100%;min-width:0}.resource-link img{height:36px;margin-right:6px}.resource-link .resource-name{flex:1;min-width:0}.resource-list{width:100%}.resource-list .resource{padding:6px 12px 5px;border-bottom:1px solid rgba(0,0,0,.08);position:relative;width:100%;overflow:hidden;display:flex;align-items:center;word-wrap:break-word}.resource-list .resource:hover{background-color:rgba(255,255,255,.8)}.resource-list .resource:hover .select{right:0px}.resource-list .resource .select-resource-checkbox-wrapper{height:24px;margin-right:12px}#resource-details{background-color:#fff;overflow:hidden;padding:0}#resource-details .o-description,#resource-details .property{margin-bottom:0}.confirm-main{position:absolute;top:0;bottom:60px;overflow-y:auto;left:0;right:0;padding:12px 12px 0}.confirm-panel{position:absolute;bottom:0;right:0;left:0;padding:12px;background-color:#f7f7f7;border-top:1px solid #dfdfdf}.confirm-panel button,.confirm-panel .button{width:100%;margin:0}.sidebar .field-meta{width:100%;position:relative;padding-right:36px;margin-bottom:12px;border-bottom:3px solid #dfdfdf}.sidebar .field-meta .label,.sidebar .field-meta label{margin:0;width:auto;display:inline-block;padding:0 0 6px}.sidebar .field-meta .label:after,.sidebar .field-meta label:after{content:none}.sidebar .field-meta .collapsible{margin-bottom:12px}.sidebar .field-meta button.add-value{padding:0;background:transparent;color:#676767;min-height:0;position:absolute;top:0;right:0}.sidebar .field-meta button.add-value:before{height:auto;line-height:1.5}.sidebar .inputs{width:100%}.sidebar #advanced-search .value{flex-wrap:wrap}.sidebar #advanced-search .value:not(:first-child){margin-top:6px}.sidebar .multi-value .value:not(:only-child){width:calc(100% - 36px);position:relative;padding-bottom:0;margin-bottom:5px;border-bottom:0}.sidebar .multi-value .value:only-child .remove-value{display:none}.sidebar .multi-value .remove-value{position:absolute;right:-36px;bottom:0}.sidebar #advanced-search .value select,.sidebar #advanced-search .value input{margin-left:0}.sidebar #advanced-search .confirm-panel{display:flex;justify-content:space-between}.sidebar #advanced-search .confirm-panel button{width:calc(33.33% - 6px)}.block .block-content input[type=hidden]+button{padding-top:6px}.query-form-element .active{display:block}.query-form-element .inactive{display:none}.query-display .search-filters{margin-bottom:0}.query-display .filter{background-color:#fff;box-shadow:0 0 0 1px #dfdfdf inset}.query-display .filter-label{background-color:#dfdfdf}.query-form-element button.active{display:inline-block}.query-display{min-height:42px}input[type=text].query-form-query{margin-top:0}.query-display .filter-value:not(:last-child):after{content:none}#save-search{display:none}#save-search.active{display:flex;margin-top:-6px;padding:0 6px 12px calc(30% + 3px);background-color:rgba(0,0,0,.04)}#save-search.active input{margin-left:6px}.vocabs .field [type=file]{margin:6px 0 0}.vocabulary ul{padding-left:0;list-style:none;overflow:hidden}.vocabulary h2{margin-bottom:0}.vocabs.update td{vertical-align:top}.vocabs.update td:first-of-type,.vocabs.update td:nth-of-type(2){width:15%;word-wrap:break-word}.vocabs.update td:nth-of-type(3),.vocabs.update td:nth-of-type(4){width:35%}.vocabs.update td:nth-of-type(3):last-child{width:auto}.vocabs.update td:nth-of-type(3):not(:last-child){background-color:#ffe6e6}.vocabs.update td:nth-of-type(4){background-color:#cdffcd}.show .property,.meta-group{overflow:hidden;display:flex;justify-content:flex-end;flex-wrap:wrap}.show .property dt,.meta-group dt{width:22.2222222222%;vertical-align:top;padding:6px 0;font-weight:bold}.show .property dd,.show .property .values,.meta-group dd,.meta-group .values{padding:6px;margin:0;word-wrap:break-word;width:77.7777777778%}.show .property dd:not(:first-of-type),.show .property .values:not(:first-of-type),.meta-group dd:not(:first-of-type),.meta-group .values:not(:first-of-type){padding-top:0}.show .property .language,.meta-group .language{font-size:12px;padding:0 6px;margin-right:6px;background-color:rgba(0,0,0,.04)}#linked-filter label{display:flex;align-items:center;margin-bottom:24px}#linked-filter label select{margin-left:12px}#linked-resources table{margin-bottom:24px}#linked-resources caption{background-color:rgba(0,0,0,.04);font-family:bold;padding:6px;font-family:"Lato",sans-serif;font-weight:bold;text-align:left;font-size:20px}#linked-resources th{border-bottom:3px solid #dfdfdf}.linked-resource{margin-bottom:12px;padding-bottom:11px;border-bottom:1px solid #dfdfdf}.has-annotation:before{display:inline-block}.o-icon-annotation:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900}.show .value.resource,.show .value.resource .value-content{display:flex;flex-wrap:wrap;align-items:center}.show .value .o-icon-private,.show .value .value-content{margin-right:12px}.collapsible.annotation{border-left:3px solid #dfdfdf;padding:0;border-radius:3px;margin:6px 0 12px 24px;width:100%}.collapsible.annotation h4,.collapsible.annotation .values{width:100%;padding:0}.collapsible.annotation .property{padding:0 12px}.collapsible.annotation .property:not(:first-child){margin-top:12px;border-top:1px solid #dfdfdf;padding-top:12px}.property .value .resource-name:after,.property .value.uri .uri-value-link:after{font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;margin-left:.5em}.property .value.uri .uri-value-link:after{content:""}.property .value.items .resource-name:after{content:""}.property .value.media .resource-name:after{content:""}.property .value.item_sets .resource-name:after{content:""}.class-row{border-bottom:1px solid #dfdfdf;padding-bottom:11px}.class-label{font-weight:bold}.class-label:after{content:": "}.sidebar{position:fixed;top:48px;left:100%;visibility:hidden;bottom:0;background-color:#f7f7f7;z-index:3;border-left:1px solid #dfdfdf;overflow-y:auto;overflow-x:hidden;width:25%;padding:12px}body.transitions-enabled .sidebar{transition:left .5s,visibility .5s}.sidebar.active,.sidebar.always-open{left:75%;visibility:visible}.sidebar.loading{overflow:hidden}.sidebar.loading *{visibility:hidden}.sidebar.loading:after{font-family:"Font Awesome 5 Free";font-weight:900;content:"";line-height:1;position:absolute;top:.75em;left:calc(50% - .5em);font-size:4em;animation:fa-spin 1s infinite linear;height:1em;width:1em;text-align:center}.sidebar a.o-icon-close{position:absolute;right:12px;top:12px;z-index:3;color:#666}.sidebar .vocabulary,.sidebar .meta-group{margin-bottom:0}.sidebar .value{margin-bottom:6px;border-bottom:1px solid #dfdfdf;padding-bottom:5px;vertical-align:middle}.sidebar .value *:last-child{margin-bottom:0}.sidebar .value:last-child{border-color:transparent;margin-bottom:0}.sidebar input,.sidebar textarea,.sidebar select{width:100%}.sidebar input[type=checkbox],.sidebar input[type=radio]{width:auto}.sidebar h2{font-size:24px;margin-bottom:12px}.sidebar h3,.sidebar label,.sidebar .label{display:block;font-size:16px;font-weight:bold;margin:0 0 12px 0;padding:0 24px 12px 0;position:relative;width:100%;word-wrap:break-word;max-width:none}.sidebar h3:after,.sidebar label:after,.sidebar .label:after{content:"";position:absolute;left:-12px;right:-12px;bottom:0;top:-12px;background-color:#dfdfdf;z-index:-1}.sidebar .field{background-color:transparent;padding:0;margin-bottom:24px;flex-wrap:wrap;justify-content:flex-start}.sidebar .field .option{width:100%}.sidebar .field div.option+div.option{padding-top:11px;border-top:1px solid #dfdfdf;margin-top:12px}.sidebar .button,.sidebar button{background-color:#676767;border-color:#676767;color:#fff}.sidebar .button:disabled,.sidebar .button.disabled,.sidebar button:disabled,.sidebar button.disabled{background-color:rgba(0,0,0,.04);border-color:rgba(0,0,0,.04);color:#676767;box-shadow:none !important}.sidebar button.option{width:100%;text-align:left;border-color:#dfdfdf;background-color:#fff;color:#676767;display:inline-flex;justify-content:space-between}.sidebar button.option:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;color:#dfdfdf}#sidebar-confirm{display:block;padding-bottom:12px;margin-bottom:12px}#sidebar-confirm input[type=submit]{background-color:#a91919;color:#fff;box-shadow:none}body.sidebar-open #content{width:56.25%}.sidebar .meta-group{margin-bottom:12px}.sidebar .meta-group .value{width:100%;padding:6px 0;margin:0;word-wrap:break-word;display:block}.sidebar .meta-group .value:not(:last-child){border-bottom:1px solid #dfdfdf;padding-bottom:5px}.sidebar .meta-group h4{display:block;background-color:transparent;border-color:#dfdfdf;padding:6px 0;border-bottom:2px solid #dfdfdf;padding-bottom:4px;margin-bottom:0;width:100%}.sidebar .media a:first-child img,.sidebar>img:first-child{height:168px;width:auto;display:block;margin-bottom:12px}.sidebar .meta-group img{height:48px;box-shadow:0 0 0 1px #dfdfdf}.source-type{font-weight:bold}.resource-templates #properties{list-style:none;padding-left:0;margin-left:0}.resource-templates table{width:100%}.resource-templates th,.resource-templates td{padding:6px;vertical-align:top}.resource-templates .property.row{display:flex}.resource-templates .property.row.delete{background-color:#fcc}.resource-templates .property.row.delete .actions li:not(:last-child){display:none}.resource-templates .property.row:not(.delete) .sortable-handle{display:inline-flex}.resource-templates #properties{margin:24px 0 0;clear:both;padding:0}.resource-templates #edit-sidebar{padding-bottom:48px}.resource-templates #edit-sidebar .field h4,.resource-templates #edit-sidebar .field h4+span{width:100%}.resource-templates #edit-sidebar .field h4+span{margin-bottom:12px}.resource-templates #edit-sidebar .field label:not(:first-child),.resource-templates #edit-sidebar .field .option label{margin:0;padding-bottom:6px;padding-right:0;display:flex;justify-content:space-between}.resource-templates #edit-sidebar .field label:not(:first-child):only-child,.resource-templates #edit-sidebar .field .option label:only-child{padding-bottom:0}.resource-templates #edit-sidebar .field label:not(:first-child):after,.resource-templates #edit-sidebar .field .option label:after{padding:0;margin:0;background:transparent}.alternate-label-cell:not(:empty){background-color:#dfdfdf;display:inline-block;padding:0 6px;margin:0 6px;position:relative}.alternate-label-cell:not(:empty):after{content:"";border-top:12px solid transparent;border-bottom:12px solid transparent;border-left:6px solid #dfdfdf;width:0;height:0;position:absolute;left:100%;top:0}.title-property-cell,.description-property-cell{text-transform:uppercase;font-size:12px;font-weight:bold;margin-left:auto;margin-right:12px}.title-property-cell:after,.description-property-cell:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;margin-left:6px}.title-property-cell~.actions,.description-property-cell~.actions{margin-left:0}.title-property-cell~.description-property-cell,.description-property-cell~.title-property-cell{margin-left:12px}#modules.installed tbody tr:not(.installed),#modules.uninstalled tbody tr:not(.uninstalled),#modules.needs-upgrade tbody tr:not(.needs-upgrade),#modules.active tbody tr:not(.active),#modules.deactivated tbody tr:not(.deactivated){display:none}.state-filter select{margin-bottom:12px}.module-name{font-weight:bold}.module-author{display:block}#modules .module{border-bottom:1px solid #dfdfdf;padding-bottom:11px;margin-bottom:12px;overflow:hidden}#modules .module-meta{float:left;max-width:50%}#modules .module-actions{float:right;max-width:50%;text-align:right}#modules .module form{display:inline-block}#modules button,#modules .button{display:inline-block;margin-left:6px;box-shadow:0 0 0 1px rgba(0,0,0,.15) inset}#modules button:hover,#modules .button:hover{box-shadow:0 0 0 1px rgba(0,0,0,.3) inset}#modules button:before,#modules .button:before{margin-right:6px}#modules .o-icon-install{box-shadow:0 0 0 1px #addead inset}#modules .o-icon-install:hover{box-shadow:0 0 0 1px #63c363 inset}#modules .o-icon-uninstall{margin-left:24px;box-shadow:0 0 0 1px #e0c3c3 inset}#modules .o-icon-uninstall:hover{box-shadow:0 0 0 1px #da8b8b inset}#edit-keys td{word-wrap:break-word}.api-delete{width:10%}.api-label{width:25%}#system-info-table .label-col{width:25%}#system-info-table th,#system-info-table td{font-size:.875em;padding:0;line-height:1.75;border:none;vertical-align:top}#system-info-table th[scope=rowgroup]{font-size:1em;border-bottom:1px solid #dfdfdf;padding-left:6px}#system-info-table tbody:not(:last-child) tr:last-child td{padding-bottom:24px}#system-info-table th[scope=row]{padding-left:1.5em}.breadcrumbs{border-bottom:1px solid #dfdfdf;padding-bottom:11px;margin-bottom:24px}.breadcrumbs+.field{margin-top:24px}.breadcrumbs a:before{margin-right:6px}.breadcrumbs>*:not(:last-child):after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;margin:0 calc(12px - 3px) 0 12px;color:#000;cursor:default}#site-item-sets th:first-child,#site-item-sets th:last-child{width:36px}.manual-assignment .inputs label{display:block;padding:0;margin:6px 0 0;min-height:0;line-height:24px}.manual-assignment .inputs label:last-child{margin-bottom:6px}.manual-assignment #advanced-search{margin-top:-6px;padding:12px 0 6px;background-color:rgba(0,0,0,.04);border-top:1px solid #dfdfdf}.manual-assignment #advanced-search.inactive{display:none}.manual-assignment .advanced-search-header{padding:0 6px}.manual-assignment .advanced-search-header a.button{margin-bottom:6px}.manual-assignment .advanced-search-content .field{background-color:transparent}.keep-search,.keep-search input{margin:0 0 0 6px}tr.value.delete>td:not(.input-footer){display:table-cell}tr.value.delete .user-name,tr.value.delete select,tr.value.delete .o-icon-delete{display:none}td.user-meta{width:50%}#site-user-permissions.empty+.no-resources:before{content:""}#site-user-permissions .actions{justify-content:flex-end;padding:6px 0}.indent:before{content:"—";margin-right:-1px}.expand-collapse-all{margin-top:12px;text-align:right}.block{margin-bottom:6px}.block .block-header{position:relative;display:flex;align-items:center;background-color:rgba(0,0,0,.12);padding:6px;font-weight:bold}.block .block-header .actions a:before{text-align:center}.block .block-content input[type=hidden]+*{padding-top:0;margin-top:0}.block.html>div{border:1px solid #dfdfdf}.block .field{padding:0;border-color:transparent;background-color:transparent;margin-top:6px}.block .field:last-child{margin-bottom:0}.block.delete>.block-header{font-weight:normal;display:flex;background:transparent}.block.delete>*:not(.block-header){display:none}.block.delete span.restore-value{padding:0 3px;text-transform:lowercase;width:auto}.block.delete a.restore-value:before{padding:0}.block.delete .sortable-handle{display:none}.delete .block-type,.block .delete div.item-title{margin-left:30px}.delete .block-type{font-weight:bold}.block div.item-title{margin:6px 0;display:flex;align-items:center}.block .item-title img{height:36px;width:auto;display:inline-block;margin-right:6px;vertical-align:top}.block .delete.attachment{background-color:#fcc}.block .delete.attachment .actions .undo{display:inline-block}.block .delete.attachment .sortable-handle,.block .delete.attachment .actions li:not(.undo){display:none}.block .attachments-form{margin-bottom:12px}.block .attachments-form a h4{display:inline-block}.block .attachment .actions{margin-left:auto}.block .attachment .actions .button{background-color:transparent;color:#a91919;padding:0;min-height:0}.block .attachment .actions .button:hover{color:#a91919}.block .attachment .actions .undo{display:none}.block .block-content{clear:both;background-color:rgba(0,0,0,.04);padding:6px}.block.sortable-ghost .block-content{display:none}.block-content fieldset:last-of-type{margin-bottom:0}.block .attachment{display:flex;align-items:center;position:relative;padding:0 6px}.block .attachment:not(:last-child){border-bottom:1px solid #dfdfdf;padding-bottom:-1px}.block .attachment .button{margin-bottom:0}.block .attachment-add{margin:6px 0 0}.block-header.collapse:after{content:none}.block-content .expand,.block-content .collapse{width:100%;display:flex;padding:0 6px 0 0;justify-content:space-between}.block .field-meta .collapse+.collapsible{width:auto;border:0}.block .expand h4,.block .collapse h4{display:inline-block;padding:0}.block-content .collapse+.collapsible{border-top:1px solid #dfdfdf;padding:-1px 0 0 24px;margin-top:6px}.block[data-block-layout=html] [contenteditable=true]{resize:vertical;min-height:72px;max-height:288px}#attachment-options .option{position:relative;margin-bottom:12px}#attachment-options .expand,#attachment-options .collapse{position:absolute;right:0;top:0}#attachment-options h3{overflow:visible;white-space:normal}#attachment-item-select{display:block;margin:12px 0 0}#attachment-options .selected-attachment{margin-bottom:12px;margin-top:-12px;box-sizing:content-box;margin-right:-12px;margin-left:-12px;padding-right:12px;padding-left:12px;padding-top:12px;padding-bottom:12px;overflow:hidden}#attachment-options .selected-attachment img{height:96px;width:auto;float:right;margin:0 0 0 12px}#attachment-options .selected-attachment p:first-child{margin:0}#attachment-options h3.item-title{text-align:left}#attachment-options .item-thumbnail~h3.item-title{width:100%}#attachment-options .media-title{font-size:12px;display:block;width:calc(100% - 108px);float:left;word-wrap:break-word;text-align:left;clear:left}#attachment-options .item-thumbnail~#attachment-item-select{font-size:12px;display:inline-block;width:calc(100% - 108px);word-wrap:break-word}#attachment-options h3{word-wrap:break-word}#attachment-options .media-list{list-style:none;padding:0;margin:0 0 12px}#attachment-options .media-list li.media{position:relative;height:48px;width:48px;cursor:pointer;display:inline-block;padding:3px;border:1px solid #dfdfdf}#attachment-options .media-list li.media.attached,#attachment-options .media-list li.media:hover{background-color:rgba(0,0,0,.04)}#attachment-options .media-list img{width:100%;height:auto}#asset-options .selected-asset{overflow:hidden}#asset-options .selected-asset-image{float:left;margin:0 12px 0 0;max-width:50%}#asset-list.active{z-index:6}#asset-options .selected-asset .selected-asset-name{display:none}.asset-attachments-form{margin-bottom:12px}.add-asset-attachment{margin-top:6px}#asset-options .sidebar-content>div{margin-bottom:2rem}.asset-attachment-select{margin-top:.5rem}.asset-title{display:flex;align-items:center}.asset-title img{height:100%;width:auto}.asset-title .thumbnail:not(:empty){height:2rem;position:relative;width:2rem;margin:.25rem .25rem .25rem 0;overflow:hidden;display:inline-flex;justify-content:center}#asset-options .none-selected.inactive{display:none}#asset-options .none-selected:not(.inactive)~*{display:none}#asset-options .page-status{margin-bottom:12px}#asset-options .selected-page+.o-icon-external{margin-left:6px}.browse-defualts-form-element{display:flex;justify-content:space-between}.browse-defualts-form-element select{width:49.5%}input[type=text].page-selector-filter{width:100%;margin-bottom:12px}#nav-page-links,#nav-custom-links{width:100%}.page-selector-filter.empty,#nav-page-links .nav-page-link,#nav-page-links .added.active.nav-page-link,#no-pages{display:none}#nav-page-links .active.nav-page-link{display:flex}.empty~#no-pages{display:block}.site-page-add{margin:0}.jstree>.jstree-node:first-child .jstree-anchor{margin-top:0}.block-pagelist-tree li:last-child{margin-bottom:6px}.selectable-themes,.current-theme{display:flex;flex-wrap:wrap}.selectable-themes img,.current-theme img{max-width:100%;height:auto;vertical-align:bottom;position:relative;z-index:1}.selectable-themes .error,.current-theme .error{background-color:#f4b4b4;border-radius:3px;padding:6px 10px;margin:6px 0;display:block;width:100%;order:2}.theme-thumbnail{align-self:flex-start}.current-theme .error+ul{font-family:monospace;padding:11px;border:1px solid #dfdfdf;list-style-type:none}.invalid .theme-thumbnail img{opacity:.5}.selectable-themes .theme{width:calc(33.33% - 24px);margin:0 24px 24px 0;padding:11px;border:1px solid #dfdfdf;background-color:#fff;display:flex;flex-wrap:wrap}.selectable-themes .theme:hover{border:3px solid #9f9f9f;padding:9px}.selectable-themes .invalid.theme:hover{border:1px solid #dfdfdf;padding:11px}.selectable-themes .theme-thumbnail{width:100%;margin-bottom:12px;border:1px solid #dfdfdf}.selectable-themes .active.theme{background-color:#e7e7e7;position:relative;overflow:hidden;border-width:3px;padding:9px}.selectable-themes .active.theme:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;position:absolute;bottom:0;right:0;opacity:.15;font-size:96px;line-height:96px}.current-theme{padding-bottom:23px;border-bottom:1px solid #dfdfdf;margin-bottom:24px;flex-wrap:nowrap}.current-theme .theme-thumbnail{width:50%;margin:0 24px 0 0;border:1px solid #dfdfdf}.current-theme .current-theme-info{width:calc(50% - 24px)}.current-theme-label{font-size:16px;text-transform:uppercase;display:block;margin-bottom:6px}.theme-meta{display:flex;flex-direction:column;width:100%}.theme-resource-pages .blocks{list-style:none;padding-left:0;border:1px solid #dfdfdf;padding:12px;min-height:30px}.theme-resource-pages .block{width:100%;background-color:rgba(0,0,0,.04);padding:6px;position:relative;margin-bottom:6px;display:flex;height:36px}.theme-resource-pages .block.delete{background-color:#fcc;padding-left:36px}.theme-resource-pages .block.delete>*:not(.block-header){display:block}.theme-resource-pages .block.delete .sortable-handle{display:none}.theme-resource-pages button:disabled{display:none}.jobs.browse th:first-child,.jobs.browse td:first-child{width:10%}body.minimal{padding:0;margin:48px 0;width:93.75%;max-width:100%;margin-left:auto;margin-right:auto;height:auto;background-color:#404e61}body.minimal:after{content:" ";display:block;clear:both}body.minimal div[role=main]>h1:first-of-type{position:static;padding:0;width:100%;height:auto;display:inline-block;margin:0 0 24px 0}body.minimal h2{font-size:20px;margin-bottom:12px}body.minimal h3{font-size:18px;margin-bottom:12px}body.minimal fieldset legend{font-weight:bold;font-size:20px;margin-bottom:12px}body.minimal .logo{position:static;width:auto;float:none;padding:0;text-align:center;font-size:32px;line-height:48px}body.minimal div[role=main]{width:100%;min-height:0;margin:0;padding:48px 6.25%;overflow:hidden}body.minimal .inputs{width:70%}body.minimal .inputs input{width:calc(66.66% - 6px);vertical-align:top}body.minimal .inputs *:only-child{width:100%}body.minimal [type=submit]{width:100%;display:block;margin:auto;clear:both}body.minimal .field:last-child{margin-bottom:0}body.minimal .site-list{margin-bottom:24px;display:flex;flex-wrap:wrap}body.minimal .site-list .site{margin-bottom:12px;overflow:auto;max-width:60rem;width:50%;padding-right:1rem}body.minimal .site-list .site-link{display:inline-block;font-size:18px}body.minimal .site-list .site-summary{margin:0;line-height:20px}body.minimal .site-list .site-thumbnail{float:left;display:block;margin-right:1rem}body.minimal .site-list .site-thumbnail-image{max-width:15rem;vertical-align:bottom}body.minimal .results{margin-bottom:24px}body.minimal .results>ul{padding-left:0}body.minimal .results>ul>li{list-style-type:none}body.minimal .advanced-search{margin:-12px 0 24px;display:block}body.minimal .advanced-search-actions{margin:12px 0}body.minimal .advanced-search-actions input[type=submit]{width:auto;display:inline-block}.forgot-password{margin:6px 0}.sitewide-search-form{display:flex;margin-bottom:24px}.sitewide-search-form input[type=text]{min-width:60%;margin-right:6px}.sitewide-search-form input[type=submit]{width:auto;margin:0}body.minimal .site.results thead{background-color:rgba(0,0,0,.04)}.results>ul{display:flex;flex-wrap:wrap;align-items:flex-start;margin-bottom:0}.results>ul>li{border:1px solid #dfdfdf;border-radius:3px;padding:6px 6px 0;margin-bottom:12px;width:calc(50% - 12px)}.results>ul>li:nth-child(2n){margin-left:12px}.results ul ul{list-style:none;padding:0;margin-top:6px}.results li li{padding:6px;border-top:1px solid #dfdfdf;margin:0px -6px}.results .result-title{background-color:rgba(0,0,0,.04);display:block;padding:6px;margin:-6px;font-weight:bold}.results+.pagination{margin-top:-24px}.site.results .result-title{border-bottom:1px solid #dfdfdf;margin-bottom:6px}.site.results .result-site{margin-bottom:6px;display:block}.asset-form-element{line-height:36px}.asset-form-element.empty .asset-form-clear{display:none}.asset-form-element:not(.empty) .no-selected-asset{display:none}.selected-asset,.no-selected-asset{display:block}.selected-asset-name:not(:empty)~.none-selected,.selected-page:empty+a,.selected-page:not(:empty)~.none-selected{display:none}.selected-asset-image{max-width:100%}.asset-form-select{margin-top:12px}.new.attachment{display:none}.asset-upload{overflow:hidden;margin-bottom:24px}.asset-upload button{margin:6px 0 0;display:none}.asset-upload button.active{display:inline-block}.asset-upload ul.errors{color:#a91919;margin-top:0;word-wrap:break-word}.asset-upload ul.errors:empty{display:none}.asset-upload ul.errors a{border-bottom:1px solid #a91919}.asset-upload label{margin:6px 0;padding:0}.asset-upload label:after{content:none}.asset-upload input[type=file]{width:100%}.asset-filters{margin-bottom:6px}.asset-list .asset{padding-bottom:5px;border-bottom:1px solid #dfdfdf;margin-bottom:6px}.asset-list .asset:last-child{border-bottom-color:transparent}.asset-entry{display:flex;align-items:center;word-wrap:break-word}.asset-entry img{margin-right:6px;max-height:48px;max-width:50%}.asset-entry .asset-name{flex-grow:1}.color-picker{display:flex}.color-picker input[type=text]{margin:0}.color-picker .color-picker-sample{border:1px solid #dfdfdf;width:30%;margin-left:6px}}@media screen and (max-width: 640px){script{display:none !important}body{padding:0}.mobile-only{display:block}button.mobile-only{width:100%}header{width:100%;float:none;text-align:center;position:fixed;top:0;left:0;padding:0;right:0;z-index:1000;min-height:0}header .button{border-radius:0px;position:absolute;top:0;z-index:1001;color:#fff;background-color:#222933;box-shadow:none}header .o-icon-menu.button{left:0;border-right:1px solid rgba(0,0,0,.08);width:36px}header .o-icon-search.button{left:36px}header .o-icon-user.button{right:0}header nav ul.navigation>li:not(:first-of-type){margin-top:0}.logo{line-height:36px;padding:0 16.6666666667%;width:100%;text-align:center;display:block;background-color:#404e61}#user,#search,header nav{position:fixed;top:-9999px;left:-9999px;z-index:1000}header nav#site-nav{position:static;background-color:#fff;padding:0;margin-bottom:0}header nav#site-nav h5{border-top:1px solid #dfdfdf;padding-top:6px -1px;margin-bottom:0}header nav#site-nav h5 a{padding:0;border-bottom:0}#menu.active,#user.active,#search.active{top:36px;left:0;bottom:0;right:0;background-color:#fff;margin:0}footer{margin:0;padding:0;position:static;width:100%;text-align:center}footer:after{position:static;background:transparent}.browse td:first-child,.browse th:first-child{width:100%}td .o-icon-private,td .o-icon-user-inactive{vertical-align:top;margin:0}div[role=main]{margin:36px 0 0 0;width:100%;min-height:calc(100% - 72px);position:relative;padding-top:48px}div[role=main]>h1:first-of-type{width:auto;position:static;padding:12px 1.0416666667%;height:auto;margin:0 -1.0416666667% 12px;white-space:normal;line-height:36px}#menu{text-align:left;background-color:#fff;position:fixed;overflow:scroll}#menu ul{margin-bottom:0;border-bottom:0;padding-bottom:0}#menu a{display:block;padding:6px 12px 5px;color:#676767;border-bottom:1px solid #dfdfdf}#menu li:last-child a{border-bottom:0;padding-bottom:6px}#menu h5 a{padding:0;border-bottom:0}#menu h5{height:36px;color:#676767;background-color:rgba(0,0,0,.04);padding:6px 12px 5px;border:1px solid #dfdfdf;border-width:1px 0}#menu h4{background-color:rgba(0,0,0,.12);margin-bottom:0}#menu h4:not(:first-of-type){margin-top:0}#menu a.public,#menu a.expand,#menu a.collapse{height:36px;margin:-36px 0 0;padding:0 12px 0 0}#menu a.public:before,#menu a.public:after,#menu a.expand:before,#menu a.expand:after,#menu a.collapse:before,#menu a.collapse:after{height:36px;line-height:36px}#mobile-nav{display:block}#mobile-nav a.active{background-color:#500c0c}#user{text-align:center}#user .user-id{color:#676767;width:100%;margin:0 6px 24px}#user .user-id a{color:#a91919}#user .logout{display:block;margin:12px 6px;font-size:16px;color:#676767;border-radius:3px;width:calc(100% - 12px);min-height:36px;background-color:rgba(0,0,0,.08);border-radius:3px;border:0;box-shadow:0 0 0 1px rgba(0,0,0,.15) inset;padding:6px 10px;display:inline-block;text-align:center;cursor:pointer;margin:0 6px}#user .logout:last-of-type:before{content:""}#user .logout a{color:#676767}#page-actions{top:36px;background-color:#fff;width:100%;border-bottom:1px solid rgba(0,0,0,.08);height:48px;padding-bottom:5px}#sidebar{position:fixed;top:36px;z-index:100;width:100%}#sidebar #content.sidebar-open{left:0}body.sidebar-open #content{width:100%}.sidebar{width:100%;top:36px;z-index:1000}.sidebar.always-open{left:100%}.sidebar.active,.confirm-panel{left:0;width:100%}fieldset.section>.always.active{content:"";bottom:0;left:0;right:0;height:48px;background-color:#fff;position:fixed;border-top:1px solid rgba(0,0,0,.04)}fieldset.section>.always.active button{width:100%;margin:6px}#modules .module-meta,#modules .module-actions{width:100%;max-width:100%}#modules .module-meta{margin-bottom:12px}#modules .module-actions{text-align:left}#modules button,#modules .button{margin:0 6px 0 0}.vocabs.update td{width:100% !important}#search-form{margin:48px 4.1666666667%}.batch-edit.button{margin:0;border-radius:0px;position:relative;z-index:1}.browse table{position:relative}.browse .sorting{float:left}.browse .pagination{margin-right:48px}.jobs.browse th:first-child,.jobs.browse td:first-child{width:100%}fieldset.section,fieldset.section{margin-bottom:0;position:relative}fieldset.section>legend:first-child{position:relative;left:auto;display:block;width:100%;font-size:20px;padding:6px 9px 6px 0;color:#a91919;cursor:pointer;border-bottom:3px solid rgba(0,0,0,.08);padding-bottom:-3px;margin-bottom:12px}fieldset.section>legend:after{content:"";font-family:"Font Awesome 5 Free";position:absolute;right:9px;top:12px}fieldset.section.mobile-active>legend:after{content:""}.add .active.section>.button,.edit .active.section>.button{display:inline-block}.field-meta,.inputs{width:100%}.field-actions{position:absolute;top:9px;right:1.6666666667%;z-index:1;width:50%}.field-actions a{float:right;display:block}.field-actions a.button{margin-left:.5em !important}.field-meta label,.field-description p{line-height:24px;margin-bottom:6px}.field-meta label{font-weight:bold}.unset .field-meta{width:100%}.show .sidebar.active{position:static;border:1px solid #dfdfdf;padding:11px;margin-top:24px}.show .section .property,.show .section .meta-group{margin-bottom:6px;box-shadow:0 0 0 1px #dfdfdf;border-radius:2px}.show .section .meta-group h4,.show .section .property h4{padding-bottom:6px;border-bottom:1px solid #dfdfdf;background-color:rgba(0,0,0,.04)}.show .section .meta-group h4,.show .section .meta-group .value,.show .section .property h4,.show .section .property .values{width:100% !important;padding:6px !important}.show .section .meta-group .value:not(:first-of-type),.show .section .property .value:not(:first-of-type){border-top:1px solid #dfdfdf;padding-top:6px -1px;margin-top:6px}.show .sidebar .meta-group .value:not(:first-of-type),.show .sidebar .property .value:not(:first-of-type){padding-top:6px}body.minimal{width:100%;margin:0}body.minimal .logo{background-color:transparent}body.minimal div[role=main]{padding:24px 6.25%}body.minimal div[role=main]>.messages{margin-top:24px}body.minimal .inputs{width:100%;margin-left:0}body.minimal footer{color:#fff}.tablesaw tr{overflow:hidden;margin-bottom:0}.tablesaw tr:first-of-type{border-top:1px solid #dfdfdf}.browse td:not(:first-of-type) .tablesaw-cell-content,#properties td:not(:first-of-type) .tablesaw-cell-content{display:inline-block}.tablesaw td:first-of-type{background-color:rgba(0,0,0,.04)}.tablesaw td:first-of-type .tablesaw-cell-label{width:0;height:0;overflow:hidden;padding:0;display:block}.tablesaw td:first-of-type .tablesaw-cell-content{width:100%;max-width:100%}.batch-edit.tablesaw td:first-of-type{width:100%;background:rgba(0,0,0,.04)}.batch-edit.tablesaw td:first-of-type img{margin-bottom:0}.batch-edit.tablesaw td:first-of-type .tablesaw-cell-label{width:0;overflow:hidden;padding:0}.batch-edit .tablesaw-cell-content{display:inline-flex}.tablesaw-cell-content{width:70%;max-width:70%}.tablesaw-cell-content img{margin:0 6px 0 0}.tablesaw tr:last-of-type td,.tablesaw tr:last-of-type th,.tablesaw th,.tablesaw td{padding-top:6px;padding-bottom:6px;vertical-align:top}.tablesaw th:not(:last-of-type),.tablesaw td:not(:last-of-type){border-bottom:1px solid #dfdfdf}.tablesaw tr.delete{border:0}.tablesaw tr.delete td{border:0}.tablesaw tr.delete td:not(:first-of-type){display:none}.resource-template th:first-of-type,.resource-template td:first-of-type{width:100%}#site-user-permissions tr.user.value{position:relative}#site-user-permissions td:nth-child(3){position:absolute;top:0;right:0;padding:0 6px 0 0}#site-user-permissions td:nth-child(3) .tablesaw-cell-label{display:none}#site-user-permissions td:nth-child(3) .tablesaw-cell-content{width:100%;max-width:100%}#site-user-permissions.tablesaw-stack tbody tr{border-bottom:0}} \ No newline at end of file +/*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}@media screen{*{box-sizing:border-box}em,i{font-style:italic}strong,b{font-weight:bold}a{text-decoration:none}a:link,a:visited{color:#a91919}a:active,a:hover{color:#e34545}h1,h2,h3,h4,h5,h6{margin:0}h3,h4,h5,h6{font-weight:bold}h1{font-size:32px;line-height:48px;margin-bottom:24px}h2{font-size:30px;line-height:36px;margin-bottom:24px}h3{font-size:24px;margin-bottom:24px}h5{font-size:14px}p{margin:24px 0}ul{padding-left:24px;list-style:disc}pre{max-width:100%;overflow-x:auto}html,body{height:100%}body{font-family:"Lato",sans-serif;font-size:16px;line-height:24px;color:#676767;overflow-x:hidden}table{width:100%;border-spacing:0;table-layout:fixed}th,table.tablesaw th{font-weight:bold;text-align:left;padding:6px .5em}table,table.tablesaw{margin-bottom:12px;border:1px solid #dfdfdf;border-radius:3px;border-collapse:separate}.tablesaw tr:not(:last-child) td{border-bottom:1px solid #dfdfdf}tr.delete{background-color:#fcc}td,table.tablesaw td{padding:6px .5em 5px;position:relative;vertical-align:middle}table.tablesaw td:first-child a{word-wrap:break-word}table.tablesaw thead tr:first-child th{padding-top:6px;padding-bottom:5px;border-bottom:1px solid #dfdfdf}legend{font-size:20px;padding:12px 0;font-weight:bold}[contenteditable=true],textarea{clear:both;padding:6px;border:1px solid rgba(0,0,0,.15);display:block;background-color:#fff;min-height:72px;overflow-y:auto}[contenteditable=true] p{margin:12px 0}.cke_dialog_body textarea{max-height:none}input,[contenteditable=true],textarea,button,select{font-family:"Lato",sans-serif;font-size:16px;line-height:24px;margin:0;color:#676767}input[type=text],input[type=password],input[type=email],input[type=url],input[type=number],input[type=date],input[type=datetime-local]{-webkit-appearance:none;appearance:none;border-radius:0;height:36px;border:1px solid rgba(0,0,0,.15);padding:6px;margin:0}:disabled{background-color:rgba(0,0,0,.04);box-shadow:0 0 0 1px rgba(0,0,0,.15) inset;color:#a7a7a7;-webkit-text-fill-color:#a7a7a7;cursor:default}:disabled:hover{box-shadow:0 0 0 1px rgba(0,0,0,.15) inset !important}::placeholder{font-style:italic}[contenteditable=true]>*:first-child{margin-top:0}[contenteditable=true]>*:last-child{margin-bottom:0}input[type=submit],button,a.button,.button{min-height:36px;background-color:rgba(0,0,0,.08);color:#676767;border-radius:3px;border:0;box-shadow:0 0 0 1px rgba(0,0,0,.15) inset;padding:6px 10px;display:inline-block;text-align:center;cursor:pointer;margin:0 0 12px 0}input[type=submit]:hover:not(.inactive),button:hover:not(.inactive),a.button:hover:not(.inactive),.button:hover:not(.inactive){box-shadow:0 0 0 1px rgba(0,0,0,.3) inset}input[type=submit].inactive,button.inactive,a.button.inactive,.button.inactive{box-shadow:none;background-color:#d2d2d2;cursor:default;border:0}.red.button{background-color:#fdefef;box-shadow:0 0 0 1px #e0c3c3 inset;color:#a91919}.red.button:hover{box-shadow:0 0 0 1px #da8b8b inset}.green.button{background-color:#cdffcd;color:green;box-shadow:0 0 0 1px #addead inset}.green.button:hover{box-shadow:0 0 0 1px #63c363 inset}.required .field-meta{position:relative;padding-right:36px}.required .field-meta:after{font-family:"Font Awesome 5 Free";font-weight:900;content:"";font-size:12px;position:absolute;right:12px;color:#a91919;top:6px}label input[type=checkbox]{display:inline-block;width:auto}label.required:after{font-family:"Font Awesome 5 Free";font-weight:900;content:"";font-size:12px;color:#a91919;float:right;padding-right:12px}.touched:invalid{box-shadow:0 0 2px 2px #a91919}.field{width:100%;background-color:rgba(0,0,0,.04);padding:6px;position:relative;margin-bottom:6px;display:flex;flex-wrap:wrap}.field:first-child{border-color:transparent}.media-field-wrapper{width:100%;padding:12px 6px;margin-bottom:6px;background-color:rgba(0,0,0,.04);position:relative}.media-field-wrapper .field{width:100%;margin:0 0 6px;padding:0;background-color:transparent}.media-field-wrapper .field:last-of-type{margin-bottom:0}.media-field-wrapper .field:last-of-type .field-meta,.media-field-wrapper .field:last-of-type .inputs{margin-bottom:-6px}.media-field-wrapper .actions{font-size:16px;padding:6px 0}select{background:#fff url("../img/select-arrow.svg") no-repeat;background-position:right 6px center;background-size:8px;border:1px solid #dfdfdf;height:36px;line-height:36px;font-size:16px;margin:0;padding:0 24px 0 6px;border-radius:3px;vertical-align:top;-webkit-appearance:none;appearance:none}select::-ms-expand{display:none}label input{margin-right:.5em}fieldset{margin:0 0 24px;border:0;padding:0;min-width:100%}.selector input[type=text],.selector>ul{width:100%}.selector>ul{margin:0}.chosen-container{max-width:100%}.chosen-container-single .chosen-single,.chosen-container-multi .chosen-choices{background-image:none;background-color:#fff;box-shadow:none;font-size:16px;line-height:24px;padding:6px;height:auto;border-radius:3px;border-collapse:#dfdfdf;color:#676767;border-color:#dfdfdf}.chosen-container-multi.chosen-container-active .chosen-choices{border-color:#aaa;border-radius:3px 3px 0 0}.chosen-container-multi.chosen-container.chosen-drop-up .chosen-choices{border-radius:0 0 3px 3px}.chosen-container-multi.chosen-container .chosen-drop{top:calc(100% - 1px);border-top:1px solid #aaa}.chosen-container-multi.chosen-container.chosen-drop-up .chosen-drop{bottom:calc(100% - 1px)}.chosen-container-multi .chosen-choices{padding:3px}.chosen-container-multi .chosen-choices li.search-field input[type=text]{font-family:"Lato",sans-serif;margin:0}.chosen-container-multi .chosen-choices li.search-choice{background:#f0f0f0;font-size:14px;line-height:24px;border:0;padding:0 27px 0 0}.chosen-container-multi .chosen-choices li.search-choice span{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;display:block}.chosen-container .search-choice .group-name{color:#676767;position:relative;background-color:rgba(0,0,0,.04);margin-right:6px;padding:0 6px;display:inline-block;vertical-align:top}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close{top:50%;right:6px;transform:translateY(-50%)}.chosen-container .search-choice .group-name:after{content:""}.chosen-container-multi .chosen-choices li.search-field input[type=text]{min-height:0;margin:3px;height:auto;line-height:24px}.chosen-container-active.chosen-with-drop .chosen-single{background-image:none}.chosen-container-single .chosen-single abbr{top:12px}.chosen-container-single .chosen-single div b{background:none !important}.chosen-container-single .chosen-single div b:after{font-family:"Font Awesome 5 Free";font-weight:900;content:"";line-height:24px;padding:6px 0;display:inline-block}.chosen-container-active.chosen-with-drop .chosen-single div b:after{content:""}.chosen-container-single .chosen-search input[type=text]{background:none !important}.chosen-search{position:relative}.chosen-search:after{font-family:"Font Awesome 5 Free";font-weight:900;content:"";line-height:24px;padding:6px 0;display:block;position:absolute;top:3px;right:12px}.chosen-container .chosen-results li.highlighted{background-color:#676767;background-image:none}.chosen-container.chosen-drop-up .chosen-drop{top:auto;bottom:100%;border-radius:3px 3px 0 0;box-shadow:0 -1px 2px rgba(0,0,0,.15);border-top:1px solid #aaa}.chosen-container-active.chosen-drop-up.chosen-with-drop .chosen-single{border-radius:0 0 3px 3px}.flex{display:flex}.mobile-only{display:none}.sr-only{left:-9999px}div[role=main]>.messages{margin-bottom:12px}div[role=main]>.messages li{margin:0 0 6px}div[role=main]>.messages .error{background-color:#f4b4b4}div[role=main]>.messages .success{background-color:#cdffcd}div[role=main]>.messages .warning{background-color:#fff6e6}div[role=main]>.messages a{text-decoration:underline}.messages{padding:0;margin:0;clear:both}.messages li{background-color:rgba(255,255,255,.5);border-radius:3px;padding:6px 10px;margin-top:6px;display:block;width:100%}.field .messages{width:70%;color:#a91919;margin-left:auto}.field .messages li{box-shadow:0 0 0 1px inset}.error,.error a{color:#a91919}.success,.success a{color:green}.warning,.warning a{color:orange}.version-notification{background-color:#cdffcd;color:green;border-radius:3px;padding:6px 10px;margin-top:6px;display:block;width:100%}.version-notification a{color:green;text-decoration:underline}table .icon-sortable{opacity:.4;font-size:12px;line-height:100%}.row{width:100%;background-color:rgba(0,0,0,.04);padding:6px;position:relative;margin-bottom:6px}.row.delete{background-color:#fcc;overflow:hidden}.jstree-themeicon,.sortable-handle{cursor:move;margin-right:12px;width:18px}.jstree-themeicon:before,.sortable-handle:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900;opacity:.35;font-size:20px;line-height:24px}.jstree i.jstree-themeicon{color:#676767;position:static;top:auto;right:auto}.o-description{margin-bottom:0}a.expand,a.collapse{color:#676767}.expand:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;margin-left:3px}.collapse:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;margin-left:3px}.selector-table{display:table}.selector-table.empty,.selector-table+.no-resources{display:none}.selector-table.empty+.no-resources{display:block}.selector .resources-available.empty,.selector .resources-available+.resources-unavailable{display:none}.selector .resources-available.empty+.resources-unavailable{display:block}.selector .selector-child.filter-hidden,.selector .selector-child.added{display:none}header{background-color:#404e61;width:18.75%;min-height:100vh;text-align:left;padding:0 1.0416666667% 24px;color:#bdcde3}.skip{position:absolute;left:-9999px}.skip:focus{position:absolute;top:0;left:45%;width:10%;z-index:1002;text-align:center;background-color:#fff;border-radius:0 0 3px 3px;border:1px solid #dfdfdf;padding:5px}.logo a,#user a{color:#bdcde3}#user{color:#fff;padding-top:12px;margin-bottom:-6px;display:flex;flex-wrap:wrap}#user p{margin:0 0 6px;display:inline-flex;vertical-align:top}#user .user-id{text-transform:uppercase;font-size:12px;margin-right:auto}#user .user-id a.button{display:inline-block;font-size:12px;text-transform:none;margin-bottom:0;background-color:#222933;padding:0 6px;min-height:0;border:0}#user .user-show{border-radius:3px 0 0 3px;margin-right:1px;display:inline-flex;max-width:85%;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}#user .user-show:before{margin-right:6px}#user .user-settings{border-radius:0 3px 3px 0;border-left:0}#user .user-settings:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900}#user .logout{font-size:12px;padding:0 6px;background-color:#222933;border-radius:3px;display:inline-block;min-width:25%;text-align:center}.logo{padding:6px 6.25%;margin:0 -6.25%;background-color:#222933}#search{width:100%;display:inline-block;vertical-align:top;margin:24px 0}#search input[type=text]{width:calc(100% - 72px);float:left}#search button{width:36px;text-indent:-9999px;background-color:#222933;color:#bdcde3;border:0;float:left;margin:0;border-radius:0;position:relative;height:36px;box-shadow:none}#search button:last-of-type{border-left:1px solid rgba(255,255,255,.2);border-radius:0 3px 3px 0}#search button:last-of-type:after{content:""}#search button:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;text-indent:0;position:absolute;top:0;left:0;width:36px;line-height:36px;text-align:center}#advanced-options{display:none}div[role=main]>h1:first-of-type{background-color:#fff;font-size:24px;position:fixed;padding:3px 30% 3px 1.0416666667%;z-index:3;top:0;right:0;width:81.25%;height:48px;border-bottom:1px solid #dfdfdf;overflow:hidden;line-height:36px}div[role=main]>h1:first-of-type .title{text-overflow:ellipsis;white-space:nowrap;max-width:65%;display:inline-block;overflow:hidden;vertical-align:middle}.subhead{text-transform:uppercase;font-size:14px;padding:0 6px;background-color:#eee;line-height:36px;vertical-align:middle;margin:0 12px 0 0;font-weight:normal;display:inline-block}.subhead:before{font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;margin-right:6px;font-size:16px;vertical-align:top}.action{display:inline-block;vertical-align:middle}.action:before{content:"·";margin:0 12px}.sidebar-open footer{margin-right:25%}footer{font-size:12px;position:relative;margin-top:-27px;margin-left:18.75%;padding-right:1.0416666667%;text-align:right}footer .site-version{margin:0;display:inline-block}footer .version-number{display:inline-block;margin:0 12px;line-height:1}body.transitions-enabled footer{transition:margin-right .5s}footer>a:not(:last-child){margin-right:12px}nav ul{padding:0;list-style:none;margin:0}nav.pagination{margin-bottom:12px;overflow:hidden}nav.pagination form,nav.pagination .button,nav.pagination .row-count{float:left}nav.pagination form{margin-right:12px}nav.pagination form *{display:inline-block;padding:0;text-align:center}nav.pagination .button{border-radius:0;margin:0;padding:0 10px}nav.pagination .button,nav.pagination input[type=text],.sorting button,.sorting select{font-size:13.08px;min-height:0;height:24px;line-height:24px;vertical-align:top;background-size:6.5408px}nav.pagination .button{box-shadow:0 0 0 1px #c8c8c8 inset;position:relative}nav.pagination .button:hover{z-index:1}nav.pagination .button:before{vertical-align:top;line-height:24px}nav.pagination .previous.button{border-radius:3px 0 0 3px}nav.pagination .next.button{border-radius:0 3px 3px 0;margin-left:-1px}nav.pagination form input[type=text]{margin-right:.25em;width:48px;border:1px solid #dfdfdf;padding:5px}nav.pagination+*:not(.sorting){clear:left}#mobile-nav{display:none}.mobile-container{position:relative}button .o-icon-private{margin:0 6px;color:#dfdfdf}header nav h4{padding-bottom:5px;border-bottom:1px solid #364252;margin-bottom:6px}header nav h4:not(:first-of-type){margin-top:24px}header nav ul.navigation>li:not(:first-of-type){margin-top:6px}header nav ul.navigation>li:not(:last-of-type){border-color:#dfdfdf}header nav ul.navigation li li{display:none}header nav ul.navigation li.active li{display:block;margin-left:24px}header nav ul.navigation li.active>a{color:#fff}header nav a:link,header nav a:visited{color:#bdcde3}header nav li>a:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;width:24px}header nav .items:before,.items .subhead:before{content:""}header nav .media:before,.media .subhead:before{content:""}header nav .item-sets:before,.item-sets .subhead:before{content:""}header nav .vocabularies:before,.vocabularies .subhead:before{content:""}header nav .resource-templates:before,.resource-templates .subhead:before{content:""}header nav .users:before,.users .subhead:before{content:""}header nav .modules:before,.modules .subhead:before{content:""}header nav .jobs:before,.jobs .subhead:before{content:""}header nav .sites:before,.sites .subhead:before{content:""}header nav .settings:before,.settings .subhead:before{content:""}header nav .assets:before,.assets .subhead:before{content:""}header nav li li a:before{content:""}header ul.navigation{margin-bottom:6px}#menu{position:relative}#menu h5{text-transform:uppercase;border-top:1px solid #364252;padding-top:5px;margin-bottom:0}#menu .expand,#menu .collapse{width:100%;z-index:1;padding-bottom:6px;margin-bottom:6px}#site-nav{background-color:#364252;padding:6px;margin-bottom:12px;border-radius:3px}#site-nav h5{border-top:0;border-bottom:1px solid #2c3542;padding:0 24px 5px 0;margin-bottom:6px}header nav#site-nav h5 a:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900;width:24px;display:inline-block;font-size:16px}#menu .pages:before,.site-pages .subhead:before{content:""}#menu a.navigation:before{content:""}#menu a.public{float:right;text-align:right;font-size:16px;line-height:30px;margin-top:-39px}#menu a.resources:before{content:""}#menu a.site-info:before{content:""}#menu a.theme:before,.theme-settings .subhead:before{content:""}div[role=main]{width:81.25%;padding:60px 1.0416666667% 36px;background-color:#fff;min-height:100%;overflow:hidden}body.transitions-enabled div[role=main]{transition:width .5s}#dashboard>p{width:100%;margin-top:12px}#manage-resources .add.button:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900}.panel{width:48.9583333333%;float:left;padding-left:1.0416666667%;padding-right:1.0416666667%;border:1px solid #dfdfdf;padding:5px;margin:0 1.0416666667% 0 0;float:left;overflow:hidden}.panel .row{width:100%;background-color:rgba(0,0,0,.04);padding:6px;position:relative;margin-bottom:6px}.panel>.row:last-child{margin-bottom:0}.panel .button{float:right;margin:0}.panel .row a.button{box-shadow:none;padding:0;color:#a91919;background-color:transparent}.panel h2{font-size:18px;line-height:24px;margin-bottom:6px}.browse .add.button,.browse .batch-edit.button{float:left;margin-right:.25em}.browse td:first-child,.browse th:first-child{width:50%}.browse td,.browse th{padding:12px 6px;overflow:hidden}.browse .browse-controls{display:flex;justify-content:space-between;flex-wrap:wrap;font-size:13.08px}.sites.pages.browse .browse-controls{justify-content:flex-end}.browse .browse-controls .advanced-search:before{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;font-style:normal;font-variant:normal;font-weight:normal;line-height:1;font-family:"Font Awesome 5 Free";font-weight:900;content:"";padding:.25em}.browse-controls select,.browse-controls input,.browse-controls button,.browse-controls .button{font-size:13.08px;min-height:0;height:24px;line-height:24px;vertical-align:top;background-size:6.5408px}.browse-controls .sorting:not(:last-child){margin-left:auto}.browse-controls button,.browse-controls .button{padding:0 10px}.browse-controls .filtering{margin-left:24px}.browse .select-all{width:12px;margin-right:12px}.browse .tablesaw-cell-content,#properties .tablesaw-cell-content{display:flex;align-items:center;justify-content:flex-start;word-wrap:break-word}.browse .tablesaw-cell-content>.actions,#properties .tablesaw-cell-content>.actions{white-space:nowrap}.browse .batch-edit .tablesaw-cell-content>input[type=checkbox]{margin-right:12px;flex-shrink:0}.browse .tablesaw-cell-content>span.indent{display:inline-block;vertical-align:top;flex:0;min-width:1em}.actions{margin:0 0 0 auto;display:flex;padding:0}.actions li{list-style-type:none}.actions a,.actions a:before,.actions button,.actions button:before{width:24px;height:24px;line-height:24px;vertical-align:top;border:0;box-shadow:none;display:inline-block}.actions .button:hover,.actions button:hover{box-shadow:none !important}.actions a,.actions button{opacity:.5}.actions a:before,.actions button:before{text-align:right}.actions a:hover,.actions a:active,.actions button:hover{opacity:1}.actions .inactive{display:none}.actions button{background-color:transparent;color:#a91919;margin:0;text-indent:-9999px;position:relative;padding:0;min-height:0}.actions button:before{text-indent:0;position:absolute;top:0;left:0}.row-count{margin:0 6px}.no-resources{text-align:center;position:relative;margin-top:96px}.no-resources:before{font-family:"Font Awesome 5 Free";font-weight:900;font-size:96px;position:absolute;top:0;left:0;width:100%;opacity:.08;content:""}.no-resources p{font-size:24px;line-height:48px;margin-top:48px}td .o-icon-private,td .o-icon-user-inactive{display:inline-block;vertical-align:bottom;margin-left:.5em;opacity:.5}.items .no-resources:before{content:""}.item-sets .no-resources:before{content:""}.media .no-resources:before,#media-list .no-resources:before{content:""}.modules .no-resources:before{content:""}.vocabs .no-resources:before{content:""}.resource-templates .no-resources:before,.resources-templates{content:""}.users .no-resources:before{content:""}.jobs .no-resources:before{content:""}.sites .no-resources:before{content:""}.sidebar .no-resources{display:block}.browse.assets td:first-child,.browse.assets th:first-child{width:75%}.asset-inline{max-width:100%}#batch-form{border:1px solid #dfdfdf;border-bottom:0;border-radius:3px;margin-bottom:12px}#batch-form table.tablesaw{border-width:1px 0;border-radius:0 0 3px 3px;margin-bottom:0}#batch-form .batch-actions{display:inline-block}#batch-form .batch-inputs{display:flex;align-items:center;padding:6px;background-color:rgba(0,0,0,.04)}#batch-form .batch-actions>a.button,#batch-form .batch-actions>button,#batch-form .batch-actions>input[type=submit]{display:none;margin:0 12px 0 0;font-size:14px;line-height:24px;min-height:0;padding:0 6px}#batch-form .batch-actions>a.button.active,#batch-form .batch-actions>button.active,#batch-form .batch-actions>input[type=submit].active{display:inline-block}#batch-form select{font-size:14px;min-height:0;height:auto;line-height:24px;padding:0 24px 0 6px;margin-right:6px;border:0;box-shadow:0 0 0 1px #dfdfdf inset}.batch-selected{padding-left:0;list-style:none}.batch-selected li{padding:12px 0 11px;border-bottom:1px solid #dfdfdf}.batch-selected li:first-child{padding-top:0}.batch-selected li:last-child{border-color:transparent}#advanced-options{background-color:#fff;padding:6px 12px calc(6px - 1px);clear:both;border:1px solid rgba(0,0,0,.15);border-top:0;color:#676767}#advanced-options legend{float:left;width:calc(100% + 24px);font-weight:bold;padding:6px 12px;margin:-6px -12px 12px;background-color:rgba(0,0,0,.04);max-width:none}#advanced-options input{float:left;clear:left;margin-right:.5em;height:24px;margin-bottom:6px}#advanced-options label{float:left;margin-bottom:6px}.search-filters{margin-bottom:6px;display:inline-block}.filter{display:inline-block;font-size:13.08px;margin:0 6px 6px 0;border-radius:3px;background-color:#f0f0f0;padding:0;vertical-align:top}.filter-label{display:inline-block;background-color:rgba(0,0,0,.04);border-radius:3px 0 0 3px}.filter-label,.filter-value{padding:0 6px}.filter-value:not(:last-child):after{content:","}.multi-value .value{display:flex}.multi-value .add-value,.multi-value.field .remove-value{background-color:transparent;color:#a91919;display:inline-block;text-indent:-9999px;position:relative;min-width:36px;width:36px;text-align:center;box-shadow:none}.multi-value .add-value:before,.multi-value.field .remove-value:before{position:absolute;top:0;left:0;width:36px;line-height:36px;text-indent:0}.multi-value .add-value:hover,.multi-value.field .remove-value:hover{box-shadow:none;color:#a91919}.multi-value .add-value{position:absolute;top:0;right:0}.multi-value .field-meta{padding-right:36px}.item-set-select-type{max-width:25%}fieldset.section>legend{position:absolute;left:-9999px}.section-nav{border-top:1px solid #fff;height:42px;position:relative;margin-bottom:12px;clear:both}.section-nav:before{content:"";height:3px;position:absolute;bottom:1px;left:0;right:0;z-index:0;background:#fff;border:1px solid #dfdfdf;border-width:1px 0}.section-nav a{display:block;float:left;height:36px;line-height:30px;padding:3px 1em;position:relative;z-index:1;background-color:#fff;border-color:#dfdfdf;border:1px solid #dfdfdf;margin-left:.25em;color:#676767}.section-nav .active a{font-weight:bold;border-bottom-color:#fff}.section:not(a){display:none}.section.active{display:block;clear:both}#page-actions{position:fixed;padding:6px 1.0416666667%;z-index:4;top:0;height:36px;right:0;text-align:right;margin-bottom:0}#page-actions input[type=submit],#page-actions button,#page-actions .button{display:inline-block;height:36px;padding:6px 1em;min-height:0;vertical-align:top}#page-actions .delete.button{background-color:#fdefef;box-shadow:0 0 0 1px #e0c3c3 inset;color:#a91919}#page-actions .delete.button:hover{box-shadow:0 0 0 1px #da8b8b inset}.page-action-menu{display:inline-block;position:relative}.page-action-menu ul{display:none;list-style:none;border:1px solid #dfdfdf;background-color:#fff;border-radius:3px;text-align:left;padding:0;position:relative;box-shadow:0 0 5px #dfdfdf;position:absolute;right:0;width:auto;white-space:nowrap;margin:12px 0}.page-action-menu ul:before{content:"";position:absolute;bottom:calc(100% - 1px);right:12px;width:0;height:0;border-bottom:12px solid #fff;border-left:6px solid transparent;border-right:6px solid transparent}.page-action-menu ul:after{content:"";position:absolute;bottom:calc(100% - 1px);right:11px;width:0;height:0;border-bottom:14px solid #dfdfdf;border-left:7px solid transparent;border-right:7px solid transparent;z-index:-1}.page-action-menu ul a,.page-action-menu ul .inactive{padding:6px 12px 5px;display:block;position:relative}.page-action-menu ul .inactive{color:#dfdfdf}.page-action-menu ul li{position:relative}.page-action-menu ul li:hover:before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background-color:#dfdfdf}.page-action-menu ul li:not(:last-child) a,.page-action-menu ul li:not(:last-child) span,.page-action-menu ul li:not(:last-child) [type=submit]{border-bottom:1px solid #dfdfdf}.page-action-menu [type=submit]{background:none;box-shadow:none;width:100%;margin-bottom:0;text-align:left}.page-action-menu li label{display:inline-block;height:36px;padding:6px 1em;min-height:0;vertical-align:top;width:100%}.page-action-menu li label input{margin-left:.25em}.page-action-menu li:not(:last-child) label{border-bottom:1px solid #dfdfdf}.page-action-menu .expand:after{content:""}.page-action-menu .expand:after,.page-action-menu .collapse:after{margin-left:6px}.page-action-menu .collapse+.collapsible{overflow:visible;display:block}.add-property.button{margin-top:24px}.field-term{display:inline-block;font-family:"Source Code Pro",monospace;font-size:12px}.value .input-body a.value-language{margin-right:0;vertical-align:top;position:absolute;top:0;right:0;height:36px;width:36px;line-height:36px;border:1px solid #dfdfdf;border-width:0 0 1px 1px;overflow:hidden;text-align:center;color:#f19d9d;z-index:1}.value .input-body a.value-language~textarea{padding-right:42px}.value .input-body .language-wrapper.active a.value-language{border-color:transparent;color:#a91919}.value .language-wrapper:not(.active)~textarea{padding-right:48px}.value .actions a.o-icon-more{display:block;height:36px}.more-actions.active a.o-icon-more{border-bottom:1px solid #dfdfdf}.language-wrapper input[type=text].value-language{line-height:24px;background-color:transparent;border:0;min-height:0;padding:6px 42px 6px 6px;display:block;background-color:#fff}.language-wrapper.active input[type=text].value-language~textarea{padding-left:6px;border-top:0}.input-body .language-wrapper:not(.active) .language-label{display:none}.sidebar .language-label{font-weight:inherit}.language-wrapper .language-label,.value[data-data-type=uri] .input-body label{display:flex;align-items:flex-start;background-color:#fff;margin:0;padding:0 42px 0 6px;box-shadow:0 0 0 1px #dfdfdf}.value-label-text{background-color:rgba(0,0,0,.04);border-radius:2px;font-size:14px;margin:6px;padding:0 6px}.sidebar .value-annotation .value{padding-bottom:0}.sidebar .value-annotation label:after{content:none}.sidebar .value-annotation p.selected-resource{border-bottom:1px solid #dfdfdf}.sidebar .value-annotation-resource-select{margin:6px !important}.sidebar [data-data-type^=resource] .o-title:not(:empty){padding:0;border-bottom:0}.sidebar [data-data-type^=resource] .o-title:not(:empty) a:empty{display:none}.sidebar [data-data-type^=resource] .o-title:not(:empty) img{margin:6px}.sidebar [data-data-type^=resource] .o-title:not(:empty) a{padding:6px;width:100%}.non-properties{margin-bottom:12px}.resource-form .values .sortable-handle{width:12px;background-color:rgba(0,0,0,.04);border:1px solid #dfdfdf;border-radius:2px 0 0 2px;align-self:stretch;border-right:0;margin:0;display:flex;align-items:center;justify-content:center}.resource-form .values .sortable-handle:before{font-size:10px}.visibility{display:inline-block;padding:6px;margin-right:12px}.add .visibility:before,.edit .visibility:before{margin-right:.25em}.add .visibility [type=checkbox],.edit .visibility [type=checkbox]{margin-left:.5em}#add-item .remove.field{background-color:#ea7171;opacity:.6}.resource.input-option span{display:block;background-color:rgba(255,255,255,.5);padding:6px 10px 0;width:100%;float:left}.field-meta{width:30%;padding-right:6px;position:relative}.field-meta legend,.field-meta label,.field-meta .label{max-width:80%;padding:6px 0;display:inline-block}.field-meta legend{position:static;float:left}.field-meta .error{float:left}.field-meta ul{margin:0}.field-label-text{display:block}.template{display:none}.selector ul{list-style:none;padding-left:0}.selector>ul{margin-top:6px}.selector li{position:relative}.selector li.total-count-heading{background-color:#404e61;color:#fff;border-radius:3px;text-transform:uppercase;font-size:12px;padding:6px 10px}.selector li.total-count-heading>ul{margin:6px -10px -6px;border-radius:0 0 3px 3px}.selector li.selector-parent.empty{display:none}.selector li.show>ul{position:relative;top:0;left:0;overflow:visible}.selector .selectable-list{background-color:#fff;color:#676767;overflow:visible;border-radius:3px;font-weight:bold;position:relative;border:1px solid #dfdfdf;margin:6px 0 0;text-transform:uppercase;font-size:12px}.selector .selectable-list li{padding:6px 12px}.selector .selectable-list .selector-parent{cursor:pointer;padding-right:24px;margin-bottom:0}.selector .selectable-list .selector-parent:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;position:absolute;right:0;top:6px;width:18px}.selector .selectable-list .selector-parent.show:after{content:""}.selector .selectable-list .selector-parent:hover:before{content:"";position:absolute;top:0;bottom:0;left:0;width:5px;background-color:#dfdfdf}.selector .selectable-list .selector-parent:not(:last-of-type){border-bottom:1px solid #dfdfdf;padding-bottom:5px;border-color:#dfdfdf}.selector-parent ul{position:absolute;top:-9999px;left:-9999px}.selector-child{border-radius:0;font-weight:normal;padding:6px 10px;margin:0 -12px;font-size:16px;text-transform:none;width:calc(100% + 36px)}.selector-child:hover{background-color:rgba(0,0,0,.04)}.selector-child:last-of-type{margin-bottom:-6px}.selector .description{display:inline-block;vertical-align:top}.selector .description.no-comment{opacity:0}.selector .description .o-icon-info{display:inline-block;margin:0 6px 0 0;opacity:.75;width:1em}.selector .description .o-icon-info:hover+.field-comment{left:5px;right:0;top:36px;padding:3px 10px 3px 36px;line-height:18px;background-color:#fff;z-index:1;margin:0;border-bottom:1px solid #dfdfdf;font-size:12px}.selector .description .o-icon-info:hover+.field-comment:before{content:"";position:absolute;left:7px;top:-6px;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff}.selector .description .o-icon-info:hover+.field-comment.above{bottom:100%;top:auto}.selector .description .o-icon-info:hover+.field-comment.above:before{top:calc(100% - 6px);transform:rotate(180deg)}.selector .description .o-icon-info+.field-comment{position:absolute;top:-9999px;left:-9999px;width:calc(100% - 5px)}.selector .selectable{display:inline-block;width:calc(100% - 36px);word-wrap:break-word}.field-actions{width:60%;display:inline-block;margin:24px 0 0 30%}.field .field-label{display:inline-block}.field .field-description,.field .docs-link{font-size:14px;line-height:18px;position:static;text-align:left;height:auto}.field .field-description:not(:only-child){margin-bottom:6px}.field-description{display:block;margin-right:10px;line-height:36px;height:36px;position:absolute;top:0;right:0;text-align:right;left:0}.field-description .o-icon-info{margin:0;cursor:pointer}.field-description .field-comment.open{left:inherit;right:0px;top:36px;background-color:#333;color:#fff;border-radius:3px;z-index:1;max-width:100%;font-size:14px;padding:6px 5px;margin:12px 0}.field-description .field-comment.open.above{top:auto;bottom:30px}.field-description .field-comment.open:before{content:"";display:block;height:0;width:0;position:absolute;top:-6px;bottom:0;right:3px;font-size:16px;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:12px solid #333}.field-description .field-comment.open.above:before{top:auto;bottom:-12px;transform:rotate(180deg)}.field .docs-link:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;margin-right:6px;font-size:14px;line-height:18px}.field-meta .expand,.field-meta .collapse{display:inline-block !important;margin-left:.5em !important;padding:0 !important;border:0 !important;width:auto !important}.field-meta .expand:after,.field-meta .collapse:after{float:none !important;margin-right:0 !important}.collapsible{display:none}.collapse+.collapsible{display:block;clear:both;overflow:hidden}.field-description .field-comment{position:absolute;top:-9999px;left:-9999px}.resource-property .field-term{display:block}.inputs{line-height:36px;width:70%}.inputs:only-child{width:100%}.inputs p:only-child{margin:0}.inputs label,.inputs select,.inputs textarea,.inputs input[type=text],.inputs input[type=password],.inputs input[type=email],.inputs input[type=url],.inputs input[type=date],.inputs input[type=datetime-local]{width:100%;min-height:36px;margin:6px 0}.inputs label:only-child,.inputs select:only-child,.inputs textarea:only-child,.inputs input[type=text]:only-child,.inputs input[type=password]:only-child,.inputs input[type=email]:only-child,.inputs input[type=url]:only-child,.inputs input[type=date]:only-child,.inputs input[type=datetime-local]:only-child{margin:0}.inputs textarea{resize:vertical;line-height:1.5;background-color:#fff;min-width:0}.inputs label{padding:6px 0;margin:0 24px 0 0}.inputs .button,.inputs button,.inputs input[type=submit]{margin:6px 0;line-height:24px}.inputs input:focus,.inputs textarea:focus{position:relative;z-index:100}#resource-values div.value{display:flex;align-items:stretch}#resource-values div.value:only-of-type .sortable-handle{display:none}.value{margin-bottom:6px}.value:last-of-type{margin-bottom:0}.value:last-of-type .remove-value{margin-bottom:0;box-shadow:none}.value.template{display:none}.inputs p.no-values{padding:12px;border-radius:3px;background-color:rgba(0,0,0,.04);line-height:24px}.inputs p.no-values:not(:only-child){display:none}.add-values{margin:6px 0 -3px}.add-values *{display:inline-block;min-width:36px;height:36px;border-radius:2px;text-align:center;margin:0}.inputs .add-values a.button{margin:0 0 3px}.inputs .add-values a.button:before{margin-right:.25em}.add-values label{background-color:rgba(0,0,0,.04);line-height:36px;margin-right:0;overflow:hidden;width:12px;vertical-align:top}.input-footer{display:flex;width:30px}.input-footer .actions{margin-left:6px;flex-direction:column}.input-footer .actions a:before{line-height:36px;height:36px;text-align:center}.more-actions ul{padding:0;display:none}.more-actions.active{box-shadow:0 0 0 1px #dfdfdf;background-color:#fff;border-radius:2px}.more-actions.active ul{display:block}.value.delete{background-color:#fcc;overflow:hidden}.value .restore-value,.value.delete a.tab,.value.delete [class*=o-icon-]:not(.restore-value),.value.delete .block-page-layout-grid-controls{display:none}.value.delete .input-footer{background-color:transparent;width:100%}.value.delete .restore-value{display:inline-block}.value [class*=o-icon-].label{position:absolute;top:0;left:0;height:36px;width:36px;background-color:rgba(0,0,0,.04);text-align:center;line-height:36px;overflow:hidden}.value label,.add-values label{margin:0;min-height:0;line-height:24px}.block.value .inputs label{margin-right:24px}.add-values button,.add-values .button{line-height:24px}.inputs .value textarea,.inputs .value input[type=text]{width:100%;margin:0}.inputs .value textarea{min-height:72px;border:0;box-shadow:0 0 0 1px #dfdfdf}.inputs .value .input-body>textarea{padding:6px 12px}[data-data-type^=resource] .default,[data-data-type^=resource] .o-title:not(:empty){padding:6px;border-bottom:1px solid #dfdfdf;word-wrap:break-word;line-height:24px;display:flex}[data-data-type^=resource].delete .o-icon-undo:before{padding-right:0}.input-body{clear:both;background-color:#fff;flex:1;position:relative;box-shadow:0 0 0 1px inset #dfdfdf;max-width:calc(100% - 30px)}.value:not(:only-of-type) .input-body{max-width:calc(100% - 48px)}.inputs .input-body input[type=text]{margin:0;background-color:transparent}.inputs .input-body input[type=text]:focus,.inputs .input-body textarea:focus{z-index:10}.inputs .input-body .chosen-container{max-width:calc(100% - 12px);margin:6px}[data-data-type^=resource] .button{font-size:14px;padding:0 6px;line-height:24px;min-height:0;margin-right:3px}[data-data-type^=resource] .button:before{margin-right:6px}.value.delete span.restore-value{display:inline-block;padding:0 6px;width:calc(100% - 36px)}.value.delete>*:not(.input-footer){display:none}.sortable-handle~.input-body{background-color:transparent}.resource-inputs{background-color:#fff;box-shadow:0 0 0 1px #dfdfdf}p.selected-resource{position:relative;width:100%;margin:0}.selected-resource a{width:calc(100% - 72px)}.selected-resource+a.button{margin-left:6px}.selected-resource img{height:24px;margin-right:6px}.selected-resource .o-title a:after{font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;margin:0 6px}.selected-resource .items a:after{content:""}.selected-resource .item_sets a:after{content:""}.selected-resource .media a:after{content:""}[data-data-type=literal] .sortable-handle~.input-body{background-color:#fff}.inputs [data-data-type=literal] textarea.input-value{background-color:transparent;padding-right:42px}[data-data-type=uri] .input{position:relative;clear:both;background-color:#fff;box-shadow:0 0 0 1px #dfdfdf}[data-data-type=uri] .input:first-child{border-bottom:1px solid #dfdfdf}.value[data-data-type=uri] .input-body label{padding-right:0}.sidebar [data-data-type=uri] label{font-weight:inherit}[data-data-type=uri] .input-body input.uri-value,[data-data-type=uri] textarea.value-label{height:36px;border:0;box-shadow:none;padding:6px 42px 6px 6px;font-weight:normal;background:transparent;min-height:36px}[data-data-type=uri] textarea.value-label{border-top-width:0}.annotation-form{padding-bottom:12px}.annotation-form>div,.annotation-form>select{margin-bottom:6px}.value-annotation:not(:last-child){border-bottom:1px solid #dfdfdf;padding-bottom:12px;margin-bottom:12px}.value-annotation .restore-value{line-height:36px}#resource-files button{margin:24px 0 0}#add-media-field{margin-bottom:0}.media.row{padding:6px;margin-bottom:6px;display:flex;align-items:center;word-wrap:break-word}.media.row img{width:36px;height:auto;margin-right:12px}.media.row .resource-name{margin-right:12px;min-width:0}.media.row .primary-media{text-transform:uppercase;font-size:12px;font-weight:bold;margin:0 0 0 auto}.media.row .primary-media input{margin-left:6px}.media.row .actions{margin-left:24px}.media.value.delete span.restore-value{padding:0}.media.value.delete>*:not(.restore-value),.media.value.delete .actions a:not(.o-icon-undo){display:none}.media.value.delete>.actions{display:block;top:18px}.media-header{font-size:16px;margin:6px -6px;margin-top:-12px;background-color:rgba(0,0,0,.04);padding:0 6px;display:flex;align-items:center}.value.delete>.actions{display:inline-block}.media-render{margin-bottom:24px}.media-render>*{max-width:100%}.media-render img{max-width:100%;height:auto}#item-media .sidebar button{width:100%;text-align:left}.media-file-info{display:flex;align-items:flex-start;flex-wrap:wrap}.media-file-thumbnail img{vertical-align:bottom;margin:6px 12px 0 0}#item-item-sets+.no-resources:before,#site-item-sets+.no-resources:before{content:""}#item-item-sets tr.delete{background-color:#fcc}#page-actions [class*=o-icon-].button{background-color:transparent;width:auto;padding:6px 6px;box-shadow:none}.o-icon-private.button,.o-icon-public.button{margin-right:6px;box-shadow:none}#item-sites.empty+.no-resources:before{content:""}.media.edit #media .cke_contents{min-height:500px}.search-nav{width:100%}.search-nav .resource-search{width:100%;position:relative;margin-bottom:6px;display:flex;flex-wrap:wrap}.search-nav .chosen-container{margin-bottom:6px}.search-nav button.o-icon-search{height:36px;width:36px;line-height:24px;padding:0 10px;border-radius:0 3px 3px 0;min-height:0;position:relative;text-indent:-9999px;margin:0}.search-nav button.o-icon-search:before{text-indent:0px;position:absolute;left:0;top:6px;line-height:24px;width:100%}.search-nav .resource-search>input[type=text]{width:calc(100% - 36px);border-right:0;margin-bottom:6px}.resource-search-filters{padding-bottom:5px;border-bottom:1px solid #dfdfdf;margin-bottom:6px;width:100%}.resource-search-filters a.expand:after,.resource-search-filters a.collapse:after{float:right}.resource-search-filters .collapsible{margin-top:6px;overflow:visible}.sidebar .pagination{font-size:13.08px;border-bottom:1px solid rgba(0,0,0,.08);padding-bottom:11px;margin-bottom:0;overflow:hidden;width:100%}.sidebar .pagination li{float:left}.sidebar .pagination li:first-of-type{padding-right:10px}.sidebar .pagination input{width:3em;text-align:center;color:#333;margin:0 3px}.sidebar .pagination .next.button{margin-right:5px}.sidebar .pagination input[type=text]{float:left;line-height:19.62px;height:24px;border:1px solid #dfdfdf;margin-left:0}.sidebar .pagination .page-count{float:left;margin-right:12px}.sidebar .pagination .inactive{background-color:#e6e6e6;color:#b9b9b9}.sidebar textarea{resize:vertical}#item-results+.confirm-panel,#item-results .select-resource-checkbox-wrapper{display:none}#item-results.active{padding-bottom:72px}#item-results.active+.confirm-panel{display:block}#item-results.active .select-resource-checkbox-wrapper{display:inline-flex;align-items:center}.sidebar button.select-all,.sidebar button.quick-select-toggle{background-color:transparent;color:#676767;box-shadow:none;margin:12px;padding:0;line-height:1;min-height:0}.success-statuses{position:absolute}.success-statuses .status,.sidebar button .sr-only{display:none}.sidebar button:not(.active) .sr-only.off,.sidebar button.active .sr-only.on,.success-statuses:not(.active) .sr-only.off,.success-statuses.active .sr-only.on{display:block}.sidebar button.select-all:before,.sidebar button.quick-select-toggle:before{font-family:"Font Awesome 5 Free";font-weight:900;content:"";display:inline-block;margin-right:6px}.sidebar button.quick-select-toggle.active:before{content:""}.sidebar button.select-all:before{content:"";font-weight:400}.sidebar button.select-all.active:before{content:""}.sidebar button.quick-select-toggle+.resource-list{border-top:1px solid #dfdfdf}.resource-link{display:inline-flex;align-items:center;max-width:100%;min-width:0}.resource-link img{height:36px;margin-right:6px}.resource-link .resource-name{flex:1;min-width:0}.resource-list{width:100%}.resource-list .resource{padding:6px 12px 5px;border-bottom:1px solid rgba(0,0,0,.08);position:relative;width:100%;overflow:hidden;display:flex;align-items:center;word-wrap:break-word}.resource-list .resource:hover{background-color:rgba(255,255,255,.8)}.resource-list .resource:hover .select{right:0px}.resource-list .resource .select-resource-checkbox-wrapper{height:24px;margin-right:12px}#resource-details{background-color:#fff;overflow:hidden;padding:0}#resource-details .o-description,#resource-details .property{margin-bottom:0}.confirm-main{position:absolute;top:0;bottom:60px;overflow-y:auto;left:0;right:0;padding:12px 12px 0}.confirm-panel{position:absolute;bottom:0;right:0;left:0;padding:12px;background-color:#f7f7f7;border-top:1px solid #dfdfdf}.confirm-panel button,.confirm-panel .button{width:100%;margin:0}.sidebar .field-meta{width:100%;position:relative;padding-right:36px;margin-bottom:12px;border-bottom:3px solid #dfdfdf}.sidebar .field-meta .label,.sidebar .field-meta label{margin:0;width:auto;display:inline-block;padding:0 0 6px}.sidebar .field-meta .label:after,.sidebar .field-meta label:after{content:none}.sidebar .field-meta .collapsible{margin-bottom:12px}.sidebar .field-meta button.add-value{padding:0;background:transparent;color:#676767;min-height:0;position:absolute;top:0;right:0}.sidebar .field-meta button.add-value:before{height:auto;line-height:1.5}.sidebar .inputs{width:100%}.sidebar #advanced-search .value{flex-wrap:wrap}.sidebar #advanced-search .value:not(:first-child){margin-top:6px}.sidebar .multi-value .value:not(:only-child){width:calc(100% - 36px);position:relative;padding-bottom:0;margin-bottom:5px;border-bottom:0}.sidebar .multi-value .value:only-child .remove-value{display:none}.sidebar .multi-value .remove-value{position:absolute;right:-36px;bottom:0}.sidebar #advanced-search .value select,.sidebar #advanced-search .value input{margin-left:0}.sidebar #advanced-search .confirm-panel{display:flex;justify-content:space-between}.sidebar #advanced-search .confirm-panel button{width:calc(33.33% - 6px)}.block .block-content input[type=hidden]+button{padding-top:6px}.query-form-element .active{display:block}.query-form-element .inactive{display:none}.query-display .search-filters{margin-bottom:0}.query-display .filter{background-color:#fff;box-shadow:0 0 0 1px #dfdfdf inset}.query-display .filter-label{background-color:#dfdfdf}.query-form-element button.active{display:inline-block}.query-display{min-height:42px}input[type=text].query-form-query{margin-top:0}.query-display .filter-value:not(:last-child):after{content:none}#save-search{display:none}#save-search.active{display:flex;margin-top:-6px;padding:0 6px 12px calc(30% + 3px);background-color:rgba(0,0,0,.04)}#save-search.active input{margin-left:6px}.vocabs .field [type=file]{margin:6px 0 0}.vocabulary ul{padding-left:0;list-style:none;overflow:hidden}.vocabulary h2{margin-bottom:0}.vocabs.update td{vertical-align:top}.vocabs.update td:first-of-type,.vocabs.update td:nth-of-type(2){width:15%;word-wrap:break-word}.vocabs.update td:nth-of-type(3),.vocabs.update td:nth-of-type(4){width:35%}.vocabs.update td:nth-of-type(3):last-child{width:auto}.vocabs.update td:nth-of-type(3):not(:last-child){background-color:#ffe6e6}.vocabs.update td:nth-of-type(4){background-color:#cdffcd}.show .property,.meta-group{overflow:hidden;display:flex;justify-content:flex-end;flex-wrap:wrap}.show .property dt,.meta-group dt{width:22.2222222222%;vertical-align:top;padding:6px 0;font-weight:bold}.show .property dd,.show .property .values,.meta-group dd,.meta-group .values{padding:6px;margin:0;word-wrap:break-word;width:77.7777777778%}.show .property dd:not(:first-of-type),.show .property .values:not(:first-of-type),.meta-group dd:not(:first-of-type),.meta-group .values:not(:first-of-type){padding-top:0}.show .property .language,.meta-group .language{font-size:12px;padding:0 6px;margin-right:6px;background-color:rgba(0,0,0,.04)}#linked-filter label{display:flex;align-items:center;margin-bottom:24px}#linked-filter label select{margin-left:12px}#linked-resources table{margin-bottom:24px}#linked-resources caption{background-color:rgba(0,0,0,.04);font-family:bold;padding:6px;font-family:"Lato",sans-serif;font-weight:bold;text-align:left;font-size:20px}#linked-resources th{border-bottom:3px solid #dfdfdf}.linked-resource{margin-bottom:12px;padding-bottom:11px;border-bottom:1px solid #dfdfdf}.has-annotation:before{display:inline-block}.o-icon-annotation:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900}.show .value.resource,.show .value.resource .value-content{display:flex;flex-wrap:wrap;align-items:center}.show .value .o-icon-private,.show .value .value-content{margin-right:12px}.collapsible.annotation{border-left:3px solid #dfdfdf;padding:0;border-radius:3px;margin:6px 0 12px 24px;width:100%}.collapsible.annotation h4,.collapsible.annotation .values{width:100%;padding:0}.collapsible.annotation .property{padding:0 12px}.collapsible.annotation .property:not(:first-child){margin-top:12px;border-top:1px solid #dfdfdf;padding-top:12px}.property .value .resource-name:after,.property .value.uri .uri-value-link:after{font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;margin-left:.5em}.property .value.uri .uri-value-link:after{content:""}.property .value.items .resource-name:after{content:""}.property .value.media .resource-name:after{content:""}.property .value.item_sets .resource-name:after{content:""}.sidebar .meta-group.item-sites .o-icon-external{float:right}.class-row{border-bottom:1px solid #dfdfdf;padding-bottom:11px}.class-label{font-weight:bold}.class-label:after{content:": "}.sidebar{position:fixed;top:48px;left:100%;visibility:hidden;bottom:0;background-color:#f7f7f7;z-index:3;border-left:1px solid #dfdfdf;overflow-y:auto;overflow-x:hidden;width:25%;padding:12px}body.transitions-enabled .sidebar{transition:left .5s,visibility .5s}.sidebar.active,.sidebar.always-open{left:75%;visibility:visible}.sidebar.loading{overflow:hidden}.sidebar.loading *{visibility:hidden}.sidebar.loading:after{font-family:"Font Awesome 5 Free";font-weight:900;content:"";line-height:1;position:absolute;top:.75em;left:calc(50% - .5em);font-size:4em;animation:fa-spin 1s infinite linear;height:1em;width:1em;text-align:center}.sidebar a.o-icon-close{position:absolute;right:12px;top:12px;z-index:3;color:#666}.sidebar .vocabulary,.sidebar .meta-group{margin-bottom:0}.sidebar .value{margin-bottom:6px;border-bottom:1px solid #dfdfdf;padding-bottom:5px;vertical-align:middle}.sidebar .value *:last-child{margin-bottom:0}.sidebar .value:last-child{border-color:transparent;margin-bottom:0}.sidebar input,.sidebar textarea,.sidebar select{width:100%}.sidebar input[type=checkbox],.sidebar input[type=radio]{width:auto}.sidebar h2{font-size:24px;margin-bottom:12px}.sidebar h3,.sidebar label,.sidebar .label{display:block;font-size:16px;font-weight:bold;margin:0 0 12px 0;padding:0 24px 12px 0;position:relative;width:100%;word-wrap:break-word;max-width:none}.sidebar h3:after,.sidebar label:after,.sidebar .label:after{content:"";position:absolute;left:-12px;right:-12px;bottom:0;top:-12px;background-color:#dfdfdf;z-index:-1}.sidebar .field{background-color:transparent;padding:0;margin-bottom:24px;flex-wrap:wrap;justify-content:flex-start}.sidebar .field .option{width:100%}.sidebar .field div.option+div.option{padding-top:11px;border-top:1px solid #dfdfdf;margin-top:12px}.sidebar .button,.sidebar button{background-color:#676767;border-color:#676767;color:#fff}.sidebar .button:disabled,.sidebar .button.disabled,.sidebar button:disabled,.sidebar button.disabled{background-color:rgba(0,0,0,.04);border-color:rgba(0,0,0,.04);color:#676767;box-shadow:none !important}.sidebar button.option{width:100%;text-align:left;border-color:#dfdfdf;background-color:#fff;color:#676767;display:inline-flex;justify-content:space-between}.sidebar button.option:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;color:#dfdfdf}#sidebar-confirm{display:block;padding-bottom:12px;margin-bottom:12px}#sidebar-confirm input[type=submit]{background-color:#a91919;color:#fff;box-shadow:none}body.sidebar-open #content{width:56.25%}.sidebar .meta-group{margin-bottom:12px}.sidebar .meta-group .value{width:100%;padding:6px 0;margin:0;word-wrap:break-word;display:block}.sidebar .meta-group .value:not(:last-child){border-bottom:1px solid #dfdfdf;padding-bottom:5px}.sidebar .meta-group h4{display:block;background-color:transparent;border-color:#dfdfdf;padding:6px 0;border-bottom:2px solid #dfdfdf;padding-bottom:4px;margin-bottom:0;width:100%}.sidebar .media a:first-child img,.sidebar>img:first-child{height:168px;width:auto;display:block;margin-bottom:12px}.sidebar .meta-group img{height:48px;box-shadow:0 0 0 1px #dfdfdf}.source-type{font-weight:bold}.resource-templates #properties{list-style:none;padding-left:0;margin-left:0}.resource-templates table{width:100%}.resource-templates th,.resource-templates td{padding:6px;vertical-align:top}.resource-templates .property.row{display:flex}.resource-templates .property.row.delete{background-color:#fcc}.resource-templates .property.row.delete .actions li:not(:last-child){display:none}.resource-templates .property.row:not(.delete) .sortable-handle{display:inline-flex}.resource-templates #properties{margin:24px 0 0;clear:both;padding:0}.resource-templates #edit-sidebar{padding-bottom:48px}.resource-templates #edit-sidebar .field h4,.resource-templates #edit-sidebar .field h4+span{width:100%}.resource-templates #edit-sidebar .field h4+span{margin-bottom:12px}.resource-templates #edit-sidebar .field label:not(:first-child),.resource-templates #edit-sidebar .field .option label{margin:0;padding-bottom:6px;padding-right:0;display:flex;justify-content:space-between}.resource-templates #edit-sidebar .field label:not(:first-child):only-child,.resource-templates #edit-sidebar .field .option label:only-child{padding-bottom:0}.resource-templates #edit-sidebar .field label:not(:first-child):after,.resource-templates #edit-sidebar .field .option label:after{padding:0;margin:0;background:transparent}.alternate-label-cell:not(:empty){background-color:#dfdfdf;display:inline-block;padding:0 6px;margin:0 6px;position:relative}.alternate-label-cell:not(:empty):after{content:"";border-top:12px solid transparent;border-bottom:12px solid transparent;border-left:6px solid #dfdfdf;width:0;height:0;position:absolute;left:100%;top:0}.title-property-cell,.description-property-cell{text-transform:uppercase;font-size:12px;font-weight:bold;margin-left:auto;margin-right:12px}.title-property-cell:after,.description-property-cell:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;margin-left:6px}.title-property-cell~.actions,.description-property-cell~.actions{margin-left:0}.title-property-cell~.description-property-cell,.description-property-cell~.title-property-cell{margin-left:12px}#modules.installed tbody tr:not(.installed),#modules.uninstalled tbody tr:not(.uninstalled),#modules.needs-upgrade tbody tr:not(.needs-upgrade),#modules.active tbody tr:not(.active),#modules.deactivated tbody tr:not(.deactivated){display:none}.state-filter select{margin-bottom:12px}.module-name{font-weight:bold}.module-author{display:block}#modules .module{border-bottom:1px solid #dfdfdf;padding-bottom:11px;margin-bottom:12px;overflow:hidden}#modules .module-meta{float:left;max-width:50%}#modules .module-actions{float:right;max-width:50%;text-align:right}#modules .module form{display:inline-block}#modules button,#modules .button{display:inline-block;margin-left:6px;box-shadow:0 0 0 1px rgba(0,0,0,.15) inset}#modules button:hover,#modules .button:hover{box-shadow:0 0 0 1px rgba(0,0,0,.3) inset}#modules button:before,#modules .button:before{margin-right:6px}#modules .o-icon-install{box-shadow:0 0 0 1px #addead inset}#modules .o-icon-install:hover{box-shadow:0 0 0 1px #63c363 inset}#modules .o-icon-uninstall{margin-left:24px;box-shadow:0 0 0 1px #e0c3c3 inset}#modules .o-icon-uninstall:hover{box-shadow:0 0 0 1px #da8b8b inset}#edit-keys td{word-wrap:break-word}.api-delete{width:10%}.api-label{width:25%}#system-info-table .label-col{width:25%}#system-info-table th,#system-info-table td{font-size:.875em;padding:0;line-height:1.75;border:none;vertical-align:top}#system-info-table th[scope=rowgroup]{font-size:1em;border-bottom:1px solid #dfdfdf;padding-left:6px}#system-info-table tbody:not(:last-child) tr:last-child td{padding-bottom:24px}#system-info-table th[scope=row]{padding-left:1.5em}.breadcrumbs{border-bottom:1px solid #dfdfdf;padding-bottom:11px;margin-bottom:24px}.breadcrumbs+.field{margin-top:24px}.breadcrumbs a:before{margin-right:6px}.breadcrumbs>*:not(:last-child):after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;display:inline-block;margin:0 calc(12px - 3px) 0 12px;color:#000;cursor:default}#site-item-sets th:first-child,#site-item-sets th:last-child{width:36px}.manual-assignment .inputs label{display:block;padding:0;margin:6px 0 0;min-height:0;line-height:24px}.manual-assignment .inputs label:last-child{margin-bottom:6px}.manual-assignment #advanced-search{margin-top:-6px;padding:12px 0 6px;background-color:rgba(0,0,0,.04);border-top:1px solid #dfdfdf}.manual-assignment #advanced-search.inactive{display:none}.manual-assignment .advanced-search-header{padding:0 6px}.manual-assignment .advanced-search-header a.button{margin-bottom:6px}.manual-assignment .advanced-search-content .field{background-color:transparent}.keep-search,.keep-search input{margin:0 0 0 6px}tr.value.delete>td:not(.input-footer){display:table-cell}tr.value.delete .user-name,tr.value.delete select,tr.value.delete .o-icon-delete{display:none}td.user-meta{width:50%}#site-user-permissions.empty+.no-resources:before{content:""}#site-user-permissions .actions{justify-content:flex-end;padding:6px 0}#block-controls-header{display:flex;justify-content:space-between;flex-wrap:wrap;margin-top:12px}#page-layout-controls{display:flex;align-items:center;justify-content:flex-end;margin-bottom:12px}#page-layout-label{display:flex;align-items:center}#page-layout-select{margin-left:6px}#page-layout-controls>*:not(:last-child){margin-right:6px}#page-layout-controls button{margin-bottom:0}.indent:before{content:"—";margin-right:-1px}.expand-collapse-all{text-align:right}.block{margin-bottom:6px}.block .block-header{position:relative;display:flex;align-items:center;background-color:rgba(0,0,0,.12);padding:6px;font-weight:bold}.block .block-header .actions a:before{text-align:center}.block .block-header .block-type{margin-right:auto}.block .block-header select{margin-right:6px;font-weight:normal}.block-page-layout-grid-controls+.actions{margin-left:0}.block .block-content input[type=hidden]+*{padding-top:0;margin-top:0}.block.html>div{border:1px solid #dfdfdf}.block .field{padding:0;border-color:transparent;background-color:transparent;margin-top:6px}.block .field:last-child{margin-bottom:0}.block.delete>.block-header{font-weight:normal;display:flex;background:transparent}.block.delete>*:not(.block-header){display:none}.block.delete span.restore-value{padding:0 3px;text-transform:lowercase;width:auto}.block.delete a.restore-value:before{padding:0}.block.delete .sortable-handle{display:none}.delete .block-type,.block .delete div.item-title{margin-left:30px}.delete .block-type{font-weight:bold}.block div.item-title{margin:6px 0;display:flex;align-items:center}.block .item-title img{height:36px;width:auto;display:inline-block;margin-right:6px;vertical-align:top}.block .delete.attachment{background-color:#fcc}.block .delete.attachment .actions .undo{display:inline-block}.block .delete.attachment .sortable-handle,.block .delete.attachment .actions li:not(.undo){display:none}.block .attachments-form{margin-bottom:12px}.block .attachments-form a h4{display:inline-block}.block .attachment .actions{margin-left:auto}.block .attachment .actions .button{background-color:transparent;color:#a91919;padding:0;min-height:0}.block .attachment .actions .button:hover{color:#a91919}.block .attachment .actions .undo{display:none}.block .block-content{clear:both;background-color:rgba(0,0,0,.04);padding:6px}.block.sortable-ghost .block-content{display:none}.block-content fieldset:last-of-type{margin-bottom:0}.block .attachment{display:flex;align-items:center;position:relative;padding:0 6px}.block .attachment:not(:last-child){border-bottom:1px solid #dfdfdf;padding-bottom:-1px}.block .attachment .button{margin-bottom:0}.block .attachment-add{margin:6px 0 0}.block-header.collapse:after{content:none}.block-content .expand,.block-content .collapse{width:100%;display:flex;padding:0 6px 0 0;justify-content:space-between}.block .field-meta .collapse+.collapsible{width:auto;border:0}.block .expand h4,.block .collapse h4{display:inline-block;padding:0}.block-content .collapse+.collapsible{border-top:1px solid #dfdfdf;padding:-1px 0 0 24px;margin-top:6px}.block[data-block-layout=html] [contenteditable=true]{resize:vertical;min-height:72px;max-height:288px}#attachment-options .option{position:relative;margin-bottom:12px}#attachment-options .expand,#attachment-options .collapse{position:absolute;right:0;top:0}#attachment-options h3{overflow:visible;white-space:normal}#attachment-item-select{display:block;margin:12px 0 0}#attachment-options .selected-attachment{margin-bottom:12px;margin-top:-12px;box-sizing:content-box;margin-right:-12px;margin-left:-12px;padding-right:12px;padding-left:12px;padding-top:12px;padding-bottom:12px;overflow:hidden}#attachment-options .selected-attachment img{height:96px;width:auto;float:right;margin:0 0 0 12px}#attachment-options .selected-attachment p:first-child{margin:0}#attachment-options h3.item-title{text-align:left}#attachment-options .item-thumbnail~h3.item-title{width:100%}#attachment-options .media-title{font-size:12px;display:block;width:calc(100% - 108px);float:left;word-wrap:break-word;text-align:left;clear:left}#attachment-options .item-thumbnail~#attachment-item-select{font-size:12px;display:inline-block;width:calc(100% - 108px);word-wrap:break-word}#attachment-options h3{word-wrap:break-word}#attachment-options .media-list{list-style:none;padding:0;margin:0 0 12px}#attachment-options .media-list li.media{position:relative;height:48px;width:48px;cursor:pointer;display:inline-block;padding:3px;border:1px solid #dfdfdf}#attachment-options .media-list li.media.attached,#attachment-options .media-list li.media:hover{background-color:rgba(0,0,0,.04)}#attachment-options .media-list img{width:100%;height:auto}#asset-options .selected-asset{overflow:hidden}#asset-options .selected-asset-image{float:left;margin:0 12px 0 0;max-width:50%}#asset-list.active{z-index:6}#asset-options .selected-asset .selected-asset-name{display:none}.asset-attachments-form{margin-bottom:12px}.add-asset-attachment{margin-top:6px}#asset-options .sidebar-content>div{margin-bottom:2rem}.asset-attachment-select{margin-top:.5rem}.asset-title{display:flex;align-items:center}.asset-title img{height:100%;width:auto}.asset-title .thumbnail:not(:empty){height:2rem;position:relative;width:2rem;margin:.25rem .25rem .25rem 0;overflow:hidden;display:inline-flex;justify-content:center}#asset-options .none-selected.inactive{display:none}#asset-options .none-selected:not(.inactive)~*{display:none}#asset-options .page-status{margin-bottom:12px}#asset-options .selected-page+.o-icon-external{margin-left:6px}#grid-layout-preview{display:grid;gap:6px}.grid-layout-previewing-block{min-height:60px;background-color:#dfdfdf}.hovered-block{box-shadow:0 0 0 1px #676767 inset}#grid-layout-preview .grid-layout-previewing{box-shadow:0 0 0 2px #676767 inset;display:flex;justify-content:center;align-items:center}.grid-layout-previewing.block{box-shadow:0 0 0 2px #676767 inset}.selected-tooltip:before{content:"";font-family:"Font Awesome 5 Free";font-weight:900}.browse-defualts-form-element{display:flex;justify-content:space-between}.browse-defualts-form-element select{width:49.5%}input[type=text].page-selector-filter{width:100%;margin-bottom:12px}#nav-page-links,#nav-custom-links{width:100%}.page-selector-filter.empty,#nav-page-links .nav-page-link,#nav-page-links .added.active.nav-page-link,#no-pages{display:none}#nav-page-links .active.nav-page-link{display:flex}.empty~#no-pages{display:block}.site-page-add{margin:0}.jstree>.jstree-node:first-child .jstree-anchor{margin-top:0}.block-pagelist-tree li:last-child{margin-bottom:6px}.selectable-themes,.current-theme{display:flex;flex-wrap:wrap}.selectable-themes img,.current-theme img{max-width:100%;height:auto;vertical-align:bottom;position:relative;z-index:1}.selectable-themes .error,.current-theme .error{background-color:#f4b4b4;border-radius:3px;padding:6px 10px;margin:6px 0;display:block;width:100%;order:2}.theme-thumbnail{align-self:flex-start}.current-theme .error+ul{font-family:monospace;padding:11px;border:1px solid #dfdfdf;list-style-type:none}.invalid .theme-thumbnail img{opacity:.5}.selectable-themes .theme{width:calc(33.33% - 24px);margin:0 24px 24px 0;padding:11px;border:1px solid #dfdfdf;background-color:#fff;display:flex;flex-wrap:wrap}.selectable-themes .theme:hover{border:3px solid #9f9f9f;padding:9px}.selectable-themes .invalid.theme:hover{border:1px solid #dfdfdf;padding:11px}.selectable-themes .theme-thumbnail{width:100%;margin-bottom:12px;border:1px solid #dfdfdf}.selectable-themes .active.theme{background-color:#e7e7e7;position:relative;overflow:hidden;border-width:3px;padding:9px}.selectable-themes .active.theme:after{content:"";font-family:"Font Awesome 5 Free";font-weight:900;position:absolute;bottom:0;right:0;opacity:.15;font-size:96px;line-height:96px}.current-theme{padding-bottom:23px;border-bottom:1px solid #dfdfdf;margin-bottom:24px;flex-wrap:nowrap}.current-theme .theme-thumbnail{width:50%;margin:0 24px 0 0;border:1px solid #dfdfdf}.current-theme .current-theme-info{width:calc(50% - 24px)}.current-theme-label{font-size:16px;text-transform:uppercase;display:block;margin-bottom:6px}.theme-meta{display:flex;flex-direction:column;width:100%}.theme-resource-pages .blocks{list-style:none;padding-left:0;border:1px solid #dfdfdf;padding:12px;min-height:30px}.theme-resource-pages .block{width:100%;background-color:rgba(0,0,0,.04);padding:6px;position:relative;margin-bottom:6px;display:flex;height:36px}.theme-resource-pages .block.delete{background-color:#fcc;padding-left:36px}.theme-resource-pages .block.delete>*:not(.block-header){display:block}.theme-resource-pages .block.delete .sortable-handle{display:none}.theme-resource-pages button:disabled{display:none}.jobs.browse th:first-child,.jobs.browse td:first-child{width:10%}body.minimal{padding:0;margin:48px 0;width:93.75%;max-width:100%;margin-left:auto;margin-right:auto;height:auto;background-color:#404e61}body.minimal:after{content:" ";display:block;clear:both}body.minimal div[role=main]>h1:first-of-type{position:static;padding:0;width:100%;height:auto;display:inline-block;margin:0 0 24px 0}body.minimal h2{font-size:20px;margin-bottom:12px}body.minimal h3{font-size:18px;margin-bottom:12px}body.minimal fieldset legend{font-weight:bold;font-size:20px;margin-bottom:12px}body.minimal .logo{position:static;width:auto;float:none;padding:0;text-align:center;font-size:32px;line-height:48px}body.minimal div[role=main]{width:100%;min-height:0;margin:0;padding:48px 6.25%;overflow:hidden}body.minimal .inputs{width:70%}body.minimal .inputs input{width:calc(66.66% - 6px);vertical-align:top}body.minimal .inputs *:only-child{width:100%}body.minimal [type=submit]{width:100%;display:block;margin:auto;clear:both}body.minimal .field:last-child{margin-bottom:0}body.minimal .site-list{margin-bottom:24px;display:flex;flex-wrap:wrap}body.minimal .site-list .site{margin-bottom:12px;overflow:auto;max-width:60rem;width:50%;padding-right:1rem}body.minimal .site-list .site-link{display:inline-block;font-size:18px}body.minimal .site-list .site-summary{margin:0;line-height:20px}body.minimal .site-list .site-thumbnail{float:left;display:block;margin-right:1rem}body.minimal .site-list .site-thumbnail-image{max-width:15rem;vertical-align:bottom}body.minimal .results{margin-bottom:24px}body.minimal .results>ul{padding-left:0}body.minimal .results>ul>li{list-style-type:none}body.minimal .advanced-search{margin:-12px 0 24px;display:block}body.minimal .advanced-search-actions{margin:12px 0}body.minimal .advanced-search-actions input[type=submit]{width:auto;display:inline-block}.forgot-password{margin:6px 0}.sitewide-search-form{display:flex;margin-bottom:24px}.sitewide-search-form input[type=text]{min-width:60%;margin-right:6px}.sitewide-search-form input[type=submit]{width:auto;margin:0}body.minimal .site.results thead{background-color:rgba(0,0,0,.04)}.results>ul{display:flex;flex-wrap:wrap;align-items:flex-start;margin-bottom:0}.results>ul>li{border:1px solid #dfdfdf;border-radius:3px;padding:6px 6px 0;margin-bottom:12px;width:calc(50% - 12px)}.results>ul>li:nth-child(2n){margin-left:12px}.results ul ul{list-style:none;padding:0;margin-top:6px}.results li li{padding:6px;border-top:1px solid #dfdfdf;margin:0px -6px}.results .result-title{background-color:rgba(0,0,0,.04);display:block;padding:6px;margin:-6px;font-weight:bold}.results+.pagination{margin-top:-24px}.site.results .result-title{border-bottom:1px solid #dfdfdf;margin-bottom:6px}.site.results .result-site{margin-bottom:6px;display:block}.asset-form-element{line-height:36px}.asset-form-element.empty .asset-form-clear{display:none}.asset-form-element:not(.empty) .no-selected-asset{display:none}.selected-asset,.no-selected-asset{display:block}.selected-asset-name:not(:empty)~.none-selected,.selected-page:empty+a,.selected-page:not(:empty)~.none-selected{display:none}.selected-asset-image{max-width:100%}.asset-form-select{margin-top:12px}.new.attachment{display:none}.asset-upload{overflow:hidden;margin-bottom:24px}.asset-upload button{margin:6px 0 0;display:none}.asset-upload button.active{display:inline-block}.asset-upload ul.errors{color:#a91919;margin-top:0;word-wrap:break-word}.asset-upload ul.errors:empty{display:none}.asset-upload ul.errors a{border-bottom:1px solid #a91919}.asset-upload label{margin:6px 0;padding:0}.asset-upload label:after{content:none}.asset-upload input[type=file]{width:100%}.asset-filters{margin-bottom:6px}.asset-list .asset{padding-bottom:5px;border-bottom:1px solid #dfdfdf;margin-bottom:6px}.asset-list .asset:last-child{border-bottom-color:transparent}.asset-entry{display:flex;align-items:center;word-wrap:break-word}.asset-entry img{margin-right:6px;max-height:48px;max-width:50%}.asset-entry .asset-name{flex-grow:1}.color-picker{display:flex}.color-picker input[type=text]{margin:0}.color-picker .color-picker-sample{border:1px solid #dfdfdf;width:30%;margin-left:6px}}@media screen and (max-width: 640px){script{display:none !important}body{padding:0}.mobile-only{display:block}button.mobile-only{width:100%}header{width:100%;float:none;text-align:center;position:fixed;top:0;left:0;padding:0;right:0;z-index:1000;min-height:0}header .button{border-radius:0px;position:absolute;top:0;z-index:1001;color:#fff;background-color:#222933;box-shadow:none}header .o-icon-menu.button{left:0;border-right:1px solid rgba(0,0,0,.08);width:36px}header .o-icon-search.button{left:36px}header .o-icon-user.button{right:0}header nav ul.navigation>li:not(:first-of-type){margin-top:0}.logo{line-height:36px;padding:0 16.6666666667%;width:100%;text-align:center;display:block;background-color:#404e61}#user,#search,header nav{position:fixed;top:-9999px;left:-9999px;z-index:1000}header nav#site-nav{position:static;background-color:#fff;padding:0;margin-bottom:0}header nav#site-nav h5{border-top:1px solid #dfdfdf;padding-top:6px -1px;margin-bottom:0}header nav#site-nav h5 a{padding:0;border-bottom:0}#menu.active,#user.active,#search.active{top:36px;left:0;bottom:0;right:0;background-color:#fff;margin:0}footer{margin:0;padding:0;position:static;width:100%;text-align:center}footer:after{position:static;background:transparent}.browse td:first-child,.browse th:first-child{width:100%}td .o-icon-private,td .o-icon-user-inactive{vertical-align:top;margin:0}div[role=main]{margin:36px 0 0 0;width:100%;min-height:calc(100% - 72px);position:relative;padding-top:48px}div[role=main]>h1:first-of-type{width:auto;position:static;padding:12px 1.0416666667%;height:auto;margin:0 -1.0416666667% 12px;white-space:normal;line-height:36px}#menu{text-align:left;background-color:#fff;position:fixed;overflow:scroll}#menu ul{margin-bottom:0;border-bottom:0;padding-bottom:0}#menu a{display:block;padding:6px 12px 5px;color:#676767;border-bottom:1px solid #dfdfdf}#menu li:last-child a{border-bottom:0;padding-bottom:6px}#menu h5 a{padding:0;border-bottom:0}#menu h5{height:36px;color:#676767;background-color:rgba(0,0,0,.04);padding:6px 12px 5px;border:1px solid #dfdfdf;border-width:1px 0}#menu h4{background-color:rgba(0,0,0,.12);margin-bottom:0}#menu h4:not(:first-of-type){margin-top:0}#menu a.public,#menu a.expand,#menu a.collapse{height:36px;margin:-36px 0 0;padding:0 12px 0 0}#menu a.public:before,#menu a.public:after,#menu a.expand:before,#menu a.expand:after,#menu a.collapse:before,#menu a.collapse:after{height:36px;line-height:36px}#mobile-nav{display:block}#mobile-nav a.active{background-color:#500c0c}#user{text-align:center}#user .user-id{color:#676767;width:100%;margin:0 6px 24px}#user .user-id a{color:#a91919}#user .logout{display:block;margin:12px 6px;font-size:16px;color:#676767;border-radius:3px;width:calc(100% - 12px);min-height:36px;background-color:rgba(0,0,0,.08);border-radius:3px;border:0;box-shadow:0 0 0 1px rgba(0,0,0,.15) inset;padding:6px 10px;display:inline-block;text-align:center;cursor:pointer;margin:0 6px}#user .logout:last-of-type:before{content:""}#user .logout a{color:#676767}#page-actions{top:36px;background-color:#fff;width:100%;border-bottom:1px solid rgba(0,0,0,.08);height:48px;padding-bottom:5px}#sidebar{position:fixed;top:36px;z-index:100;width:100%}#sidebar #content.sidebar-open{left:0}body.sidebar-open #content{width:100%}.sidebar{width:100%;top:36px;z-index:1000}.sidebar.always-open{left:100%}.sidebar.active,.confirm-panel{left:0;width:100%}fieldset.section>.always.active{content:"";bottom:0;left:0;right:0;height:48px;background-color:#fff;position:fixed;border-top:1px solid rgba(0,0,0,.04)}fieldset.section>.always.active button{width:100%;margin:6px}#modules .module-meta,#modules .module-actions{width:100%;max-width:100%}#modules .module-meta{margin-bottom:12px}#modules .module-actions{text-align:left}#modules button,#modules .button{margin:0 6px 0 0}.vocabs.update td{width:100% !important}#search-form{margin:48px 4.1666666667%}.batch-edit.button{margin:0;border-radius:0px;position:relative;z-index:1}.browse table{position:relative}.browse .sorting{float:left}.browse .pagination{margin-right:48px}.jobs.browse th:first-child,.jobs.browse td:first-child{width:100%}fieldset.section,fieldset.section{margin-bottom:0;position:relative}fieldset.section>legend:first-child{position:relative;left:auto;display:block;width:100%;font-size:20px;padding:6px 9px 6px 0;color:#a91919;cursor:pointer;border-bottom:3px solid rgba(0,0,0,.08);padding-bottom:-3px;margin-bottom:12px}fieldset.section>legend:after{content:"";font-family:"Font Awesome 5 Free";position:absolute;right:9px;top:12px}fieldset.section.mobile-active>legend:after{content:""}.add .active.section>.button,.edit .active.section>.button{display:inline-block}.field-meta,.inputs{width:100%}.field-actions{position:absolute;top:9px;right:1.6666666667%;z-index:1;width:50%}.field-actions a{float:right;display:block}.field-actions a.button{margin-left:.5em !important}.field-meta label,.field-description p{line-height:24px;margin-bottom:6px}.field-meta label{font-weight:bold}.unset .field-meta{width:100%}.show .sidebar.active{position:static;border:1px solid #dfdfdf;padding:11px;margin-top:24px}.show .section .property,.show .section .meta-group{margin-bottom:6px;box-shadow:0 0 0 1px #dfdfdf;border-radius:2px}.show .section .meta-group h4,.show .section .property h4{padding-bottom:6px;border-bottom:1px solid #dfdfdf;background-color:rgba(0,0,0,.04)}.show .section .meta-group h4,.show .section .meta-group .value,.show .section .property h4,.show .section .property .values{width:100% !important;padding:6px !important}.show .section .meta-group .value:not(:first-of-type),.show .section .property .value:not(:first-of-type){border-top:1px solid #dfdfdf;padding-top:6px -1px;margin-top:6px}.show .sidebar .meta-group .value:not(:first-of-type),.show .sidebar .property .value:not(:first-of-type){padding-top:6px}body.minimal{width:100%;margin:0}body.minimal .logo{background-color:transparent}body.minimal div[role=main]{padding:24px 6.25%}body.minimal div[role=main]>.messages{margin-top:24px}body.minimal .inputs{width:100%;margin-left:0}body.minimal footer{color:#fff}.tablesaw tr{overflow:hidden;margin-bottom:0}.tablesaw tr:first-of-type{border-top:1px solid #dfdfdf}.browse td:not(:first-of-type) .tablesaw-cell-content,#properties td:not(:first-of-type) .tablesaw-cell-content{display:inline-block}.tablesaw td:first-of-type{background-color:rgba(0,0,0,.04)}.tablesaw td:first-of-type .tablesaw-cell-label{width:0;height:0;overflow:hidden;padding:0;display:block}.tablesaw td:first-of-type .tablesaw-cell-content{width:100%;max-width:100%}.batch-edit.tablesaw td:first-of-type{width:100%;background:rgba(0,0,0,.04)}.batch-edit.tablesaw td:first-of-type img{margin-bottom:0}.batch-edit.tablesaw td:first-of-type .tablesaw-cell-label{width:0;overflow:hidden;padding:0}.batch-edit .tablesaw-cell-content{display:inline-flex}.tablesaw-cell-content{width:70%;max-width:70%}.tablesaw-cell-content img{margin:0 6px 0 0}.tablesaw tr:last-of-type td,.tablesaw tr:last-of-type th,.tablesaw th,.tablesaw td{padding-top:6px;padding-bottom:6px;vertical-align:top}.tablesaw th:not(:last-of-type),.tablesaw td:not(:last-of-type){border-bottom:1px solid #dfdfdf}.tablesaw tr.delete{border:0}.tablesaw tr.delete td{border:0}.tablesaw tr.delete td:not(:first-of-type){display:none}.resource-template th:first-of-type,.resource-template td:first-of-type{width:100%}#site-user-permissions tr.user.value{position:relative}#site-user-permissions td:nth-child(3){position:absolute;top:0;right:0;padding:0 6px 0 0}#site-user-permissions td:nth-child(3) .tablesaw-cell-label{display:none}#site-user-permissions td:nth-child(3) .tablesaw-cell-content{width:100%;max-width:100%}#site-user-permissions.tablesaw-stack tbody tr{border-bottom:0}} \ No newline at end of file diff --git a/application/asset/js/asset-browse.js b/application/asset/js/asset-browse.js index b612c6d8e3..0ac32dd29f 100644 --- a/application/asset/js/asset-browse.js +++ b/application/asset/js/asset-browse.js @@ -12,14 +12,20 @@ jQuery(function ($) { processData: false }).done(function () { window.location.reload(); - }).fail(function (jqXHR) { + }).fail(function (jqXHR, textStatus, errorThrown) { var errorList = form.find('ul.errors'); errorList.empty(); - $.each(JSON.parse(jqXHR.responseText), function () { + if ('application/json' === jqXHR.getResponseHeader('content-type')) { + $.each(JSON.parse(jqXHR.responseText), function () { + errorList.append($('
  • ', { + text: this + })); + }) + } else { errorList.append($('
  • ', { - text: this + text: errorThrown })); - }) + } }); }); }); diff --git a/application/asset/js/asset-form.js b/application/asset/js/asset-form.js index 8e08466541..ffbf931ce1 100644 --- a/application/asset/js/asset-form.js +++ b/application/asset/js/asset-form.js @@ -50,14 +50,20 @@ processData: false }).done(function () { Omeka.populateSidebarContent(sidebar, selectingForm.find('.asset-form-select').data('sidebar-content-url')); - }).fail(function (jqXHR) { + }).fail(function (jqXHR, textStatus, errorThrown) { var errorList = form.find('ul.errors'); errorList.empty(); - $.each(JSON.parse(jqXHR.responseText), function () { + if ('application/json' === jqXHR.getResponseHeader('content-type')) { + $.each(JSON.parse(jqXHR.responseText), function () { + errorList.append($('
  • ', { + text: this + })); + }) + } else { errorList.append($('
  • ', { - text: this + text: errorThrown })); - }) + } }); }); }); diff --git a/application/asset/js/item-manage-media.js b/application/asset/js/item-manage-media.js index 648e70ce73..987d8c795d 100644 --- a/application/asset/js/item-manage-media.js +++ b/application/asset/js/item-manage-media.js @@ -1,30 +1,36 @@ $(document).ready(function() { -var mediaList = $('#media-list'); -var index = mediaList.data('mediaCount'); +const mediaList = $('#media-list'); +let index = mediaList.data('mediaCount'); + +const createMediaFromTemplate = function(type) { + const mediaTemplate = $('#media-template-' + type) + .data('template') + .replace(/__index__/g, index++); + return $(mediaTemplate); +} + +const humanFileSize = function(size) { + const i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024)); + return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i]; +} new Sortable(mediaList[0], { - draggable: ".media", - handle: ".sortable-handle" + draggable: '.media', + handle: '.sortable-handle' }); -$('#media-selector button').click(function () { - var thisButton = $(this); - var type = thisButton.data('media-type'); - if (!type) { - return; - } - - var template = $('#media-template-' + type).data('template'); - mediaList.append(template.replace(/__index__/g, index++)); - thisButton.val(''); +$('#media-selector button').on('click', function(e) { + const thisButton = $(this); + const type = thisButton.data('media-type'); + mediaList.append(createMediaFromTemplate(type)); $('html, body').animate({ scrollTop: ($('.media-field-wrapper').last().offset().top -100) - },200); + }, 200); $('#media-list .no-resources').hide(); }); -$('#item-media').on('click', 'a.remove-new-media-field', function (e) { +$('#item-media').on('click', 'a.remove-new-media-field', function(e) { e.preventDefault(); $(this).parents(".media-field-wrapper").remove(); if ($('.media-field-wrapper').length < 1) { @@ -32,4 +38,62 @@ $('#item-media').on('click', 'a.remove-new-media-field', function (e) { } }); +// Handle file selection for upload media. +$(document).on('change', '.media-file-input', function(e) { + + const thisFileInput = $(this); + const thisUploadMedia = thisFileInput.closest('.media'); + const additionalUploadMedia = []; + + // Iterate every file in the FileList. + for (const [fileIndex, file] of Object.entries(this.files)) { + + let uploadMedia; + let fileInput; + + // Use the DataTransfer API to create a new FileList containing one + // file, then set the FileList to this file input or an additional file + // input if the original FileList contains more than one file. + const dataTransfer = new DataTransfer(); + dataTransfer.items.add(file); + if (0 == fileIndex) { + // Add the first file to this file input. + uploadMedia = thisUploadMedia; + fileInput = thisFileInput; + } else { + // Add each additional file to a new file input. + uploadMedia = createMediaFromTemplate('upload'); + fileInput = uploadMedia.find('.media-file-input'); + additionalUploadMedia.push(uploadMedia); + } + fileInput[0].files = dataTransfer.files; + + // Display file info. + uploadMedia.find('.media-file-info').remove(); + const fileInfo = $(fileInput.data('info-template')); + + // Add the formatted file size. + fileInfo.find('.media-file-size').html(humanFileSize(file.size)); + + // Add a thumbnail when the file is an image. + if ((/^image\/(png|jpe?g|gif)$/).test(file.type)) { + const imageSrc = URL.createObjectURL(file); + const img = new Image(); + img.onload = function() { + const maxSize = 100; + const smallestPercent = Math.min(maxSize / this.width, maxSize / this.height); + img.width = this.width * smallestPercent; + img.height = this.height * smallestPercent; + fileInfo.find('.media-file-thumbnail').html(img); + } + img.src = imageSrc; + } + + fileInput.closest('.inputs').append(fileInfo); + } + + // Append the additional upload interfaces in the order they were added. + thisUploadMedia.after(additionalUploadMedia); +}); + }); diff --git a/application/asset/js/site-page-edit.js b/application/asset/js/site-page-edit.js index abea7d9aa3..b387d83687 100644 --- a/application/asset/js/site-page-edit.js +++ b/application/asset/js/site-page-edit.js @@ -208,6 +208,11 @@ replaceIndex(thisAttachment, 'attachmentIndex', attachmentIndex); }); } + // Set block layout data to form. + const blockLayoutData = thisBlock.data('block-layout-data'); + blockLayoutData.grid_column_position = thisBlock.find('.block-page-layout-grid-column-position-select').val(); + blockLayoutData.grid_column_span = thisBlock.find('.block-page-layout-grid-column-span-select').val(); + thisBlock.find('.block-layout-data').val(JSON.stringify(blockLayoutData)); }); }); @@ -427,5 +432,290 @@ $('#content').on('click', '.page-clear', function() { resetAssetOption('#asset-options .page-link'); }); + + // Prepare page layout for use. + const preparePageLayout = function() { + const layoutSelect = $('#page-layout-select'); + const gridColumnsSelect = $('#page-layout-grid-columns-select'); + const gridColumnGapInput = $('#page-layout-grid-column-gap-input'); + const gridRowGapInput = $('#page-layout-grid-row-gap-input'); + const gridPreview = $('#preview-page-layout-grid'); + const blockGridControls = $('.block-page-layout-grid-controls'); + const blockGridPreview = $('.preview-block-page-layout-grid'); + // Disable and hide all layout-specific controls by default. + gridColumnsSelect.hide(); + gridColumnGapInput.closest('.field').hide(); + gridRowGapInput.closest('.field').hide(); + gridPreview.hide(); + blockGridControls.hide(); + blockGridPreview.hide(); + switch (layoutSelect.val()) { + case 'grid': + // Prepare grid layout. + gridColumnsSelect.show(); + gridColumnGapInput.closest('.field').show(); + gridRowGapInput.closest('.field').show(); + gridPreview.show(); + blockGridControls.show(); + blockGridPreview.show(); + preparePageGridLayout(); + break; + case '': + default: + // Prepare normal flow layout. Do nothing. + break; + } + }; + + // Prepare page grid layout for use. + const preparePageGridLayout = function() { + const gridColumns = parseInt($('#page-layout-grid-columns-select').val(), 10); + $('.block').each(function() { + const thisBlock = $(this); + const gridColumnPositionSelect = thisBlock.find('.block-page-layout-grid-column-position-select'); + const gridColumnPositionSelectValue = parseInt(gridColumnPositionSelect.val(), 10); + const gridColumnSpanSelect = thisBlock.find('.block-page-layout-grid-column-span-select'); + const gridColumnSpanSelectValue = parseInt(gridColumnSpanSelect.val(), 10); + // Hide invalid positions according to the column # and span #. + gridColumnPositionSelect.find('option').show() + .filter(function() { + const thisOption = $(this); + const thisValue = parseInt(thisOption.attr('value'), 10); + return (thisValue > gridColumns) || (thisValue > (1 + gridColumns - gridColumnSpanSelectValue)); + }).hide(); + // Hide invalid spans according to the column # and position #. + gridColumnSpanSelect.find('option').show() + .filter(function() { + const thisOption = $(this); + const thisValue = parseInt(thisOption.attr('value'), 10); + return (thisValue > gridColumns) || (thisValue > (1 + gridColumns - gridColumnPositionSelectValue)); + }).hide(); + }); + }; + + // Set layout-specific block controls to their default values. + const setPageLayoutBlockDefaults = function(blockElements) { + const layoutSelect = $('#page-layout-select'); + switch (layoutSelect.val()) { + case 'grid': + // Set grid layout defaults. + const gridColumns = $('#page-layout-grid-columns-select').val(); + blockElements.each(function() { + const thisBlock = $(this); + thisBlock.find('.block-page-layout-grid-column-position-select').val('auto'); + thisBlock.find('.block-page-layout-grid-column-span-select').val(gridColumns); + }); + break; + case '': + default: + // Set normal flow layout defaults. Do nothing. + break; + } + } + + // Preview the page layout grid. + const previewPageLayoutGrid = function() { + const gridLayoutPreview = $('#grid-layout-preview'); + const gridColumns = parseInt($('#page-layout-grid-columns-select').val(), 10); + gridLayoutPreview + .empty() + .css('grid-template-columns', `repeat(${gridColumns}, 1fr)`); + $('.block').each(function() { + const thisBlock = $(this); + const gridColumnPositionSelect = thisBlock.find('.block-page-layout-grid-column-position-select'); + const gridColumnPositionSelectValue = parseInt(gridColumnPositionSelect.val(), 10) || 'auto'; + const gridColumnSpanSelect = thisBlock.find('.block-page-layout-grid-column-span-select'); + const gridColumnSpanSelectValue = parseInt(gridColumnSpanSelect.val(), 10); + const selectedTooltip = $('
    '); + const blockDiv = $('
    ') + .css('grid-column', `${gridColumnPositionSelectValue} / span ${gridColumnSpanSelectValue}`); + if (thisBlock.hasClass('grid-layout-previewing')) { + blockDiv.addClass('grid-layout-previewing').append(selectedTooltip); + } + blockDiv.hover( + function() { + thisBlock.addClass('hovered-block'); + $(this).addClass('hovered-block'); + }, + function() { + thisBlock.removeClass('hovered-block'); + $(this).removeClass('hovered-block'); + } + ); + gridLayoutPreview.append(blockDiv); + }); + Omeka.openSidebar($('#grid-layout-preview-sidebar')); + }; + + // Prepare page layout on initial load. + preparePageLayout(); + + // Handle adding a block. + $('#blocks').on('o:block-added', '.block', function(e) { + const thisBlock = $(this); + setPageLayoutBlockDefaults(thisBlock); + preparePageLayout(); + }); + + // Handle a page layout change. + $('#page-layout-select').on('change', function() { + // Revert to the previous grid state, if any. + const columnsSelect = $('#page-layout-grid-columns-select'); + columnsSelect.val(columnsSelect.data('page-layout-grid-columns')); + $('.block').each(function() { + const thisBlock = $(this); + const positionSelect = thisBlock.find('.block-page-layout-grid-column-position-select'); + const spanSelect = thisBlock.find('.block-page-layout-grid-column-span-select'); + positionSelect.val(positionSelect.data('block-page-layout-grid-column-position')); + spanSelect.val(spanSelect.data('block-page-layout-grid-column-span')); + }); + preparePageLayout(); + $('#page-layout-restore').show(); + }); + + // Handle a grid columns change. + $('#page-layout-grid-columns-select').on('change', function() { + setPageLayoutBlockDefaults($('.block')); + preparePageGridLayout(); + $('#page-layout-restore').show(); + }); + + // Handle a grid position and grid span change. + $('#blocks').on('change', '.block-page-layout-grid-column-position-select, .block-page-layout-grid-column-span-select', function() { + preparePageGridLayout(); + $('#page-layout-restore').show(); + }); + + // Handle a page layout grid preview click. + $('#preview-page-layout-grid').on('click', function(e) { + e.preventDefault(); + $('.block').removeClass('grid-layout-previewing'); + previewPageLayoutGrid(); + }) + + $('#configure-page-layout-data').on('click', function(e) { + e.preventDefault(); + const pageLayoutDataSidebar = $('#page-layout-data-sidebar'); + Omeka.openSidebar(pageLayoutDataSidebar); + }); + + // Handle a page layout grid preview click for a specific block. + $('#blocks').on('click', '.preview-block-page-layout-grid', function(e) { + e.preventDefault(); + $('.block').removeClass('grid-layout-previewing'); + $(this).closest('.block').addClass('grid-layout-previewing'); + previewPageLayoutGrid(); + }); + + // Handle closing a page layout grid preview. + $('#grid-layout-preview-sidebar').on('o:sidebar-closed', function(e) { + $('.block').removeClass('grid-layout-previewing'); + }); + + // Handle a configure block layout click. (open the sidebar) + $('#blocks').on('click', '.configure-block-layout-data', function(e) { + e.preventDefault(); + const thisBlock = $(this).closest('.block'); + const blockLayout = thisBlock.data('block-layout'); + const blockLayoutData = thisBlock.data('block-layout-data'); + const blockLayoutDataSidebar = $('#block-layout-data-sidebar'); + $('.block').removeClass('block-layout-data-configuring'); + thisBlock.addClass('block-layout-data-configuring'); + + // Prepare form elements that need special handling. + const templateNameInput = $('#block-layout-data-template-name'); + const blockTemplates = templateNameInput.data('block-templates'); + let templateName = ''; + if (blockTemplates[blockLayout] && blockTemplates[blockLayout][blockLayoutData.template_name]) { + // Verify that the current theme provides this template. + templateName = blockLayoutData.template_name; + } + templateNameInput.empty() + .append(templateNameInput.data('empty-option')) + .append(templateNameInput.data('value-options')[blockLayout]); + if (blockLayoutData.background_image_asset) { + const apiEndpointUrl = blockLayoutDataSidebar.data('api-endpoint-url'); + const assetId = parseInt(blockLayoutData.background_image_asset, 10); + $.get(`${apiEndpointUrl}/assets/${assetId}`, function(data) { + blockLayoutDataSidebar.find('.selected-asset').show(); + blockLayoutDataSidebar.find('img.selected-asset-image').attr('src', data['o:asset_url']); + blockLayoutDataSidebar.find('selected-asset-name').attr('src', data['o:name']); + blockLayoutDataSidebar.find('.no-selected-asset').hide(); + blockLayoutDataSidebar.find('.asset-form-clear').show(); + }); + } else { + blockLayoutDataSidebar.find('.selected-asset').hide(); + blockLayoutDataSidebar.find('.no-selected-asset').show(); + blockLayoutDataSidebar.find('.asset-form-clear').hide(); + } + + // Automatically populate block layout data for inputs with a data-key attribute. + blockLayoutDataSidebar.find(':input[data-key]').each(function() { + const thisInput = $(this); + const key = thisInput.data('key'); + thisInput.val(blockLayoutData[key]); + }); + + // Allow special handling of block layout data. + $(document).trigger('o:prepare-block-layout-data', [thisBlock]); + + Omeka.openSidebar(blockLayoutDataSidebar); + }); + + // Handle a configure block layout apply changes click (close the sidebar). + $('#apply-block-layout-data').on('click', function(e) { + e.preventDefault(); + const block = $('.block-layout-data-configuring'); + const blockLayoutData = block.data('block-layout-data'); + + // Automatically apply block layout data for inputs with a data-key attribute. + $('#block-layout-data-sidebar').find(':input[data-key]').each(function() { + const thisInput = $(this); + const key = thisInput.data('key'); + blockLayoutData[key] = thisInput.val(); + }); + + // Allow special handling of block layout data. + $(document).trigger('o:apply-block-layout-data', [block]); + + Omeka.closeSidebar($('#block-layout-data-sidebar')); + }); + + // Handle a layout restore click. + $('#page-layout-restore').on('click', function() { + const restoreButton = $(this); + const layoutSelect = $('#page-layout-select'); + layoutSelect.val(layoutSelect.data('page-layout')); + preparePageLayout(); + switch (layoutSelect.val()) { + case 'grid': + // Restore grid layout. + const gridColumnsSelect = $('#page-layout-grid-columns-select'); + gridColumnsSelect.val(gridColumnsSelect.data('page-layout-grid-columns')); + $('.block').each(function() { + const thisBlock = $(this); + const gridColumnPositionSelect = thisBlock.find('.block-page-layout-grid-column-position-select'); + const gridColumnSpanSelect = thisBlock.find('.block-page-layout-grid-column-span-select'); + let originalGridColumnPosition = gridColumnPositionSelect.data('block-page-layout-grid-column-position'); + let originalGridColumnSpan = gridColumnSpanSelect.data('block-page-layout-grid-column-span'); + // Set default values if this is a new block. + if ('' === originalGridColumnPosition) { + originalGridColumnPosition = 'auto'; + } + if ('' === originalGridColumnSpan) { + originalGridColumnSpan = $('#page-layout-grid-columns-select').val(); + } + gridColumnPositionSelect.val(originalGridColumnPosition); + gridColumnSpanSelect.val(originalGridColumnSpan); + }); + preparePageGridLayout(); + break; + case '': + default: + // Restore normal flow layout. Do nothing. + break; + } + restoreButton.hide(); + }); }); })(window.jQuery); diff --git a/application/asset/js/vocabulary-form.js b/application/asset/js/vocabulary-form.js new file mode 100644 index 0000000000..37d818e812 --- /dev/null +++ b/application/asset/js/vocabulary-form.js @@ -0,0 +1,48 @@ +$(document).ready(function() { + +const fileUpload = $('#file-upload'); +const fileUrl = $('#file-url'); +const fileUploadField = fileUpload.closest('.field'); +const fileUrlField = fileUrl.closest('.field'); + +const selectedImportType = $('.import-type-select:checked'); +if ('upload' === selectedImportType.val()) { + fileUploadField.show(); + fileUrlField.hide(); +} else if ('url' === selectedImportType.val()) { + fileUploadField.hide(); + fileUrlField.show(); +} + +$('.import-type-select').on('change', function(e) { + const thisRadio = $(this); + if ('upload' === thisRadio.val()) { + fileUploadField.show(); + fileUrlField.hide(); + } else if ('url' === thisRadio.val()) { + fileUploadField.hide(); + fileUrlField.show(); + } +}); + +$('#vocabulary-form').on('submit', function(e) { + const namespaceUriInput = $('#o\\:namespace_uri'); + const namespaceUri = namespaceUriInput.val(); + const originalNamespaceUri = namespaceUriInput.data('originalNamespaceUri'); + + // The user must confirm that the namespace URI has changed. + if (originalNamespaceUri && (namespaceUri !== originalNamespaceUri)) { + if (!window.confirm(namespaceUriInput.data('confirmChange'))) { + e.preventDefault(); + } + } + + // The user must confirm that the namespace URI does not end with / or #. + if (!(namespaceUri.endsWith('/') || namespaceUri.endsWith('#'))) { + if (!window.confirm(namespaceUriInput.data('confirmEndsWith'))) { + e.preventDefault(); + } + } +}); + +}); diff --git a/application/asset/sass/_screen.scss b/application/asset/sass/_screen.scss index 512c08a77e..38d9e69e9b 100755 --- a/application/asset/sass/_screen.scss +++ b/application/asset/sass/_screen.scss @@ -689,11 +689,11 @@ a.collapse { .selector-table + .no-resources { display: none; } - + .selector-table.empty + .no-resources { display: block; } - + .selector .resources-available.empty, .selector .resources-available + .resources-unavailable { display: none; @@ -1688,7 +1688,7 @@ td .o-icon-user-inactive { .multi-value .value { display: flex; } - + .multi-value .add-value, .multi-value.field .remove-value { background-color: transparent; @@ -1715,13 +1715,13 @@ td .o-icon-user-inactive { color: $red; } } - + .multi-value .add-value { position: absolute; top: 0; right: 0; } - + .multi-value .field-meta { padding-right: 1.5 * $spacing-large; } @@ -2049,7 +2049,7 @@ fieldset.section > legend { padding: 0; border-bottom: 0; - a:empty { + a:empty { display: none; } @@ -2079,7 +2079,7 @@ fieldset.section > legend { display: flex; align-items: center; justify-content: center; - + &:before { font-size: 10px; } @@ -2177,7 +2177,7 @@ fieldset.section > legend { border-radius: 0 0 3px 3px; } } - + .selector li.selector-parent.empty { display: none; } @@ -2510,7 +2510,7 @@ fieldset.section > legend { #resource-values div.value { display: flex; align-items: stretch; - + &:only-of-type .sortable-handle { display: none; } @@ -2604,7 +2604,7 @@ fieldset.section > legend { display: block; } } - + .value.delete { background-color: $delete-bg; overflow: hidden; @@ -2612,7 +2612,8 @@ fieldset.section > legend { .value .restore-value, .value.delete a.tab, - .value.delete [class*="o-icon-"]:not(.restore-value) { + .value.delete [class*="o-icon-"]:not(.restore-value), + .value.delete .block-page-layout-grid-controls { display: none; } @@ -2658,13 +2659,13 @@ fieldset.section > legend { width: 100%; margin: 0; } - + .inputs .value textarea { min-height: 3 * $spacing-large; border: 0; box-shadow: 0 0 0 1px $border-gray; } - + .inputs .value .input-body > textarea { padding: $spacing-small $spacing-medium; } @@ -2750,7 +2751,7 @@ fieldset.section > legend { .selected-resource a { width: calc(100% - #{3 * $spacing-large}); } - + .selected-resource + a.button { margin-left: $spacing-small; } @@ -2882,7 +2883,7 @@ fieldset.section > legend { } } - .media.row .actions { + .media.row .actions { margin-left: $spacing-large; } @@ -2932,6 +2933,17 @@ fieldset.section > legend { text-align: left; } + .media-file-info { + display: flex; + align-items: flex-start; + flex-wrap: wrap; + } + + .media-file-thumbnail img { + vertical-align: bottom; + margin: $spacing-small $spacing-medium 0 0; + } + /* @end */ /* @group ----- Item Sets ----- */ @@ -2940,7 +2952,7 @@ fieldset.section > legend { #site-item-sets + .no-resources:before { content: fa-content($fa-var-cubes); } - + #item-item-sets tr.delete { background-color: $delete-bg; } @@ -2959,13 +2971,13 @@ fieldset.section > legend { } /* @end */ - + /* @group ----- Sites ----- */ - + #item-sites.empty + .no-resources:before { content: fa-content($fa-var-laptop); } - + /* @end */ /* @group ----- Media ----- */ @@ -3258,7 +3270,7 @@ fieldset.section > legend { margin-bottom: $spacing-medium; border-bottom: 3px solid $border-gray; - .label, + .label, label { margin: 0; width: auto; @@ -3321,7 +3333,7 @@ fieldset.section > legend { bottom: 0;; } -.sidebar #advanced-search .value select, +.sidebar #advanced-search .value select, .sidebar #advanced-search .value input { margin-left: 0; } @@ -3547,7 +3559,7 @@ input[type=text].query-form-query { width: 100%; } -.collapsible.annotation h4, +.collapsible.annotation h4, .collapsible.annotation .values { width: 100%; padding: 0; @@ -3590,6 +3602,10 @@ input[type=text].query-form-query { content: fa-content($fa-var-cubes); } + .sidebar .meta-group.item-sites .o-icon-external { + float: right; + } + /* @end */ /* @group ----- Resource Template: Show ----- */ @@ -3917,7 +3933,7 @@ body.sidebar-open #content { padding: 0 $spacing-small; margin: 0 $spacing-small; position: relative; - + &:after { content: ""; border-top: $spacing-medium solid transparent; @@ -3938,14 +3954,14 @@ body.sidebar-open #content { font-weight: bold; margin-left: auto; margin-right: $spacing-medium; - + &:after { content: "\f00c"; @include font-awesome; display: inline-block; margin-left: $spacing-small; } - + ~ .actions { margin-left: 0; } @@ -4109,43 +4125,43 @@ body.sidebar-open #content { } /* @group ----- Resources ----- */ - + #site-item-sets th:first-child, #site-item-sets th:last-child { width: 1.5 * $spacing-large; } - + .manual-assignment .inputs label { display: block; padding: 0; margin: $spacing-small 0 0; min-height: 0; line-height: $base-line-height; - + &:last-child { margin-bottom: $spacing-small; } } - + .manual-assignment #advanced-search { margin-top: -1 * $spacing-small; padding: $spacing-medium 0 $spacing-small; background-color: $gray-on-white; border-top: 1px solid $border-gray; - + &.inactive { display: none; } } - + .manual-assignment .advanced-search-header { padding: 0 $spacing-small; } - + .manual-assignment .advanced-search-header a.button { margin-bottom: $spacing-small; } - + .manual-assignment .advanced-search-content .field { background-color: transparent; } @@ -4154,9 +4170,9 @@ body.sidebar-open #content { .keep-search input { margin: 0 0 0 $spacing-small; } - - - + + + /* @end */ /* @group ----- User Permissions ----- */ @@ -4165,7 +4181,7 @@ body.sidebar-open #content { tr.value.delete > td:not(.input-footer) { display: table-cell; } - + tr.value.delete .user-name, tr.value.delete select, tr.value.delete .o-icon-delete { @@ -4189,13 +4205,43 @@ body.sidebar-open #content { /* @group ----- Pages ----- */ + #block-controls-header { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + margin-top: $spacing-medium; + } + + #page-layout-controls { + display: flex; + align-items: center; + justify-content: flex-end; + margin-bottom: $spacing-medium; + } + + #page-layout-label { + display: flex; + align-items: center; + } + + #page-layout-select { + margin-left: $spacing-small; + } + + #page-layout-controls > *:not(:last-child) { + margin-right: $spacing-small; + } + + #page-layout-controls button { + margin-bottom: 0; + } + .indent:before { content: "\2014"; margin-right: -1px; } .expand-collapse-all { - margin-top: $spacing-medium; text-align: right; } @@ -4216,6 +4262,19 @@ body.sidebar-open #content { text-align: center; } + .block .block-header .block-type { + margin-right: auto; + } + + .block .block-header select { + margin-right: $spacing-small; + font-weight: normal; + } + + .block-page-layout-grid-controls + .actions { + margin-left: 0; + } + .block .block-content input[type="hidden"] + * { padding-top: 0; margin-top: 0; @@ -4514,25 +4573,25 @@ body.sidebar-open #content { .add-asset-attachment { margin-top: $spacing-small; } - + #asset-options .sidebar-content > div { margin-bottom: 2rem; } - + .asset-attachment-select { margin-top: .5rem; } - + .asset-title { display: flex; align-items: center; } - + .asset-title img { height: 100%; width: auto; } - + .asset-title .thumbnail:not(:empty) { height: 2rem; position: relative; @@ -4542,7 +4601,7 @@ body.sidebar-open #content { display: inline-flex; justify-content: center; } - + #asset-options .none-selected.inactive { display: none; } @@ -4559,6 +4618,41 @@ body.sidebar-open #content { margin-left: $spacing-small; } + /* @group ----- Page Grid ----- */ + + #grid-layout-preview { + display: grid; + gap: $spacing-small; + } + + .grid-layout-previewing-block { + min-height: 60px; + background-color: $border-gray; + } + + .hovered-block { + box-shadow: 0 0 0 1px $copy-gray inset; + } + + #grid-layout-preview .grid-layout-previewing { + box-shadow: 0 0 0 2px $copy-gray inset; + display: flex; + justify-content: center; + align-items: center; + } + + .grid-layout-previewing.block { + box-shadow: 0 0 0 2px $copy-gray inset; + } + + .selected-tooltip:before { + content: fa-content($fa-var-asterisk); + font-family: "Font Awesome 5 Free"; + font-weight: 900; + } + + /* @end */ + /* @end */ /* @group ----- Site Admin ----- */ @@ -4640,7 +4734,7 @@ body.sidebar-open #content { order: 2; } } - + .theme-thumbnail { align-self: flex-start; } @@ -4713,7 +4807,7 @@ body.sidebar-open #content { margin: 0 $spacing-large 0 0; border: 1px solid $border-gray; } - + .current-theme .current-theme-info { width: calc(50% - #{$spacing-large}); } @@ -4737,11 +4831,12 @@ body.sidebar-open #content { /* @groups ----- Page Block Config ----- */ + .theme-resource-pages .blocks { list-style: none; padding-left: 0; - border: 1px solid $border-gray; - padding: $spacing-medium; + border: 1px solid $border-gray; + padding: $spacing-medium; min-height: 30px; } @@ -4861,7 +4956,7 @@ body.minimal { margin-bottom: $spacing-large; display: flex; flex-wrap: wrap; - + .site { margin-bottom: $spacing-medium; overflow: auto; @@ -4874,12 +4969,12 @@ body.minimal { display: inline-block; font-size: 1.125 * $base-font-size; } - + .site-summary { margin: 0; line-height: 20px; } - + .site-thumbnail { float: left; display: block; @@ -4895,23 +4990,23 @@ body.minimal { .results { margin-bottom: $spacing-large; } - + .results > ul { padding-left: 0; } - + .results > ul > li { list-style-type: none; } - + .advanced-search { margin: (-1 * $spacing-medium) 0 $spacing-large; display: block; } - + .advanced-search-actions { margin: $spacing-medium 0; - + input[type="submit"] { width: auto; display: inline-block; @@ -4923,15 +5018,15 @@ body.minimal { margin: $spacing-small 0; } -.sitewide-search-form { +.sitewide-search-form { display: flex; margin-bottom: $spacing-large; input[type="text"] { min-width: 60%; - margin-right: $spacing-small; + margin-right: $spacing-small; } - + input[type="submit"] { width: auto; margin: 0; @@ -4955,7 +5050,7 @@ body.minimal .site.results thead { padding: $spacing-small $spacing-small 0; margin-bottom: $spacing-medium; width: calc(50% - #{$spacing-medium}); - + &:nth-child(2n) { margin-left: $spacing-medium; } diff --git a/application/asset/sass/jstree.scss b/application/asset/sass/jstree.scss index 93c8e9f27b..d40720b7cf 100755 --- a/application/asset/sass/jstree.scss +++ b/application/asset/sass/jstree.scss @@ -61,6 +61,10 @@ } } +.value .jstree-editlink-container label { + line-height: 1.5 * $base-line-height; +} + .jstree-hovered, .jstree-clicked { background-color: opacify($gray-on-white, .08); diff --git a/application/asset/sass/page-blocks.scss b/application/asset/sass/page-blocks.scss index 155cbf04e2..68f38c8a94 100644 --- a/application/asset/sass/page-blocks.scss +++ b/application/asset/sass/page-blocks.scss @@ -1,5 +1,117 @@ @import "base"; + +.block-layout-background-position-y-top { + background-position-y: top; +} + +.block-layout-background-position-y-center { + background-position-y: center; +} + +.block-layout-background-position-y-bottom { + background-position-y: bottom; +} + +.block-layout-background-position-x-left { + background-position-x: left; +} + +.block-layout-background-position-x-center { + background-position-x: center; +} + +.block-layout-background-position-x-right { + background-position-x: right; +} + +.page-layout-normal .block-layout-alignment-right, +.page-layout-normal .block-layout-alignment-left { + overflow: hidden; + max-width: 33.33%; +} + +.block-layout-alignment-left .item.resource, +.block-layout-alignment-right .item.resource { + margin: 0 0 1rem 0; + + &:first-of-type { + padding-top: calc(1rem - 1px); + margin-top: 0; + } + + &:last-of-type { + padding-bottom: -1px; + } + + .media-render a { + display: block; + } + + audio, + canvas, + video, + progress, + img { + max-width: 100%; + vertical-align: bottom; + margin-bottom: .5rem; + } +} + +.block-layout-alignment-left { + float: left; + clear: left; + margin: 0 1rem 1rem 0; +} + +.block-layout-alignment-right { + float: right; + clear: right; + margin: 0 0 1rem 1rem; +} + +.block-layout-alignment-center { + display: flex; + justify-content: center; + flex-wrap: wrap; + text-align: center; + + .item { + width: 100%; + } +} + +.block-layout-alignment-left .item.resource > a:first-child, +.block-layout-alignment-right .item.resource > a:first-child { + vertical-align: top; +} + + + +.block-layout-alignment-left .item.resource > h3, +.block-layout-alignment-right .item.resource > h3 { + margin: 0; +} + +.block-layout-alignment-left .item.resource + p, +.block-layout-alignment-right .item.resource + p { + margin-top: 0; +} + +.block-layout-background-size-cover, +.block-layout-background-size-contain { + background-repeat: no-repeat; +} + +.block-layout-background-size-cover { + background-size: cover; +} + +.block-layout-background-size-contain { + background-size: contain; +} + .item-showcase { margin: 1rem 0; border-top: 1px solid $border-gray; @@ -61,40 +173,6 @@ } } -.right, -.left { - overflow: hidden; - max-width: 33.33%; -} - -.left .item.resource, -.right .item.resource { - margin: 0 0 1rem 0; - - &:first-of-type { - padding-top: calc(1rem - 1px); - margin-top: 0; - } - - &:last-of-type { - padding-bottom: -1px; - } - - .media-render a { - display: block; - } - - audio, - canvas, - video, - progress, - img { - max-width: 100%; - vertical-align: bottom; - margin-bottom: .5rem; - } -} - /* IE/Edge min-content alternative */ .file { border-top: 1px solid $border-gray; @@ -103,53 +181,12 @@ margin-bottom: 1rem; } -.left.file, -.left.assets { - float: left; - clear: left; - margin: 0 1rem 1rem 0; -} - -.right.file, -.right.assets { - float: right; - clear: right; - margin: 0 0 1rem 1rem; -} - -.center.file, -.center.assets { - display: flex; - justify-content: center; - flex-wrap: wrap; - text-align: center; - - .item { - width: 100%; - } -} - -.left .item.resource > a:first-child, -.right .item.resource > a:first-child { - vertical-align: top; -} - .medium .item.resource > h3, .square .item.resource > h3 { font-size: $base-font-size; line-height: 1.5rem; } -.left .item.resource > h3, -.right .item.resource > h3 { - margin: 0; -} - -.left .item.resource + p, -.right .item.resource + p { - margin-top: 0; -} - .break { width: 100%; clear: both; @@ -268,4 +305,5 @@ .page-date-time .value { display: inline-block; margin: 0; -} \ No newline at end of file +} + diff --git a/application/asset/sass/page-grid.scss b/application/asset/sass/page-grid.scss new file mode 100644 index 0000000000..a240a7876d --- /dev/null +++ b/application/asset/sass/page-grid.scss @@ -0,0 +1,13 @@ +.page-layout-grid { + display: grid; +} + +.page-layout-grid > div { + min-height: 50px; +} + +@media screen and (max-width:896px) { + .page-layout-grid { + display: block; + } +} diff --git a/application/asset/vendor/compare-versions/index.js b/application/asset/vendor/compare-versions/index.js new file mode 100644 index 0000000000..2cfef261bc --- /dev/null +++ b/application/asset/vendor/compare-versions/index.js @@ -0,0 +1,216 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.compareVersions = {})); +})(this, (function (exports) { 'use strict'; + + const semver = /^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i; + const validateAndParse = (version) => { + if (typeof version !== 'string') { + throw new TypeError('Invalid argument expected string'); + } + const match = version.match(semver); + if (!match) { + throw new Error(`Invalid argument not valid semver ('${version}' received)`); + } + match.shift(); + return match; + }; + const isWildcard = (s) => s === '*' || s === 'x' || s === 'X'; + const tryParse = (v) => { + const n = parseInt(v, 10); + return isNaN(n) ? v : n; + }; + const forceType = (a, b) => typeof a !== typeof b ? [String(a), String(b)] : [a, b]; + const compareStrings = (a, b) => { + if (isWildcard(a) || isWildcard(b)) + return 0; + const [ap, bp] = forceType(tryParse(a), tryParse(b)); + if (ap > bp) + return 1; + if (ap < bp) + return -1; + return 0; + }; + const compareSegments = (a, b) => { + for (let i = 0; i < Math.max(a.length, b.length); i++) { + const r = compareStrings(a[i] || '0', b[i] || '0'); + if (r !== 0) + return r; + } + return 0; + }; + + /** + * Compare [semver](https://semver.org/) version strings to find greater, equal or lesser. + * This library supports the full semver specification, including comparing versions with different number of digits like `1.0.0`, `1.0`, `1`, and pre-release versions like `1.0.0-alpha`. + * @param v1 - First version to compare + * @param v2 - Second version to compare + * @returns Numeric value compatible with the [Array.sort(fn) interface](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters). + */ + const compareVersions = (v1, v2) => { + // validate input and split into segments + const n1 = validateAndParse(v1); + const n2 = validateAndParse(v2); + // pop off the patch + const p1 = n1.pop(); + const p2 = n2.pop(); + // validate numbers + const r = compareSegments(n1, n2); + if (r !== 0) + return r; + // validate pre-release + if (p1 && p2) { + return compareSegments(p1.split('.'), p2.split('.')); + } + else if (p1 || p2) { + return p1 ? -1 : 1; + } + return 0; + }; + + /** + * Compare [semver](https://semver.org/) version strings using the specified operator. + * + * @param v1 First version to compare + * @param v2 Second version to compare + * @param operator Allowed arithmetic operator to use + * @returns `true` if the comparison between the firstVersion and the secondVersion satisfies the operator, `false` otherwise. + * + * @example + * ``` + * compare('10.1.8', '10.0.4', '>'); // return true + * compare('10.0.1', '10.0.1', '='); // return true + * compare('10.1.1', '10.2.2', '<'); // return true + * compare('10.1.1', '10.2.2', '<='); // return true + * compare('10.1.1', '10.2.2', '>='); // return false + * ``` + */ + const compare = (v1, v2, operator) => { + // validate input operator + assertValidOperator(operator); + // since result of compareVersions can only be -1 or 0 or 1 + // a simple map can be used to replace switch + const res = compareVersions(v1, v2); + return operatorResMap[operator].includes(res); + }; + const operatorResMap = { + '>': [1], + '>=': [0, 1], + '=': [0], + '<=': [-1, 0], + '<': [-1], + '!=': [-1, 1], + }; + const allowedOperators = Object.keys(operatorResMap); + const assertValidOperator = (op) => { + if (typeof op !== 'string') { + throw new TypeError(`Invalid operator type, expected string but got ${typeof op}`); + } + if (allowedOperators.indexOf(op) === -1) { + throw new Error(`Invalid operator, expected one of ${allowedOperators.join('|')}`); + } + }; + + /** + * Match [npm semver](https://docs.npmjs.com/cli/v6/using-npm/semver) version range. + * + * @param version Version number to match + * @param range Range pattern for version + * @returns `true` if the version number is within the range, `false` otherwise. + * + * @example + * ``` + * satisfies('1.1.0', '^1.0.0'); // return true + * satisfies('1.1.0', '~1.0.0'); // return false + * ``` + */ + const satisfies = (version, range) => { + // clean input + range = range.replace(/([><=]+)\s+/g, '$1'); + // handle multiple comparators + if (range.includes('||')) { + return range.split('||').some((r) => satisfies(version, r)); + } + else if (range.includes(' - ')) { + const [a, b] = range.split(' - ', 2); + return satisfies(version, `>=${a} <=${b}`); + } + else if (range.includes(' ')) { + return range + .trim() + .replace(/\s{2,}/g, ' ') + .split(' ') + .every((r) => satisfies(version, r)); + } + // if no range operator then "=" + const m = range.match(/^([<>=~^]+)/); + const op = m ? m[1] : '='; + // if gt/lt/eq then operator compare + if (op !== '^' && op !== '~') + return compare(version, range, op); + // else range of either "~" or "^" is assumed + const [v1, v2, v3, , vp] = validateAndParse(version); + const [r1, r2, r3, , rp] = validateAndParse(range); + const v = [v1, v2, v3]; + const r = [r1, r2 !== null && r2 !== void 0 ? r2 : 'x', r3 !== null && r3 !== void 0 ? r3 : 'x']; + // validate pre-release + if (rp) { + if (!vp) + return false; + if (compareSegments(v, r) !== 0) + return false; + if (compareSegments(vp.split('.'), rp.split('.')) === -1) + return false; + } + // first non-zero number + const nonZero = r.findIndex((v) => v !== '0') + 1; + // pointer to where segments can be >= + const i = op === '~' ? 2 : nonZero > 1 ? nonZero : 1; + // before pointer must be equal + if (compareSegments(v.slice(0, i), r.slice(0, i)) !== 0) + return false; + // after pointer must be >= + if (compareSegments(v.slice(i), r.slice(i)) === -1) + return false; + return true; + }; + + /** + * Validate [semver](https://semver.org/) version strings. + * + * @param version Version number to validate + * @returns `true` if the version number is a valid semver version number, `false` otherwise. + * + * @example + * ``` + * validate('1.0.0-rc.1'); // return true + * validate('1.0-rc.1'); // return false + * validate('foo'); // return false + * ``` + */ + const validate = (version) => typeof version === 'string' && /^[v\d]/.test(version) && semver.test(version); + /** + * Validate [semver](https://semver.org/) version strings strictly. Will not accept wildcards and version ranges. + * + * @param version Version number to validate + * @returns `true` if the version number is a valid semver version number `false` otherwise + * + * @example + * ``` + * validate('1.0.0-rc.1'); // return true + * validate('1.0-rc.1'); // return false + * validate('foo'); // return false + * ``` + */ + const validateStrict = (version) => typeof version === 'string' && + /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(version); + + exports.compare = compare; + exports.compareVersions = compareVersions; + exports.satisfies = satisfies; + exports.validate = validate; + exports.validateStrict = validateStrict; + +})); +//# sourceMappingURL=index.js.map diff --git a/application/asset/vendor/semver/semver.min.js b/application/asset/vendor/semver/semver.min.js deleted file mode 100644 index dea027b11b..0000000000 --- a/application/asset/vendor/semver/semver.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(e){if(typeof module==="object"&&module.exports===e)e=module.exports=K;e.SEMVER_SPEC_VERSION="2.0.0";var r=256;var t=Number.MAX_SAFE_INTEGER||9007199254740991;var n=e.re=[];var i=e.src=[];var s=0;var o=s++;i[o]="0|[1-9]\\d*";var a=s++;i[a]="[0-9]+";var f=s++;i[f]="\\d*[a-zA-Z-][a-zA-Z0-9-]*";var u=s++;i[u]="("+i[o]+")\\."+"("+i[o]+")\\."+"("+i[o]+")";var l=s++;i[l]="("+i[a]+")\\."+"("+i[a]+")\\."+"("+i[a]+")";var p=s++;i[p]="(?:"+i[o]+"|"+i[f]+")";var c=s++;i[c]="(?:"+i[a]+"|"+i[f]+")";var h=s++;i[h]="(?:-("+i[p]+"(?:\\."+i[p]+")*))";var v=s++;i[v]="(?:-?("+i[c]+"(?:\\."+i[c]+")*))";var m=s++;i[m]="[0-9A-Za-z-]+";var g=s++;i[g]="(?:\\+("+i[m]+"(?:\\."+i[m]+")*))";var w=s++;var y="v?"+i[u]+i[h]+"?"+i[g]+"?";i[w]="^"+y+"$";var d="[v=\\s]*"+i[l]+i[v]+"?"+i[g]+"?";var j=s++;i[j]="^"+d+"$";var b=s++;i[b]="((?:<|>)?=?)";var E=s++;i[E]=i[a]+"|x|X|\\*";var $=s++;i[$]=i[o]+"|x|X|\\*";var k=s++;i[k]="[v=\\s]*("+i[$]+")"+"(?:\\.("+i[$]+")"+"(?:\\.("+i[$]+")"+"(?:"+i[h]+")?"+i[g]+"?"+")?)?";var R=s++;i[R]="[v=\\s]*("+i[E]+")"+"(?:\\.("+i[E]+")"+"(?:\\.("+i[E]+")"+"(?:"+i[v]+")?"+i[g]+"?"+")?)?";var S=s++;i[S]="^"+i[b]+"\\s*"+i[k]+"$";var x=s++;i[x]="^"+i[b]+"\\s*"+i[R]+"$";var I=s++;i[I]="(?:~>?)";var T=s++;i[T]="(\\s*)"+i[I]+"\\s+";n[T]=new RegExp(i[T],"g");var V="$1~";var A=s++;i[A]="^"+i[I]+i[k]+"$";var C=s++;i[C]="^"+i[I]+i[R]+"$";var M=s++;i[M]="(?:\\^)";var N=s++;i[N]="(\\s*)"+i[M]+"\\s+";n[N]=new RegExp(i[N],"g");var _="$1^";var z=s++;i[z]="^"+i[M]+i[k]+"$";var P=s++;i[P]="^"+i[M]+i[R]+"$";var X=s++;i[X]="^"+i[b]+"\\s*("+d+")$|^$";var Z=s++;i[Z]="^"+i[b]+"\\s*("+y+")$|^$";var q=s++;i[q]="(\\s*)"+i[b]+"\\s*("+d+"|"+i[k]+")";n[q]=new RegExp(i[q],"g");var L="$1$2$3";var F=s++;i[F]="^\\s*("+i[k]+")"+"\\s+-\\s+"+"("+i[k]+")"+"\\s*$";var G=s++;i[G]="^\\s*("+i[R]+")"+"\\s+-\\s+"+"("+i[R]+")"+"\\s*$";var O=s++;i[O]="(<|>)?=?\\s*\\*";for(var B=0;Br)return null;var i=t?n[j]:n[w];if(!i.test(e))return null;try{return new K(e,t)}catch(s){return null}}e.valid=H;function H(e,r){var t=D(e,r);return t?t.version:null}e.clean=J;function J(e,r){var t=D(e.trim().replace(/^[=v]+/,""),r);return t?t.version:null}e.SemVer=K;function K(e,i){if(e instanceof K){if(e.loose===i)return e;else e=e.version}else if(typeof e!=="string"){throw new TypeError("Invalid Version: "+e)}if(e.length>r)throw new TypeError("version is longer than "+r+" characters");if(!(this instanceof K))return new K(e,i);this.loose=i;var s=e.trim().match(i?n[j]:n[w]);if(!s)throw new TypeError("Invalid Version: "+e);this.raw=e;this.major=+s[1];this.minor=+s[2];this.patch=+s[3];if(this.major>t||this.major<0)throw new TypeError("Invalid major version");if(this.minor>t||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>t||this.patch<0)throw new TypeError("Invalid patch version");if(!s[4])this.prerelease=[];else this.prerelease=s[4].split(".").map(function(e){if(/^[0-9]+$/.test(e)){var r=+e;if(r>=0&&r'};K.prototype.toString=function(){return this.version};K.prototype.compare=function(e){if(!(e instanceof K))e=new K(e,this.loose);return this.compareMain(e)||this.comparePre(e)};K.prototype.compareMain=function(e){if(!(e instanceof K))e=new K(e,this.loose);return Y(this.major,e.major)||Y(this.minor,e.minor)||Y(this.patch,e.patch)};K.prototype.comparePre=function(e){if(!(e instanceof K))e=new K(e,this.loose);if(this.prerelease.length&&!e.prerelease.length)return-1;else if(!this.prerelease.length&&e.prerelease.length)return 1;else if(!this.prerelease.length&&!e.prerelease.length)return 0;var r=0;do{var t=this.prerelease[r];var n=e.prerelease[r];if(t===undefined&&n===undefined)return 0;else if(n===undefined)return 1;else if(t===undefined)return-1;else if(t===n)continue;else return Y(t,n)}while(++r)};K.prototype.inc=function(e,r){switch(e){case"premajor":this.prerelease.length=0;this.patch=0;this.minor=0;this.major++;this.inc("pre",r);break;case"preminor":this.prerelease.length=0;this.patch=0;this.minor++;this.inc("pre",r);break;case"prepatch":this.prerelease.length=0;this.inc("patch",r);this.inc("pre",r);break;case"prerelease":if(this.prerelease.length===0)this.inc("patch",r);this.inc("pre",r);break;case"major":if(this.minor!==0||this.patch!==0||this.prerelease.length===0)this.major++;this.minor=0;this.patch=0;this.prerelease=[];break;case"minor":if(this.patch!==0||this.prerelease.length===0)this.minor++;this.patch=0;this.prerelease=[];break;case"patch":if(this.prerelease.length===0)this.patch++;this.prerelease=[];break;case"pre":if(this.prerelease.length===0)this.prerelease=[0];else{var t=this.prerelease.length;while(--t>=0){if(typeof this.prerelease[t]==="number"){this.prerelease[t]++;t=-2}}if(t===-1)this.prerelease.push(0)}if(r){if(this.prerelease[0]===r){if(isNaN(this.prerelease[1]))this.prerelease=[r,0]}else this.prerelease=[r,0]}break;default:throw new Error("invalid increment argument: "+e)}this.format();return this};e.inc=Q;function Q(e,r,t,n){if(typeof t==="string"){n=t;t=undefined}try{return new K(e,t).inc(r,n).version}catch(i){return null}}e.diff=U;function U(e,r){if(pr(e,r)){return null}else{var t=D(e);var n=D(r);if(t.prerelease.length||n.prerelease.length){for(var i in t){if(i==="major"||i==="minor"||i==="patch"){if(t[i]!==n[i]){return"pre"+i}}}return"prerelease"}for(var i in t){if(i==="major"||i==="minor"||i==="patch"){if(t[i]!==n[i]){return i}}}}}e.compareIdentifiers=Y;var W=/^[0-9]+$/;function Y(e,r){var t=W.test(e);var n=W.test(r);if(t&&n){e=+e;r=+r}return t&&!n?-1:n&&!t?1:er?1:0}e.rcompareIdentifiers=er;function er(e,r){return Y(r,e)}e.major=rr;function rr(e,r){return new K(e,r).major}e.minor=tr;function tr(e,r){return new K(e,r).minor}e.patch=nr;function nr(e,r){return new K(e,r).patch}e.compare=ir;function ir(e,r,t){return new K(e,t).compare(r)}e.compareLoose=sr;function sr(e,r){return ir(e,r,true)}e.rcompare=or;function or(e,r,t){return ir(r,e,t)}e.sort=ar;function ar(r,t){return r.sort(function(r,n){return e.compare(r,n,t)})}e.rsort=fr;function fr(r,t){return r.sort(function(r,n){return e.rcompare(r,n,t)})}e.gt=ur;function ur(e,r,t){return ir(e,r,t)>0}e.lt=lr;function lr(e,r,t){return ir(e,r,t)<0}e.eq=pr;function pr(e,r,t){return ir(e,r,t)===0}e.neq=cr;function cr(e,r,t){return ir(e,r,t)!==0}e.gte=hr;function hr(e,r,t){return ir(e,r,t)>=0}e.lte=vr;function vr(e,r,t){return ir(e,r,t)<=0}e.cmp=mr;function mr(e,r,t,n){var i;switch(r){case"===":if(typeof e==="object")e=e.version;if(typeof t==="object")t=t.version;i=e===t;break;case"!==":if(typeof e==="object")e=e.version;if(typeof t==="object")t=t.version;i=e!==t;break;case"":case"=":case"==":i=pr(e,t,n);break;case"!=":i=cr(e,t,n);break;case">":i=ur(e,t,n);break;case">=":i=hr(e,t,n);break;case"<":i=lr(e,t,n);break;case"<=":i=vr(e,t,n);break;default:throw new TypeError("Invalid operator: "+r)}return i}e.Comparator=gr;function gr(e,r){if(e instanceof gr){if(e.loose===r)return e;else e=e.value}if(!(this instanceof gr))return new gr(e,r);this.loose=r;this.parse(e);if(this.semver===wr)this.value="";else this.value=this.operator+this.semver.version}var wr={};gr.prototype.parse=function(e){var r=this.loose?n[X]:n[Z];var t=e.match(r);if(!t)throw new TypeError("Invalid comparator: "+e);this.operator=t[1];if(this.operator==="=")this.operator="";if(!t[2])this.semver=wr;else this.semver=new K(t[2],this.loose)};gr.prototype.inspect=function(){return''};gr.prototype.toString=function(){return this.value};gr.prototype.test=function(e){if(this.semver===wr)return true;if(typeof e==="string")e=new K(e,this.loose);return mr(e,this.operator,this.semver,this.loose)};e.Range=yr;function yr(e,r){if(e instanceof yr&&e.loose===r)return e;if(!(this instanceof yr))return new yr(e,r);this.loose=r;this.raw=e;this.set=e.split(/\s*\|\|\s*/).map(function(e){return this.parseRange(e.trim())},this).filter(function(e){return e.length});if(!this.set.length){throw new TypeError("Invalid SemVer Range: "+e)}this.format()}yr.prototype.inspect=function(){return''};yr.prototype.format=function(){this.range=this.set.map(function(e){return e.join(" ").trim()}).join("||").trim();return this.range};yr.prototype.toString=function(){return this.range};yr.prototype.parseRange=function(e){var r=this.loose;e=e.trim();var t=r?n[G]:n[F];e=e.replace(t,Tr);e=e.replace(n[q],L);e=e.replace(n[T],V);e=e.replace(n[N],_);e=e.split(/\s+/).join(" ");var i=r?n[X]:n[Z];var s=e.split(" ").map(function(e){return jr(e,r)}).join(" ").split(/\s+/);if(this.loose){s=s.filter(function(e){return!!e.match(i)})}s=s.map(function(e){return new gr(e,r)});return s};e.toComparators=dr;function dr(e,r){return new yr(e,r).set.map(function(e){return e.map(function(e){return e.value}).join(" ").trim().split(" ")})}function jr(e,r){e=kr(e,r);e=Er(e,r);e=Sr(e,r);e=Ir(e,r);return e}function br(e){return!e||e.toLowerCase()==="x"||e==="*"}function Er(e,r){return e.trim().split(/\s+/).map(function(e){return $r(e,r)}).join(" ")}function $r(e,r){var t=r?n[C]:n[A];return e.replace(t,function(e,r,t,n,i){var s;if(br(r))s="";else if(br(t))s=">="+r+".0.0 <"+(+r+1)+".0.0";else if(br(n))s=">="+r+"."+t+".0 <"+r+"."+(+t+1)+".0";else if(i){if(i.charAt(0)!=="-")i="-"+i;s=">="+r+"."+t+"."+n+i+" <"+r+"."+(+t+1)+".0"}else s=">="+r+"."+t+"."+n+" <"+r+"."+(+t+1)+".0";return s})}function kr(e,r){return e.trim().split(/\s+/).map(function(e){return Rr(e,r)}).join(" ")}function Rr(e,r){var t=r?n[P]:n[z];return e.replace(t,function(e,r,t,n,i){var s;if(br(r))s="";else if(br(t))s=">="+r+".0.0 <"+(+r+1)+".0.0";else if(br(n)){if(r==="0")s=">="+r+"."+t+".0 <"+r+"."+(+t+1)+".0";else s=">="+r+"."+t+".0 <"+(+r+1)+".0.0"}else if(i){if(i.charAt(0)!=="-")i="-"+i;if(r==="0"){if(t==="0")s=">="+r+"."+t+"."+n+i+" <"+r+"."+t+"."+(+n+1);else s=">="+r+"."+t+"."+n+i+" <"+r+"."+(+t+1)+".0"}else s=">="+r+"."+t+"."+n+i+" <"+(+r+1)+".0.0"}else{if(r==="0"){if(t==="0")s=">="+r+"."+t+"."+n+" <"+r+"."+t+"."+(+n+1);else s=">="+r+"."+t+"."+n+" <"+r+"."+(+t+1)+".0"}else s=">="+r+"."+t+"."+n+" <"+(+r+1)+".0.0"}return s})}function Sr(e,r){return e.split(/\s+/).map(function(e){return xr(e,r)}).join(" ")}function xr(e,r){e=e.trim();var t=r?n[x]:n[S];return e.replace(t,function(e,r,t,n,i,s){var o=br(t);var a=o||br(n);var f=a||br(i);var u=f;if(r==="="&&u)r="";if(o){if(r===">"||r==="<"){e="<0.0.0"}else{e="*"}}else if(r&&u){if(a)n=0;if(f)i=0;if(r===">"){r=">=";if(a){t=+t+1;n=0;i=0}else if(f){n=+n+1;i=0}}else if(r==="<="){r="<";if(a)t=+t+1;else n=+n+1}e=r+t+"."+n+"."+i}else if(a){e=">="+t+".0.0 <"+(+t+1)+".0.0"}else if(f){e=">="+t+"."+n+".0 <"+t+"."+(+n+1)+".0"}return e})}function Ir(e,r){return e.trim().replace(n[O],"")}function Tr(e,r,t,n,i,s,o,a,f,u,l,p,c){if(br(t))r="";else if(br(n))r=">="+t+".0.0";else if(br(i))r=">="+t+"."+n+".0";else r=">="+r;if(br(f))a="";else if(br(u))a="<"+(+f+1)+".0.0";else if(br(l))a="<"+f+"."+(+u+1)+".0";else if(p)a="<="+f+"."+u+"."+l+"-"+p;else a="<="+a;return(r+" "+a).trim()}yr.prototype.test=function(e){if(!e)return false;if(typeof e==="string")e=new K(e,this.loose);for(var r=0;r0){var n=e[t].semver;if(n.major===r.major&&n.minor===r.minor&&n.patch===r.patch)return true}}return false}return true}e.satisfies=Ar;function Ar(e,r,t){try{r=new yr(r,t)}catch(n){return false}return r.test(e)}e.maxSatisfying=Cr;function Cr(e,r,t){return e.filter(function(e){return Ar(e,r,t)}).sort(function(e,r){return or(e,r,t)})[0]||null}e.validRange=Mr;function Mr(e,r){try{return new yr(e,r).range||"*"}catch(t){return null}}e.ltr=Nr;function Nr(e,r,t){return zr(e,r,"<",t)}e.gtr=_r;function _r(e,r,t){return zr(e,r,">",t)}e.outside=zr;function zr(e,r,t,n){e=new K(e,n);r=new yr(r,n);var i,s,o,a,f;switch(t){case">":i=ur;s=vr;o=lr;a=">";f=">=";break;case"<":i=lr;s=hr;o=ur;a="<";f="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(Ar(e,r,n)){return false}for(var u=0;u=0.0.0")}p=p||e;c=c||e;if(i(e.semver,p.semver,n)){p=e}else if(o(e.semver,c.semver,n)){c=e}});if(p.operator===a||p.operator===f){return false}if((!c.operator||c.operator===a)&&s(e,c.semver)){return false}else if(c.operator===f&&o(e,c.semver)){return false}}return true}if(typeof define==="function"&&define.amd)define(e)})(typeof exports==="object"?exports:typeof define==="function"&&define.amd?{}:semver={}); \ No newline at end of file diff --git a/application/config/module.config.php b/application/config/module.config.php index 6111c268f4..f9291fcc5d 100644 --- a/application/config/module.config.php +++ b/application/config/module.config.php @@ -40,6 +40,21 @@ ], ], ], + 'api_assets' => [ + 'allowed_media_types' => [ + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/webp', + ], + 'allowed_extensions' => [ + 'jpeg', + 'jpg', + 'png', + 'gif', + 'webp', + ], + ], 'permissions' => [ 'acl_resources' => [ 'Omeka\Module\Manager', @@ -68,6 +83,9 @@ 'site_page_visibility' => Db\Filter\SitePageVisibilityFilter::class, 'value_visibility' => Db\Filter\ValueVisibilityFilter::class, ], + 'data_types' => [ + 'ip_address' => Db\Type\IpAddress::class, + ], 'functions' => [ 'datetime' => [ 'convert_tz' => \DoctrineExtensions\Query\Mysql\ConvertTz::class, @@ -246,6 +264,7 @@ 'Omeka\Logger' => Service\LoggerFactory::class, 'Omeka\MigrationManager' => Service\MigrationManagerFactory::class, 'Omeka\ViewApiJsonStrategy' => Service\ViewApiJsonStrategyFactory::class, + 'Omeka\ViewApiJsonRenderer' => Service\ViewApiJsonRendererFactory::class, 'Omeka\HttpClient' => Service\HttpClientFactory::class, 'Omeka\Mailer' => Service\MailerFactory::class, 'Omeka\HtmlPurifier' => Service\HtmlPurifierFactory::class, @@ -272,6 +291,7 @@ 'Omeka\Settings' => Service\Settings\SettingsFactory::class, 'Omeka\Settings\Site' => Service\Settings\SiteSettingsFactory::class, 'Omeka\Settings\User' => Service\Settings\UserSettingsFactory::class, + 'Omeka\Settings\Fallback' => Service\Settings\FallbackSettingsFactory::class, 'Omeka\Job\Dispatcher' => Service\Job\DispatcherFactory::class, 'Omeka\Job\DispatchStrategy\PhpCli' => Service\Job\DispatchStrategy\PhpCliFactory::class, 'Omeka\Job\DispatchStrategy\Synchronous' => Service\Job\DispatchStrategy\SynchronousFactory::class, @@ -288,7 +308,6 @@ 'ModuleRouteListener' => \Laminas\Mvc\ModuleRouteListener::class, 'Omeka\MvcExceptionListener' => Mvc\ExceptionListener::class, 'Omeka\MvcListeners' => Mvc\MvcListeners::class, - 'Omeka\ViewApiJsonRenderer' => View\Renderer\ApiJsonRenderer::class, ], 'delegators' => [ 'Laminas\I18n\Translator\TranslatorInterface' => [ @@ -317,7 +336,6 @@ 'Omeka\Controller\Site\Item' => Controller\Site\ItemController::class, 'Omeka\Controller\Site\ItemSet' => Controller\Site\ItemSetController::class, 'Omeka\Controller\Site\Media' => Controller\Site\MediaController::class, - 'Omeka\Controller\Site\Page' => Controller\Site\PageController::class, 'Omeka\Controller\Site\CrossSiteSearch' => Controller\Site\CrossSiteSearchController::class, 'Omeka\Controller\Admin\Asset' => Controller\Admin\AssetController::class, 'Omeka\Controller\Admin\Query' => Controller\Admin\QueryController::class, @@ -344,6 +362,7 @@ 'Omeka\Controller\Admin\Vocabulary' => Service\Controller\Admin\VocabularyControllerFactory::class, 'Omeka\Controller\Admin\Item' => Service\Controller\Admin\ItemControllerFactory::class, 'Omeka\Controller\SiteAdmin\Index' => Service\Controller\SiteAdmin\IndexControllerFactory::class, + 'Omeka\Controller\Site\Page' => Service\Controller\Site\PageControllerFactory::class, ], ], 'controller_plugins' => [ @@ -365,6 +384,7 @@ 'settings' => Service\ControllerPlugin\SettingsFactory::class, 'siteSettings' => Service\ControllerPlugin\SiteSettingsFactory::class, 'userSettings' => Service\ControllerPlugin\UserSettingsFactory::class, + 'fallbackSettings' => Service\ControllerPlugin\FallbackSettingsFactory::class, 'status' => Service\ControllerPlugin\StatusFactory::class, 'viewHelpers' => Service\ControllerPlugin\ViewHelpersFactory::class, 'browse' => Service\ControllerPlugin\BrowseFactory::class, @@ -421,6 +441,7 @@ 'formQuery' => Form\View\Helper\FormQuery::class, 'formColumns' => Form\View\Helper\FormColumns::class, 'formBrowseDefaults' => Form\View\Helper\FormBrowseDefaults::class, + 'formBackground' => Form\View\Helper\FormBackground::class, 'themeSettingAsset' => View\Helper\ThemeSettingAsset::class, 'themeSettingAssetUrl' => View\Helper\ThemeSettingAssetUrl::class, 'formColorPicker' => Form\View\Helper\FormColorPicker::class, @@ -435,6 +456,7 @@ 'factories' => [ 'api' => Service\ViewHelper\ApiFactory::class, 'assetUrl' => Service\ViewHelper\AssetUrlFactory::class, + 'pageLayout' => Service\ViewHelper\PageLayoutFactory::class, 'blockLayout' => Service\ViewHelper\BlockLayoutFactory::class, 'blockThumbnailTypeSelect' => Service\ViewHelper\BlockThumbnailTypeSelectFactory::class, 'dataType' => Service\ViewHelper\DataTypeFactory::class, @@ -447,6 +469,7 @@ 'setting' => Service\ViewHelper\SettingFactory::class, 'userSetting' => Service\ViewHelper\UserSettingFactory::class, 'siteSetting' => Service\ViewHelper\SiteSettingFactory::class, + 'fallbackSetting' => Service\ViewHelper\FallbackSettingFactory::class, 'themeSetting' => Service\ViewHelper\ThemeSettingFactory::class, 'trigger' => Service\ViewHelper\TriggerFactory::class, 'userIsAllowed' => Service\ViewHelper\UserIsAllowedFactory::class, @@ -497,6 +520,7 @@ ], 'factories' => [ 'Omeka\Form\ResourceForm' => Service\Form\ResourceFormFactory::class, + 'Omeka\Form\VocabularyForm' => Service\Form\VocabularyFormFactory::class, 'Omeka\Form\ResourceBatchUpdateForm' => Service\Form\ResourceBatchUpdateFormFactory::class, 'Omeka\Form\UserForm' => Service\Form\UserFormFactory::class, 'Omeka\Form\SettingForm' => Service\Form\SettingFormFactory::class, @@ -504,6 +528,9 @@ 'Omeka\Form\SiteForm' => Service\Form\SiteFormFactory::class, 'Omeka\Form\SiteSettingsForm' => Service\Form\SiteSettingsFormFactory::class, 'Omeka\Form\UserBatchUpdateForm' => Service\Form\UserBatchUpdateFormFactory::class, + 'Omeka\Form\PageLayoutDataForm' => Service\Form\PageLayoutDataFormFactory::class, + 'Omeka\Form\BlockLayoutDataForm' => Service\Form\BlockLayoutDataFormFactory::class, + 'Omeka\Form\SitePageForm' => Service\Form\SitePageFormFactory::class, 'Omeka\Form\Element\ResourceSelect' => Service\Form\Element\ResourceSelectFactory::class, 'Omeka\Form\Element\ResourceClassSelect' => Service\Form\Element\ResourceClassSelectFactory::class, 'Omeka\Form\Element\ResourceTemplateSelect' => Service\Form\Element\ResourceTemplateSelectFactory::class, diff --git a/application/config/routes.config.php b/application/config/routes.config.php index 68d4c9782b..0bcf0eeaa1 100644 --- a/application/config/routes.config.php +++ b/application/config/routes.config.php @@ -226,6 +226,7 @@ 'route' => '/api', 'defaults' => [ '__API__' => true, + '__KEYAUTH__' => true, 'controller' => 'Omeka\Controller\Api', ], ], @@ -247,6 +248,7 @@ 'options' => [ 'route' => '/api-local', 'defaults' => [ + '__API__' => true, 'controller' => 'Omeka\Controller\ApiLocal', ], ], diff --git a/application/data/doctrine-proxies/__CG__OmekaEntitySitePage.php b/application/data/doctrine-proxies/__CG__OmekaEntitySitePage.php index 7b4b7dd28b..492b5d2baf 100644 --- a/application/data/doctrine-proxies/__CG__OmekaEntitySitePage.php +++ b/application/data/doctrine-proxies/__CG__OmekaEntitySitePage.php @@ -67,10 +67,10 @@ public function __construct(?\Closure $initializer = null, ?\Closure $cloner = n public function __sleep() { if ($this->__isInitialized__) { - return ['__isInitialized__', 'id', 'slug', 'title', 'isPublic', 'site', 'created', 'modified', 'blocks']; + return ['__isInitialized__', 'id', 'slug', 'title', 'isPublic', 'layout', 'layoutData', 'site', 'created', 'modified', 'blocks']; } - return ['__isInitialized__', 'id', 'slug', 'title', 'isPublic', 'site', 'created', 'modified', 'blocks']; + return ['__isInitialized__', 'id', 'slug', 'title', 'isPublic', 'layout', 'layoutData', 'site', 'created', 'modified', 'blocks']; } /** @@ -258,6 +258,50 @@ public function isPublic() return parent::isPublic(); } + /** + * {@inheritDoc} + */ + public function setLayout($layout) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setLayout', [$layout]); + + return parent::setLayout($layout); + } + + /** + * {@inheritDoc} + */ + public function getLayout() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getLayout', []); + + return parent::getLayout(); + } + + /** + * {@inheritDoc} + */ + public function setLayoutData($layoutData) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setLayoutData', [$layoutData]); + + return parent::setLayoutData($layoutData); + } + + /** + * {@inheritDoc} + */ + public function getLayoutData() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getLayoutData', []); + + return parent::getLayoutData(); + } + /** * {@inheritDoc} */ diff --git a/application/data/doctrine-proxies/__CG__OmekaEntitySitePageBlock.php b/application/data/doctrine-proxies/__CG__OmekaEntitySitePageBlock.php index 2c26235da4..99da6f79a6 100644 --- a/application/data/doctrine-proxies/__CG__OmekaEntitySitePageBlock.php +++ b/application/data/doctrine-proxies/__CG__OmekaEntitySitePageBlock.php @@ -67,10 +67,10 @@ public function __construct(?\Closure $initializer = null, ?\Closure $cloner = n public function __sleep() { if ($this->__isInitialized__) { - return ['__isInitialized__', 'id', 'layout', 'data', 'position', 'page', 'attachments']; + return ['__isInitialized__', 'id', 'layout', 'data', 'layoutData', 'position', 'page', 'attachments']; } - return ['__isInitialized__', 'id', 'layout', 'data', 'position', 'page', 'attachments']; + return ['__isInitialized__', 'id', 'layout', 'data', 'layoutData', 'position', 'page', 'attachments']; } /** @@ -258,6 +258,28 @@ public function getPosition() return parent::getPosition(); } + /** + * {@inheritDoc} + */ + public function setLayoutData($layoutData) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setLayoutData', [$layoutData]); + + return parent::setLayoutData($layoutData); + } + + /** + * {@inheritDoc} + */ + public function getLayoutData() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getLayoutData', []); + + return parent::getLayoutData(); + } + /** * {@inheritDoc} */ diff --git a/application/data/install/schema.sql b/application/data/install/schema.sql index 0230ee292b..5aeaf9fe02 100644 --- a/application/data/install/schema.sql +++ b/application/data/install/schema.sql @@ -155,6 +155,8 @@ CREATE TABLE `resource` ( KEY `IDX_BC91F416448CC1BD` (`resource_class_id`), KEY `IDX_BC91F41616131EA` (`resource_template_id`), KEY `IDX_BC91F416FDFF2E92` (`thumbnail_id`), + KEY `title` (`title`(190)), + KEY `is_public` (`is_public`), CONSTRAINT `FK_BC91F41616131EA` FOREIGN KEY (`resource_template_id`) REFERENCES `resource_template` (`id`) ON DELETE SET NULL, CONSTRAINT `FK_BC91F416448CC1BD` FOREIGN KEY (`resource_class_id`) REFERENCES `resource_class` (`id`) ON DELETE SET NULL, CONSTRAINT `FK_BC91F4167E3C61F9` FOREIGN KEY (`owner_id`) REFERENCES `user` (`id`) ON DELETE SET NULL, @@ -280,8 +282,11 @@ CREATE TABLE `site_page` ( `slug` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL, `title` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL, `is_public` tinyint(1) NOT NULL, + `layout` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `layout_data` longtext COLLATE utf8mb4_unicode_ci COMMENT '(DC2Type:json)', `created` datetime NOT NULL, `modified` datetime DEFAULT NULL, + KEY `is_public` (`is_public`), PRIMARY KEY (`id`), UNIQUE KEY `UNIQ_2F900BD9F6BD1646989D9B62` (`site_id`,`slug`), KEY `IDX_2F900BD9F6BD1646` (`site_id`), @@ -292,6 +297,7 @@ CREATE TABLE `site_page_block` ( `page_id` int NOT NULL, `layout` varchar(80) COLLATE utf8mb4_unicode_ci NOT NULL, `data` longtext COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '(DC2Type:json_array)', + `layout_data` longtext COLLATE utf8mb4_unicode_ci COMMENT '(DC2Type:json)', `position` int NOT NULL, PRIMARY KEY (`id`), KEY `IDX_C593E731C4663E4` (`page_id`), @@ -356,6 +362,7 @@ CREATE TABLE `value` ( KEY `IDX_1D7758344BC72506` (`value_resource_id`), KEY `value` (`value`(190)), KEY `uri` (`uri`(190)), + KEY `is_public` (`is_public`), CONSTRAINT `FK_1D7758344BC72506` FOREIGN KEY (`value_resource_id`) REFERENCES `resource` (`id`) ON DELETE CASCADE, CONSTRAINT `FK_1D775834549213EC` FOREIGN KEY (`property_id`) REFERENCES `property` (`id`) ON DELETE CASCADE, CONSTRAINT `FK_1D77583489329D25` FOREIGN KEY (`resource_id`) REFERENCES `resource` (`id`), diff --git a/application/data/migrations/20230124033031_AddPageGridLayout.php b/application/data/migrations/20230124033031_AddPageGridLayout.php new file mode 100644 index 0000000000..b2f6cbff12 --- /dev/null +++ b/application/data/migrations/20230124033031_AddPageGridLayout.php @@ -0,0 +1,14 @@ +query("ALTER TABLE site_page ADD layout VARCHAR(255) DEFAULT NULL, ADD layout_data LONGTEXT DEFAULT NULL COMMENT '(DC2Type:json)';"); + $conn->query("ALTER TABLE site_page_block ADD layout_data LONGTEXT DEFAULT NULL COMMENT '(DC2Type:json)';"); + } +} diff --git a/application/data/migrations/20230523085358_MigrateBlockLayoutData.php b/application/data/migrations/20230523085358_MigrateBlockLayoutData.php new file mode 100644 index 0000000000..310ac557f4 --- /dev/null +++ b/application/data/migrations/20230523085358_MigrateBlockLayoutData.php @@ -0,0 +1,67 @@ +get('Omeka\EntityManager')); + } + + public function __construct($em) + { + $this->em = $em; + } + + public function up(Connection $conn) + { + $blocksRepository = $this->em->getRepository('Omeka\Entity\SitePageBlock'); + + // Migrate "HTML" (html) blocks. + foreach ($blocksRepository->findBy(['layout' => 'html']) as $block) { + $data = $block->getData(); + $layoutData = $block->getLayoutData(); + if (isset($data['divclass'])) { + $layoutData['class'] = $data['divclass']; + unset($data['divclass']); + $block->setData($data); + $block->setLayoutData($layoutData); + } + } + // Migrate "Media embed" (media) blocks. + foreach ($blocksRepository->findBy(['layout' => 'media']) as $block) { + $data = $block->getData(); + $layoutData = $block->getLayoutData(); + if (isset($data['alignment'])) { + $layoutData['alignment'] = $data['alignment']; + unset($data['alignment']); + $block->setData($data); + $block->setLayoutData($layoutData); + } + } + // Migrate "Asset" (asset) blocks. + foreach ($blocksRepository->findBy(['layout' => 'asset']) as $block) { + $data = $block->getData(); + $layoutData = $block->getLayoutData(); + if (isset($data['className'])) { + $layoutData['class'] = $data['className']; + unset($data['className']); + $block->setData($data); + $block->setLayoutData($layoutData); + } + if (isset($data['alignment'])) { + $layoutData['alignment'] = $data['alignment']; + unset($data['alignment']); + $block->setData($data); + $block->setLayoutData($layoutData); + } + } + $this->em->flush(); + } +} diff --git a/application/data/migrations/20230601060113_AddMediaRender.php b/application/data/migrations/20230601060113_AddMediaRender.php new file mode 100644 index 0000000000..d4606cbdcf --- /dev/null +++ b/application/data/migrations/20230601060113_AddMediaRender.php @@ -0,0 +1,40 @@ +get('Omeka\EntityManager')); + } + + public function __construct($em) + { + $this->em = $em; + } + + public function up(Connection $conn) + { + // Add the mediaRender resource page block layout to media pages that + // only have the values block layout. + $query = $this->em->createQuery('SELECT s FROM Omeka\Entity\SiteSetting s WHERE s.id LIKE :id'); + $query->setParameter('id', 'theme_settings_%'); + $siteSettings = $query->getResult(); + foreach ($siteSettings as $siteSetting) { + $value = $siteSetting->getValue(); + if (isset($value['resource_page_blocks']['media']['main']) + && ['values'] === $value['resource_page_blocks']['media']['main'] + ) { + $value['resource_page_blocks']['media']['main'] = ['mediaRender', 'values']; + $siteSetting->setValue($value); + } + } + $this->em->flush(); + } +} diff --git a/application/data/migrations/20230713101012_AddTitleIndexToResourceEntity.php b/application/data/migrations/20230713101012_AddTitleIndexToResourceEntity.php new file mode 100644 index 0000000000..e197463246 --- /dev/null +++ b/application/data/migrations/20230713101012_AddTitleIndexToResourceEntity.php @@ -0,0 +1,13 @@ +query('CREATE INDEX title ON resource (title(190));'); + } +} diff --git a/application/data/migrations/20231016000000_AddIndexIsPublic.php b/application/data/migrations/20231016000000_AddIndexIsPublic.php new file mode 100644 index 0000000000..58ec6d46c3 --- /dev/null +++ b/application/data/migrations/20231016000000_AddIndexIsPublic.php @@ -0,0 +1,30 @@ +executeStatement('ALTER TABLE `resource` ADD INDEX `is_public` (`is_public`);'); + } catch (\Exception $e) { + // Index exists. + } + + try { + $conn->executeStatement('ALTER TABLE `value` ADD INDEX `is_public` (`is_public`);'); + } catch (\Exception $e) { + // Index exists. + } + + try { + $conn->executeStatement('ALTER TABLE `site_page` ADD INDEX `is_public` (`is_public`);'); + } catch (\Exception $e) { + // Index exists. + } + } +} diff --git a/application/language/ca_ES.mo b/application/language/ca_ES.mo index f6815f9fb6..57967ece2c 100644 Binary files a/application/language/ca_ES.mo and b/application/language/ca_ES.mo differ diff --git a/application/language/ca_ES.po b/application/language/ca_ES.po index 5cd96bc5de..75df7d0477 100644 --- a/application/language/ca_ES.po +++ b/application/language/ca_ES.po @@ -4,8 +4,8 @@ # FIRST AUTHOR , YEAR. # # Translators: -# Rubén Alcaraz Martínez , 2023 # John Flatness , 2023 +# Rubén Alcaraz Martínez , 2023 # #, fuzzy msgid "" @@ -14,7 +14,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-10 21:23-0400\n" "PO-Revision-Date: 2017-06-13 18:56+0000\n" -"Last-Translator: John Flatness , 2023\n" +"Last-Translator: Rubén Alcaraz Martínez , 2023\n" "Language-Team: Catalan (Spain) (https://app.transifex.com/omeka/teams/14184/ca_ES/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -2429,7 +2429,7 @@ msgstr "Veure el registre" #: application/view/omeka/admin/job/show.phtml:66 msgid "[No log]" -msgstr "[No log]" +msgstr "[Sense log]" #: application/view/omeka/admin/media/batch-edit.phtml:7 msgid "Batch edit media" @@ -4996,7 +4996,7 @@ msgstr "sense títol" #: application/src/View/Helper/Browse.php:55 msgid "Relevance" -msgstr "" +msgstr "Rellevància" #: application/src/View/Helper/Browse.php:162 msgid "Add a column…" diff --git a/application/language/el_GR.mo b/application/language/el_GR.mo index 8433af4283..4a150dc48d 100644 Binary files a/application/language/el_GR.mo and b/application/language/el_GR.mo differ diff --git a/application/language/el_GR.po b/application/language/el_GR.po index d2495eaf3c..a16193ac6e 100644 --- a/application/language/el_GR.po +++ b/application/language/el_GR.po @@ -5,8 +5,8 @@ # # Translators: # John P , 2020 -# Yannis Kaskamanidis , 2023 # John Flatness , 2023 +# Yannis Kaskamanidis , 2023 # #, fuzzy msgid "" @@ -15,7 +15,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-10 21:23-0400\n" "PO-Revision-Date: 2017-06-13 18:56+0000\n" -"Last-Translator: John Flatness , 2023\n" +"Last-Translator: Yannis Kaskamanidis , 2023\n" "Language-Team: Greek (Greece) (https://app.transifex.com/omeka/teams/14184/el_GR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -66,7 +66,7 @@ msgstr "Ο προσαρμογέας %1$s δεν υλοποιεί τη λειτο #: application/src/Api/Adapter/AbstractEntityAdapter.php:292 #, php-format msgid "The \"%1$s\" field is not available in the %2$s adapter class." -msgstr "" +msgstr "Το πεδίο \"%1$s\" δεν είναι διαθέσιμο στην κατηγορία προσαρμογέα %2$s." #: application/src/Api/Adapter/AbstractEntityAdapter.php:308 #, php-format @@ -190,12 +190,12 @@ msgstr "Προσθήκη νέου resource template;" #: application/src/Controller/Admin/SystemInfoController.php:89 #: application/src/Controller/Admin/SystemInfoController.php:94 msgid "[invalid]" -msgstr "" +msgstr "[μη έγκυρο]" #: application/src/Controller/Admin/SystemInfoController.php:134 #: application/src/Controller/Admin/SystemInfoController.php:145 msgid "[Unable to execute command]" -msgstr "" +msgstr "[Αδυναμία εκτέλεσης της εντολής]" #: application/src/Controller/Admin/UserController.php:119 msgid "Add another user?" @@ -525,22 +525,22 @@ msgstr "δεν περιλαμβάνει" #: application/src/View/Helper/SearchFilters.php:36 #: application/view/common/advanced-search/properties.phtml:80 msgid "starts with" -msgstr "" +msgstr "αρχίζει με" #: application/src/View/Helper/SearchFilters.php:37 #: application/view/common/advanced-search/properties.phtml:81 msgid "does not start with" -msgstr "" +msgstr "δεν αρχίζει με" #: application/src/View/Helper/SearchFilters.php:38 #: application/view/common/advanced-search/properties.phtml:82 msgid "ends with" -msgstr "" +msgstr "τελειώνει με" #: application/src/View/Helper/SearchFilters.php:39 #: application/view/common/advanced-search/properties.phtml:83 msgid "does not end with" -msgstr "" +msgstr "δεν τελειώνει με" #: application/src/View/Helper/SearchFilters.php:40 #: application/view/common/advanced-search/properties.phtml:84 @@ -634,7 +634,7 @@ msgstr "Άγνωστο πρότυπο" #: application/src/View/Helper/SearchFilters.php:160 msgid "In item set" -msgstr "" +msgstr "Βρίσκεται στην ομάδα αντικειμένων" #: application/src/View/Helper/SearchFilters.php:164 #: application/src/View/Helper/SearchFilters.php:182 @@ -643,7 +643,7 @@ msgstr "Άγνωστη ομάδα αντικειμένων" #: application/src/View/Helper/SearchFilters.php:178 msgid "Not in item set" -msgstr "" +msgstr "Δεν βρίσκεται στην ομάδα αντικειμένων" #: application/src/View/Helper/SearchFilters.php:190 #: application/view/omeka/site-admin/index/users.phtml:54 @@ -699,17 +699,17 @@ msgstr "Μη δημόσια" #: application/src/View/Helper/SearchFilters.php:215 msgid "Media presence" -msgstr "" +msgstr "Παρουσία μέσου" #: application/src/View/Helper/SearchFilters.php:216 #: application/view/common/advanced-search/has-media.phtml:5 msgid "Has media" -msgstr "" +msgstr "Έχει πολυμέσο" #: application/src/View/Helper/SearchFilters.php:216 #: application/view/common/advanced-search/has-media.phtml:6 msgid "Has no media" -msgstr "" +msgstr "Δεν έχει πολυμέσο" #: application/src/View/Helper/SearchFilters.php:220 #: application/view/omeka/admin/item-set/show-details.phtml:13 @@ -803,15 +803,15 @@ msgstr "Προβολή" #: application/view/common/advanced-search/has-media.phtml:3 msgid "Search by media presence" -msgstr "" +msgstr "Αναζήτηση με παρουσία πολυμέσου" #: application/view/common/advanced-search/has-media.phtml:8 msgid "Select media presence…" -msgstr "" +msgstr "Επιλογή παρουσίας πολυμέσου..." #: application/view/common/advanced-search/ids.phtml:12 msgid "Search by ID" -msgstr "" +msgstr "Αναζήτηση με ID" #: application/view/common/advanced-search/ids.phtml:13 #: application/view/common/advanced-search/item-sets.phtml:44 @@ -831,6 +831,8 @@ msgid "" "Searches for resources by Omeka S ID. You can search for more than one ID by" " separating them by commas." msgstr "" +"Αναζήτηση πόρων με Omeka S ID. Μπορείτε να κάνετε αναζήτηση με περισσότερα " +"από ένα ID διαχωρίζοντάς τα με κόμματα." #: application/view/common/advanced-search/item-sets.phtml:43 msgid "Search by item set" @@ -850,11 +852,11 @@ msgstr "Προσθήκη νέας ομάδας αντικειμένων" #: application/view/common/advanced-search/item-sets.phtml:54 msgid "In" -msgstr "" +msgstr "Εντός" #: application/view/common/advanced-search/item-sets.phtml:55 msgid "Not in" -msgstr "" +msgstr "Όχι εντός" #: application/view/common/advanced-search/item-sets.phtml:66 #: application/view/common/advanced-search/properties.phtml:90 @@ -975,11 +977,11 @@ msgstr "Αναζήτηση με δραστηριότητα" #: application/view/common/advanced-search/visibility.phtml:3 msgid "Search by visibility" -msgstr "" +msgstr "Αναζήτηση με ορατότητα" #: application/view/common/advanced-search/visibility.phtml:8 msgid "Select visibility…" -msgstr "" +msgstr "Επιλογή ορατότητας..." #: application/view/common/asset-block-form.phtml:7 #: application/view/common/asset-block-form.phtml:40 @@ -1185,11 +1187,11 @@ msgstr "Τροποποιήθηκε" #: application/view/common/browse-defaults-form.phtml:12 msgid "[Custom sort by]" -msgstr "" +msgstr "[Προσαρμοσμένη ταξινόμηση με]" #: application/view/common/browse-defaults-form.phtml:17 msgid "Enter a custom sort by" -msgstr "" +msgstr "Καταχώριση προσαρμοσμένης ταξινόμησης με" #: application/view/common/columns-form.phtml:16 #: application/view/omeka/admin/item/add.phtml:13 @@ -1386,12 +1388,12 @@ msgstr "Περισσότερες πληροφορίες" #: application/view/common/linked-resources.phtml:54 msgid "Filter by resource type and property:" -msgstr "" +msgstr "Φιλτράρισμα με είδος πόρου και ιδιότητα:" #: application/view/common/linked-resources.phtml:64 #, php-format msgid "%s with \"%s: %s\"" -msgstr "" +msgstr "%s με \"%s: %s\"" #: application/view/common/linked-resources.phtml:74 #: application/view/omeka/admin/item-set/browse.phtml:54 @@ -1543,7 +1545,7 @@ msgstr "Κείμενο" #: application/view/common/resource-page-block-layout/lightbox-gallery-item.phtml:11 msgid "Other Media" -msgstr "" +msgstr "Άλλα πολυμέσα" #: application/view/common/resource-page-block-layout/linked-resources.phtml:14 #: application/view/omeka/admin/item-set/show.phtml:22 @@ -1553,7 +1555,7 @@ msgstr "Συνδεδεμένα δεδομένα" #: application/view/common/resource-page-block-layout/resource-class.phtml:7 msgid "Resource class" -msgstr "" +msgstr "Κατηγορία πόρου" #: application/view/common/resource-select-sidebar.phtml:20 msgid "Select resource" @@ -1607,11 +1609,11 @@ msgstr "Ανενεργός" #: application/view/common/sidebar-select-quick-add.phtml:8 msgid "Quick add checkboxes are now available." -msgstr "" +msgstr "Τα πλαίσια ελέγχου γρήγορης προσθήκης είναι πλέον διαθέσιμα." #: application/view/common/sidebar-select-quick-add.phtml:9 msgid "Quick add checkboxes are now hidden." -msgstr "" +msgstr "Τα πλαίσια ελέγχου γρήγορης προσθήκης είναι κρυμμένα." #: application/view/common/sidebar-select-quick-add.phtml:12 #: application/view/omeka/admin/item-set/browse.phtml:53 @@ -1622,11 +1624,11 @@ msgstr "Επιλογή όλων" #: application/view/common/sidebar-select-quick-add.phtml:17 msgid "All results are now selected." -msgstr "" +msgstr "Όλα τα αποτελέσματα είναι πλέον επιλεγμένα." #: application/view/common/sidebar-select-quick-add.phtml:18 msgid "All results are now deselected." -msgstr "" +msgstr "Όλα τα αποτελέσματα έχουν πλέον αποεπιλεγεί." #: application/view/common/site-page-pagination.phtml:3 msgid "Prev" @@ -1963,23 +1965,23 @@ msgstr "Φιλτράρισμα με βάση τον ιδιοκτήτη" #: application/view/omeka/admin/columns/column-edit-sidebar.phtml:5 #: application/view/omeka/admin/columns/column-row.phtml:10 msgid "Edit column" -msgstr "" +msgstr "Επεξεργασία στήλης" #: application/view/omeka/admin/columns/column-edit-sidebar.phtml:10 msgid "Set column" -msgstr "" +msgstr "Ορισμός στήλης" #: application/view/omeka/admin/columns/column-row.phtml:5 msgid "Column to be removed" -msgstr "" +msgstr "Στήλη που θα αφαιρεθεί" #: application/view/omeka/admin/columns/column-row.phtml:14 msgid "Remove column" -msgstr "" +msgstr "Αφαίρεση στήλης" #: application/view/omeka/admin/columns/column-row.phtml:18 msgid "Restore column" -msgstr "" +msgstr "Επαναφορά στήλης" #: application/view/omeka/admin/index/browse.phtml:4 #: application/view/omeka/index/index.phtml:33 @@ -2275,7 +2277,7 @@ msgstr "Αναζήτηση φίλτρου" #: application/view/omeka/admin/item-set/sidebar-select.phtml:36 msgid "Filter by item set ID" -msgstr "" +msgstr "Φιλτράρισμα με ID ομάδας αντικειμέν ων" #: application/view/omeka/admin/item-set/sidebar-select.phtml:70 #: application/view/omeka/admin/item/browse.phtml:178 @@ -2363,7 +2365,7 @@ msgstr "Πολυμέσο προς αφαίρεση" #: application/view/omeka/admin/item/manage-media.phtml:33 msgid "Primary media" -msgstr "" +msgstr "Πρωτεύον πολυμέσο" #: application/view/omeka/admin/item/manage-media.phtml:75 msgid "" @@ -2706,7 +2708,7 @@ msgstr "Απαραίτητο" #: application/view/omeka/admin/resource-template/review-import.phtml:72 #: application/view/omeka/admin/resource-template/show.phtml:32 msgid "Default language" -msgstr "" +msgstr "Προκαθορισμένη γλώσσα" #: application/view/omeka/admin/resource-template/form.phtml:101 #: application/view/omeka/admin/resource-template/review-import.phtml:67 @@ -2790,11 +2792,11 @@ msgstr "Γενικές ρυθμίσεις" #: application/view/omeka/admin/system-info/browse.phtml:31 msgid "Get PHP CLI version" -msgstr "" +msgstr "Λήψη έκδοσης PHP CLI" #: application/view/omeka/admin/system-info/browse.phtml:35 msgid "Get ImageMagick version" -msgstr "" +msgstr "Λήψη έκδοσης ImageMagick" #: application/view/omeka/admin/user/add.phtml:7 msgid "New user" @@ -3155,16 +3157,16 @@ msgstr "Μικρογραφία" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:6 msgid "Remove block" -msgstr "" +msgstr "Αφαίρεση πλαισίου" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:7 msgid "Restore block" -msgstr "" +msgstr "Επαναφορά πλαισίου" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:21 #: application/view/omeka/site-admin/index/theme.phtml:47 msgid "Configure resource pages" -msgstr "" +msgstr "Διαμόρφωση σελίδων πόρων" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:33 msgid "Item page" @@ -3176,24 +3178,24 @@ msgstr "Σελίδα πολυμέσων" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:35 msgid "Item set page" -msgstr "" +msgstr "Σελίδα ομάδας αντικειμένων" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:42 #, php-format msgid "Region: %s" -msgstr "" +msgstr "Περιοχή: %s" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:53 msgid "Select a region" -msgstr "" +msgstr "Επιλογή περιοχής" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:60 msgid "Add a block to selected region" -msgstr "" +msgstr "Προσθήκη πλαισίου στην επιλεγμένη περιοχή" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:66 msgid "There are no available blocks." -msgstr "" +msgstr "Δεν υπάρχουν διαθέσιμα πλαίσια." #: application/view/omeka/site-admin/index/theme-selector.phtml:26 msgid "Invalid theme.ini file" @@ -3206,7 +3208,7 @@ msgstr "Αυτό το θέμα εμφάνισης απαιτεί Omeka S %s" #: application/view/omeka/site-admin/index/theme-settings.phtml:6 msgid "Edit settings" -msgstr "" +msgstr "Επεξεργασία ρυθμίσεων" #: application/view/omeka/site-admin/index/theme-settings.phtml:17 msgid "The current theme has no configuration options." @@ -3284,11 +3286,11 @@ msgstr "Δεν έχει επιλεγεί αντικείμενο." #: application/view/omeka/site-admin/page/edit.phtml:37 msgid "Expand all" -msgstr "" +msgstr "Επέκταση όλων" #: application/view/omeka/site-admin/page/edit.phtml:38 msgid "Collapse all" -msgstr "" +msgstr "Σύμπτυξη όλων" #: application/view/omeka/site-admin/page/edit.phtml:46 msgid "Add new block" @@ -3338,7 +3340,7 @@ msgstr "Δεν βρέθηκαν ιστοσελίδες" #: application/src/Stdlib/Browse.php:124 #, php-format msgid "Custom (%s)" -msgstr "" +msgstr "Προσαρμοσμένο (%s)" #: application/src/Stdlib/Cli.php:105 application/src/Stdlib/Cli.php:160 #, php-format @@ -3521,7 +3523,7 @@ msgstr "Αντικείμενο με μεταδεδομένα" #: application/src/Site/BlockLayout/Media.php:14 msgid "Media embed" -msgstr "" +msgstr "Ενσωμάτωση πολυμέσων" #: application/src/Site/BlockLayout/LineBreak.php:14 msgid "Line break" @@ -3537,19 +3539,19 @@ msgstr "Αδιαφάνεια" #: application/src/Site/BlockLayout/PageDateTime.php:20 msgid "Page date/time" -msgstr "" +msgstr "Ημερομηνία/ώρα σελίδας" #: application/src/Site/BlockLayout/PageDateTime.php:30 msgid "Display date/time" -msgstr "" +msgstr "Εμφάνιση ημερομηνίας/ώρας" #: application/src/Site/BlockLayout/PageDateTime.php:32 msgid "Created & modified" -msgstr "" +msgstr "Δημιουργήθηκε & τροποποιήθηκε" #: application/src/Site/BlockLayout/PageDateTime.php:42 msgid "Date format" -msgstr "" +msgstr "Μορφή ημερομηνίας" #: application/src/Site/BlockLayout/PageDateTime.php:44 #: application/src/Site/BlockLayout/PageDateTime.php:58 @@ -3561,7 +3563,7 @@ msgstr "Κανένα" #: application/src/Site/BlockLayout/PageDateTime.php:45 #: application/src/Site/BlockLayout/PageDateTime.php:59 msgid "Short" -msgstr "" +msgstr "Σύντομη" #: application/src/Site/BlockLayout/PageDateTime.php:46 #: application/src/Site/BlockLayout/PageDateTime.php:60 @@ -3571,16 +3573,16 @@ msgstr "Μικρό" #: application/src/Site/BlockLayout/PageDateTime.php:47 #: application/src/Site/BlockLayout/PageDateTime.php:61 msgid "Long" -msgstr "" +msgstr "Μεγάλη" #: application/src/Site/BlockLayout/PageDateTime.php:48 #: application/src/Site/BlockLayout/PageDateTime.php:62 msgid "Full" -msgstr "" +msgstr "Πλήρης" #: application/src/Site/BlockLayout/PageDateTime.php:56 msgid "Time format" -msgstr "" +msgstr "Μορφή ώρας" #: application/src/Site/BlockLayout/ListOfSites.php:24 msgid "List of sites" @@ -3648,23 +3650,23 @@ msgstr "Άγνωστο [%s]" #: application/src/Site/ResourcePageBlockLayout/MediaRender.php:11 msgid "Media render" -msgstr "" +msgstr "Απόδοση πολυμέσων" #: application/src/Site/ResourcePageBlockLayout/MediaList.php:11 msgid "Media list" -msgstr "" +msgstr "Κατάλογος πολυμέσων" #: application/src/Site/ResourcePageBlockLayout/Manager.php:210 msgid "Main" -msgstr "" +msgstr "Κύριο" #: application/src/Site/ResourcePageBlockLayout/LightboxGallery.php:13 msgid "Lightbox gallery" -msgstr "" +msgstr "Γκαλερί Lightbox" #: application/src/Site/ResourcePageBlockLayout/MediaEmbeds.php:11 msgid "Media embeds" -msgstr "" +msgstr "Ενσωμάτωση πολυμέσων" #: application/src/Site/Navigation/Link/Url.php:11 msgid "Custom URL" @@ -3766,25 +3768,27 @@ msgstr "Ερευνητής" #: application/src/ColumnType/IsPublic.php:11 msgid "Is public" -msgstr "" +msgstr "Είναι δημόσιο" #: application/src/ColumnType/Value.php:25 msgid "Value" -msgstr "" +msgstr "Τιμή" #: application/src/ColumnType/Value.php:56 msgid "Max values" -msgstr "" +msgstr "Μέγιστες τιμές" #: application/src/ColumnType/Value.php:57 msgid "" "Enter the maximum number of values to display. Set to blank to display all " "values." msgstr "" +"Εισαγάγετε τον μέγιστο αριθμό τιμών για εμφάνιση. Ορίστε κενό για να " +"εμφανιστούν όλες οι τιμές." #: application/src/ColumnType/IsOpen.php:11 msgid "Is open" -msgstr "" +msgstr "Είναι ανοιχτό" #: application/src/ColumnType/ResourceTemplate.php:11 #: application/src/Form/ResourceForm.php:42 @@ -3793,11 +3797,11 @@ msgstr "Πρότυπο πόρου" #: application/src/ColumnType/Unknown.php:22 msgid "[Unknown]" -msgstr "" +msgstr "[Άγνωστο]" #: application/src/ColumnType/Unknown.php:40 msgid "Unknown column data" -msgstr "" +msgstr "Άγνωστα δεδομένα στήλης" #: application/src/Api/Adapter/ItemAdapter.php:152 msgid "Item sets must be an array" @@ -4028,15 +4032,15 @@ msgstr "σφάλμα" #: application/src/Media/Ingester/IiifPresentation.php:27 msgid "IIIF presentation" -msgstr "" +msgstr "Παρουσίαση IIIF" #: application/src/Media/Ingester/IiifPresentation.php:39 msgid "IIIF presentation URL" -msgstr "" +msgstr "URL παρουσίασης IIIF" #: application/src/Media/Ingester/IiifPresentation.php:40 msgid "Enter the URL to a IIIF collection or manifest." -msgstr "" +msgstr "Εισαγάγετε τo URL μιας συλλογής ή δήλωση IIIF." #: application/src/Media/Ingester/IIIF.php:33 msgid "IIIF image" @@ -4050,6 +4054,8 @@ msgstr "URL εικόνας IIIF" msgid "" "Enter the URL to a IIIF image information file (ending with /info.json)." msgstr "" +"Εισαγάγετε το URL για ένα αρχείο πληροφοριών εικόνας IIIF (που τελειώνει με " +"/info.json)." #: application/src/Media/Ingester/Upload.php:69 msgid "Upload file" @@ -4743,7 +4749,7 @@ msgstr "" #: application/src/Form/SiteSettingsForm.php:245 #: application/src/Form/UserForm.php:253 msgid "Item browse defaults" -msgstr "" +msgstr "Προεπιλογές περιήγησης αντικειμένων" #: application/src/Form/SiteSettingsForm.php:260 msgid "Show attached pages" @@ -4766,15 +4772,15 @@ msgstr "Εμφάνιση σχολίων που έχουν οριστεί για #: application/src/Form/SiteSettingsForm.php:286 msgid "Exclude resources not in site" -msgstr "" +msgstr "Εξαίρεση πόρων που δεν βρίσκονται στον ιστότοπο" #: application/src/Form/SiteSettingsForm.php:287 msgid "Exclude resources that are not assigned to this site." -msgstr "" +msgstr "Εξαιρέστε πόρους που δεν έχουν εκχωρηθεί σε αυτόν τον ιστότοπο." #: application/src/Form/SiteSettingsForm.php:299 msgid "Embed media on item pages (legacy)" -msgstr "" +msgstr "Ενσωμάτωση πολυμέσων σε σελίδες αντικειμένων (κληρονομικό)" #: application/src/Form/SiteSettingsForm.php:313 msgid "Search type" @@ -4807,23 +4813,23 @@ msgstr "" #: application/src/Form/SiteSettingsForm.php:352 msgid "Advanced search vocabulary members" -msgstr "" +msgstr "Μέλη λεξιλογίου προχωρημένης αναζήτησης" #: application/src/Form/SiteSettingsForm.php:353 msgid "Limit the search options for property and class" -msgstr "" +msgstr "Περιορίστε τις επιλογές αναζήτησης για ιδιότητα και κατηγορία" #: application/src/Form/SiteSettingsForm.php:354 msgid "All vocabulary members" -msgstr "" +msgstr "Όλα τα μέλη του λεξιλογίου" #: application/src/Form/SiteSettingsForm.php:356 msgid "Used by resources in this site" -msgstr "" +msgstr "Χρησιμοποιείται από πόρους σε αυτόν τον ιστότοπο" #: application/src/Form/SiteSettingsForm.php:357 msgid "Used by any resource in the installation" -msgstr "" +msgstr "Χρησιμοποιείται από οποιονδήποτε πόρο στην εγκατάσταση" #: application/src/Form/SiteSettingsForm.php:371 msgid "Templates" @@ -4922,11 +4928,11 @@ msgstr "Αρχείο προτύπου πόρων" #: application/src/Form/UserForm.php:134 msgid "Admin browse columns" -msgstr "" +msgstr "Στήλες περιήγησης διαχειριστή" #: application/src/Form/UserForm.php:135 msgid "Admin browse defaults" -msgstr "" +msgstr "Προεπιλογές περιήγησης διαχειριστή" #: application/src/Form/UserForm.php:160 msgid "Default resource template" @@ -4934,7 +4940,7 @@ msgstr "Καθορισμένο πρότυπο πόρου" #: application/src/Form/UserForm.php:184 msgid "Default item sets for items" -msgstr "" +msgstr "Προεπιλεγμένες ομάδες αντικειμένων για αντικείμενα" #: application/src/Form/UserForm.php:200 msgid "Default sites for items" @@ -4942,31 +4948,31 @@ msgstr "Καθορισμένοι ιστότοποι για αντικείμεν #: application/src/Form/UserForm.php:209 msgid "Item browse columns" -msgstr "" +msgstr "Στήλες περιήγησης αντικειμένου" #: application/src/Form/UserForm.php:220 msgid "Item set browse columns" -msgstr "" +msgstr "Στήλες περιήγησης ομάδας αντικειμένων" #: application/src/Form/UserForm.php:231 msgid "Media browse columns" -msgstr "" +msgstr "Στήλες περιήγησης πολυμέσων" #: application/src/Form/UserForm.php:242 msgid "Site browse columns" -msgstr "" +msgstr "Στήλες περιήγησης ιστότοπου" #: application/src/Form/UserForm.php:267 msgid "Item set browse defaults" -msgstr "" +msgstr "Προεπιλογές περιήγησης ομάδας αντικειμένων" #: application/src/Form/UserForm.php:281 msgid "Media browse defaults" -msgstr "" +msgstr "Προεπιλογές περιήγησης πολυμέσων" #: application/src/Form/UserForm.php:295 msgid "Site browse defaults" -msgstr "" +msgstr "Προεπιλογές περιήγησης ιστότοπου" #: application/src/Form/UserForm.php:311 msgid "Current password" @@ -5030,19 +5036,19 @@ msgstr "χωρίς τίτλο" #: application/src/View/Helper/Browse.php:55 msgid "Relevance" -msgstr "" +msgstr "Συνάφεια" #: application/src/View/Helper/Browse.php:162 msgid "Add a column…" -msgstr "" +msgstr "Προσθήκη στήλης..." #: application/src/View/Helper/Browse.php:181 msgid "Column type" -msgstr "" +msgstr "Είδος στήλης" #: application/src/View/Helper/Browse.php:192 msgid "Header" -msgstr "" +msgstr "Κεφαλίδα" #: application/src/View/Helper/ResourceTemplateSelect.php:39 msgid "Select template…" @@ -5117,7 +5123,7 @@ msgstr "Οι ρυθμίσεις θέματος εμφάνισης ενημερώ #: application/src/Controller/SiteAdmin/IndexController.php:457 msgid "Theme resource pages successfully updated" -msgstr "" +msgstr "Οι σελίδες πόρων του θέματος ενημερώθηκαν με επιτυχία" #: application/src/Controller/SiteAdmin/IndexController.php:480 msgid "Site successfully deleted" @@ -5498,21 +5504,21 @@ msgstr "Το πρότυπο πόρων δημιουργήθηκε με επιτ #: application/config/module.config.php:676 msgid "Owner email" -msgstr "" +msgstr "Email ιδιοκτήτη" #: application/config/module.config.php:682 #: application/config/module.config.php:698 #: application/config/module.config.php:703 msgid "Item count" -msgstr "" +msgstr "Μέτρηση αντικειμένων" #: application/config/module.config.php:692 msgid "Resource class count" -msgstr "" +msgstr "Μέτρηση κατηγορίας πόρου" #: application/config/module.config.php:693 msgid "Property count" -msgstr "" +msgstr "Μέτρηση ιδιότητας" #: application/config/module.config.php:865 msgid "Something went wrong" @@ -5552,11 +5558,11 @@ msgstr "Περιγραφή" #: application/config/module.config.php:881 msgid "Unknown block layout" -msgstr "" +msgstr "Άγνωστη διάταξη μπλοκ" #: application/config/module.config.php:882 msgid "Required field must be completed" -msgstr "" +msgstr "Το υποχρεωτικό πεδίο πρέπει να συμπληρωθεί" #: application/config/navigation.config.php:201 msgid "Site admin" diff --git a/application/language/es.mo b/application/language/es.mo index 524f2c3d32..f0b93cefd5 100644 Binary files a/application/language/es.mo and b/application/language/es.mo differ diff --git a/application/language/es.po b/application/language/es.po index 72f55156e5..7537b4eb3e 100644 --- a/application/language/es.po +++ b/application/language/es.po @@ -15,8 +15,8 @@ # Carlos Rivera , 2019 # Adriana Hernández, 2021 # Rubén Alcaraz Martínez , 2021 -# Alfonso Montejo , 2022 # John Flatness , 2023 +# Alfonso Montejo , 2023 # #, fuzzy msgid "" @@ -25,7 +25,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-10 21:23-0400\n" "PO-Revision-Date: 2017-06-13 18:56+0000\n" -"Last-Translator: John Flatness , 2023\n" +"Last-Translator: Alfonso Montejo , 2023\n" "Language-Team: Spanish (https://app.transifex.com/omeka/teams/14184/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -5045,7 +5045,7 @@ msgstr "sin título" #: application/src/View/Helper/Browse.php:55 msgid "Relevance" -msgstr "" +msgstr "Relevancia" #: application/src/View/Helper/Browse.php:162 msgid "Add a column…" diff --git a/application/language/et.mo b/application/language/et.mo index 76a9042894..e1211f3088 100644 Binary files a/application/language/et.mo and b/application/language/et.mo differ diff --git a/application/language/et.po b/application/language/et.po index ab5151ba09..01d281fcb7 100644 --- a/application/language/et.po +++ b/application/language/et.po @@ -4,9 +4,9 @@ # FIRST AUTHOR , YEAR. # # Translators: -# Moon Ika, 2020 # Rivo Zängov , 2022 # John Flatness , 2023 +# Moon Ika, 2023 # #, fuzzy msgid "" @@ -15,7 +15,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-10 21:23-0400\n" "PO-Revision-Date: 2017-06-13 18:56+0000\n" -"Last-Translator: John Flatness , 2023\n" +"Last-Translator: Moon Ika, 2023\n" "Language-Team: Estonian (https://app.transifex.com/omeka/teams/14184/et/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -613,7 +613,7 @@ msgstr "Tundmatu ühikute kogum" #: application/src/View/Helper/SearchFilters.php:178 msgid "Not in item set" -msgstr "Pole ühiku kogumis" +msgstr "Pole ühikute kogumis" #: application/src/View/Helper/SearchFilters.php:190 #: application/view/omeka/site-admin/index/users.phtml:54 @@ -1352,7 +1352,7 @@ msgstr "Rohkem infot" #: application/view/common/linked-resources.phtml:54 msgid "Filter by resource type and property:" -msgstr "" +msgstr "Filtreeri ressursi liigi ja omaduse järgi:" #: application/view/common/linked-resources.phtml:64 #, php-format @@ -2235,7 +2235,7 @@ msgstr "Filtreeri otsing" #: application/view/omeka/admin/item-set/sidebar-select.phtml:36 msgid "Filter by item set ID" -msgstr "" +msgstr "Filtreeri ühikute kogumi ID järgi" #: application/view/omeka/admin/item-set/sidebar-select.phtml:70 #: application/view/omeka/admin/item/browse.phtml:178 @@ -2263,7 +2263,7 @@ msgstr "Mõjutatud ühikud" #: application/view/omeka/admin/item/batch-edit.phtml:29 #, php-format msgid "You are editing the following %s items:" -msgstr "" +msgstr "Sa muudad %s ühikuid:" #: application/view/omeka/admin/item/batch-edit.phtml:36 #, php-format @@ -3109,7 +3109,7 @@ msgstr "Meedia lehekülg" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:35 msgid "Item set page" -msgstr "" +msgstr "Ühikute kogumi lehekülg" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:42 #, php-format @@ -5327,7 +5327,7 @@ msgstr "" #: application/config/module.config.php:698 #: application/config/module.config.php:703 msgid "Item count" -msgstr "" +msgstr "Ühikute arv" #: application/config/module.config.php:692 msgid "Resource class count" diff --git a/application/language/eu.mo b/application/language/eu.mo index f81e499132..dc1e3f2481 100644 Binary files a/application/language/eu.mo and b/application/language/eu.mo differ diff --git a/application/language/eu.po b/application/language/eu.po index e777b1e981..2763fd1fc9 100644 --- a/application/language/eu.po +++ b/application/language/eu.po @@ -6,8 +6,8 @@ # Translators: # Margari León , 2019 # Ereiten Omeka, 2022 -# Iametza Interaktiboa, 2022 # John Flatness , 2023 +# Iametza Interaktiboa, 2023 # #, fuzzy msgid "" @@ -16,7 +16,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-10 21:23-0400\n" "PO-Revision-Date: 2017-06-13 18:56+0000\n" -"Last-Translator: John Flatness , 2023\n" +"Last-Translator: Iametza Interaktiboa, 2023\n" "Language-Team: Basque (https://app.transifex.com/omeka/teams/14184/eu/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -1977,7 +1977,7 @@ msgstr "Baliabideak kudeatu" #: application/view/omeka/admin/index/browse.phtml:15 #, php-format msgid "Items (%s)" -msgstr "($s) fitxak" +msgstr "(%s) fitxak" #: application/view/omeka/admin/index/browse.phtml:17 #: application/view/omeka/admin/item/browse.phtml:19 diff --git a/application/language/fi_FI.mo b/application/language/fi_FI.mo index ae2a9384ad..58571e8753 100644 Binary files a/application/language/fi_FI.mo and b/application/language/fi_FI.mo differ diff --git a/application/language/fi_FI.po b/application/language/fi_FI.po index 26e0004246..ffd9d0f0e3 100644 --- a/application/language/fi_FI.po +++ b/application/language/fi_FI.po @@ -5,9 +5,9 @@ # # Translators: # Sami Varjo , 2017 -# Matti Lassila , 2018 # Kai Metsävainio , 2022 # John Flatness , 2023 +# Matti Lassila , 2023 # #, fuzzy msgid "" @@ -16,7 +16,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-10 21:23-0400\n" "PO-Revision-Date: 2017-06-13 18:56+0000\n" -"Last-Translator: John Flatness , 2023\n" +"Last-Translator: Matti Lassila , 2023\n" "Language-Team: Finnish (Finland) (https://app.transifex.com/omeka/teams/14184/fi_FI/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -32,12 +32,12 @@ msgstr "Sovitin %1$s ei toteuta hakutoimintoa." #: application/src/Api/Adapter/AbstractAdapter.php:50 #, php-format msgid "The %1$s adapter does not implement the create operation." -msgstr "The %1$s adapter does not implement the create operation." +msgstr "Sovitin %1$s ei toteuta luontioperaatiota." #: application/src/Api/Adapter/AbstractAdapter.php:60 #, php-format msgid "The %1$s adapter does not implement the batch create operation." -msgstr "The %1$s adapter does not implement the batch create operation." +msgstr "Sovitin %1$s ei toteuta massaluontioperaatiota." #: application/src/Api/Adapter/AbstractAdapter.php:70 #, php-format @@ -191,12 +191,12 @@ msgstr "Lisää toinen tallennuspohja?" #: application/src/Controller/Admin/SystemInfoController.php:89 #: application/src/Controller/Admin/SystemInfoController.php:94 msgid "[invalid]" -msgstr "" +msgstr "[virheellinen]" #: application/src/Controller/Admin/SystemInfoController.php:134 #: application/src/Controller/Admin/SystemInfoController.php:145 msgid "[Unable to execute command]" -msgstr "" +msgstr "[toimintoa ei voida suorittaa]" #: application/src/Controller/Admin/UserController.php:119 msgid "Add another user?" @@ -238,7 +238,7 @@ msgstr "Aineistot" #: application/src/DataType/Resource/ItemSet.php:27 msgid "Item Sets" -msgstr "" +msgstr "Kokoelmat" #: application/src/DataType/Resource/Media.php:27 #: application/view/common/block-layout/item-with-metadata.phtml:29 @@ -506,22 +506,22 @@ msgstr "ei sisällä" #: application/src/View/Helper/SearchFilters.php:36 #: application/view/common/advanced-search/properties.phtml:80 msgid "starts with" -msgstr "" +msgstr "alkaa merkkijonolla" #: application/src/View/Helper/SearchFilters.php:37 #: application/view/common/advanced-search/properties.phtml:81 msgid "does not start with" -msgstr "" +msgstr "ei ala merkkijonoilla" #: application/src/View/Helper/SearchFilters.php:38 #: application/view/common/advanced-search/properties.phtml:82 msgid "ends with" -msgstr "" +msgstr "alkaa merkkijonoilla" #: application/src/View/Helper/SearchFilters.php:39 #: application/view/common/advanced-search/properties.phtml:83 msgid "does not end with" -msgstr "" +msgstr "ei pääty merkkijonoilla" #: application/src/View/Helper/SearchFilters.php:40 #: application/view/common/advanced-search/properties.phtml:84 @@ -607,15 +607,15 @@ msgstr "Hae" #: application/src/View/Helper/SearchFilters.php:141 msgid "Template" -msgstr "" +msgstr "Tallennuspohja" #: application/src/View/Helper/SearchFilters.php:145 msgid "Unknown template" -msgstr "" +msgstr "Tuntematon tallennuspohja" #: application/src/View/Helper/SearchFilters.php:160 msgid "In item set" -msgstr "" +msgstr "Kokoelmassa" #: application/src/View/Helper/SearchFilters.php:164 #: application/src/View/Helper/SearchFilters.php:182 @@ -624,7 +624,7 @@ msgstr "Tuntematon kokoelma" #: application/src/View/Helper/SearchFilters.php:178 msgid "Not in item set" -msgstr "" +msgstr "Ei sisälly kokoelmaan" #: application/src/View/Helper/SearchFilters.php:190 #: application/view/omeka/site-admin/index/users.phtml:54 @@ -792,7 +792,7 @@ msgstr "" #: application/view/common/advanced-search/ids.phtml:12 msgid "Search by ID" -msgstr "" +msgstr "Hae tunnisteella" #: application/view/common/advanced-search/ids.phtml:13 #: application/view/common/advanced-search/item-sets.phtml:44 @@ -812,6 +812,8 @@ msgid "" "Searches for resources by Omeka S ID. You can search for more than one ID by" " separating them by commas." msgstr "" +"Hae tunnisteella. Voit käyttää useampaa tunnistetta erottamalla tunnisteet " +"pilkulla." #: application/view/common/advanced-search/item-sets.phtml:43 msgid "Search by item set" @@ -829,11 +831,11 @@ msgstr "Lisää kokoelma hakuehtoihin" #: application/view/common/advanced-search/item-sets.phtml:54 msgid "In" -msgstr "" +msgstr "Sisältyy" #: application/view/common/advanced-search/item-sets.phtml:55 msgid "Not in" -msgstr "" +msgstr "Ei sisälly" #: application/view/common/advanced-search/item-sets.phtml:66 #: application/view/common/advanced-search/properties.phtml:90 @@ -893,15 +895,15 @@ msgstr "Lisää uusi aineistotyyppi" #: application/view/common/advanced-search/resource-template.phtml:16 msgid "Search by template" -msgstr "" +msgstr "Hae tallennuspohjan mukaan" #: application/view/common/advanced-search/resource-template.phtml:19 msgid "Searches for resources that use any of these templates." -msgstr "" +msgstr "Hakee aineistoja jotka käyttävät tallennuspohjaa" #: application/view/common/advanced-search/resource-template.phtml:21 msgid "Add new template" -msgstr "" +msgstr "Lisää uusi tallennuspohja" #: application/view/common/advanced-search/site.phtml:3 msgid "Search by site" @@ -954,21 +956,21 @@ msgstr "Etsi aktiviteetillä" #: application/view/common/advanced-search/visibility.phtml:3 msgid "Search by visibility" -msgstr "" +msgstr "Hae näkyvyyden mukaan" #: application/view/common/advanced-search/visibility.phtml:8 msgid "Select visibility…" -msgstr "" +msgstr "Valitse näkyvyys..." #: application/view/common/asset-block-form.phtml:7 #: application/view/common/asset-block-form.phtml:40 msgid "No asset selected" -msgstr "" +msgstr "Ei valittua tiedostoa" #: application/view/common/asset-block-form.phtml:9 #: application/view/common/asset-block-form.phtml:43 msgid "Open asset options" -msgstr "" +msgstr "Avaa tiedostoasetukset" #: application/view/common/asset-block-form.phtml:10 #: application/view/common/asset-block-form.phtml:44 @@ -999,11 +1001,11 @@ msgstr "Sulje" #: application/view/omeka/admin/asset/browse.phtml:8 #: application/view/omeka/admin/asset/edit.phtml:10 msgid "Assets" -msgstr "" +msgstr "Tiedostot" #: application/view/common/asset-block-form.phtml:54 msgid "Add asset" -msgstr "" +msgstr "Lisää tiedosto" #: application/view/common/asset-form.phtml:35 #: application/view/common/asset-options.phtml:15 @@ -1024,7 +1026,7 @@ msgstr "Tyhjennä" #: application/view/common/asset-options.phtml:10 msgid "No Asset" -msgstr "" +msgstr "Ei tiedostoja" #: application/view/common/asset-options.phtml:19 #: application/view/omeka/admin/query/sidebar-edit.phtml:12 @@ -1164,11 +1166,11 @@ msgstr "Tallenteen muokkausajankohta" #: application/view/common/browse-defaults-form.phtml:12 msgid "[Custom sort by]" -msgstr "" +msgstr "[muokattu järjestys]" #: application/view/common/browse-defaults-form.phtml:17 msgid "Enter a custom sort by" -msgstr "" +msgstr "Lisää järjestysehto" #: application/view/common/columns-form.phtml:16 #: application/view/omeka/admin/item/add.phtml:13 @@ -1250,7 +1252,7 @@ msgstr "Poistettava arvo" #: application/view/common/data-type-wrapper.phtml:21 msgid "More actions" -msgstr "" +msgstr "Lisää toimintoja" #: application/view/common/data-type-wrapper.phtml:24 #: application/view/common/media-field-wrapper.phtml:10 @@ -1685,15 +1687,15 @@ msgstr "Käyttäjät (%s)" #: application/view/common/value-annotation-sidebar.phtml:20 msgid "Add annotation" -msgstr "" +msgstr "Lisää merkkaus" #: application/view/common/value-annotation-sidebar.phtml:22 msgid "Annotations" -msgstr "" +msgstr "Merkkaukset" #: application/view/common/value-annotation-sidebar.phtml:27 msgid "Set annotations" -msgstr "" +msgstr "Kokoelmien merkkaukset" #: application/view/common/value-annotation-wrapper.phtml:13 #: application/view/omeka/admin/item-set/form.phtml:49 @@ -1865,7 +1867,7 @@ msgstr "Lataa" #: application/view/omeka/admin/asset/browse.phtml:17 msgid "Add new asset" -msgstr "" +msgstr "Lisää tiedosto" #: application/view/omeka/admin/asset/browse.phtml:28 #: application/view/omeka/admin/item-set/show.phtml:77 @@ -1917,7 +1919,7 @@ msgstr "Lisätietoja" #: application/view/omeka/admin/asset/browse.phtml:98 #: application/view/omeka/admin/asset/sidebar-select.phtml:56 msgid "Omeka could not find any assets." -msgstr "" +msgstr "Omeka ei löytänyt tiedostoja" #: application/view/omeka/admin/asset/show-details.phtml:12 msgid "Media type" @@ -1938,7 +1940,7 @@ msgstr "Suodata omistajan mukaan" #: application/view/omeka/admin/columns/column-edit-sidebar.phtml:5 #: application/view/omeka/admin/columns/column-row.phtml:10 msgid "Edit column" -msgstr "" +msgstr "Muokkaa saraketta" #: application/view/omeka/admin/columns/column-edit-sidebar.phtml:10 msgid "Set column" @@ -2668,7 +2670,7 @@ msgstr "Pakollinen" #: application/view/omeka/admin/resource-template/review-import.phtml:72 #: application/view/omeka/admin/resource-template/show.phtml:32 msgid "Default language" -msgstr "" +msgstr "Oletuskieli" #: application/view/omeka/admin/resource-template/form.phtml:101 #: application/view/omeka/admin/resource-template/review-import.phtml:67 @@ -2752,11 +2754,11 @@ msgstr "Yleisasetukset" #: application/view/omeka/admin/system-info/browse.phtml:31 msgid "Get PHP CLI version" -msgstr "" +msgstr "Tunnista PHP CLI -versio" #: application/view/omeka/admin/system-info/browse.phtml:35 msgid "Get ImageMagick version" -msgstr "" +msgstr "Tunnista ImageMagick -versio" #: application/view/omeka/admin/user/add.phtml:7 msgid "New user" @@ -2942,7 +2944,7 @@ msgstr "" #: application/view/omeka/api/root.phtml:12 msgid "Omeka S REST API documentation" -msgstr "" +msgstr "Omeka S REST-rajapinnan dokumentaatio" #: application/view/omeka/index/index.phtml:32 #, php-format @@ -3111,11 +3113,11 @@ msgstr "Esikatselukuva" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:6 msgid "Remove block" -msgstr "" +msgstr "Poista lohko" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:7 msgid "Restore block" -msgstr "" +msgstr "Palauta lohko" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:21 #: application/view/omeka/site-admin/index/theme.phtml:47 @@ -3137,11 +3139,11 @@ msgstr "" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:42 #, php-format msgid "Region: %s" -msgstr "" +msgstr "Alue: %s" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:53 msgid "Select a region" -msgstr "" +msgstr "Valitse alue" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:60 msgid "Add a block to selected region" @@ -3162,7 +3164,7 @@ msgstr "Teema vaatii Omeka S -version %s" #: application/view/omeka/site-admin/index/theme-settings.phtml:6 msgid "Edit settings" -msgstr "" +msgstr "Muokkaa asetuksia" #: application/view/omeka/site-admin/index/theme-settings.phtml:17 msgid "The current theme has no configuration options." @@ -3239,11 +3241,11 @@ msgstr "Ei valittua aineistoa." #: application/view/omeka/site-admin/page/edit.phtml:37 msgid "Expand all" -msgstr "" +msgstr "Laajenna kaikki" #: application/view/omeka/site-admin/page/edit.phtml:38 msgid "Collapse all" -msgstr "" +msgstr "Sulje kaikki" #: application/view/omeka/site-admin/page/edit.phtml:46 msgid "Add new block" @@ -3380,7 +3382,7 @@ msgstr "Sisällysluettelo" #: application/src/Site/BlockLayout/Asset.php:17 msgid "Asset" -msgstr "" +msgstr "Tiedosto" #: application/src/Site/BlockLayout/Asset.php:34 #: application/src/Site/BlockLayout/Asset.php:40 @@ -3489,11 +3491,11 @@ msgstr "Näkyvä" #: application/src/Site/BlockLayout/PageDateTime.php:20 msgid "Page date/time" -msgstr "" +msgstr "Muokkaus- tai luontiajankohta" #: application/src/Site/BlockLayout/PageDateTime.php:30 msgid "Display date/time" -msgstr "" +msgstr "Näytä ajankohta" #: application/src/Site/BlockLayout/PageDateTime.php:32 msgid "Created & modified" @@ -3501,7 +3503,7 @@ msgstr "" #: application/src/Site/BlockLayout/PageDateTime.php:42 msgid "Date format" -msgstr "" +msgstr "Päivämäärän esitysmuoto" #: application/src/Site/BlockLayout/PageDateTime.php:44 #: application/src/Site/BlockLayout/PageDateTime.php:58 @@ -3513,7 +3515,7 @@ msgstr "Ei lisätietoja" #: application/src/Site/BlockLayout/PageDateTime.php:45 #: application/src/Site/BlockLayout/PageDateTime.php:59 msgid "Short" -msgstr "" +msgstr "Lyhyt" #: application/src/Site/BlockLayout/PageDateTime.php:46 #: application/src/Site/BlockLayout/PageDateTime.php:60 @@ -3523,16 +3525,16 @@ msgstr "Tietoväline" #: application/src/Site/BlockLayout/PageDateTime.php:47 #: application/src/Site/BlockLayout/PageDateTime.php:61 msgid "Long" -msgstr "" +msgstr "Pitkä" #: application/src/Site/BlockLayout/PageDateTime.php:48 #: application/src/Site/BlockLayout/PageDateTime.php:62 msgid "Full" -msgstr "" +msgstr "Täysi" #: application/src/Site/BlockLayout/PageDateTime.php:56 msgid "Time format" -msgstr "" +msgstr "Aikaleiman muoto" #: application/src/Site/BlockLayout/ListOfSites.php:24 msgid "List of sites" @@ -3711,7 +3713,7 @@ msgstr "Lukija" #: application/src/ColumnType/IsPublic.php:11 msgid "Is public" -msgstr "" +msgstr "Julkinen" #: application/src/ColumnType/Value.php:25 msgid "Value" @@ -3738,7 +3740,7 @@ msgstr "Tallennuspohja" #: application/src/ColumnType/Unknown.php:22 msgid "[Unknown]" -msgstr "" +msgstr "[tuntematon]" #: application/src/ColumnType/Unknown.php:40 msgid "Unknown column data" @@ -4719,11 +4721,11 @@ msgstr "" #: application/src/Form/SiteSettingsForm.php:377 msgid "Select templates" -msgstr "" +msgstr "Valitse tallennuspohja" #: application/src/Form/SiteSettingsForm.php:386 msgid "Restrict to templates" -msgstr "" +msgstr "Rajoita tallennuspohjiin" #: application/src/Form/SiteSettingsForm.php:387 msgid "Restrict search results to resources of the selected templates." @@ -4911,11 +4913,11 @@ msgstr "ei nimekettä" #: application/src/View/Helper/Browse.php:55 msgid "Relevance" -msgstr "" +msgstr "Relevanssi" #: application/src/View/Helper/Browse.php:162 msgid "Add a column…" -msgstr "" +msgstr "Lisää sarake..." #: application/src/View/Helper/Browse.php:181 msgid "Column type" @@ -4927,7 +4929,7 @@ msgstr "" #: application/src/View/Helper/ResourceTemplateSelect.php:39 msgid "Select template…" -msgstr "" +msgstr "Valitse tallennuspohja..." #: application/src/View/Helper/PropertySelect.php:39 msgid "Select property…" @@ -5273,7 +5275,7 @@ msgstr "" #: application/src/Controller/Admin/AssetController.php:137 msgid "Asset successfully deleted" -msgstr "" +msgstr "Tiedosto on poistettu" #: application/src/Controller/Admin/ItemSetController.php:32 #, php-format @@ -5365,7 +5367,7 @@ msgstr "Tallennuspohjan luonti onnistui. %s" #: application/config/module.config.php:676 msgid "Owner email" -msgstr "" +msgstr "Omistajan sähköpostiosoite" #: application/config/module.config.php:682 #: application/config/module.config.php:698 diff --git a/application/language/fr.mo b/application/language/fr.mo index d620ac79f5..e461789c6e 100644 Binary files a/application/language/fr.mo and b/application/language/fr.mo differ diff --git a/application/language/fr.po b/application/language/fr.po index 62a6b6ed46..69eea5f6b4 100644 --- a/application/language/fr.po +++ b/application/language/fr.po @@ -9,9 +9,9 @@ # symac , 2018 # Laurent Thomas, 2020 # Julian Maurice , 2021 -# Daniel Berthereau , 2022 # Pols12 , 2023 # John Flatness , 2023 +# Daniel Berthereau , 2023 # #, fuzzy msgid "" @@ -20,7 +20,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-10 21:23-0400\n" "PO-Revision-Date: 2017-06-13 18:56+0000\n" -"Last-Translator: John Flatness , 2023\n" +"Last-Translator: Daniel Berthereau , 2023\n" "Language-Team: French (https://app.transifex.com/omeka/teams/14184/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -71,7 +71,8 @@ msgstr "L’adaptateur %1$s n’exécute pas l’opération de suppression en lo #: application/src/Api/Adapter/AbstractEntityAdapter.php:292 #, php-format msgid "The \"%1$s\" field is not available in the %2$s adapter class." -msgstr "Le champ « %1$s » n’est pas disponible dans classe d’adaptateur %2$s." +msgstr "" +"Le champ « %1$s » n’est pas disponible dans la classe d’adaptateur %2$s." #: application/src/Api/Adapter/AbstractEntityAdapter.php:308 #, php-format @@ -452,7 +453,7 @@ msgstr "" "Cliquez sur ce lien pour définir un mot de passe et commencer à utiliser Omeka S :\n" "%3$s\n" "\n" -"Votre lien d’activation expirera à %4$s. Si vous n’avez pas terminé le processus d’activation de l’utilisateur au moment où le lien expire, vous devrez demander un autre email d’activation de votre administrateur de site." +"Votre lien d’activation expirera à %4$s. Si vous n’avez pas terminé le processus d’activation de l’utilisateur au moment où le lien expire, vous devrez demander un autre mail d’activation de votre administrateur de site." #: application/src/Stdlib/Mailer.php:233 #, php-format @@ -702,7 +703,7 @@ msgstr "Présence de médias" #: application/src/View/Helper/SearchFilters.php:216 #: application/view/common/advanced-search/has-media.phtml:5 msgid "Has media" -msgstr "A le média" +msgstr "A un média" #: application/src/View/Helper/SearchFilters.php:216 #: application/view/common/advanced-search/has-media.phtml:6 @@ -725,7 +726,7 @@ msgstr "ID" #: application/view/omeka/admin/user/browse.phtml:64 #: application/view/omeka/admin/user/show.phtml:18 msgid "Email" -msgstr "E-mail" +msgstr "Mail" #: application/src/View/Helper/SearchUserFilters.php:54 #: application/view/omeka/admin/asset/browse.phtml:27 @@ -1388,7 +1389,7 @@ msgstr "Filtrer par type de ressource et par propriété :" #: application/view/common/linked-resources.phtml:64 #, php-format msgid "%s with \"%s: %s\"" -msgstr "" +msgstr "%s avec \" %s : %s \"" #: application/view/common/linked-resources.phtml:74 #: application/view/omeka/admin/item-set/browse.phtml:54 @@ -1497,7 +1498,7 @@ msgstr "Filtrer les propriétés" #: application/view/common/query-form.phtml:8 #: application/view/omeka/admin/query/search-filters.phtml:4 msgid "[Edit below]" -msgstr "[Modifier plus bas]" +msgstr "[Modifier ci-dessous]" #: application/view/common/query-form.phtml:24 msgid "Advanced edit" @@ -1539,7 +1540,7 @@ msgstr "Texte" #: application/view/common/resource-page-block-layout/lightbox-gallery-item.phtml:11 msgid "Other Media" -msgstr "" +msgstr "Autres médias" #: application/view/common/resource-page-block-layout/linked-resources.phtml:14 #: application/view/omeka/admin/item-set/show.phtml:22 @@ -1549,7 +1550,7 @@ msgstr "Ressources liées" #: application/view/common/resource-page-block-layout/resource-class.phtml:7 msgid "Resource class" -msgstr "" +msgstr "Classe de ressource" #: application/view/common/resource-select-sidebar.phtml:20 msgid "Select resource" @@ -1604,10 +1605,12 @@ msgstr "Inactif" #: application/view/common/sidebar-select-quick-add.phtml:8 msgid "Quick add checkboxes are now available." msgstr "" +"L’ajout rapide de contenus avec les cases à cocher est désormais disponible." #: application/view/common/sidebar-select-quick-add.phtml:9 msgid "Quick add checkboxes are now hidden." msgstr "" +"L’ajout rapide de contenus avec les cases à cocher est désormais caché." #: application/view/common/sidebar-select-quick-add.phtml:12 #: application/view/omeka/admin/item-set/browse.phtml:53 @@ -1618,11 +1621,11 @@ msgstr "Tout sélectionner" #: application/view/common/sidebar-select-quick-add.phtml:17 msgid "All results are now selected." -msgstr "" +msgstr "Tous les résultats sont sélectionnés." #: application/view/common/sidebar-select-quick-add.phtml:18 msgid "All results are now deselected." -msgstr "" +msgstr "Tous les résultats sont désélectionnés." #: application/view/common/site-page-pagination.phtml:3 msgid "Prev" @@ -1958,23 +1961,23 @@ msgstr "Filtrer par propriétaire" #: application/view/omeka/admin/columns/column-edit-sidebar.phtml:5 #: application/view/omeka/admin/columns/column-row.phtml:10 msgid "Edit column" -msgstr "" +msgstr "Modifier la colonne" #: application/view/omeka/admin/columns/column-edit-sidebar.phtml:10 msgid "Set column" -msgstr "" +msgstr "Choisir la colonne" #: application/view/omeka/admin/columns/column-row.phtml:5 msgid "Column to be removed" -msgstr "" +msgstr "Colonne à supprimer" #: application/view/omeka/admin/columns/column-row.phtml:14 msgid "Remove column" -msgstr "" +msgstr "Supprimer la colonne" #: application/view/omeka/admin/columns/column-row.phtml:18 msgid "Restore column" -msgstr "" +msgstr "Restaurer la colonne" #: application/view/omeka/admin/index/browse.phtml:4 #: application/view/omeka/index/index.phtml:33 @@ -2091,7 +2094,7 @@ msgstr "Traitements en lot" #: application/view/omeka/admin/media/browse.phtml:24 #: application/view/omeka/admin/user/browse.phtml:34 msgid "Edit selected" -msgstr "Modifier sélectionnés" +msgstr "Modifier la sélection" #: application/view/omeka/admin/item-set/browse.phtml:32 #: application/view/omeka/admin/item/browse.phtml:32 @@ -2105,7 +2108,7 @@ msgstr "Modifier tout" #: application/view/omeka/admin/media/browse.phtml:28 #: application/view/omeka/admin/user/browse.phtml:38 msgid "Delete selected" -msgstr "Supprimer sélectionnés" +msgstr "Supprimer la selection" #: application/view/omeka/admin/item-set/browse.phtml:36 #: application/view/omeka/admin/item/browse.phtml:36 @@ -2270,7 +2273,7 @@ msgstr "Filtre de recherche" #: application/view/omeka/admin/item-set/sidebar-select.phtml:36 msgid "Filter by item set ID" -msgstr "" +msgstr "Filtrer par numéro de collection" #: application/view/omeka/admin/item-set/sidebar-select.phtml:70 #: application/view/omeka/admin/item/browse.phtml:178 @@ -2358,7 +2361,7 @@ msgstr "Média à enlever" #: application/view/omeka/admin/item/manage-media.phtml:33 msgid "Primary media" -msgstr "" +msgstr "Média principal" #: application/view/omeka/admin/item/manage-media.phtml:75 msgid "" @@ -2472,7 +2475,7 @@ msgstr "Vous allez modifier %s médias." #: application/view/omeka/admin/media/browse.phtml:59 #: application/view/omeka/admin/media/sidebar-select.phtml:8 msgid "Select media" -msgstr "Choisir le média" +msgstr "Choisir un média" #: application/view/omeka/admin/media/browse.phtml:116 #: application/view/omeka/admin/media/browse.phtml:134 @@ -2701,7 +2704,7 @@ msgstr "Requis" #: application/view/omeka/admin/resource-template/review-import.phtml:72 #: application/view/omeka/admin/resource-template/show.phtml:32 msgid "Default language" -msgstr "" +msgstr "Langue par défaut" #: application/view/omeka/admin/resource-template/form.phtml:101 #: application/view/omeka/admin/resource-template/review-import.phtml:67 @@ -2785,11 +2788,11 @@ msgstr "Paramètres généraux" #: application/view/omeka/admin/system-info/browse.phtml:31 msgid "Get PHP CLI version" -msgstr "" +msgstr "Voir la version PHP en ligne de commandes" #: application/view/omeka/admin/system-info/browse.phtml:35 msgid "Get ImageMagick version" -msgstr "" +msgstr "Voir la version d’ImageMagick" #: application/view/omeka/admin/user/add.phtml:7 msgid "New user" @@ -3008,7 +3011,7 @@ msgstr "Mot de passe oublié" #: application/view/omeka/login/forgot-password.phtml:11 msgid "Send password reset email" -msgstr "Envoyer un email de réinitialisation de mot de passe" +msgstr "Envoyer un mail de réinitialisation de mot de passe" #: application/view/omeka/login/login.phtml:7 msgid "Forgot password?" @@ -3150,16 +3153,16 @@ msgstr "Vignette" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:6 msgid "Remove block" -msgstr "" +msgstr "Supprimer le bloc" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:7 msgid "Restore block" -msgstr "" +msgstr "Restaurer le bloc" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:21 #: application/view/omeka/site-admin/index/theme.phtml:47 msgid "Configure resource pages" -msgstr "" +msgstr "Configurer les pages de ressources" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:33 msgid "Item page" @@ -3171,24 +3174,24 @@ msgstr "Page de média" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:35 msgid "Item set page" -msgstr "" +msgstr "Page de collection" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:42 #, php-format msgid "Region: %s" -msgstr "" +msgstr "Région : %s" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:53 msgid "Select a region" -msgstr "" +msgstr "Choisir une région" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:60 msgid "Add a block to selected region" -msgstr "" +msgstr "Ajouter un bloc dans la région choisie" #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:66 msgid "There are no available blocks." -msgstr "" +msgstr "Aucun bloc n’est disponible." #: application/view/omeka/site-admin/index/theme-selector.phtml:26 msgid "Invalid theme.ini file" @@ -3201,7 +3204,7 @@ msgstr "Ce thème requiert Omeka S %s" #: application/view/omeka/site-admin/index/theme-settings.phtml:6 msgid "Edit settings" -msgstr "" +msgstr "Modifier les paramètres" #: application/view/omeka/site-admin/index/theme-settings.phtml:17 msgid "The current theme has no configuration options." @@ -3278,11 +3281,11 @@ msgstr "Pas de contenu sélectionné." #: application/view/omeka/site-admin/page/edit.phtml:37 msgid "Expand all" -msgstr "" +msgstr "Tout étendre" #: application/view/omeka/site-admin/page/edit.phtml:38 msgid "Collapse all" -msgstr "" +msgstr "Tout réduire" #: application/view/omeka/site-admin/page/edit.phtml:46 msgid "Add new block" @@ -3332,7 +3335,7 @@ msgstr "Aucune page correspondante" #: application/src/Stdlib/Browse.php:124 #, php-format msgid "Custom (%s)" -msgstr "" +msgstr "Personnalisé (%s)" #: application/src/Stdlib/Cli.php:105 application/src/Stdlib/Cli.php:160 #, php-format @@ -3517,7 +3520,7 @@ msgstr "Contenus avec métadonnées" #: application/src/Site/BlockLayout/Media.php:14 msgid "Media embed" -msgstr "" +msgstr "Média" #: application/src/Site/BlockLayout/LineBreak.php:14 msgid "Line break" @@ -3533,19 +3536,19 @@ msgstr "Opaque" #: application/src/Site/BlockLayout/PageDateTime.php:20 msgid "Page date/time" -msgstr "" +msgstr "Date et heure de la page" #: application/src/Site/BlockLayout/PageDateTime.php:30 msgid "Display date/time" -msgstr "" +msgstr "Afficher la date et l’heure" #: application/src/Site/BlockLayout/PageDateTime.php:32 msgid "Created & modified" -msgstr "" +msgstr "Créée et modifiée" #: application/src/Site/BlockLayout/PageDateTime.php:42 msgid "Date format" -msgstr "" +msgstr "Format de la date" #: application/src/Site/BlockLayout/PageDateTime.php:44 #: application/src/Site/BlockLayout/PageDateTime.php:58 @@ -3557,7 +3560,7 @@ msgstr "Aucun" #: application/src/Site/BlockLayout/PageDateTime.php:45 #: application/src/Site/BlockLayout/PageDateTime.php:59 msgid "Short" -msgstr "" +msgstr "Court" #: application/src/Site/BlockLayout/PageDateTime.php:46 #: application/src/Site/BlockLayout/PageDateTime.php:60 @@ -3567,16 +3570,16 @@ msgstr "Moyen" #: application/src/Site/BlockLayout/PageDateTime.php:47 #: application/src/Site/BlockLayout/PageDateTime.php:61 msgid "Long" -msgstr "" +msgstr "Long" #: application/src/Site/BlockLayout/PageDateTime.php:48 #: application/src/Site/BlockLayout/PageDateTime.php:62 msgid "Full" -msgstr "" +msgstr "Complet" #: application/src/Site/BlockLayout/PageDateTime.php:56 msgid "Time format" -msgstr "" +msgstr "Format de l’heure" #: application/src/Site/BlockLayout/ListOfSites.php:24 msgid "List of sites" @@ -3644,23 +3647,23 @@ msgstr "Inconnu [%s]" #: application/src/Site/ResourcePageBlockLayout/MediaRender.php:11 msgid "Media render" -msgstr "" +msgstr "Affichage du média" #: application/src/Site/ResourcePageBlockLayout/MediaList.php:11 msgid "Media list" -msgstr "" +msgstr "Liste de médias" #: application/src/Site/ResourcePageBlockLayout/Manager.php:210 msgid "Main" -msgstr "" +msgstr "Principal" #: application/src/Site/ResourcePageBlockLayout/LightboxGallery.php:13 msgid "Lightbox gallery" -msgstr "" +msgstr "Galerie Lightbox" #: application/src/Site/ResourcePageBlockLayout/MediaEmbeds.php:11 msgid "Media embeds" -msgstr "" +msgstr "Affichage d’une liste de médias" #: application/src/Site/Navigation/Link/Url.php:11 msgid "Custom URL" @@ -3760,25 +3763,27 @@ msgstr "Chercheur" #: application/src/ColumnType/IsPublic.php:11 msgid "Is public" -msgstr "" +msgstr "Est public" #: application/src/ColumnType/Value.php:25 msgid "Value" -msgstr "" +msgstr "Valeur" #: application/src/ColumnType/Value.php:56 msgid "Max values" -msgstr "" +msgstr "Nombre de valeurs maximum" #: application/src/ColumnType/Value.php:57 msgid "" "Enter the maximum number of values to display. Set to blank to display all " "values." msgstr "" +"Indiquer le nombre de valeurs maximum à afficher. Laisser vide pour afficher" +" toutes les valeurs." #: application/src/ColumnType/IsOpen.php:11 msgid "Is open" -msgstr "" +msgstr "Est ouvert" #: application/src/ColumnType/ResourceTemplate.php:11 #: application/src/Form/ResourceForm.php:42 @@ -3787,11 +3792,11 @@ msgstr "Modèle de ressource" #: application/src/ColumnType/Unknown.php:22 msgid "[Unknown]" -msgstr "" +msgstr "[Inconnu]" #: application/src/ColumnType/Unknown.php:40 msgid "Unknown column data" -msgstr "" +msgstr "Colonne de données inconnues" #: application/src/Api/Adapter/ItemAdapter.php:152 msgid "Item sets must be an array" @@ -3836,7 +3841,7 @@ msgstr "Le nom doit être renseigné." #: application/src/Api/Adapter/UserAdapter.php:130 #, php-format msgid "The email %s is already taken." -msgstr "L’email %s est déjà pris." +msgstr "L’adresse mail %s est déjà pris." #: application/src/Api/Adapter/UserAdapter.php:136 msgid "Users must have a role." @@ -4021,15 +4026,15 @@ msgstr "erreur" #: application/src/Media/Ingester/IiifPresentation.php:27 msgid "IIIF presentation" -msgstr "" +msgstr "Présentation IIIF" #: application/src/Media/Ingester/IiifPresentation.php:39 msgid "IIIF presentation URL" -msgstr "" +msgstr "Url de la présentation IIIF" #: application/src/Media/Ingester/IiifPresentation.php:40 msgid "Enter the URL to a IIIF collection or manifest." -msgstr "" +msgstr "Indiquer l’url du manifeste ou de la collection IIIF" #: application/src/Media/Ingester/IIIF.php:33 msgid "IIIF image" @@ -4043,6 +4048,8 @@ msgstr "URL de l’image IIIF" msgid "" "Enter the URL to a IIIF image information file (ending with /info.json)." msgstr "" +"Indiquer l’url du fichier d’information IIIF de l’image (se termine par " +"info.json)." #: application/src/Media/Ingester/Upload.php:69 msgid "Upload file" @@ -4115,7 +4122,7 @@ msgstr "Sécurité" #: application/src/Form/SettingForm.php:117 msgid "Administrator email" -msgstr "Email de l’administrateur" +msgstr "Mail de l’administrateur" #: application/src/Form/SettingForm.php:131 #: application/src/Form/InstallationForm.php:80 @@ -4740,7 +4747,7 @@ msgstr "" #: application/src/Form/SiteSettingsForm.php:245 #: application/src/Form/UserForm.php:253 msgid "Item browse defaults" -msgstr "" +msgstr "Configuration par défaut de la liste des contenus" #: application/src/Form/SiteSettingsForm.php:260 msgid "Show attached pages" @@ -4755,7 +4762,7 @@ msgstr "" #: application/src/Form/SiteSettingsForm.php:273 msgid "Show value annotations" -msgstr "Afficher les annotations des valeurs" +msgstr "Afficher les annotations de valeur" #: application/src/Form/SiteSettingsForm.php:274 msgid "Show annotations that are set to a value, if any." @@ -4763,15 +4770,15 @@ msgstr "Afficher les annotations définies pour une valeur." #: application/src/Form/SiteSettingsForm.php:286 msgid "Exclude resources not in site" -msgstr "" +msgstr "Exclure les ressources absentes du site" #: application/src/Form/SiteSettingsForm.php:287 msgid "Exclude resources that are not assigned to this site." -msgstr "" +msgstr "Exclure les ressources qui ne sont pas assignées à ce site" #: application/src/Form/SiteSettingsForm.php:299 msgid "Embed media on item pages (legacy)" -msgstr "" +msgstr "Afficher les médias dans la page du contenu (anciens thèmes)" #: application/src/Form/SiteSettingsForm.php:313 msgid "Search type" @@ -4805,23 +4812,23 @@ msgstr "" #: application/src/Form/SiteSettingsForm.php:352 msgid "Advanced search vocabulary members" -msgstr "" +msgstr "Éléments des ontologies en recherche avancée " #: application/src/Form/SiteSettingsForm.php:353 msgid "Limit the search options for property and class" -msgstr "" +msgstr "Liste des propriétés et classes dans la recherche avancée" #: application/src/Form/SiteSettingsForm.php:354 msgid "All vocabulary members" -msgstr "" +msgstr "Tous les éléments des ontologies" #: application/src/Form/SiteSettingsForm.php:356 msgid "Used by resources in this site" -msgstr "" +msgstr "Éléments utilisés dans les ressources de ce site" #: application/src/Form/SiteSettingsForm.php:357 msgid "Used by any resource in the installation" -msgstr "" +msgstr "Éléments utilisés par les ressources dans toute la base" #: application/src/Form/SiteSettingsForm.php:371 msgid "Templates" @@ -4921,11 +4928,11 @@ msgstr "Fichier Modèle de ressource" #: application/src/Form/UserForm.php:134 msgid "Admin browse columns" -msgstr "" +msgstr "Colonnes pour les listes en admin" #: application/src/Form/UserForm.php:135 msgid "Admin browse defaults" -msgstr "" +msgstr "Configuration par défaut des listes en admin" #: application/src/Form/UserForm.php:160 msgid "Default resource template" @@ -4933,7 +4940,7 @@ msgstr "Modèle de ressource par défaut" #: application/src/Form/UserForm.php:184 msgid "Default item sets for items" -msgstr "" +msgstr "Collections par défaut pour les contenus" #: application/src/Form/UserForm.php:200 msgid "Default sites for items" @@ -4941,31 +4948,31 @@ msgstr "Sites par défaut pour les contenus" #: application/src/Form/UserForm.php:209 msgid "Item browse columns" -msgstr "" +msgstr "Colonnes de la liste des contenus" #: application/src/Form/UserForm.php:220 msgid "Item set browse columns" -msgstr "" +msgstr "Colonnes de la liste des collections" #: application/src/Form/UserForm.php:231 msgid "Media browse columns" -msgstr "" +msgstr "Colonnes de la liste des médias" #: application/src/Form/UserForm.php:242 msgid "Site browse columns" -msgstr "" +msgstr "Colonnes de la liste des sites" #: application/src/Form/UserForm.php:267 msgid "Item set browse defaults" -msgstr "" +msgstr "Configuration par défaut de la liste des collections" #: application/src/Form/UserForm.php:281 msgid "Media browse defaults" -msgstr "" +msgstr "Configuration par défaut de la liste des médias" #: application/src/Form/UserForm.php:295 msgid "Site browse defaults" -msgstr "" +msgstr "Configuration par défaut de la liste des sites" #: application/src/Form/UserForm.php:311 msgid "Current password" @@ -4989,11 +4996,11 @@ msgstr "Créer le premier utilisateur" #: application/src/Form/InstallationForm.php:52 msgid "Confirm email" -msgstr "Confirmer l’email" +msgstr "Confirmer l’adresse mail" #: application/src/Form/InstallationForm.php:128 msgid "The emails did not match" -msgstr "Les email ne correspondent pas" +msgstr "Les adresses mails ne correspondent pas" #: application/src/Form/ConfirmForm.php:17 msgid "Confirm" @@ -5029,19 +5036,19 @@ msgstr "Sans titre" #: application/src/View/Helper/Browse.php:55 msgid "Relevance" -msgstr "" +msgstr "Pertinence" #: application/src/View/Helper/Browse.php:162 msgid "Add a column…" -msgstr "" +msgstr "Ajouter une colonne…" #: application/src/View/Helper/Browse.php:181 msgid "Column type" -msgstr "" +msgstr "Type de colonne" #: application/src/View/Helper/Browse.php:192 msgid "Header" -msgstr "" +msgstr "Entête" #: application/src/View/Helper/ResourceTemplateSelect.php:39 msgid "Select template…" @@ -5117,6 +5124,8 @@ msgstr "Paramètres du thème mis à jour avec succès" #: application/src/Controller/SiteAdmin/IndexController.php:457 msgid "Theme resource pages successfully updated" msgstr "" +"La configuration des pages de ressource du thème a été enregistrée avec " +"succès." #: application/src/Controller/SiteAdmin/IndexController.php:480 msgid "Site successfully deleted" @@ -5144,7 +5153,7 @@ msgstr "Connexion réussie" #: application/src/Controller/LoginController.php:65 msgid "Email or password is invalid" -msgstr "Email ou mot de passe invalide" +msgstr "Adresse mail ou mot de passe invalide" #: application/src/Controller/LoginController.php:88 msgid "Successfully logged out" @@ -5507,21 +5516,21 @@ msgstr "Modèle de ressource créé avec succès. %s" #: application/config/module.config.php:676 msgid "Owner email" -msgstr "" +msgstr "Mail du propriétaire" #: application/config/module.config.php:682 #: application/config/module.config.php:698 #: application/config/module.config.php:703 msgid "Item count" -msgstr "" +msgstr "Total des contenus" #: application/config/module.config.php:692 msgid "Resource class count" -msgstr "" +msgstr "Total des classes de ressources" #: application/config/module.config.php:693 msgid "Property count" -msgstr "" +msgstr "Total des propriétés" #: application/config/module.config.php:865 msgid "Something went wrong" @@ -5561,11 +5570,11 @@ msgstr "Description" #: application/config/module.config.php:881 msgid "Unknown block layout" -msgstr "" +msgstr "Bloc inconnu" #: application/config/module.config.php:882 msgid "Required field must be completed" -msgstr "" +msgstr "Les champs obligatoires doivent être complétés." #: application/config/navigation.config.php:201 msgid "Site admin" @@ -5918,7 +5927,7 @@ msgstr "Une information à propos des droits détenus dans et sur la ressource." #. Property label for Dublin Core:audience msgid "Audience" -msgstr "Auditoire" +msgstr "Public" #. Property comment for Dublin Core:audience msgid "A class of entity for whom the resource is intended or useful." @@ -6214,7 +6223,7 @@ msgstr "La date de soumission de la ressource." #. Property label for Dublin Core:educationLevel msgid "Audience Education Level" -msgstr "Niveau d’éducation de l’auditoire" +msgstr "Niveau d’éducation du public" #. Property comment for Dublin Core:educationLevel msgid "" @@ -6551,7 +6560,7 @@ msgstr "Une assemblée pour consultation ou discussion." #. Class label for Bibliographic Ontology:CourtReporter msgid "Court Reporter" -msgstr "Rapport de cour" +msgstr "Recueil de jurisprudence" #. Class comment for Bibliographic Ontology:CourtReporter msgid "A collection of legal cases." @@ -6602,7 +6611,7 @@ msgstr "Un livre édité." #. Class label for Bibliographic Ontology:Email msgid "EMail" -msgstr "Email" +msgstr "Mail" #. Class comment for Bibliographic Ontology:Email msgid "" diff --git a/application/language/it.mo b/application/language/it.mo index 1aa570b2b3..a729208add 100644 Binary files a/application/language/it.mo and b/application/language/it.mo differ diff --git a/application/language/it.po b/application/language/it.po index 5436aa0e30..367318042b 100644 --- a/application/language/it.po +++ b/application/language/it.po @@ -8,8 +8,8 @@ # Latino Imparato , 2018 # Simone Falteri , 2018 # Tommaso Vitale, 2019 -# Giorgio Comai , 2023 # John Flatness , 2023 +# Giorgio Comai , 2023 # #, fuzzy msgid "" @@ -18,7 +18,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-10 21:23-0400\n" "PO-Revision-Date: 2017-06-13 18:56+0000\n" -"Last-Translator: John Flatness , 2023\n" +"Last-Translator: Giorgio Comai , 2023\n" "Language-Team: Italian (https://app.transifex.com/omeka/teams/14184/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -5013,7 +5013,7 @@ msgstr "nessun titolo" #: application/src/View/Helper/Browse.php:55 msgid "Relevance" -msgstr "" +msgstr "Rilevanza" #: application/src/View/Helper/Browse.php:162 msgid "Add a column…" diff --git a/application/language/mn.mo b/application/language/mn.mo index f0d744643e..277a40205b 100644 Binary files a/application/language/mn.mo and b/application/language/mn.mo differ diff --git a/application/language/mn.po b/application/language/mn.po index bc99362e82..d5a5d52567 100644 --- a/application/language/mn.po +++ b/application/language/mn.po @@ -5,9 +5,9 @@ # # Translators: # Jishee Oyutan , 2017 -# Khaidav Tumur , 2020 -# Khaidav T. , 2021 # John Flatness , 2023 +# Khaidav Tumur , 2023 +# Khaidav T. , 2023 # #, fuzzy msgid "" @@ -16,7 +16,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-10 21:23-0400\n" "PO-Revision-Date: 2017-06-13 18:56+0000\n" -"Last-Translator: John Flatness , 2023\n" +"Last-Translator: Khaidav T. , 2023\n" "Language-Team: Mongolian (https://app.transifex.com/omeka/teams/14184/mn/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -191,7 +191,7 @@ msgstr "Өөр нөөцийн загвар нэмэх үү?" #: application/src/Controller/Admin/SystemInfoController.php:89 #: application/src/Controller/Admin/SystemInfoController.php:94 msgid "[invalid]" -msgstr "" +msgstr "[хүчингүй]" #: application/src/Controller/Admin/SystemInfoController.php:134 #: application/src/Controller/Admin/SystemInfoController.php:145 @@ -238,7 +238,7 @@ msgstr "Баримтууд" #: application/src/DataType/Resource/ItemSet.php:27 msgid "Item Sets" -msgstr "" +msgstr "Баримтын бүрдлүүд" #: application/src/DataType/Resource/Media.php:27 #: application/view/common/block-layout/item-with-metadata.phtml:29 @@ -355,7 +355,7 @@ msgstr "" #: application/src/Site/BlockLayout/Fallback.php:37 msgid "This layout is invalid." -msgstr "" +msgstr "Энэ бүдүүвч хүчингүй байна" #: application/src/Site/BlockLayout/ItemShowcase.php:22 #: application/src/Site/BlockLayout/Media.php:22 @@ -488,7 +488,7 @@ msgstr "агуулагдаагүй" #: application/src/View/Helper/SearchFilters.php:36 #: application/view/common/advanced-search/properties.phtml:80 msgid "starts with" -msgstr "" +msgstr "-р эхэлсэн" #: application/src/View/Helper/SearchFilters.php:37 #: application/view/common/advanced-search/properties.phtml:81 @@ -498,7 +498,7 @@ msgstr "" #: application/src/View/Helper/SearchFilters.php:38 #: application/view/common/advanced-search/properties.phtml:82 msgid "ends with" -msgstr "" +msgstr "-р төгссөн" #: application/src/View/Helper/SearchFilters.php:39 #: application/view/common/advanced-search/properties.phtml:83 @@ -542,11 +542,11 @@ msgstr "Бүтэн текстээр хайх" #: application/view/omeka/admin/resource-template/review-import.phtml:32 #: application/view/omeka/admin/resource-template/show.phtml:18 msgid "Class" -msgstr "" +msgstr "Анги" #: application/src/View/Helper/SearchFilters.php:68 msgid "Unknown class" -msgstr "" +msgstr "Тодорхойгүй анги" #: application/src/View/Helper/SearchFilters.php:106 msgid "Unknown property" @@ -634,7 +634,7 @@ msgstr "Тодорхойгүй сайт" #: application/view/omeka/admin/media/show-details.phtml:49 #: application/view/omeka/admin/media/show.phtml:38 msgid "Visibility" -msgstr "" +msgstr "Харагдах байдал" #: application/src/View/Helper/SearchFilters.php:211 #: application/view/common/advanced-search/visibility.phtml:5 @@ -684,7 +684,7 @@ msgstr "" #: application/view/omeka/admin/media/show.phtml:34 #: application/view/omeka/admin/user/edit.phtml:39 msgid "ID" -msgstr "" +msgstr "ID" #: application/src/View/Helper/SearchUserFilters.php:49 #: application/view/omeka/admin/user/browse.phtml:64 @@ -3150,7 +3150,7 @@ msgstr "" #: application/view/omeka/site-admin/index/theme.phtml:67 #, php-format msgid "Status: %s" -msgstr "" +msgstr "Статус: 1%s" #: application/view/omeka/site-admin/index/theme.phtml:69 msgid "" @@ -4185,7 +4185,7 @@ msgstr "" #: application/src/Form/ResourceForm.php:63 #: application/src/Form/ResourceBatchUpdateForm.php:93 msgid "Select a class" -msgstr "" +msgstr "Анги сонгох" #: application/src/Form/ResourceForm.php:67 msgid "" @@ -4264,7 +4264,7 @@ msgstr "" #: application/src/Form/VocabularyForm.php:119 msgid "JSON-LD (.jsonld)" -msgstr "" +msgstr "JSON-LD (.jsonld)" #: application/src/Form/VocabularyForm.php:120 msgid "N-Triples (.nt)" @@ -4291,7 +4291,7 @@ msgstr "" #: application/src/Form/VocabularyForm.php:146 msgid "Label property" -msgstr "" +msgstr "Шошгын шинж чанар" #: application/src/Form/VocabularyForm.php:147 msgid "" @@ -4333,7 +4333,7 @@ msgstr "" #: application/src/Form/UserBatchUpdateForm.php:77 #: application/src/Form/UserBatchUpdateForm.php:92 msgid "[No change]" -msgstr "" +msgstr "[Өөрчлөгдөөгүй]" #: application/src/Form/ResourceBatchUpdateForm.php:51 msgid "Set openness" @@ -6926,7 +6926,7 @@ msgstr "" #. Property label for Bibliographic Ontology:content msgid "content" -msgstr "" +msgstr "агуулга" #. Property comment for Bibliographic Ontology:content msgid "" @@ -6937,7 +6937,7 @@ msgstr "" #. Property label for Bibliographic Ontology:doi msgid "doi" -msgstr "" +msgstr "doi" #. Property label for Bibliographic Ontology:eanucc13 msgid "eanucc13" @@ -6945,7 +6945,7 @@ msgstr "" #. Property label for Bibliographic Ontology:edition msgid "edition" -msgstr "" +msgstr "хэвлэлт" #. Property comment for Bibliographic Ontology:edition msgid "" @@ -7027,7 +7027,7 @@ msgstr "" #. Property label for Bibliographic Ontology:number msgid "number" -msgstr "" +msgstr "дугаар" #. Property comment for Bibliographic Ontology:number msgid "" @@ -7040,7 +7040,7 @@ msgstr "" #. Property label for Bibliographic Ontology:pageEnd msgid "page end" -msgstr "" +msgstr "хуудасны төгсгөл" #. Property comment for Bibliographic Ontology:pageEnd msgid "Ending page number within a continuous page range." @@ -7048,7 +7048,7 @@ msgstr "" #. Property label for Bibliographic Ontology:pageStart msgid "page start" -msgstr "" +msgstr "хуудасны эхлэл" #. Property comment for Bibliographic Ontology:pageStart msgid "Starting page number within a continuous page range." @@ -7056,7 +7056,7 @@ msgstr "" #. Property label for Bibliographic Ontology:pages msgid "pages" -msgstr "" +msgstr "хуудас" #. Property comment for Bibliographic Ontology:pages msgid "" @@ -7091,7 +7091,7 @@ msgstr "" #. Property label for Bibliographic Ontology:shortTitle msgid "short title" -msgstr "" +msgstr "хураангуй нэр - гарчиг" #. Property comment for Bibliographic Ontology:shortTitle msgid "The abbreviation of a title." @@ -7149,7 +7149,7 @@ msgstr "" #. Class label for Friend of a Friend:Person msgid "Person" -msgstr "" +msgstr "Хувь хүн" #. Class comment for Friend of a Friend:Person msgid "A person." @@ -7169,7 +7169,7 @@ msgstr "" #. Class label for Friend of a Friend:Group msgid "Group" -msgstr "" +msgstr "Бүлэг" #. Class comment for Friend of a Friend:Group msgid "A class of Agents." @@ -7201,7 +7201,7 @@ msgstr "" #. Class label for Friend of a Friend:OnlineAccount msgid "Online Account" -msgstr "" +msgstr "Онлайн бүртгэл" #. Class comment for Friend of a Friend:OnlineAccount msgid "An online account." @@ -7233,7 +7233,7 @@ msgstr "" #. Property label for Friend of a Friend:mbox msgid "personal mailbox" -msgstr "" +msgstr "хувийн шуудангийн хайрцаг" #. Property comment for Friend of a Friend:mbox msgid "" @@ -7420,7 +7420,7 @@ msgstr "" #. Property label for Friend of a Friend:phone msgid "phone" -msgstr "" +msgstr "утас" #. Property comment for Friend of a Friend:phone msgid "" @@ -7430,7 +7430,7 @@ msgstr "" #. Property label for Friend of a Friend:homepage msgid "homepage" -msgstr "" +msgstr "нүүр хуудас" #. Property comment for Friend of a Friend:homepage msgid "A homepage for some thing." @@ -7540,7 +7540,7 @@ msgstr "" #. Property label for Friend of a Friend:workInfoHomepage msgid "work info homepage" -msgstr "" +msgstr "ажлын мэдээллийн нүүр хуудас" #. Property comment for Friend of a Friend:workInfoHomepage msgid "" @@ -7550,7 +7550,7 @@ msgstr "" #. Property label for Friend of a Friend:schoolHomepage msgid "schoolHomepage" -msgstr "" +msgstr "сургуулийнНүүрхуудас" #. Property comment for Friend of a Friend:schoolHomepage msgid "A homepage of a school attended by the person." @@ -7616,7 +7616,7 @@ msgstr "" #. Property label for Friend of a Friend:logo msgid "logo" -msgstr "" +msgstr "лого" #. Property comment for Friend of a Friend:logo msgid "A logo representing some thing." @@ -7624,7 +7624,7 @@ msgstr "" #. Property label for Friend of a Friend:topic msgid "topic" -msgstr "" +msgstr "сэдэв" #. Property comment for Friend of a Friend:topic msgid "A topic of some page or document." @@ -7640,7 +7640,7 @@ msgstr "" #. Property label for Friend of a Friend:focus msgid "focus" -msgstr "" +msgstr "фокус" #. Property comment for Friend of a Friend:focus msgid "" @@ -7662,7 +7662,7 @@ msgstr "" #. Property label for Friend of a Friend:theme msgid "theme" -msgstr "" +msgstr "загвар" #. Property comment for Friend of a Friend:theme msgid "A theme." @@ -7696,7 +7696,7 @@ msgstr "" #. Property label for Friend of a Friend:member msgid "member" -msgstr "" +msgstr "гишүүн" #. Property comment for Friend of a Friend:member msgid "Indicates a member of a Group" diff --git a/application/language/nl_NL.mo b/application/language/nl_NL.mo index e29ab3174c..2f0a2076f2 100644 Binary files a/application/language/nl_NL.mo and b/application/language/nl_NL.mo differ diff --git a/application/language/nl_NL.po b/application/language/nl_NL.po index 4f8fdbabf8..932151a6a5 100644 --- a/application/language/nl_NL.po +++ b/application/language/nl_NL.po @@ -7,6 +7,7 @@ # PaddoInWonderland , 2018 # Blair Kneppers , 2019 # John Flatness , 2023 +# Bob Coret, 2023 # #, fuzzy msgid "" @@ -15,7 +16,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-10 21:23-0400\n" "PO-Revision-Date: 2017-06-13 18:56+0000\n" -"Last-Translator: John Flatness , 2023\n" +"Last-Translator: Bob Coret, 2023\n" "Language-Team: Dutch (Netherlands) (https://app.transifex.com/omeka/teams/14184/nl_NL/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -204,11 +205,11 @@ msgstr "Nog een gebruiker toevoegen?" #: application/src/Controller/Admin/VocabularyController.php:92 msgid "Must provide a vocabulary file or a vocabulary URL" -msgstr "" +msgstr "Je moet een vocabulaire bestand or URL opgeven" #: application/src/Controller/Admin/VocabularyController.php:101 msgid "Import another vocabulary?" -msgstr "Nog een woordenschat importeren?" +msgstr "Nog een vocabulaire importeren?" #: application/src/DataType/Resource/AbstractResource.php:62 #, php-format @@ -1989,12 +1990,12 @@ msgstr "Collecties (%s)" #: application/view/omeka/admin/index/browse.phtml:27 #, php-format msgid "Vocabularies (%s)" -msgstr "Woordenschatten (%s)" +msgstr "Vocabulaires (%s)" #: application/view/omeka/admin/index/browse.phtml:29 #: application/view/omeka/admin/vocabulary/browse.phtml:11 msgid "Import new vocabulary" -msgstr "Woordenschat importeren" +msgstr "Vocabulaire importeren" #: application/view/omeka/admin/index/browse.phtml:33 #, php-format @@ -2591,7 +2592,7 @@ msgstr "Weet je zeker dat je deze module wil verwijderen?" #: application/view/omeka/admin/property/show-details.phtml:6 #: application/view/omeka/admin/resource-class/show-details.phtml:6 msgid "Vocabulary" -msgstr "Woordenschat" +msgstr "Vocabulaire" #: application/view/omeka/admin/property/show-details.phtml:10 #: application/view/omeka/admin/resource-class/show-details.phtml:10 @@ -2873,7 +2874,7 @@ msgstr "Naam" #: application/view/omeka/admin/vocabulary/properties.phtml:7 #: application/view/omeka/admin/vocabulary/update.phtml:20 msgid "Vocabularies" -msgstr "Woordenlijsten" +msgstr "Vocabulaires" #: application/view/omeka/admin/vocabulary/browse.phtml:27 msgid "Prefix" @@ -2891,7 +2892,7 @@ msgstr "Eigenschappen" #: application/view/omeka/admin/vocabulary/browse.phtml:83 msgid "Omeka could not find any vocabularies." -msgstr "Omeka kon geen enkele woordenlijst vinden." +msgstr "Omeka kon geen enkel vocabulaire vinden." #: application/view/omeka/admin/vocabulary/classes.phtml:10 #: application/view/omeka/admin/vocabulary/properties.phtml:10 @@ -2906,23 +2907,23 @@ msgstr "Naamruimte URI:" #: application/view/omeka/admin/vocabulary/classes.phtml:60 msgid "This vocabulary has no classes." -msgstr "Deze woordenlijst heeft geen klassen." +msgstr "Dit vocabulaire heeft geen klassen." #: application/view/omeka/admin/vocabulary/edit.phtml:18 msgid "" "You may update this vocabulary to a newer version. You will be able to " "review the changes before you accept." msgstr "" -"Je kunt deze woordenlijst bijwerken naar een nieuwere versie. Je kunt de " +"U kunt dit vocabulaire bijwerken naar een nieuwere versie. U kunt de " "wijzigingen bekijken voordat je accepteert." #: application/view/omeka/admin/vocabulary/import.phtml:7 msgid "New vocabulary" -msgstr "Nieuwe woordenlijst" +msgstr "Nieuw vocabulaire" #: application/view/omeka/admin/vocabulary/properties.phtml:61 msgid "This vocabulary has no properties." -msgstr "Deze woordenlijst heeft geen eigenschappen." +msgstr "Dit vocabulaire heeft geen eigenschappen." #: application/view/omeka/admin/vocabulary/update.phtml:20 msgid "Update" @@ -3801,7 +3802,7 @@ msgstr "" #: application/src/Api/Adapter/PropertyAdapter.php:197 #: application/src/Api/Adapter/ResourceClassAdapter.php:189 msgid "A vocabulary must be set." -msgstr "" +msgstr "Er moet een vocabulaire ingesteld worden." #: application/src/Api/Adapter/AbstractResourceEntityAdapter.php:209 #, php-format @@ -4081,7 +4082,7 @@ msgstr "" #: application/src/Form/SettingForm.php:181 #: application/src/Form/SiteSettingsForm.php:92 msgid "Show Vocabulary" -msgstr "Toon woordenlijst" +msgstr "Toon vocabulaire" #: application/src/Form/SettingForm.php:182 #: application/src/Form/SiteSettingsForm.php:93 @@ -4267,11 +4268,11 @@ msgstr "" #: application/src/Form/VocabularyForm.php:46 msgid "Enter a human-readable title of the vocabulary." -msgstr "" +msgstr "Voer een voor mensen leesbare titel van het vocabulaire in." #: application/src/Form/VocabularyForm.php:58 msgid "Enter a human-readable description of the vocabulary." -msgstr "" +msgstr "Voer een voor mensen leesbare beschrijving van het vocabulaire in." #: application/src/Form/VocabularyForm.php:69 msgid "Namespace URI" @@ -4282,6 +4283,8 @@ msgid "" "Enter the unique namespace URI used to identify the classes and properties " "of the vocabulary." msgstr "" +"Voer de unieke naamruimte-URI in die wordt gebruikt om de klassen en " +"eigenschappen van het vocabulaire te identificeren." #: application/src/Form/VocabularyForm.php:81 msgid "Namespace prefix" @@ -4292,24 +4295,30 @@ msgid "" "Enter a concise vocabulary identifier used as a shorthand for the namespace " "URI." msgstr "" +"Voer een beknopte vocabulaire-identificatie in die wordt gebruikt als " +"afkorting voor de naamruimte-URI." #: application/src/Form/VocabularyForm.php:94 msgid "Vocabulary file" -msgstr "Woordenlijstbestand" +msgstr "Vocabulairebestand" #: application/src/Form/VocabularyForm.php:95 msgid "" "Choose a RDF vocabulary file. You must choose a file or enter a URL below." msgstr "" +"Kies een RDF-vocabulairebestand. U moet een bestand kiezen of hieronder een " +"URL invoeren." #: application/src/Form/VocabularyForm.php:105 msgid "Vocabulary URL" -msgstr "Woordenlijst URL" +msgstr "Vocabulaire URL" #: application/src/Form/VocabularyForm.php:106 msgid "" "Enter a RDF vocabulary URL. You must enter a URL or choose a file above." msgstr "" +"Voer een RDF-vocabulaire-URL in. U moet hierboven een URL invoeren of een " +"bestand kiezen." #: application/src/Form/VocabularyForm.php:116 msgid "File format" @@ -4356,6 +4365,9 @@ msgid "" "uses an unconventional property for labels. Please use the full property URI" " enclosed in angle brackets." msgstr "" +"Voer de labeleigenschap in. Dit is meestal alleen nodig als het vocabulaire " +"een onconventionele eigenschap voor labels gebruikt. Gebruik de volledige " +"eigendoms-URI tussen punthaken." #: application/src/Form/VocabularyForm.php:157 msgid "Comment property" @@ -4367,6 +4379,9 @@ msgid "" "uses an unconventional property for comments. Please use the full property " "URI enclosed in angle brackets." msgstr "" +"Voer de opmerkingseigenschap in. Dit is meestal alleen nodig als het " +"vocabulaire een onconventionele eigenschap voor opmerkingen gebruikt. " +"Gebruik de volledige eigendoms-URI tussen punthaken." #: application/src/Form/SiteForm.php:54 msgid "Choose or upload a thumbnail to display with site." @@ -4681,7 +4696,7 @@ msgstr "" #: application/src/Form/SiteSettingsForm.php:352 msgid "Advanced search vocabulary members" -msgstr "" +msgstr "Geavanceerd zoeken in vocabulaire onderdelen" #: application/src/Form/SiteSettingsForm.php:353 msgid "Limit the search options for property and class" @@ -4689,7 +4704,7 @@ msgstr "" #: application/src/Form/SiteSettingsForm.php:354 msgid "All vocabulary members" -msgstr "" +msgstr "Alle vocabulaire onderdelen" #: application/src/Form/SiteSettingsForm.php:356 msgid "Used by resources in this site" @@ -5303,12 +5318,12 @@ msgstr "Collecties worden bijgewerkt. Dat kan even duren." #: application/src/Controller/Admin/VocabularyController.php:59 msgid "vocabulary" -msgstr "woordenlijst" +msgstr "vocabulaire" #: application/src/Controller/Admin/VocabularyController.php:97 #, php-format msgid "Vocabulary successfully imported. %s" -msgstr "Woordenlijst succesvol geïmporteerd. %s" +msgstr "Vocabulaire succesvol geïmporteerd. %s" #: application/src/Controller/Admin/VocabularyController.php:176 msgid "Please review these changes before you accept them." @@ -5316,15 +5331,15 @@ msgstr "" #: application/src/Controller/Admin/VocabularyController.php:184 msgid "Vocabulary successfully updated" -msgstr "Woordenlijst succesvol bijgewerkt" +msgstr "Vocabulaire succesvol bijgewerkt" #: application/src/Controller/Admin/VocabularyController.php:204 msgid "Changes to the vocabulary successfully made" -msgstr "Wijzigingen in de woordenlijst zijn succesvol aangebracht" +msgstr "Wijzigingen in het vocabulaire zijn succesvol aangebracht" #: application/src/Controller/Admin/VocabularyController.php:220 msgid "Vocabulary successfully deleted" -msgstr "Woordenlijst succesvol verwijderd" +msgstr "Vocabulaire succesvol verwijderd" #: application/src/Controller/Admin/ResourceTemplateController.php:444 msgid "resource template" diff --git a/application/language/pt_BR.mo b/application/language/pt_BR.mo index eba5b97486..b27702969e 100644 Binary files a/application/language/pt_BR.mo and b/application/language/pt_BR.mo differ diff --git a/application/language/pt_BR.po b/application/language/pt_BR.po index 41dcc0c752..4cb84fb9b1 100644 --- a/application/language/pt_BR.po +++ b/application/language/pt_BR.po @@ -5,10 +5,10 @@ # # Translators: # Diego Ecker , 2018 -# Amarilis Correa , 2023 # Carlos Eduardo Maciel , 2023 # Deidson Rafael Trindade , 2023 # John Flatness , 2023 +# Amarilis Correa , 2023 # #, fuzzy msgid "" @@ -17,7 +17,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-10 21:23-0400\n" "PO-Revision-Date: 2017-06-13 18:56+0000\n" -"Last-Translator: John Flatness , 2023\n" +"Last-Translator: Amarilis Correa , 2023\n" "Language-Team: Portuguese (Brazil) (https://app.transifex.com/omeka/teams/14184/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -3720,15 +3720,15 @@ msgstr "Administrador Global" #: application/src/Permissions/Acl.php:22 msgid "Supervisor" -msgstr "" +msgstr "Supervisor" #: application/src/Permissions/Acl.php:23 msgid "Editor" -msgstr "" +msgstr "Editor" #: application/src/Permissions/Acl.php:24 msgid "Reviewer" -msgstr "" +msgstr "Revisor" #: application/src/Permissions/Acl.php:25 msgid "Author" @@ -3740,11 +3740,11 @@ msgstr "Pesquisador" #: application/src/ColumnType/IsPublic.php:11 msgid "Is public" -msgstr "" +msgstr "É público" #: application/src/ColumnType/Value.php:25 msgid "Value" -msgstr "" +msgstr "Valor" #: application/src/ColumnType/Value.php:56 msgid "Max values" @@ -3784,7 +3784,7 @@ msgstr "" #: application/src/Api/Adapter/ResourceTemplateAdapter.php:75 #, php-format msgid "Attempting to add duplicate property with ID %s" -msgstr "" +msgstr "Tentativa de adicionar propriedade duplicada com ID %s" #: application/src/Api/Adapter/ResourceTemplateAdapter.php:89 #: application/src/Api/Adapter/PropertyAdapter.php:178 diff --git a/application/language/sv_SE.mo b/application/language/sv_SE.mo index 3a32d173b1..d0d33c9cc8 100644 Binary files a/application/language/sv_SE.mo and b/application/language/sv_SE.mo differ diff --git a/application/language/sv_SE.po b/application/language/sv_SE.po index acfb1cdb37..8d39b9e17b 100644 --- a/application/language/sv_SE.po +++ b/application/language/sv_SE.po @@ -6,6 +6,7 @@ # Translators: # Kai Metsävainio , 2022 # John Flatness , 2023 +# Albin Larsson , 2023 # #, fuzzy msgid "" @@ -14,7 +15,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-10 21:23-0400\n" "PO-Revision-Date: 2017-06-13 18:56+0000\n" -"Last-Translator: John Flatness , 2023\n" +"Last-Translator: Albin Larsson , 2023\n" "Language-Team: Swedish (Sweden) (https://app.transifex.com/omeka/teams/14184/sv_SE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -190,7 +191,7 @@ msgstr "Vill du lägga till en annan resursmall?" #: application/src/Controller/Admin/SystemInfoController.php:89 #: application/src/Controller/Admin/SystemInfoController.php:94 msgid "[invalid]" -msgstr "" +msgstr "[ogiltig]" #: application/src/Controller/Admin/SystemInfoController.php:134 #: application/src/Controller/Admin/SystemInfoController.php:145 @@ -507,22 +508,22 @@ msgstr "innehåller inte" #: application/src/View/Helper/SearchFilters.php:36 #: application/view/common/advanced-search/properties.phtml:80 msgid "starts with" -msgstr "" +msgstr "startar med" #: application/src/View/Helper/SearchFilters.php:37 #: application/view/common/advanced-search/properties.phtml:81 msgid "does not start with" -msgstr "" +msgstr "startar inte med" #: application/src/View/Helper/SearchFilters.php:38 #: application/view/common/advanced-search/properties.phtml:82 msgid "ends with" -msgstr "" +msgstr "slutar med" #: application/src/View/Helper/SearchFilters.php:39 #: application/view/common/advanced-search/properties.phtml:83 msgid "does not end with" -msgstr "" +msgstr "slutar inte med" #: application/src/View/Helper/SearchFilters.php:40 #: application/view/common/advanced-search/properties.phtml:84 @@ -686,12 +687,12 @@ msgstr "" #: application/src/View/Helper/SearchFilters.php:216 #: application/view/common/advanced-search/has-media.phtml:5 msgid "Has media" -msgstr "" +msgstr "Har media" #: application/src/View/Helper/SearchFilters.php:216 #: application/view/common/advanced-search/has-media.phtml:6 msgid "Has no media" -msgstr "" +msgstr "Har ingen media" #: application/src/View/Helper/SearchFilters.php:220 #: application/view/omeka/admin/item-set/show-details.phtml:13 @@ -830,11 +831,11 @@ msgstr "" #: application/view/common/advanced-search/item-sets.phtml:54 msgid "In" -msgstr "" +msgstr "I" #: application/view/common/advanced-search/item-sets.phtml:55 msgid "Not in" -msgstr "" +msgstr "Inte i" #: application/view/common/advanced-search/item-sets.phtml:66 #: application/view/common/advanced-search/properties.phtml:90 diff --git a/application/language/template.pot b/application/language/template.pot index 463aa883a3..4b5d6de4ed 100644 --- a/application/language/template.pot +++ b/application/language/template.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-04-10 21:23-0400\n" +"POT-Creation-Date: 2023-12-20 13:32-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -57,32 +57,32 @@ msgstr "" msgid "The %1$s adapter does not implement the batch delete operation." msgstr "" -#: application/src/Api/Adapter/AbstractEntityAdapter.php:292 +#: application/src/Api/Adapter/AbstractEntityAdapter.php:293 #, php-format msgid "The \"%1$s\" field is not available in the %2$s adapter class." msgstr "" -#: application/src/Api/Adapter/AbstractEntityAdapter.php:308 +#: application/src/Api/Adapter/AbstractEntityAdapter.php:309 #, php-format msgid "The \"%1$s\" field is not available in the %2$s entity class." msgstr "" -#: application/src/Api/Adapter/AbstractEntityAdapter.php:680 +#: application/src/Api/Adapter/AbstractEntityAdapter.php:681 #: application/src/Api/Manager.php:209 #, php-format msgid "Permission denied for the current user to %1$s the %2$s resource." msgstr "" -#: application/src/Api/Adapter/AbstractEntityAdapter.php:722 +#: application/src/Api/Adapter/AbstractEntityAdapter.php:723 #, php-format msgid "%1$s entity with criteria %2$s not found" msgstr "" -#: application/src/Api/Adapter/SiteAdapter.php:140 +#: application/src/Api/Adapter/SiteAdapter.php:154 msgid "Welcome" msgstr "" -#: application/src/Api/Adapter/SiteAdapter.php:398 +#: application/src/Api/Adapter/SiteAdapter.php:412 msgid "Browse" msgstr "" @@ -91,7 +91,7 @@ msgstr "" msgid "The API does not support the \"%s\" resource." msgstr "" -#: application/src/Api/Representation/AbstractResourceEntityRepresentation.php:599 +#: application/src/Api/Representation/AbstractResourceEntityRepresentation.php:630 #: application/view/common/block-layout/browse-preview.phtml:25 #: application/view/omeka/site/item-set/browse.phtml:28 #: application/view/omeka/site/item/browse.phtml:46 @@ -99,12 +99,14 @@ msgid "[Untitled]" msgstr "" #: application/src/Api/Representation/ResourceTemplatePropertyRepresentation.php:129 +#: application/src/Form/BlockLayoutDataForm.php:54 #: application/view/omeka/admin/resource-template/review-import.phtml:88 msgid "Default" msgstr "" #: application/src/ColumnType/IsOpen.php:42 #: application/src/ColumnType/IsPublic.php:42 +#: application/view/common/navigation-link-form/url.phtml:15 #: application/view/omeka/admin/resource-template/review-import.phtml:112 #: application/view/omeka/admin/resource-template/review-import.phtml:113 #: application/view/omeka/admin/resource-template/show.phtml:58 @@ -115,6 +117,7 @@ msgstr "" #: application/src/ColumnType/IsOpen.php:43 #: application/src/ColumnType/IsPublic.php:43 +#: application/view/common/navigation-link-form/url.phtml:14 #: application/view/omeka/admin/resource-template/review-import.phtml:112 #: application/view/omeka/admin/resource-template/review-import.phtml:113 #: application/view/omeka/admin/resource-template/show.phtml:58 @@ -181,25 +184,21 @@ msgstr "" msgid "Add another resource template?" msgstr "" -#: application/src/Controller/Admin/SystemInfoController.php:89 -#: application/src/Controller/Admin/SystemInfoController.php:94 +#: application/src/Controller/Admin/SystemInfoController.php:90 +#: application/src/Controller/Admin/SystemInfoController.php:95 msgid "[invalid]" msgstr "" -#: application/src/Controller/Admin/SystemInfoController.php:134 -#: application/src/Controller/Admin/SystemInfoController.php:145 +#: application/src/Controller/Admin/SystemInfoController.php:154 +#: application/src/Controller/Admin/SystemInfoController.php:165 msgid "[Unable to execute command]" msgstr "" -#: application/src/Controller/Admin/UserController.php:119 +#: application/src/Controller/Admin/UserController.php:125 msgid "Add another user?" msgstr "" -#: application/src/Controller/Admin/VocabularyController.php:92 -msgid "Must provide a vocabulary file or a vocabulary URL" -msgstr "" - -#: application/src/Controller/Admin/VocabularyController.php:101 +#: application/src/Controller/Admin/VocabularyController.php:93 msgid "Import another vocabulary?" msgstr "" @@ -213,7 +212,7 @@ msgstr "" #: application/view/common/data-type/resource.phtml:23 #: application/view/layout/layout-admin.phtml:68 #: application/view/omeka/admin/item-set/show-details.phtml:22 -#: application/view/omeka/admin/item-set/show.phtml:86 +#: application/view/omeka/admin/item-set/show.phtml:83 #: application/view/omeka/admin/item/add.phtml:6 #: application/view/omeka/admin/item/browse.phtml:7 #: application/view/omeka/admin/item/edit.phtml:14 @@ -239,8 +238,8 @@ msgstr "" #: application/view/common/resource-page-block-layout/media-list.phtml:7 #: application/view/layout/layout-admin.phtml:76 #: application/view/omeka/admin/item/form.phtml:15 -#: application/view/omeka/admin/item/show-details.phtml:40 -#: application/view/omeka/admin/item/show.phtml:94 +#: application/view/omeka/admin/item/show-details.phtml:48 +#: application/view/omeka/admin/item/show.phtml:99 #: application/view/omeka/admin/media/browse.phtml:7 #: application/view/omeka/admin/media/edit.phtml:17 #: application/view/omeka/admin/media/edit.phtml:25 @@ -284,11 +283,41 @@ msgstr "" msgid "Password must:" msgstr "" +#: application/src/Form/VocabularyForm.php:79 +msgid "" +"The namespace URI you entered does not end with a / or #, as is normally " +"expected for namespace URIs. Would you like to save anyway?" +msgstr "" + +#: application/src/Form/VocabularyForm.php:80 +msgid "" +"The namespace URI you entered does not match the saved namespace URI. Would " +"you like to save anyway?" +msgstr "" + #: application/src/Media/Ingester/Fallback.php:33 #: application/view/common/navigation-link-form/fallback.phtml:4 msgid "Unknown" msgstr "" +#: application/src/Media/Ingester/Upload.php:74 +msgid "Upload file" +msgstr "" + +#: application/src/Media/Ingester/Upload.php:75 +#: application/view/common/advanced-search/ids.phtml:13 +#: application/view/common/advanced-search/item-sets.phtml:44 +#: application/view/common/advanced-search/owner.phtml:4 +#: application/view/common/advanced-search/resource-class.phtml:25 +#: application/view/common/advanced-search/resource-template.phtml:17 +#: application/view/common/advanced-search/site.phtml:4 +#: application/view/common/form-row.phtml:16 +#: application/view/common/resource-values.phtml:66 +#: application/view/omeka/admin/item-set/sidebar-select.phtml:19 +#: application/view/omeka/admin/item/sidebar-select.phtml:28 +msgid "Expand" +msgstr "" + #: application/src/Module/Manager.php:156 #, php-format msgid "Module \"%1$s\" is marked as \"%2$s\" and cannot be activated" @@ -339,7 +368,7 @@ msgstr "" msgid "Permission denied for the current user to %1$s the %2$s module." msgstr "" -#: application/src/Mvc/MvcListeners.php:458 +#: application/src/Mvc/MvcListeners.php:459 #, php-format msgid "" "Permission denied for the current user to access the %1$s action of the %2$s " @@ -351,12 +380,11 @@ msgid "This layout is invalid." msgstr "" #: application/src/Site/BlockLayout/ItemShowcase.php:22 -#: application/src/Site/BlockLayout/Media.php:22 -#: application/view/common/asset-block-form.phtml:58 +#: application/src/Site/BlockLayout/Media.php:21 msgid "Options" msgstr "" -#: application/src/Site/BlockLayout/LineBreak.php:43 +#: application/src/Site/BlockLayout/LineBreak.php:41 msgid "Break type" msgstr "" @@ -364,6 +392,13 @@ msgstr "" msgid "Add pages" msgstr "" +#: application/src/Site/BlockLayout/Oembed.php:113 +#: application/view/omeka/admin/item-set/form.phtml:14 +#: application/view/omeka/admin/item/form.phtml:18 +#: application/view/omeka/admin/media/edit.phtml:14 +msgid "Advanced" +msgstr "" + #: application/src/Site/BlockLayout/TableOfContents.php:28 msgid "Depth" msgstr "" @@ -421,12 +456,33 @@ msgstr "" msgid "User activation for %s" msgstr "" -#: application/src/View/Helper/BlockShowTitleSelect.php:33 -msgid "Show attachment title" +#: application/src/Stdlib/Oembed.php:44 +#, php-format +msgid "oEmbed: URL is not allowed %s" msgstr "" -#: application/src/View/Helper/BlockThumbnailTypeSelect.php:42 -msgid "Thumbnail type" +#: application/src/Stdlib/Oembed.php:57 +#, php-format +msgid "oEmbed: links cannot be found at %s" +msgstr "" + +#: application/src/Stdlib/Oembed.php:69 +#, php-format +msgid "oEmbed: response cannot be decoded to JSON %s" +msgstr "" + +#: application/src/Stdlib/Oembed.php:114 +#, php-format +msgid "oEmbed: URL is invalid: %s" +msgstr "" + +#: application/src/Stdlib/Oembed.php:123 +#, php-format +msgid "oEmbed: URL is unreadable at %s: %s (%s)" +msgstr "" + +#: application/src/View/Helper/BlockShowTitleSelect.php:33 +msgid "Show attachment title" msgstr "" #: application/src/View/Helper/CancelButton.php:14 @@ -526,7 +582,6 @@ msgid "Search full-text" msgstr "" #: application/src/View/Helper/SearchFilters.php:64 -#: application/view/common/asset-block-form.phtml:63 #: application/view/common/linked-resources.phtml:75 #: application/view/omeka/admin/item-set/show.phtml:41 #: application/view/omeka/admin/item/show.phtml:31 @@ -623,35 +678,33 @@ msgstr "" #: application/src/View/Helper/SearchFilters.php:210 #: application/view/omeka/admin/item-set/show-details.phtml:17 -#: application/view/omeka/admin/item-set/show.phtml:81 +#: application/view/omeka/admin/item-set/show.phtml:78 #: application/view/omeka/admin/item/show-details.phtml:17 -#: application/view/omeka/admin/item/show.phtml:63 +#: application/view/omeka/admin/item/show.phtml:60 #: application/view/omeka/admin/media/show-details.phtml:49 #: application/view/omeka/admin/media/show.phtml:38 msgid "Visibility" msgstr "" #: application/src/View/Helper/SearchFilters.php:211 -#: application/view/common/advanced-search/visibility.phtml:5 #: application/view/common/property-form-batch-edit.phtml:17 #: application/view/common/property-form-batch-edit.phtml:31 #: application/view/common/property-form-batch-edit.phtml:46 -#: application/view/common/property-form-batch-edit.phtml:66 +#: application/view/common/property-form-batch-edit.phtml:68 #: application/view/omeka/admin/item-set/show-details.phtml:18 -#: application/view/omeka/admin/item-set/show.phtml:82 +#: application/view/omeka/admin/item-set/show.phtml:79 #: application/view/omeka/admin/item/show-details.phtml:18 -#: application/view/omeka/admin/item/show.phtml:64 +#: application/view/omeka/admin/item/show.phtml:61 #: application/view/omeka/admin/media/show-details.phtml:50 #: application/view/omeka/admin/media/show.phtml:39 msgid "Public" msgstr "" #: application/src/View/Helper/SearchFilters.php:211 -#: application/view/common/advanced-search/visibility.phtml:6 #: application/view/common/property-form-batch-edit.phtml:18 #: application/view/common/property-form-batch-edit.phtml:32 #: application/view/common/property-form-batch-edit.phtml:47 -#: application/view/common/property-form-batch-edit.phtml:67 +#: application/view/common/property-form-batch-edit.phtml:69 msgid "Not public" msgstr "" @@ -660,20 +713,18 @@ msgid "Media presence" msgstr "" #: application/src/View/Helper/SearchFilters.php:216 -#: application/view/common/advanced-search/has-media.phtml:5 msgid "Has media" msgstr "" #: application/src/View/Helper/SearchFilters.php:216 -#: application/view/common/advanced-search/has-media.phtml:6 msgid "Has no media" msgstr "" #: application/src/View/Helper/SearchFilters.php:220 #: application/view/omeka/admin/item-set/show-details.phtml:13 -#: application/view/omeka/admin/item-set/show.phtml:69 +#: application/view/omeka/admin/item-set/show.phtml:66 #: application/view/omeka/admin/item/show-details.phtml:13 -#: application/view/omeka/admin/item/show.phtml:59 +#: application/view/omeka/admin/item/show.phtml:56 #: application/view/omeka/admin/job/browse.phtml:19 #: application/view/omeka/admin/media/show-details.phtml:18 #: application/view/omeka/admin/media/show.phtml:34 @@ -745,7 +796,7 @@ msgstr "" #: application/view/omeka/admin/user/browse.phtml:87 #: application/view/omeka/admin/user/edit.phtml:14 #: application/view/omeka/admin/vocabulary/browse.phtml:42 -#: application/view/omeka/admin/vocabulary/edit.phtml:7 +#: application/view/omeka/admin/vocabulary/edit.phtml:8 #: application/view/omeka/site-admin/index/index.phtml:46 #: application/view/omeka/site-admin/index/show.phtml:11 #: application/view/omeka/site-admin/page/edit.phtml:11 @@ -759,31 +810,10 @@ msgstr "" msgid "View" msgstr "" -#: application/view/common/advanced-search/has-media.phtml:3 -msgid "Search by media presence" -msgstr "" - -#: application/view/common/advanced-search/has-media.phtml:8 -msgid "Select media presence…" -msgstr "" - #: application/view/common/advanced-search/ids.phtml:12 msgid "Search by ID" msgstr "" -#: application/view/common/advanced-search/ids.phtml:13 -#: application/view/common/advanced-search/item-sets.phtml:44 -#: application/view/common/advanced-search/owner.phtml:4 -#: application/view/common/advanced-search/resource-class.phtml:25 -#: application/view/common/advanced-search/resource-template.phtml:17 -#: application/view/common/advanced-search/site.phtml:4 -#: application/view/common/form-row.phtml:16 -#: application/view/common/resource-values.phtml:73 -#: application/view/omeka/admin/item-set/sidebar-select.phtml:19 -#: application/view/omeka/admin/item/sidebar-select.phtml:28 -msgid "Expand" -msgstr "" - #: application/view/common/advanced-search/ids.phtml:15 msgid "" "Searches for resources by Omeka S ID. You can search for more than one ID by " @@ -804,6 +834,10 @@ msgstr "" msgid "Add new item set" msgstr "" +#: application/view/common/advanced-search/item-sets.phtml:53 +msgid "Condition" +msgstr "" + #: application/view/common/advanced-search/item-sets.phtml:54 msgid "In" msgstr "" @@ -816,7 +850,6 @@ msgstr "" #: application/view/common/advanced-search/properties.phtml:90 #: application/view/common/advanced-search/resource-class.phtml:44 #: application/view/common/advanced-search/resource-template.phtml:33 -#: application/view/common/block-layout.phtml:13 #: application/view/common/data-type-wrapper.phtml:18 #: application/view/common/media-field-wrapper.phtml:14 #: application/view/common/value-annotation-wrapper.phtml:11 @@ -848,8 +881,8 @@ msgstr "" msgid "Add new value" msgstr "" -#: application/view/common/advanced-search/properties.phtml:67 -msgid "Property" +#: application/view/common/advanced-search/properties.phtml:58 +msgid "Joiner" msgstr "" #: application/view/common/advanced-search/properties.phtml:75 @@ -888,27 +921,7 @@ msgstr "" msgid "Searches for items that are assigned to this site." msgstr "" -#: application/view/common/advanced-search/sort.phtml:19 -msgid "Select sort by…" -msgstr "" - -#: application/view/common/advanced-search/sort.phtml:24 -msgid "Select sort order…" -msgstr "" - -#: application/view/common/advanced-search/sort.phtml:26 -#: application/view/common/browse-defaults-form.phtml:20 -#: application/view/common/sort-selector.phtml:13 -msgid "Ascending" -msgstr "" - -#: application/view/common/advanced-search/sort.phtml:27 -#: application/view/common/browse-defaults-form.phtml:19 -#: application/view/common/sort-selector.phtml:14 -msgid "Descending" -msgstr "" - -#: application/view/common/advanced-search/sort.phtml:33 +#: application/view/common/advanced-search/sort.phtml:35 #: application/view/common/sort-selector.phtml:16 msgid "Sort" msgstr "" @@ -929,14 +942,6 @@ msgstr "" msgid "Search by activity" msgstr "" -#: application/view/common/advanced-search/visibility.phtml:3 -msgid "Search by visibility" -msgstr "" - -#: application/view/common/advanced-search/visibility.phtml:8 -msgid "Select visibility…" -msgstr "" - #: application/view/common/asset-block-form.phtml:7 #: application/view/common/asset-block-form.phtml:40 msgid "No asset selected" @@ -962,13 +967,13 @@ msgid "Restore attachment" msgstr "" #: application/view/common/asset-block-form.phtml:20 -#: application/view/common/asset-block-form.phtml:57 -#: application/view/common/block-layout.phtml:12 +#: application/view/common/block-layout.phtml:39 #: application/view/common/resource-form-templates.phtml:10 +#: application/view/common/resource-values.phtml:66 #: application/view/omeka/admin/item-set/sidebar-select.phtml:19 #: application/view/omeka/admin/item/sidebar-select.phtml:28 #: application/view/omeka/site-admin/page/attachment-item-options.phtml:35 -#: application/view/omeka/site-admin/page/edit.phtml:62 +#: application/view/omeka/site-admin/page/edit.phtml:120 msgid "Collapse" msgstr "" @@ -1052,7 +1057,10 @@ msgstr "" #: application/view/omeka/admin/vocabulary/properties.phtml:53 #: application/view/omeka/site-admin/index/index.phtml:71 #: application/view/omeka/site-admin/index/navigation.phtml:30 -#: application/view/omeka/site-admin/page/edit.phtml:56 +#: application/view/omeka/site-admin/page/edit.phtml:79 +#: application/view/omeka/site-admin/page/edit.phtml:96 +#: application/view/omeka/site-admin/page/edit.phtml:103 +#: application/view/omeka/site-admin/page/edit.phtml:114 #: application/view/omeka/site-admin/page/index.phtml:78 msgid "Close" msgstr "" @@ -1066,12 +1074,13 @@ msgid "Alternative link title" msgstr "" #: application/view/common/asset-options.phtml:44 -#: application/view/omeka/site-admin/page/edit.phtml:59 +#: application/view/omeka/site-admin/page/edit.phtml:117 msgid "Caption" msgstr "" #: application/view/common/asset-options.phtml:50 -#: application/view/omeka/site-admin/page/edit.phtml:70 +#: application/view/omeka/site-admin/page/edit.phtml:108 +#: application/view/omeka/site-admin/page/edit.phtml:128 msgid "Apply changes" msgstr "" @@ -1093,16 +1102,56 @@ msgstr "" msgid "Add attachment" msgstr "" -#: application/view/common/block-layout.phtml:10 +#: application/view/common/background-form.phtml:2 +msgid "Vertical anchor position" +msgstr "" + +#: application/view/common/background-form.phtml:4 +msgid "Horizontal anchor position" +msgstr "" + +#: application/view/common/background-form.phtml:6 +#: application/view/omeka/admin/media/show-details.phtml:43 +#: application/view/omeka/admin/media/show.phtml:64 +msgid "Size" +msgstr "" + +#: application/view/common/block-layout.phtml:5 +msgid "Auto placement" +msgstr "" + +#: application/view/common/block-layout.phtml:7 +#, php-format +msgid "Position %s" +msgstr "" + +#: application/view/common/block-layout.phtml:11 +#, php-format +msgid "Span %s" +msgstr "" + +#: application/view/common/block-layout.phtml:21 msgid "Block to be removed" msgstr "" -#: application/view/common/block-layout.phtml:14 -#: application/view/common/data-type-wrapper.phtml:19 -#: application/view/common/value-annotation-wrapper.phtml:12 -#: application/view/omeka/admin/item/manage-media.phtml:64 -#: application/view/omeka/admin/resource-template/show-property-row.phtml:42 -msgid "Restore value" +#: application/view/common/block-layout.phtml:35 +#: application/view/omeka/site-admin/page/edit.phtml:65 +msgid "Preview layout" +msgstr "" + +#: application/view/common/block-layout.phtml:36 +#: application/view/omeka/site-admin/page/edit.phtml:66 +msgid "Configure layout" +msgstr "" + +#: application/view/common/block-layout.phtml:37 +#: application/view/omeka/site-admin/index/theme-resource-pages.phtml:6 +msgid "Remove block" +msgstr "" + +#: application/view/common/block-layout.phtml:38 +#: application/view/omeka/site-admin/index/theme-resource-pages.phtml:7 +msgid "Restore block" msgstr "" #: application/view/common/block-layout/item-with-metadata.phtml:19 @@ -1118,7 +1167,7 @@ msgstr "" #: application/view/omeka/admin/item-set/show.phtml:26 #: application/view/omeka/admin/item/form.phtml:16 #: application/view/omeka/admin/item/show-details.phtml:23 -#: application/view/omeka/admin/item/show.phtml:69 +#: application/view/omeka/admin/item/show.phtml:66 #: application/view/omeka/admin/user/show-details.phtml:17 #: application/view/omeka/site-admin/index/resources.phtml:23 #: application/view/omeka/site/item-set/browse.phtml:13 @@ -1126,8 +1175,8 @@ msgid "Item sets" msgstr "" #: application/view/common/block-layout/page-date-time.phtml:13 -#: application/view/omeka/admin/item-set/show.phtml:73 -#: application/view/omeka/admin/item/show.phtml:85 +#: application/view/omeka/admin/item-set/show.phtml:70 +#: application/view/omeka/admin/item/show.phtml:90 #: application/view/omeka/admin/media/show.phtml:47 #: application/view/omeka/admin/user/browse.phtml:67 #: application/view/omeka/site-admin/page/index.phtml:26 @@ -1147,6 +1196,16 @@ msgstr "" msgid "Enter a custom sort by" msgstr "" +#: application/view/common/browse-defaults-form.phtml:19 +#: application/view/common/sort-selector.phtml:14 +msgid "Descending" +msgstr "" + +#: application/view/common/browse-defaults-form.phtml:20 +#: application/view/common/sort-selector.phtml:13 +msgid "Ascending" +msgstr "" + #: application/view/common/columns-form.phtml:16 #: application/view/omeka/admin/item/add.phtml:13 #: application/view/omeka/admin/resource-template/add.phtml:15 @@ -1225,6 +1284,13 @@ msgstr "" msgid "Value to be removed" msgstr "" +#: application/view/common/data-type-wrapper.phtml:19 +#: application/view/common/value-annotation-wrapper.phtml:12 +#: application/view/omeka/admin/item/manage-media.phtml:64 +#: application/view/omeka/admin/resource-template/show-property-row.phtml:42 +msgid "Restore value" +msgstr "" + #: application/view/common/data-type-wrapper.phtml:21 msgid "More actions" msgstr "" @@ -1279,7 +1345,7 @@ msgstr "" #: application/view/common/data-type/value-annotation-uri.phtml:17 #: application/view/common/navigation-link-form/browse.phtml:16 #: application/view/common/navigation-link-form/page.phtml:15 -#: application/view/common/navigation-link-form/url.phtml:8 +#: application/view/common/navigation-link-form/url.phtml:9 #: application/view/common/property-form-batch-edit.phtml:45 #: application/view/omeka/admin/resource-template/browse.phtml:26 #: application/view/omeka/admin/resource-template/form.phtml:55 @@ -1366,7 +1432,7 @@ msgstr "" #: application/view/common/navigation-link-form/browse.phtml:15 #: application/view/common/navigation-link-form/page.phtml:13 -#: application/view/common/navigation-link-form/url.phtml:7 +#: application/view/common/navigation-link-form/url.phtml:8 msgid "Type" msgstr "" @@ -1375,42 +1441,46 @@ msgid "Query" msgstr "" #: application/view/common/navigation-link-form/page.phtml:14 -#: application/view/common/pagination.phtml:8 +#: application/view/common/pagination.phtml:15 #: application/view/common/sidebar-pagination.phtml:5 msgid "Page" msgstr "" -#: application/view/common/navigation-link-form/url.phtml:9 +#: application/view/common/navigation-link-form/url.phtml:10 msgid "URL" msgstr "" +#: application/view/common/navigation-link-form/url.phtml:12 +msgid "Open in new tab" +msgstr "" + #: application/view/common/page-select-sidebar.phtml:8 msgid "Select Pages" msgstr "" -#: application/view/common/pagination.phtml:9 +#: application/view/common/pagination.phtml:16 #: application/view/common/sidebar-pagination.phtml:6 #, php-format msgid "of %s" msgstr "" -#: application/view/common/pagination.phtml:13 +#: application/view/common/pagination.phtml:20 #: application/view/common/sidebar-pagination.phtml:9 msgid "Previous" msgstr "" -#: application/view/common/pagination.phtml:19 +#: application/view/common/pagination.phtml:26 #: application/view/common/sidebar-pagination.phtml:15 #: application/view/common/site-page-pagination.phtml:4 msgid "Next" msgstr "" -#: application/view/common/pagination.phtml:28 +#: application/view/common/pagination.phtml:35 #, php-format msgid "%1$s–%2$s of %3$s" msgstr "" -#: application/view/common/pagination.phtml:30 +#: application/view/common/pagination.phtml:37 msgid "0 results" msgstr "" @@ -1419,7 +1489,7 @@ msgid "Select property" msgstr "" #: application/view/common/property-form-batch-edit.phtml:12 -#: application/view/common/property-form-batch-edit.phtml:76 +#: application/view/common/property-form-batch-edit.phtml:78 msgid "Add text value" msgstr "" @@ -1430,7 +1500,7 @@ msgid "Remove" msgstr "" #: application/view/common/property-form-batch-edit.phtml:26 -#: application/view/common/property-form-batch-edit.phtml:77 +#: application/view/common/property-form-batch-edit.phtml:79 msgid "Add resource value" msgstr "" @@ -1439,10 +1509,17 @@ msgid "Resource ID" msgstr "" #: application/view/common/property-form-batch-edit.phtml:40 -#: application/view/common/property-form-batch-edit.phtml:78 +#: application/view/common/property-form-batch-edit.phtml:80 msgid "Add URI value" msgstr "" +#: application/view/common/property-form-batch-edit.phtml:54 +#: application/view/omeka/admin/item-set/form.phtml:13 +#: application/view/omeka/admin/item/form.phtml:14 +#: application/view/omeka/admin/media/edit.phtml:13 +msgid "Values" +msgstr "" + #: application/view/common/property-selector.phtml:10 msgid "Click on a property to add it to the edit panel." msgstr "" @@ -1467,6 +1544,7 @@ msgstr "" #: application/view/common/query-form.phtml:27 #: application/view/omeka/site-admin/index/users.phtml:8 +#: application/view/omeka/site-admin/page/edit.phtml:67 msgid "Restore" msgstr "" @@ -1512,14 +1590,14 @@ msgstr "" msgid "Select resource" msgstr "" -#: application/view/common/resource-values.phtml:70 +#: application/view/common/resource-values.phtml:63 #: application/view/common/sidebar-pagelist.phtml:26 #: application/view/omeka/admin/item-set/browse.phtml:68 #: application/view/omeka/admin/item-set/show-details.phtml:18 -#: application/view/omeka/admin/item-set/show.phtml:82 +#: application/view/omeka/admin/item-set/show.phtml:79 #: application/view/omeka/admin/item/browse.phtml:67 #: application/view/omeka/admin/item/show-details.phtml:18 -#: application/view/omeka/admin/item/show.phtml:64 +#: application/view/omeka/admin/item/show.phtml:61 #: application/view/omeka/admin/media/browse.phtml:63 #: application/view/omeka/admin/media/show-details.phtml:50 #: application/view/omeka/admin/media/show.phtml:39 @@ -1530,7 +1608,7 @@ msgstr "" msgid "Private" msgstr "" -#: application/view/common/resource-values.phtml:74 +#: application/view/common/resource-values.phtml:67 msgid "Has annotation" msgstr "" @@ -1596,7 +1674,7 @@ msgstr "" #: application/view/common/site-selector.phtml:7 #: application/view/omeka/admin/item/form.phtml:17 #: application/view/omeka/admin/item/show-details.phtml:32 -#: application/view/omeka/admin/item/show.phtml:78 +#: application/view/omeka/admin/item/show.phtml:75 #: application/view/omeka/index/index.phtml:6 #: application/view/omeka/site-admin/index/add.phtml:12 #: application/view/omeka/site-admin/index/edit.phtml:8 @@ -1632,7 +1710,6 @@ msgid "Sort order" msgstr "" #: application/view/common/user-bar.phtml:22 -#: application/view/layout/layout-admin.phtml:48 #, php-format msgid "Signed in as %s" msgstr "" @@ -1749,6 +1826,11 @@ msgstr "" msgid "User menu" msgstr "" +#: application/view/layout/layout-admin.phtml:50 +#: application/view/omeka/admin/user/show.phtml:11 +msgid "Edit user" +msgstr "" + #: application/view/layout/layout-admin.phtml:54 msgid "not logged in" msgstr "" @@ -1827,12 +1909,12 @@ msgstr "" msgid "Upload new asset" msgstr "" -#: application/view/omeka/admin/asset/add-form.phtml:9 +#: application/view/omeka/admin/asset/add-form.phtml:10 #: application/view/omeka/admin/asset/show-details.phtml:21 msgid "Alt text" msgstr "" -#: application/view/omeka/admin/asset/add-form.phtml:11 +#: application/view/omeka/admin/asset/add-form.phtml:12 msgid "Upload" msgstr "" @@ -1841,10 +1923,10 @@ msgid "Add new asset" msgstr "" #: application/view/omeka/admin/asset/browse.phtml:28 -#: application/view/omeka/admin/item-set/show.phtml:77 +#: application/view/omeka/admin/item-set/show.phtml:74 #: application/view/omeka/admin/item/manage-item-sets.phtml:40 #: application/view/omeka/admin/item/manage-sites.phtml:37 -#: application/view/omeka/admin/item/show.phtml:89 +#: application/view/omeka/admin/item/show.phtml:94 #: application/view/omeka/admin/job/browse.phtml:22 #: application/view/omeka/admin/job/show.phtml:46 #: application/view/omeka/admin/resource-template/browse.phtml:28 @@ -1865,7 +1947,7 @@ msgstr "" #: application/view/omeka/admin/user/browse.phtml:94 #: application/view/omeka/admin/user/edit.phtml:40 #: application/view/omeka/admin/vocabulary/browse.phtml:49 -#: application/view/omeka/admin/vocabulary/edit.phtml:11 +#: application/view/omeka/admin/vocabulary/edit.phtml:12 #: application/view/omeka/site-admin/index/edit.phtml:26 #: application/view/omeka/site-admin/index/index.phtml:53 #: application/view/omeka/site-admin/index/users.phtml:7 @@ -2148,7 +2230,7 @@ msgstr "" #: application/view/omeka/admin/setting/browse.phtml:11 #: application/view/omeka/admin/user/batch-edit.phtml:19 #: application/view/omeka/admin/user/edit.phtml:19 -#: application/view/omeka/admin/vocabulary/edit.phtml:13 +#: application/view/omeka/admin/vocabulary/edit.phtml:14 #: application/view/omeka/site-admin/index/edit.phtml:29 #: application/view/omeka/site-admin/index/navigation.phtml:21 #: application/view/omeka/site-admin/index/resources.phtml:31 @@ -2160,18 +2242,6 @@ msgstr "" msgid "Save" msgstr "" -#: application/view/omeka/admin/item-set/form.phtml:13 -#: application/view/omeka/admin/item/form.phtml:14 -#: application/view/omeka/admin/media/edit.phtml:13 -msgid "Values" -msgstr "" - -#: application/view/omeka/admin/item-set/form.phtml:14 -#: application/view/omeka/admin/item/form.phtml:18 -#: application/view/omeka/admin/media/edit.phtml:14 -msgid "Advanced" -msgstr "" - #: application/view/omeka/admin/item-set/form.phtml:29 msgid "Close item set" msgstr "" @@ -2181,12 +2251,12 @@ msgid "Open item set" msgstr "" #: application/view/omeka/admin/item-set/show-details.phtml:19 -#: application/view/omeka/admin/item-set/show.phtml:83 +#: application/view/omeka/admin/item-set/show.phtml:80 msgid "Open to additions" msgstr "" #: application/view/omeka/admin/item-set/show-details.phtml:19 -#: application/view/omeka/admin/item-set/show.phtml:83 +#: application/view/omeka/admin/item-set/show.phtml:80 msgid "Closed to additions" msgstr "" @@ -2204,11 +2274,11 @@ msgstr "" msgid "View items" msgstr "" -#: application/view/omeka/admin/item-set/show.phtml:58 +#: application/view/omeka/admin/item-set/show.phtml:51 msgid "The following resources link to this item set:" msgstr "" -#: application/view/omeka/admin/item-set/show.phtml:62 +#: application/view/omeka/admin/item-set/show.phtml:59 msgid "No resources link to this item set." msgstr "" @@ -2328,11 +2398,17 @@ msgstr "" msgid "Assign to site" msgstr "" +#: application/view/omeka/admin/item/show-details.phtml:37 +#: application/view/omeka/admin/item/show.phtml:80 +#, php-format +msgid "View this item in \"%s\"" +msgstr "" + #: application/view/omeka/admin/item/show.phtml:21 msgid "Edit item" msgstr "" -#: application/view/omeka/admin/item/show.phtml:51 +#: application/view/omeka/admin/item/show.phtml:48 msgid "No resources link to this item." msgstr "" @@ -2448,11 +2524,6 @@ msgstr "" msgid "MIME type" msgstr "" -#: application/view/omeka/admin/media/show-details.phtml:43 -#: application/view/omeka/admin/media/show.phtml:64 -msgid "Size" -msgstr "" - #: application/view/omeka/admin/media/show-details.phtml:44 #: application/view/omeka/admin/media/show.phtml:65 #, php-format @@ -2597,7 +2668,7 @@ msgstr "" #: application/view/omeka/admin/resource-template/browse.phtml:10 #: application/view/omeka/admin/resource-template/import.phtml:5 -#: application/view/omeka/admin/vocabulary/import.phtml:12 +#: application/view/omeka/admin/vocabulary/import.phtml:13 msgid "Import" msgstr "" @@ -2820,18 +2891,14 @@ msgstr "" msgid "(inactive)" msgstr "" -#: application/view/omeka/admin/user/show.phtml:11 -msgid "Edit user" -msgstr "" - #: application/view/omeka/admin/user/show.phtml:24 msgid "Display name" msgstr "" #: application/view/omeka/admin/vocabulary/browse.phtml:7 #: application/view/omeka/admin/vocabulary/classes.phtml:7 -#: application/view/omeka/admin/vocabulary/edit.phtml:7 -#: application/view/omeka/admin/vocabulary/import.phtml:7 +#: application/view/omeka/admin/vocabulary/edit.phtml:8 +#: application/view/omeka/admin/vocabulary/import.phtml:8 #: application/view/omeka/admin/vocabulary/properties.phtml:7 #: application/view/omeka/admin/vocabulary/update.phtml:20 msgid "Vocabularies" @@ -2870,13 +2937,13 @@ msgstr "" msgid "This vocabulary has no classes." msgstr "" -#: application/view/omeka/admin/vocabulary/edit.phtml:18 +#: application/view/omeka/admin/vocabulary/edit.phtml:19 msgid "" "You may update this vocabulary to a newer version. You will be able to " "review the changes before you accept." msgstr "" -#: application/view/omeka/admin/vocabulary/import.phtml:7 +#: application/view/omeka/admin/vocabulary/import.phtml:8 msgid "New vocabulary" msgstr "" @@ -3061,14 +3128,6 @@ msgstr "" msgid "Thumbnail" msgstr "" -#: application/view/omeka/site-admin/index/theme-resource-pages.phtml:6 -msgid "Remove block" -msgstr "" - -#: application/view/omeka/site-admin/index/theme-resource-pages.phtml:7 -msgid "Restore block" -msgstr "" - #: application/view/omeka/site-admin/index/theme-resource-pages.phtml:21 #: application/view/omeka/site-admin/index/theme.phtml:47 msgid "Configure resource pages" @@ -3185,18 +3244,51 @@ msgstr "" msgid "No item selected." msgstr "" -#: application/view/omeka/site-admin/page/edit.phtml:37 +#: application/view/omeka/site-admin/page/edit.phtml:41 +msgid "Normal flow" +msgstr "" + +#: application/view/omeka/site-admin/page/edit.phtml:42 +msgid "Grid" +msgstr "" + +#: application/view/omeka/site-admin/page/edit.phtml:44 +msgid "1 column" +msgstr "" + +#: application/view/omeka/site-admin/page/edit.phtml:46 +#, php-format +msgid "%s columns" +msgstr "" + +#: application/view/omeka/site-admin/page/edit.phtml:53 +msgid "Layout" +msgstr "" + +#: application/view/omeka/site-admin/page/edit.phtml:71 msgid "Expand all" msgstr "" -#: application/view/omeka/site-admin/page/edit.phtml:38 +#: application/view/omeka/site-admin/page/edit.phtml:72 msgid "Collapse all" msgstr "" -#: application/view/omeka/site-admin/page/edit.phtml:46 +#: application/view/omeka/site-admin/page/edit.phtml:80 +msgid "Page layout configuration" +msgstr "" + +#: application/view/omeka/site-admin/page/edit.phtml:87 msgid "Add new block" msgstr "" +#: application/view/omeka/site-admin/page/edit.phtml:97 +msgid "Grid layout preview" +msgstr "" + +#: application/view/omeka/site-admin/page/edit.phtml:104 +msgid "Block layout configuration" +msgstr "" + #: application/view/omeka/site-admin/page/index.phtml:17 msgid "Add new page" msgstr "" @@ -3248,37 +3340,37 @@ msgstr "" msgid "Command \"%s\" failed with status code %s." msgstr "" -#: application/src/Stdlib/Environment.php:52 +#: application/src/Stdlib/Environment.php:54 msgid "Omeka requires the PHP extension json, but it is not loaded." msgstr "" -#: application/src/Stdlib/Environment.php:60 +#: application/src/Stdlib/Environment.php:62 #, php-format msgid "" "You must upgrade Omeka S to at least version 1.0.0 before upgrading to " "version %1$s. You are currently on version %2$s." msgstr "" -#: application/src/Stdlib/Environment.php:67 +#: application/src/Stdlib/Environment.php:69 #, php-format msgid "" "The installed PHP version (%1$s) is too low. Omeka requires at least version " "%2$s." msgstr "" -#: application/src/Stdlib/Environment.php:75 +#: application/src/Stdlib/Environment.php:77 #, php-format msgid "Omeka requires the PHP extension %s, but it is not loaded." msgstr "" -#: application/src/Stdlib/Environment.php:94 +#: application/src/Stdlib/Environment.php:96 #, php-format msgid "" "The installed MySQL version (%1$s) is too low. Omeka requires at least " "version %2$s." msgstr "" -#: application/src/Stdlib/Environment.php:102 +#: application/src/Stdlib/Environment.php:104 #, php-format msgid "" "The installed MariaDB version (%1$s) is too low. Omeka requires at least " @@ -3318,41 +3410,10 @@ msgstr "" msgid "Table of contents" msgstr "" -#: application/src/Site/BlockLayout/Asset.php:17 +#: application/src/Site/BlockLayout/Asset.php:16 msgid "Asset" msgstr "" -#: application/src/Site/BlockLayout/Asset.php:34 -#: application/src/Site/BlockLayout/Asset.php:40 -msgid "default" -msgstr "" - -#: application/src/Site/BlockLayout/Asset.php:35 -msgid "float left" -msgstr "" - -#: application/src/Site/BlockLayout/Asset.php:36 -msgid "float right" -msgstr "" - -#: application/src/Site/BlockLayout/Asset.php:37 -#: application/src/Site/BlockLayout/Asset.php:43 -msgid "center" -msgstr "" - -#: application/src/Site/BlockLayout/Asset.php:41 -msgid "left" -msgstr "" - -#: application/src/Site/BlockLayout/Asset.php:42 -msgid "right" -msgstr "" - -#: application/src/Site/BlockLayout/Asset.php:48 -#: application/src/Site/BlockLayout/Media.php:61 -msgid "Alignment" -msgstr "" - #: application/src/Site/BlockLayout/BrowsePreview.php:16 msgid "Browse preview" msgstr "" @@ -3411,7 +3472,7 @@ msgstr "" msgid "Item with metadata" msgstr "" -#: application/src/Site/BlockLayout/Media.php:14 +#: application/src/Site/BlockLayout/Media.php:13 msgid "Media embed" msgstr "" @@ -3419,14 +3480,24 @@ msgstr "" msgid "Line break" msgstr "" -#: application/src/Site/BlockLayout/LineBreak.php:34 +#: application/src/Site/BlockLayout/LineBreak.php:32 msgid "Transparent" msgstr "" -#: application/src/Site/BlockLayout/LineBreak.php:35 +#: application/src/Site/BlockLayout/LineBreak.php:33 msgid "Opaque" msgstr "" +#: application/src/Site/BlockLayout/Oembed.php:29 +#: application/src/Media/Ingester/OEmbed.php:30 +msgid "oEmbed" +msgstr "" + +#: application/src/Site/BlockLayout/Oembed.php:57 +#: application/src/Media/Ingester/OEmbed.php:66 +msgid "oEmbed URL" +msgstr "" + #: application/src/Site/BlockLayout/PageDateTime.php:20 msgid "Page date/time" msgstr "" @@ -3445,8 +3516,8 @@ msgstr "" #: application/src/Site/BlockLayout/PageDateTime.php:44 #: application/src/Site/BlockLayout/PageDateTime.php:58 -#: application/src/Form/SettingForm.php:180 -#: application/src/Form/SiteSettingsForm.php:91 +#: application/src/Form/SettingForm.php:242 +#: application/src/Form/SiteSettingsForm.php:287 msgid "None" msgstr "" @@ -3528,10 +3599,6 @@ msgstr "" msgid "HTML" msgstr "" -#: application/src/Site/BlockLayout/Html.php:48 -msgid "Optional CSS class for styling HTML." -msgstr "" - #: application/src/Site/BlockLayout/Fallback.php:28 #: application/src/Site/ResourcePageBlockLayout/Fallback.php:18 #, php-format @@ -3546,7 +3613,7 @@ msgstr "" msgid "Media list" msgstr "" -#: application/src/Site/ResourcePageBlockLayout/Manager.php:210 +#: application/src/Site/ResourcePageBlockLayout/Manager.php:211 msgid "Main" msgstr "" @@ -3603,7 +3670,7 @@ msgstr "" msgid "Error downloading %1$s: %2$s" msgstr "" -#: application/src/File/Downloader.php:83 +#: application/src/File/Downloader.php:84 #, php-format msgid "Error downloading %1$s: %2$s %3$s" msgstr "" @@ -3621,7 +3688,7 @@ msgid "" "\"%2$s\"." msgstr "" -#: application/src/Mvc/MvcListeners.php:325 +#: application/src/Mvc/MvcListeners.php:326 #, php-format msgid "The current theme is not active. Its current state is \"%s\"." msgstr "" @@ -3658,6 +3725,11 @@ msgstr "" msgid "Value" msgstr "" +#: application/src/ColumnType/Value.php:43 +#: application/view/common/advanced-search/properties.phtml:67 +msgid "Property" +msgstr "" + #: application/src/ColumnType/Value.php:56 msgid "Max values" msgstr "" @@ -3693,174 +3765,174 @@ msgstr "" msgid "Media must be an array" msgstr "" -#: application/src/Api/Adapter/ResourceTemplateAdapter.php:75 +#: application/src/Api/Adapter/ResourceTemplateAdapter.php:84 #, php-format msgid "Attempting to add duplicate property with ID %s" msgstr "" -#: application/src/Api/Adapter/ResourceTemplateAdapter.php:89 -#: application/src/Api/Adapter/PropertyAdapter.php:178 -#: application/src/Api/Adapter/ResourceClassAdapter.php:170 -#: application/src/Api/Adapter/VocabularyAdapter.php:214 +#: application/src/Api/Adapter/ResourceTemplateAdapter.php:98 +#: application/src/Api/Adapter/PropertyAdapter.php:187 +#: application/src/Api/Adapter/ResourceClassAdapter.php:179 +#: application/src/Api/Adapter/VocabularyAdapter.php:223 msgid "The label cannot be empty." msgstr "" -#: application/src/Api/Adapter/ResourceTemplateAdapter.php:92 +#: application/src/Api/Adapter/ResourceTemplateAdapter.php:101 msgid "The label is already taken." msgstr "" -#: application/src/Api/Adapter/MediaAdapter.php:113 +#: application/src/Api/Adapter/MediaAdapter.php:114 msgid "Media must set an ingester." msgstr "" -#: application/src/Api/Adapter/MediaAdapter.php:135 +#: application/src/Api/Adapter/MediaAdapter.php:136 msgid "Media must set a valid ingester." msgstr "" -#: application/src/Api/Adapter/MediaAdapter.php:179 +#: application/src/Api/Adapter/MediaAdapter.php:180 msgid "Media must belong to an item." msgstr "" -#: application/src/Api/Adapter/UserAdapter.php:120 +#: application/src/Api/Adapter/UserAdapter.php:130 msgid "The name cannot be empty." msgstr "" -#: application/src/Api/Adapter/UserAdapter.php:130 +#: application/src/Api/Adapter/UserAdapter.php:140 #, php-format msgid "The email %s is already taken." msgstr "" -#: application/src/Api/Adapter/UserAdapter.php:136 +#: application/src/Api/Adapter/UserAdapter.php:146 msgid "Users must have a role." msgstr "" -#: application/src/Api/Adapter/UserAdapter.php:169 +#: application/src/Api/Adapter/UserAdapter.php:179 #, php-format msgid "The current user #%d was removed from the batch process." msgstr "" -#: application/src/Api/Adapter/PropertyAdapter.php:173 -#: application/src/Api/Adapter/ResourceClassAdapter.php:165 +#: application/src/Api/Adapter/PropertyAdapter.php:182 +#: application/src/Api/Adapter/ResourceClassAdapter.php:174 msgid "The local name cannot be empty." msgstr "" -#: application/src/Api/Adapter/PropertyAdapter.php:191 -#: application/src/Api/Adapter/ResourceClassAdapter.php:183 -#: application/src/Api/Adapter/VocabularyAdapter.php:222 -#: application/src/Api/Adapter/VocabularyAdapter.php:235 +#: application/src/Api/Adapter/PropertyAdapter.php:200 +#: application/src/Api/Adapter/ResourceClassAdapter.php:192 +#: application/src/Api/Adapter/VocabularyAdapter.php:231 +#: application/src/Api/Adapter/VocabularyAdapter.php:244 #, php-format msgid "The local name \"%s\" is already taken." msgstr "" -#: application/src/Api/Adapter/PropertyAdapter.php:197 -#: application/src/Api/Adapter/ResourceClassAdapter.php:189 +#: application/src/Api/Adapter/PropertyAdapter.php:206 +#: application/src/Api/Adapter/ResourceClassAdapter.php:198 msgid "A vocabulary must be set." msgstr "" -#: application/src/Api/Adapter/AbstractResourceEntityAdapter.php:209 +#: application/src/Api/Adapter/AbstractResourceEntityAdapter.php:210 #, php-format msgid "The \"%1$s\" resource template requires a \"%2$s\" value" msgstr "" -#: application/src/Api/Adapter/SitePageAdapter.php:144 +#: application/src/Api/Adapter/SitePageAdapter.php:162 msgid "A page must belong to a site." msgstr "" -#: application/src/Api/Adapter/SitePageAdapter.php:149 +#: application/src/Api/Adapter/SitePageAdapter.php:167 msgid "A page must have a title." msgstr "" -#: application/src/Api/Adapter/SitePageAdapter.php:154 -#: application/src/Api/Adapter/SiteAdapter.php:248 +#: application/src/Api/Adapter/SitePageAdapter.php:172 +#: application/src/Api/Adapter/SiteAdapter.php:262 msgid "The slug cannot be empty." msgstr "" -#: application/src/Api/Adapter/SitePageAdapter.php:157 -#: application/src/Api/Adapter/SiteAdapter.php:251 +#: application/src/Api/Adapter/SitePageAdapter.php:175 +#: application/src/Api/Adapter/SiteAdapter.php:265 msgid "A slug can only contain letters, numbers, underscores, and hyphens." msgstr "" -#: application/src/Api/Adapter/SitePageAdapter.php:165 -#: application/src/Api/Adapter/SiteAdapter.php:255 +#: application/src/Api/Adapter/SitePageAdapter.php:183 +#: application/src/Api/Adapter/SiteAdapter.php:269 #, php-format msgid "The slug \"%s\" is already taken." msgstr "" -#: application/src/Api/Adapter/SitePageAdapter.php:209 +#: application/src/Api/Adapter/SitePageAdapter.php:227 msgid "All blocks must have a layout." msgstr "" -#: application/src/Api/Adapter/SitePageAdapter.php:213 +#: application/src/Api/Adapter/SitePageAdapter.php:231 msgid "Block data must not be a scalar value." msgstr "" -#: application/src/Api/Adapter/SiteAdapter.php:244 +#: application/src/Api/Adapter/SiteAdapter.php:258 msgid "A site must have a title." msgstr "" -#: application/src/Api/Adapter/SiteAdapter.php:261 +#: application/src/Api/Adapter/SiteAdapter.php:275 msgid "A site must have a theme." msgstr "" -#: application/src/Api/Adapter/SiteAdapter.php:266 +#: application/src/Api/Adapter/SiteAdapter.php:280 msgid "A site must have item pool data." msgstr "" -#: application/src/Api/Adapter/SiteAdapter.php:271 +#: application/src/Api/Adapter/SiteAdapter.php:285 msgid "A homepage must belong to its parent site." msgstr "" -#: application/src/Api/Adapter/SiteAdapter.php:344 +#: application/src/Api/Adapter/SiteAdapter.php:358 msgid "Invalid navigation: navigation must be an array" msgstr "" -#: application/src/Api/Adapter/SiteAdapter.php:353 +#: application/src/Api/Adapter/SiteAdapter.php:367 msgid "Invalid navigation: link missing type" msgstr "" -#: application/src/Api/Adapter/SiteAdapter.php:357 +#: application/src/Api/Adapter/SiteAdapter.php:371 msgid "Invalid navigation: link missing data" msgstr "" -#: application/src/Api/Adapter/SiteAdapter.php:361 +#: application/src/Api/Adapter/SiteAdapter.php:375 msgid "Invalid navigation: invalid link data" msgstr "" -#: application/src/Api/Adapter/SiteAdapter.php:366 +#: application/src/Api/Adapter/SiteAdapter.php:380 msgid "Invalid navigation: page links must be unique" msgstr "" -#: application/src/Api/Adapter/SiteAdapter.php:373 +#: application/src/Api/Adapter/SiteAdapter.php:387 msgid "Invalid navigation: links must be an array" msgstr "" -#: application/src/Api/Adapter/VocabularyAdapter.php:59 +#: application/src/Api/Adapter/VocabularyAdapter.php:68 msgid "Classes must be an array" msgstr "" -#: application/src/Api/Adapter/VocabularyAdapter.php:65 +#: application/src/Api/Adapter/VocabularyAdapter.php:74 msgid "Properties must be an array" msgstr "" -#: application/src/Api/Adapter/VocabularyAdapter.php:182 +#: application/src/Api/Adapter/VocabularyAdapter.php:191 msgid "The namespace URI cannot be empty." msgstr "" -#: application/src/Api/Adapter/VocabularyAdapter.php:186 +#: application/src/Api/Adapter/VocabularyAdapter.php:195 #, php-format msgid "The namespace URI \"%s\" is already taken." msgstr "" -#: application/src/Api/Adapter/VocabularyAdapter.php:194 +#: application/src/Api/Adapter/VocabularyAdapter.php:203 msgid "The prefix cannot be empty." msgstr "" -#: application/src/Api/Adapter/VocabularyAdapter.php:198 +#: application/src/Api/Adapter/VocabularyAdapter.php:207 #, php-format msgid "The prefix \"%s\" is already taken." msgstr "" -#: application/src/Api/Adapter/VocabularyAdapter.php:205 +#: application/src/Api/Adapter/VocabularyAdapter.php:214 #, php-format msgid "The prefix \"%s\" is reserved." msgstr "" @@ -3934,10 +4006,6 @@ msgid "" "Enter the URL to a IIIF image information file (ending with /info.json)." msgstr "" -#: application/src/Media/Ingester/Upload.php:69 -msgid "Upload file" -msgstr "" - #: application/src/Media/Ingester/Youtube.php:27 msgid "YouTube" msgstr "" @@ -3978,198 +4046,211 @@ msgstr "" msgid "HTML or plain text." msgstr "" -#: application/src/Media/Ingester/OEmbed.php:41 -msgid "oEmbed" +#: application/src/Media/Ingester/OEmbed.php:67 +msgid "URL for the media to embed." msgstr "" -#: application/src/Media/Ingester/OEmbed.php:114 -msgid "oEmbed URL" +#: application/src/Form/SettingForm.php:107 +#: application/src/Form/SiteSettingsForm.php:31 +msgid "General" msgstr "" -#: application/src/Media/Ingester/OEmbed.php:115 -msgid "URL for the media to embed." +#: application/src/Form/SettingForm.php:108 +msgid "Display" msgstr "" -#: application/src/Form/SettingForm.php:106 -#: application/src/Form/SiteSettingsForm.php:31 -msgid "General" +#: application/src/Form/SettingForm.php:109 +msgid "Editing" msgstr "" -#: application/src/Form/SettingForm.php:107 +#: application/src/Form/SettingForm.php:111 msgid "Security" msgstr "" -#: application/src/Form/SettingForm.php:117 +#: application/src/Form/SettingForm.php:121 msgid "Administrator email" msgstr "" -#: application/src/Form/SettingForm.php:131 +#: application/src/Form/SettingForm.php:135 #: application/src/Form/InstallationForm.php:80 msgid "Installation title" msgstr "" -#: application/src/Form/SettingForm.php:147 +#: application/src/Form/SettingForm.php:151 #: application/src/Form/InstallationForm.php:98 msgid "Time zone" msgstr "" -#: application/src/Form/SettingForm.php:162 -#: application/src/Form/SiteSettingsForm.php:194 +#: application/src/Form/SettingForm.php:166 +#: application/src/Form/SiteSettingsForm.php:149 +#: application/src/Form/UserForm.php:141 +#: application/src/Form/InstallationForm.php:112 +msgid "Locale" +msgstr "" + +#: application/src/Form/SettingForm.php:167 +#: application/src/Form/UserForm.php:142 +msgid "Global locale/language code for all interfaces." +msgstr "" + +#: application/src/Form/SettingForm.php:181 +msgid "Enable version notifications" +msgstr "" + +#: application/src/Form/SettingForm.php:182 +msgid "" +"Enable notifications when a new version of Omeka S, modules, or themes are " +"available." +msgstr "" + +#: application/src/Form/SettingForm.php:195 +msgid "Disable JSON-LD @reverse" +msgstr "" + +#: application/src/Form/SettingForm.php:196 +msgid "Disable JSON-LD reverse properties in the API output for resources." +msgstr "" + +#: application/src/Form/SettingForm.php:209 +#: application/src/Form/SiteSettingsForm.php:117 +msgid "Favicon" +msgstr "" + +#: application/src/Form/SettingForm.php:224 +#: application/src/Form/SiteSettingsForm.php:205 msgid "Results per page" msgstr "" -#: application/src/Form/SettingForm.php:163 +#: application/src/Form/SettingForm.php:225 msgid "The maximum number of results per page on browse pages." msgstr "" -#: application/src/Form/SettingForm.php:177 -#: application/src/Form/SiteSettingsForm.php:88 +#: application/src/Form/SettingForm.php:239 +#: application/src/Form/SiteSettingsForm.php:284 msgid "Property label information" msgstr "" -#: application/src/Form/SettingForm.php:178 -#: application/src/Form/SiteSettingsForm.php:89 +#: application/src/Form/SettingForm.php:240 +#: application/src/Form/SiteSettingsForm.php:285 msgid "The additional information that accompanies labels on resource pages." msgstr "" -#: application/src/Form/SettingForm.php:181 -#: application/src/Form/SiteSettingsForm.php:92 +#: application/src/Form/SettingForm.php:243 +#: application/src/Form/SiteSettingsForm.php:288 msgid "Show Vocabulary" msgstr "" -#: application/src/Form/SettingForm.php:182 -#: application/src/Form/SiteSettingsForm.php:93 +#: application/src/Form/SettingForm.php:244 +#: application/src/Form/SiteSettingsForm.php:289 msgid "Show Term" msgstr "" -#: application/src/Form/SettingForm.php:196 +#: application/src/Form/SettingForm.php:258 msgid "Default site" msgstr "" -#: application/src/Form/SettingForm.php:197 +#: application/src/Form/SettingForm.php:259 msgid "" "Select which site should appear when users go to the front page of the " "installation." msgstr "" -#: application/src/Form/SettingForm.php:202 +#: application/src/Form/SettingForm.php:264 msgid "No default (show index of sites)" msgstr "" -#: application/src/Form/SettingForm.php:214 -#: application/src/Form/SiteSettingsForm.php:138 -#: application/src/Form/UserForm.php:141 -#: application/src/Form/InstallationForm.php:112 -msgid "Locale" -msgstr "" - -#: application/src/Form/SettingForm.php:215 -#: application/src/Form/UserForm.php:142 -msgid "Global locale/language code for all interfaces." -msgstr "" - -#: application/src/Form/SettingForm.php:229 -msgid "Enable version notifications" -msgstr "" - -#: application/src/Form/SettingForm.php:230 -msgid "" -"Enable notifications when a new version of Omeka S, modules, or themes are " -"available." -msgstr "" - -#: application/src/Form/SettingForm.php:243 -#: application/src/Form/SiteSettingsForm.php:122 +#: application/src/Form/SettingForm.php:276 +#: application/src/Form/SiteSettingsForm.php:104 msgid "Disable JSON-LD embed" msgstr "" -#: application/src/Form/SettingForm.php:244 -#: application/src/Form/SiteSettingsForm.php:123 +#: application/src/Form/SettingForm.php:277 +#: application/src/Form/SiteSettingsForm.php:105 msgid "" "By default, Omeka embeds JSON-LD in resource browse and show pages for the " "purpose of machine-readable metadata discovery. Check this to disable " "embedding." msgstr "" -#: application/src/Form/SettingForm.php:257 +#: application/src/Form/SettingForm.php:292 msgid "Default content visibility to Private" msgstr "" -#: application/src/Form/SettingForm.php:258 +#: application/src/Form/SettingForm.php:293 msgid "" "If checked, all items, item sets and sites newly created will have their " "visibility set to private by default." msgstr "" -#: application/src/Form/SettingForm.php:271 +#: application/src/Form/SettingForm.php:306 msgid "Suggested languages for values" msgstr "" -#: application/src/Form/SettingForm.php:272 +#: application/src/Form/SettingForm.php:307 msgid "" "List of languages to facilitate filling of the values in the resource form. " "List them one by line. The label displayed for a language may be appended " "with a \"=\"." msgstr "" -#: application/src/Form/SettingForm.php:286 +#: application/src/Form/SettingForm.php:321 msgid "Media alt text property" msgstr "" -#: application/src/Form/SettingForm.php:287 +#: application/src/Form/SettingForm.php:322 msgid "Media property to use as alt text if no alt text is explicitly set." msgstr "" -#: application/src/Form/SettingForm.php:288 +#: application/src/Form/SettingForm.php:323 msgid "[None]" msgstr "" -#: application/src/Form/SettingForm.php:303 +#: application/src/Form/SettingForm.php:340 msgid "Index full-text search" msgstr "" -#: application/src/Form/SettingForm.php:318 +#: application/src/Form/SettingForm.php:355 msgid "Use HTMLPurifier" msgstr "" -#: application/src/Form/SettingForm.php:319 +#: application/src/Form/SettingForm.php:356 msgid "Clean up user-entered HTML." msgstr "" -#: application/src/Form/SettingForm.php:332 +#: application/src/Form/SettingForm.php:369 msgid "Disable file validation" msgstr "" -#: application/src/Form/SettingForm.php:333 +#: application/src/Form/SettingForm.php:370 msgid "Check this to disable file media type and extension validation." msgstr "" -#: application/src/Form/SettingForm.php:342 +#: application/src/Form/SettingForm.php:379 msgid "Allowed media types" msgstr "" -#: application/src/Form/SettingForm.php:343 +#: application/src/Form/SettingForm.php:380 msgid "A comma-separated list of allowed media types for file uploads." msgstr "" -#: application/src/Form/SettingForm.php:356 +#: application/src/Form/SettingForm.php:393 msgid "Allowed file extensions" msgstr "" -#: application/src/Form/SettingForm.php:357 +#: application/src/Form/SettingForm.php:394 msgid "A comma-separated list of allowed file extensions for file uploads." msgstr "" -#: application/src/Form/SettingForm.php:373 +#: application/src/Form/SettingForm.php:410 msgid "reCAPTCHA site key" msgstr "" -#: application/src/Form/SettingForm.php:385 +#: application/src/Form/SettingForm.php:422 msgid "reCAPTCHA secret key" msgstr "" #: application/src/Form/ResourceForm.php:38 -#: application/src/Form/ResourceBatchUpdateForm.php:70 +#: application/src/Form/ResourceBatchUpdateForm.php:73 #: application/src/Form/UserForm.php:156 msgid "Select a template" msgstr "" @@ -4179,7 +4260,7 @@ msgid "A pre-defined template for resource creation." msgstr "" #: application/src/Form/ResourceForm.php:63 -#: application/src/Form/ResourceBatchUpdateForm.php:93 +#: application/src/Form/ResourceBatchUpdateForm.php:96 msgid "Select a class" msgstr "" @@ -4196,111 +4277,117 @@ msgid "" "here." msgstr "" -#: application/src/Form/VocabularyForm.php:23 +#: application/src/Form/VocabularyForm.php:27 msgid "Basic info" msgstr "" -#: application/src/Form/VocabularyForm.php:30 +#: application/src/Form/VocabularyForm.php:34 msgid "File" msgstr "" -#: application/src/Form/VocabularyForm.php:46 +#: application/src/Form/VocabularyForm.php:50 msgid "Enter a human-readable title of the vocabulary." msgstr "" -#: application/src/Form/VocabularyForm.php:58 +#: application/src/Form/VocabularyForm.php:62 msgid "Enter a human-readable description of the vocabulary." msgstr "" -#: application/src/Form/VocabularyForm.php:69 +#: application/src/Form/VocabularyForm.php:72 msgid "Namespace URI" msgstr "" -#: application/src/Form/VocabularyForm.php:70 +#: application/src/Form/VocabularyForm.php:73 msgid "" "Enter the unique namespace URI used to identify the classes and properties " "of the vocabulary." msgstr "" -#: application/src/Form/VocabularyForm.php:81 +#: application/src/Form/VocabularyForm.php:89 msgid "Namespace prefix" msgstr "" -#: application/src/Form/VocabularyForm.php:82 +#: application/src/Form/VocabularyForm.php:90 msgid "" "Enter a concise vocabulary identifier used as a shorthand for the namespace " "URI." msgstr "" -#: application/src/Form/VocabularyForm.php:94 -msgid "Vocabulary file" +#: application/src/Form/VocabularyForm.php:102 +msgid "Import type" msgstr "" -#: application/src/Form/VocabularyForm.php:95 -msgid "" -"Choose a RDF vocabulary file. You must choose a file or enter a URL below." +#: application/src/Form/VocabularyForm.php:117 +msgid "File upload" msgstr "" -#: application/src/Form/VocabularyForm.php:105 -msgid "Vocabulary URL" +#: application/src/Form/VocabularyForm.php:118 +msgid "Choose a RDF vocabulary file." msgstr "" -#: application/src/Form/VocabularyForm.php:106 -msgid "" -"Enter a RDF vocabulary URL. You must enter a URL or choose a file above." +#: application/src/Form/VocabularyForm.php:128 +msgid "File URL" msgstr "" -#: application/src/Form/VocabularyForm.php:116 +#: application/src/Form/VocabularyForm.php:129 +msgid "Enter a URL to a RDF vocabulary file." +msgstr "" + +#: application/src/Form/VocabularyForm.php:139 msgid "File format" msgstr "" -#: application/src/Form/VocabularyForm.php:118 +#: application/src/Form/VocabularyForm.php:141 msgid "[Autodetect]" msgstr "" -#: application/src/Form/VocabularyForm.php:119 +#: application/src/Form/VocabularyForm.php:142 msgid "JSON-LD (.jsonld)" msgstr "" -#: application/src/Form/VocabularyForm.php:120 +#: application/src/Form/VocabularyForm.php:143 msgid "N-Triples (.nt)" msgstr "" -#: application/src/Form/VocabularyForm.php:121 +#: application/src/Form/VocabularyForm.php:144 msgid "RDF/XML (.rdf)" msgstr "" -#: application/src/Form/VocabularyForm.php:122 +#: application/src/Form/VocabularyForm.php:145 msgid "Turtle (.ttl)" msgstr "" -#: application/src/Form/VocabularyForm.php:134 +#: application/src/Form/VocabularyForm.php:148 +msgid "Notation3 (.n3)" +msgstr "" + +#: application/src/Form/VocabularyForm.php:161 msgid "Preferred language" msgstr "" -#: application/src/Form/VocabularyForm.php:135 +#: application/src/Form/VocabularyForm.php:162 msgid "" "Enter the preferred language of the labels and comments using an IETF language tag. Defaults to the first available." msgstr "" -#: application/src/Form/VocabularyForm.php:146 +#: application/src/Form/VocabularyForm.php:173 msgid "Label property" msgstr "" -#: application/src/Form/VocabularyForm.php:147 +#: application/src/Form/VocabularyForm.php:174 msgid "" "Enter the label property. This is typically only needed if the vocabulary " "uses an unconventional property for labels. Please use the full property URI " "enclosed in angle brackets." msgstr "" -#: application/src/Form/VocabularyForm.php:157 +#: application/src/Form/VocabularyForm.php:184 msgid "Comment property" msgstr "" -#: application/src/Form/VocabularyForm.php:158 +#: application/src/Form/VocabularyForm.php:185 msgid "" "Enter the comment property. This is typically only needed if the vocabulary " "uses an unconventional property for comments. Please use the full property " @@ -4315,14 +4402,15 @@ msgstr "" msgid "Suggested class" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:34 +#: application/src/Form/ResourceBatchUpdateForm.php:37 msgid "Set visibility" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:38 -#: application/src/Form/ResourceBatchUpdateForm.php:55 -#: application/src/Form/ResourceBatchUpdateForm.php:75 -#: application/src/Form/ResourceBatchUpdateForm.php:98 +#: application/src/Form/ResourceBatchUpdateForm.php:41 +#: application/src/Form/ResourceBatchUpdateForm.php:58 +#: application/src/Form/ResourceBatchUpdateForm.php:78 +#: application/src/Form/ResourceBatchUpdateForm.php:101 +#: application/src/Form/ResourceBatchUpdateForm.php:115 #: application/src/Form/UserBatchUpdateForm.php:31 #: application/src/Form/UserBatchUpdateForm.php:43 #: application/src/Form/UserBatchUpdateForm.php:60 @@ -4331,72 +4419,76 @@ msgstr "" msgid "[No change]" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:51 +#: application/src/Form/ResourceBatchUpdateForm.php:54 msgid "Set openness" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:53 +#: application/src/Form/ResourceBatchUpdateForm.php:56 msgid "Open" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:54 +#: application/src/Form/ResourceBatchUpdateForm.php:57 msgid "Not open" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:74 +#: application/src/Form/ResourceBatchUpdateForm.php:77 msgid "Set template" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:76 +#: application/src/Form/ResourceBatchUpdateForm.php:79 msgid "[Unset template]" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:96 +#: application/src/Form/ResourceBatchUpdateForm.php:99 msgid "Set class" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:97 +#: application/src/Form/ResourceBatchUpdateForm.php:100 msgid "[Unset class]" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:111 -#: application/src/Form/ResourceBatchUpdateForm.php:125 +#: application/src/Form/ResourceBatchUpdateForm.php:114 +msgid "Set owner" +msgstr "" + +#: application/src/Form/ResourceBatchUpdateForm.php:136 +#: application/src/Form/ResourceBatchUpdateForm.php:150 #: application/src/Form/UserForm.php:179 msgid "Select item sets" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:114 +#: application/src/Form/ResourceBatchUpdateForm.php:139 msgid "Add to item sets" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:128 +#: application/src/Form/ResourceBatchUpdateForm.php:153 msgid "Remove from item sets" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:139 -#: application/src/Form/ResourceBatchUpdateForm.php:153 +#: application/src/Form/ResourceBatchUpdateForm.php:164 +#: application/src/Form/ResourceBatchUpdateForm.php:178 #: application/src/Form/UserForm.php:195 msgid "Select sites" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:142 +#: application/src/Form/ResourceBatchUpdateForm.php:167 msgid "Add to sites" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:156 +#: application/src/Form/ResourceBatchUpdateForm.php:181 msgid "Remove from sites" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:166 +#: application/src/Form/ResourceBatchUpdateForm.php:191 msgid "Clear language" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:190 -#: application/view/common/property-form-batch-edit.phtml:63 +#: application/src/Form/ResourceBatchUpdateForm.php:215 +#: application/view/common/property-form-batch-edit.phtml:65 msgid "Select properties" msgstr "" -#: application/src/Form/ResourceBatchUpdateForm.php:193 +#: application/src/Form/ResourceBatchUpdateForm.php:218 msgid "Clear property values" msgstr "" @@ -4416,6 +4508,36 @@ msgstr "" msgid "Invalid or missing CSRF token" msgstr "" +#: application/src/Form/Element/Background.php:27 +msgid "Top" +msgstr "" + +#: application/src/Form/Element/Background.php:28 +#: application/src/Form/Element/Background.php:40 +#: application/src/Form/BlockLayoutDataForm.php:79 +msgid "Center" +msgstr "" + +#: application/src/Form/Element/Background.php:29 +msgid "Bottom" +msgstr "" + +#: application/src/Form/Element/Background.php:39 +msgid "Left" +msgstr "" + +#: application/src/Form/Element/Background.php:41 +msgid "Right" +msgstr "" + +#: application/src/Form/Element/Background.php:50 +msgid "Cover" +msgstr "" + +#: application/src/Form/Element/Background.php:51 +msgid "Contain" +msgstr "" + #: application/src/Form/Element/PasswordConfirm.php:73 msgid "Confirm password" msgstr "" @@ -4475,182 +4597,206 @@ msgid "" "Show pagination that helps users follow a linear narrative through a site." msgstr "" -#: application/src/Form/SiteSettingsForm.php:106 +#: application/src/Form/SiteSettingsForm.php:88 msgid "Show user bar on public views" msgstr "" -#: application/src/Form/SiteSettingsForm.php:108 +#: application/src/Form/SiteSettingsForm.php:90 msgid "Never" msgstr "" -#: application/src/Form/SiteSettingsForm.php:109 +#: application/src/Form/SiteSettingsForm.php:91 msgid "When logged in" msgstr "" -#: application/src/Form/SiteSettingsForm.php:110 +#: application/src/Form/SiteSettingsForm.php:92 msgid "Always" msgstr "" -#: application/src/Form/SiteSettingsForm.php:139 +#: application/src/Form/SiteSettingsForm.php:129 +msgid "Page subnavigation display" +msgstr "" + +#: application/src/Form/SiteSettingsForm.php:130 +msgid "Hide on leaf pages (default)" +msgstr "" + +#: application/src/Form/SiteSettingsForm.php:132 +msgid "Hide on all pages" +msgstr "" + +#: application/src/Form/SiteSettingsForm.php:133 +msgid "Show on all pages" +msgstr "" + +#: application/src/Form/SiteSettingsForm.php:150 msgid "" "Locale/language code for this site. Leave blank to use the global locale " "setting." msgstr "" -#: application/src/Form/SiteSettingsForm.php:153 +#: application/src/Form/SiteSettingsForm.php:164 msgid "Filter values based on site locale" msgstr "" -#: application/src/Form/SiteSettingsForm.php:154 +#: application/src/Form/SiteSettingsForm.php:165 msgid "" "Show only values matching the site language setting and values without " "locale ID." msgstr "" -#: application/src/Form/SiteSettingsForm.php:167 +#: application/src/Form/SiteSettingsForm.php:178 msgid "Show language labels for values" msgstr "" -#: application/src/Form/SiteSettingsForm.php:168 +#: application/src/Form/SiteSettingsForm.php:179 msgid "Show a label indicating the language of each value on show pages." msgstr "" -#: application/src/Form/SiteSettingsForm.php:182 +#: application/src/Form/SiteSettingsForm.php:193 msgid "Restrict browse to attached items" msgstr "" -#: application/src/Form/SiteSettingsForm.php:195 +#: application/src/Form/SiteSettingsForm.php:206 msgid "" "The maximum number of results per page on browse pages. Leave blank to use " "the global setting." msgstr "" -#: application/src/Form/SiteSettingsForm.php:201 +#: application/src/Form/SiteSettingsForm.php:212 msgid "Use global setting" msgstr "" -#: application/src/Form/SiteSettingsForm.php:210 +#: application/src/Form/SiteSettingsForm.php:221 msgid "Browse heading property" msgstr "" -#: application/src/Form/SiteSettingsForm.php:211 +#: application/src/Form/SiteSettingsForm.php:222 msgid "" "Use this property for the heading of each resource on a browse page. Keep " "unselected to use the default title property of each resource." msgstr "" -#: application/src/Form/SiteSettingsForm.php:219 -#: application/src/Form/SiteSettingsForm.php:237 +#: application/src/Form/SiteSettingsForm.php:230 +#: application/src/Form/SiteSettingsForm.php:248 msgid "Select a property" msgstr "" -#: application/src/Form/SiteSettingsForm.php:228 +#: application/src/Form/SiteSettingsForm.php:239 msgid "Browse body property" msgstr "" -#: application/src/Form/SiteSettingsForm.php:229 +#: application/src/Form/SiteSettingsForm.php:240 msgid "" "Use this property for the body of each resource on a browse page. Keep " "unselected to use the default description property of each resource." msgstr "" -#: application/src/Form/SiteSettingsForm.php:245 +#: application/src/Form/SiteSettingsForm.php:256 #: application/src/Form/UserForm.php:253 msgid "Item browse defaults" msgstr "" -#: application/src/Form/SiteSettingsForm.php:260 +#: application/src/Form/SiteSettingsForm.php:271 msgid "Show attached pages" msgstr "" -#: application/src/Form/SiteSettingsForm.php:261 +#: application/src/Form/SiteSettingsForm.php:272 msgid "" "Show site pages to which an item is attached on the public item show page." msgstr "" -#: application/src/Form/SiteSettingsForm.php:273 -msgid "Show value annotations" +#: application/src/Form/SiteSettingsForm.php:302 +msgid "Value annotations" +msgstr "" + +#: application/src/Form/SiteSettingsForm.php:303 +msgid "Hide value annotations" msgstr "" -#: application/src/Form/SiteSettingsForm.php:274 -msgid "Show annotations that are set to a value, if any." +#: application/src/Form/SiteSettingsForm.php:305 +msgid "Show value annotations (collapsed)" msgstr "" -#: application/src/Form/SiteSettingsForm.php:286 +#: application/src/Form/SiteSettingsForm.php:306 +msgid "Show value annotations (expanded)" +msgstr "" + +#: application/src/Form/SiteSettingsForm.php:319 msgid "Exclude resources not in site" msgstr "" -#: application/src/Form/SiteSettingsForm.php:287 +#: application/src/Form/SiteSettingsForm.php:320 msgid "Exclude resources that are not assigned to this site." msgstr "" -#: application/src/Form/SiteSettingsForm.php:299 +#: application/src/Form/SiteSettingsForm.php:332 msgid "Embed media on item pages (legacy)" msgstr "" -#: application/src/Form/SiteSettingsForm.php:313 +#: application/src/Form/SiteSettingsForm.php:346 msgid "Search type" msgstr "" -#: application/src/Form/SiteSettingsForm.php:314 +#: application/src/Form/SiteSettingsForm.php:347 msgid "Select the type of search the main search field will perform" msgstr "" -#: application/src/Form/SiteSettingsForm.php:316 +#: application/src/Form/SiteSettingsForm.php:349 msgid "This site" msgstr "" -#: application/src/Form/SiteSettingsForm.php:317 +#: application/src/Form/SiteSettingsForm.php:350 msgid "All sites" msgstr "" -#: application/src/Form/SiteSettingsForm.php:336 +#: application/src/Form/SiteSettingsForm.php:369 msgid "Search resources" msgstr "" -#: application/src/Form/SiteSettingsForm.php:337 +#: application/src/Form/SiteSettingsForm.php:370 msgid "" "Customize which types of resources will be searchable in the main search " "field." msgstr "" -#: application/src/Form/SiteSettingsForm.php:352 +#: application/src/Form/SiteSettingsForm.php:385 msgid "Advanced search vocabulary members" msgstr "" -#: application/src/Form/SiteSettingsForm.php:353 +#: application/src/Form/SiteSettingsForm.php:386 msgid "Limit the search options for property and class" msgstr "" -#: application/src/Form/SiteSettingsForm.php:354 +#: application/src/Form/SiteSettingsForm.php:387 msgid "All vocabulary members" msgstr "" -#: application/src/Form/SiteSettingsForm.php:356 +#: application/src/Form/SiteSettingsForm.php:389 msgid "Used by resources in this site" msgstr "" -#: application/src/Form/SiteSettingsForm.php:357 +#: application/src/Form/SiteSettingsForm.php:390 msgid "Used by any resource in the installation" msgstr "" -#: application/src/Form/SiteSettingsForm.php:371 +#: application/src/Form/SiteSettingsForm.php:404 msgid "Templates" msgstr "" -#: application/src/Form/SiteSettingsForm.php:372 +#: application/src/Form/SiteSettingsForm.php:405 msgid "Select which templates to apply to the advanced search form." msgstr "" -#: application/src/Form/SiteSettingsForm.php:377 +#: application/src/Form/SiteSettingsForm.php:410 msgid "Select templates" msgstr "" -#: application/src/Form/SiteSettingsForm.php:386 +#: application/src/Form/SiteSettingsForm.php:419 msgid "Restrict to templates" msgstr "" -#: application/src/Form/SiteSettingsForm.php:387 +#: application/src/Form/SiteSettingsForm.php:420 msgid "Restrict search results to resources of the selected templates." msgstr "" @@ -4799,11 +4945,27 @@ msgstr "" msgid "The emails did not match" msgstr "" +#: application/src/Form/BlockLayoutDataForm.php:74 +msgid "Alignment" +msgstr "" + +#: application/src/Form/BlockLayoutDataForm.php:77 +msgid "Float left" +msgstr "" + +#: application/src/Form/BlockLayoutDataForm.php:78 +msgid "Float right" +msgstr "" + +#: application/src/Form/BlockLayoutDataForm.php:98 +msgid "Minimum height" +msgstr "" + #: application/src/Form/ConfirmForm.php:17 msgid "Confirm" msgstr "" -#: application/src/Form/SitePageForm.php:39 +#: application/src/Form/SitePageForm.php:42 msgid "Add to navigation" msgstr "" @@ -4831,19 +4993,19 @@ msgstr "" msgid "no title" msgstr "" -#: application/src/View/Helper/Browse.php:55 +#: application/src/View/Helper/Browse.php:57 msgid "Relevance" msgstr "" -#: application/src/View/Helper/Browse.php:162 +#: application/src/View/Helper/Browse.php:164 msgid "Add a column…" msgstr "" -#: application/src/View/Helper/Browse.php:181 +#: application/src/View/Helper/Browse.php:183 msgid "Column type" msgstr "" -#: application/src/View/Helper/Browse.php:192 +#: application/src/View/Helper/Browse.php:194 msgid "Header" msgstr "" @@ -4859,6 +5021,10 @@ msgstr "" msgid "Select user…" msgstr "" +#: application/src/View/Helper/BlockThumbnailTypeSelect.php:42 +msgid "Thumbnail type" +msgstr "" + #: application/src/View/Helper/ItemSetSelect.php:39 msgid "Select item set…" msgstr "" @@ -4879,100 +5045,104 @@ msgstr "" msgid "Site successfully updated" msgstr "" -#: application/src/Controller/SiteAdmin/IndexController.php:168 +#: application/src/Controller/SiteAdmin/IndexController.php:169 msgid "Page successfully created" msgstr "" -#: application/src/Controller/SiteAdmin/IndexController.php:197 +#: application/src/Controller/SiteAdmin/IndexController.php:198 msgid "Homepage" msgstr "" -#: application/src/Controller/SiteAdmin/IndexController.php:203 +#: application/src/Controller/SiteAdmin/IndexController.php:204 msgid "First page in navigation" msgstr "" -#: application/src/Controller/SiteAdmin/IndexController.php:219 +#: application/src/Controller/SiteAdmin/IndexController.php:220 msgid "Navigation successfully updated" msgstr "" -#: application/src/Controller/SiteAdmin/IndexController.php:253 +#: application/src/Controller/SiteAdmin/IndexController.php:254 msgid "" "Item assignment in progress. To see the new item count, refresh the page." msgstr "" -#: application/src/Controller/SiteAdmin/IndexController.php:257 +#: application/src/Controller/SiteAdmin/IndexController.php:258 msgid "Site resources successfully updated" msgstr "" -#: application/src/Controller/SiteAdmin/IndexController.php:305 +#: application/src/Controller/SiteAdmin/IndexController.php:306 msgid "User permissions successfully updated" msgstr "" -#: application/src/Controller/SiteAdmin/IndexController.php:342 +#: application/src/Controller/SiteAdmin/IndexController.php:343 msgid "Site theme successfully updated" msgstr "" -#: application/src/Controller/SiteAdmin/IndexController.php:417 +#: application/src/Controller/SiteAdmin/IndexController.php:418 msgid "Theme settings successfully updated" msgstr "" -#: application/src/Controller/SiteAdmin/IndexController.php:457 +#: application/src/Controller/SiteAdmin/IndexController.php:458 msgid "Theme resource pages successfully updated" msgstr "" -#: application/src/Controller/SiteAdmin/IndexController.php:480 +#: application/src/Controller/SiteAdmin/IndexController.php:481 msgid "Site successfully deleted" msgstr "" -#: application/src/Controller/SiteAdmin/IndexController.php:503 +#: application/src/Controller/SiteAdmin/IndexController.php:504 msgid "site" msgstr "" -#: application/src/Controller/SiteAdmin/PageController.php:29 +#: application/src/Controller/SiteAdmin/PageController.php:36 msgid "Page successfully updated" msgstr "" -#: application/src/Controller/SiteAdmin/PageController.php:108 +#: application/src/Controller/SiteAdmin/PageController.php:125 msgid "page" msgstr "" -#: application/src/Controller/SiteAdmin/PageController.php:125 +#: application/src/Controller/SiteAdmin/PageController.php:142 msgid "Page successfully deleted" msgstr "" -#: application/src/Controller/LoginController.php:56 +#: application/src/Controller/LoginController.php:57 msgid "Successfully logged in" msgstr "" -#: application/src/Controller/LoginController.php:65 +#: application/src/Controller/LoginController.php:69 msgid "Email or password is invalid" msgstr "" -#: application/src/Controller/LoginController.php:88 +#: application/src/Controller/LoginController.php:92 msgid "Successfully logged out" msgstr "" -#: application/src/Controller/LoginController.php:104 +#: application/src/Controller/LoginController.php:108 msgid "Invalid password creation key." msgstr "" -#: application/src/Controller/LoginController.php:113 +#: application/src/Controller/LoginController.php:117 msgid "Password creation key expired." msgstr "" -#: application/src/Controller/LoginController.php:129 +#: application/src/Controller/LoginController.php:133 msgid "Successfully created your password. Please log in." msgstr "" -#: application/src/Controller/LoginController.php:132 +#: application/src/Controller/LoginController.php:136 msgid "Password creation unsuccessful" msgstr "" -#: application/src/Controller/LoginController.php:168 +#: application/src/Controller/LoginController.php:174 +msgid "Unable to send password reset email." +msgstr "" + +#: application/src/Controller/LoginController.php:177 msgid "Check your email for instructions on how to reset your password" msgstr "" -#: application/src/Controller/LoginController.php:171 +#: application/src/Controller/LoginController.php:180 msgid "Activation unsuccessful" msgstr "" @@ -4982,8 +5152,8 @@ msgstr "" #: application/src/Controller/Admin/ItemController.php:48 #: application/src/Controller/Admin/ItemController.php:53 -#: application/src/Controller/Admin/UserController.php:44 -#: application/src/Controller/Admin/UserController.php:49 +#: application/src/Controller/Admin/UserController.php:45 +#: application/src/Controller/Admin/UserController.php:50 #: application/src/Controller/Admin/MediaController.php:33 #: application/src/Controller/Admin/MediaController.php:38 #: application/src/Controller/Admin/ItemSetController.php:93 @@ -5032,73 +5202,77 @@ msgstr "" msgid "Editing items. This may take a while." msgstr "" -#: application/src/Controller/Admin/UserController.php:115 +#: application/src/Controller/Admin/UserController.php:118 +msgid "Unable to send user activation email." +msgstr "" + +#: application/src/Controller/Admin/UserController.php:121 #, php-format msgid "User successfully created. %s" msgstr "" -#: application/src/Controller/Admin/UserController.php:189 +#: application/src/Controller/Admin/UserController.php:200 msgid "User successfully updated" msgstr "" -#: application/src/Controller/Admin/UserController.php:204 +#: application/src/Controller/Admin/UserController.php:215 msgid "The current password entered was invalid" msgstr "" -#: application/src/Controller/Admin/UserController.php:208 +#: application/src/Controller/Admin/UserController.php:219 msgid "Password successfully changed" msgstr "" -#: application/src/Controller/Admin/UserController.php:236 +#: application/src/Controller/Admin/UserController.php:247 msgid "Key(s) successfully deleted" msgstr "" -#: application/src/Controller/Admin/UserController.php:244 +#: application/src/Controller/Admin/UserController.php:255 #, php-format msgid "" "API key successfully created.

    Here is your key ID and credential for " "access to the API. WARNING: \"key_credential\" will be unretrievable after " -"you navigate away from this page.

    key_identity: %1$s
    key_credential: %2$s" +"you navigate away from this page.

    key_identity=%1$s
    key_credential=%2$s" msgstr "" -#: application/src/Controller/Admin/UserController.php:270 +#: application/src/Controller/Admin/UserController.php:281 msgid "user" msgstr "" -#: application/src/Controller/Admin/UserController.php:283 +#: application/src/Controller/Admin/UserController.php:294 msgid "User successfully deleted" msgstr "" -#: application/src/Controller/Admin/UserController.php:305 +#: application/src/Controller/Admin/UserController.php:316 msgid "You must select at least one user to batch delete." msgstr "" -#: application/src/Controller/Admin/UserController.php:312 +#: application/src/Controller/Admin/UserController.php:323 msgid "You can’t delete yourself." msgstr "" -#: application/src/Controller/Admin/UserController.php:321 +#: application/src/Controller/Admin/UserController.php:332 msgid "Users successfully deleted" msgstr "" -#: application/src/Controller/Admin/UserController.php:347 +#: application/src/Controller/Admin/UserController.php:358 msgid "Deleting users. This may take a while." msgstr "" -#: application/src/Controller/Admin/UserController.php:366 +#: application/src/Controller/Admin/UserController.php:377 msgid "You must select at least one user to batch edit." msgstr "" -#: application/src/Controller/Admin/UserController.php:373 +#: application/src/Controller/Admin/UserController.php:384 msgid "For security reasons, you can’t batch edit yourself." msgstr "" -#: application/src/Controller/Admin/UserController.php:394 +#: application/src/Controller/Admin/UserController.php:405 msgid "Users successfully edited" msgstr "" -#: application/src/Controller/Admin/UserController.php:447 +#: application/src/Controller/Admin/UserController.php:458 msgid "Editing users. This may take a while." msgstr "" @@ -5236,28 +5410,28 @@ msgstr "" msgid "Editing item sets. This may take a while." msgstr "" -#: application/src/Controller/Admin/VocabularyController.php:59 +#: application/src/Controller/Admin/VocabularyController.php:58 msgid "vocabulary" msgstr "" -#: application/src/Controller/Admin/VocabularyController.php:97 +#: application/src/Controller/Admin/VocabularyController.php:92 #, php-format msgid "Vocabulary successfully imported. %s" msgstr "" -#: application/src/Controller/Admin/VocabularyController.php:176 -msgid "Please review these changes before you accept them." +#: application/src/Controller/Admin/VocabularyController.php:162 +msgid "Vocabulary successfully updated" msgstr "" -#: application/src/Controller/Admin/VocabularyController.php:184 -msgid "Vocabulary successfully updated" +#: application/src/Controller/Admin/VocabularyController.php:167 +msgid "Please review these changes before you accept them." msgstr "" -#: application/src/Controller/Admin/VocabularyController.php:204 +#: application/src/Controller/Admin/VocabularyController.php:192 msgid "Changes to the vocabulary successfully made" msgstr "" -#: application/src/Controller/Admin/VocabularyController.php:220 +#: application/src/Controller/Admin/VocabularyController.php:208 msgid "Vocabulary successfully deleted" msgstr "" @@ -5283,65 +5457,65 @@ msgstr "" msgid "Resource template successfully created. %s" msgstr "" -#: application/config/module.config.php:676 +#: application/config/module.config.php:704 msgid "Owner email" msgstr "" -#: application/config/module.config.php:682 -#: application/config/module.config.php:698 -#: application/config/module.config.php:703 +#: application/config/module.config.php:710 +#: application/config/module.config.php:726 +#: application/config/module.config.php:731 msgid "Item count" msgstr "" -#: application/config/module.config.php:692 +#: application/config/module.config.php:720 msgid "Resource class count" msgstr "" -#: application/config/module.config.php:693 +#: application/config/module.config.php:721 msgid "Property count" msgstr "" -#: application/config/module.config.php:865 +#: application/config/module.config.php:894 msgid "Something went wrong" msgstr "" -#: application/config/module.config.php:870 +#: application/config/module.config.php:899 msgid "You have unsaved changes." msgstr "" -#: application/config/module.config.php:871 +#: application/config/module.config.php:900 msgid "Restore item set" msgstr "" -#: application/config/module.config.php:872 +#: application/config/module.config.php:901 msgid "Close icon set" msgstr "" -#: application/config/module.config.php:873 +#: application/config/module.config.php:902 msgid "Open icon set" msgstr "" -#: application/config/module.config.php:875 +#: application/config/module.config.php:904 msgid "Failed loading resource template from API" msgstr "" -#: application/config/module.config.php:876 +#: application/config/module.config.php:905 msgid "Restore property" msgstr "" -#: application/config/module.config.php:878 +#: application/config/module.config.php:907 msgid "Please enter a valid language tag" msgstr "" -#: application/config/module.config.php:880 +#: application/config/module.config.php:909 msgid "Description" msgstr "" -#: application/config/module.config.php:881 +#: application/config/module.config.php:910 msgid "Unknown block layout" msgstr "" -#: application/config/module.config.php:882 +#: application/config/module.config.php:911 msgid "Required field must be completed" msgstr "" @@ -5349,6 +5523,30 @@ msgstr "" msgid "Site admin" msgstr "" +#: application/view/common/advanced-search/visibility.phtml:3 +msgid "Search by visibility" +msgstr "" + +#: application/view/common/advanced-search/visibility.phtml:8 +msgid "Select visibility…" +msgstr "" + +#: application/view/common/advanced-search/sort.phtml:20 +msgid "Select sort by…" +msgstr "" + +#: application/view/common/advanced-search/sort.phtml:26 +msgid "Select sort order…" +msgstr "" + +#: application/view/common/advanced-search/has-media.phtml:4 +msgid "Search by media presence" +msgstr "" + +#: application/view/common/advanced-search/has-media.phtml:9 +msgid "Select media presence…" +msgstr "" + #: application/view/common/advanced-search/properties.phtml:70 msgid "[Any Property]" msgstr "" diff --git a/application/src/Api/Adapter/AbstractEntityAdapter.php b/application/src/Api/Adapter/AbstractEntityAdapter.php index 7fcc24793b..9bca791536 100644 --- a/application/src/Api/Adapter/AbstractEntityAdapter.php +++ b/application/src/Api/Adapter/AbstractEntityAdapter.php @@ -121,20 +121,21 @@ public function buildBaseQuery(QueryBuilder $qb, array $query) { if (isset($query['id'])) { $ids = $query['id']; - if (is_string($ids) || is_int($ids)) { + if (is_int($ids)) { + $ids = [(string) $ids]; + } elseif (is_string($ids)) { // Account for comma-delimited IDs. $ids = false === strpos($ids, ',') ? [$ids] : explode(',', $ids); - } elseif (!is_array($ids)) { + } elseif (is_array($ids)) { + $ids = array_map('strval', $ids); + } else { // This is an invalid ID. Set to an empty array. $ids = []; } // Exclude null and empty-string IDs. Previous resource-only version // used is_numeric, but we want this to be able to work for possible // string IDs also. - $ids = array_map('trim', $ids); - $ids = array_filter($ids, function ($id) { - return !($id === null || $id === ''); - }); + $ids = array_filter(array_map('trim', $ids), 'strlen'); if ($ids) { $qb->andWhere($qb->expr()->in( 'omeka_root.id', diff --git a/application/src/Api/Adapter/AbstractResourceEntityAdapter.php b/application/src/Api/Adapter/AbstractResourceEntityAdapter.php index 16285a0519..12d3c26618 100644 --- a/application/src/Api/Adapter/AbstractResourceEntityAdapter.php +++ b/application/src/Api/Adapter/AbstractResourceEntityAdapter.php @@ -4,6 +4,7 @@ use DateTime; use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\QueryBuilder; +use Laminas\EventManager\Event; use Omeka\Api\Representation\ValueRepresentation; use Omeka\Api\Request; use Omeka\Entity\EntityInterface; @@ -254,6 +255,11 @@ protected function buildPropertyQuery(QueryBuilder $qb, array $query) return str_replace(['\\', '%', '_'], ['\\\\', '\\%', '\\_'], (string) $string); }; + // See below "Consecutive OR optimization" comment + $previousPropertyId = null; + $previousAlias = null; + $previousPositive = null; + foreach ($query['property'] as $queryRow) { if (!(is_array($queryRow) && array_key_exists('property', $queryRow) @@ -270,13 +276,41 @@ protected function buildPropertyQuery(QueryBuilder $qb, array $query) continue; } - $valuesAlias = $this->createAlias(); $positive = true; + if (in_array($queryType, ['neq', 'nin', 'nsw', 'new', 'nres', 'nex'])) { + $positive = false; + $queryType = substr($queryType, 1); + } + if (!in_array($queryType, ['eq', 'in', 'sw', 'ew', 'res', 'ex'])) { + continue; + } + + // Consecutive OR optimization + // + // When we have a run of query rows that are joined by OR and share + // the same property ID (or lack thereof), we don't actually need a + // separate join to the values table; we can just tack additional OR + // clauses onto the WHERE while using the same join and alias. The + // extra joins are expensive, so doing this improves performance where + // many ORs are used. + // + // Rows using "negative" searches need their own separate join to the + // values table, so they're excluded from this optimization on both + // sides: if either the current or previous row is a negative query, + // the current row does a new join. + if ($previousPropertyId === $propertyId + && $previousPositive + && $positive + && $joiner === 'or' + ) { + $valuesAlias = $previousAlias; + $usePrevious = true; + } else { + $valuesAlias = $this->createAlias(); + $usePrevious = false; + } switch ($queryType) { - case 'neq': - $positive = false; - // No break. case 'eq': $param = $this->createNamedParameter($qb, $value); $subqueryAlias = $this->createAlias(); @@ -292,9 +326,6 @@ protected function buildPropertyQuery(QueryBuilder $qb, array $query) ); break; - case 'nin': - $positive = false; - // No break. case 'in': $param = $this->createNamedParameter($qb, '%' . $escapeSqlLike($value) . '%'); $subqueryAlias = $this->createAlias(); @@ -310,9 +341,6 @@ protected function buildPropertyQuery(QueryBuilder $qb, array $query) ); break; - case 'nsw': - $positive = false; - // No break. case 'sw': $param = $this->createNamedParameter($qb, $escapeSqlLike($value) . '%'); $subqueryAlias = $this->createAlias(); @@ -328,9 +356,6 @@ protected function buildPropertyQuery(QueryBuilder $qb, array $query) ); break; - case 'new': - $positive = false; - // No break. case 'ew': $param = $this->createNamedParameter($qb, '%' . $escapeSqlLike($value)); $subqueryAlias = $this->createAlias(); @@ -346,9 +371,6 @@ protected function buildPropertyQuery(QueryBuilder $qb, array $query) ); break; - case 'nres': - $positive = false; - // No break. case 'res': $predicateExpr = $qb->expr()->eq( "$valuesAlias.valueResource", @@ -356,9 +378,6 @@ protected function buildPropertyQuery(QueryBuilder $qb, array $query) ); break; - case 'nex': - $positive = false; - // No break. case 'ex': $predicateExpr = $qb->expr()->isNotNull("$valuesAlias.id"); break; @@ -390,10 +409,13 @@ protected function buildPropertyQuery(QueryBuilder $qb, array $query) $whereClause = $qb->expr()->isNull("$valuesAlias.id"); } - if ($joinConditions) { - $qb->leftJoin($valuesJoin, $valuesAlias, 'WITH', $qb->expr()->andX(...$joinConditions)); - } else { - $qb->leftJoin($valuesJoin, $valuesAlias); + // See above "Consecutive OR optimization" comment + if (!$usePrevious) { + if ($joinConditions) { + $qb->leftJoin($valuesJoin, $valuesAlias, 'WITH', $qb->expr()->andX(...$joinConditions)); + } else { + $qb->leftJoin($valuesJoin, $valuesAlias); + } } if ($where == '') { @@ -403,6 +425,11 @@ protected function buildPropertyQuery(QueryBuilder $qb, array $query) } else { $where .= " AND $whereClause"; } + + // See above "Consecutive OR optimization" comment + $previousPropertyId = $propertyId; + $previousPositive = $positive; + $previousAlias = $valuesAlias; } if ($where) { @@ -550,6 +577,14 @@ public function getSubjectValues(Resource $resource, $page = null, $perPage = nu ->orderBy('property.id, resource_template_property.alternateLabel, resource.title') ->setMaxResults($perPage) ->setFirstResult($offset); + $event = new Event('api.subject_values.query', $this, [ + 'queryBuilder' => $qb, + 'resource' => $resource, + 'propertyId' => $propertyId, + 'resourceType' => $resourceType, + 'siteId' => $siteId, + ]); + $this->getEventManager()->triggerEvent($event); $results = $qb->getQuery()->getResult(); return $results; } @@ -573,6 +608,14 @@ public function getSubjectValuesSimple(Resource $resource, $propertyId = null, $ ->join('value.property', 'property') ->join('property.vocabulary', 'vocabulary') ->select("CONCAT(vocabulary.prefix, ':', property.localName) term, IDENTITY(value.resource) id, resource.title title"); + $event = new Event('api.subject_values_simple.query', $this, [ + 'queryBuilder' => $qb, + 'resource' => $resource, + 'propertyId' => $propertyId, + 'resourceType' => $resourceType, + 'siteId' => $siteId, + ]); + $this->getEventManager()->triggerEvent($event); return $qb->getQuery()->getResult(); } @@ -677,7 +720,14 @@ public function getFulltextText($resource) $services = $this->getServiceLocator(); $dataTypes = $services->get('Omeka\DataTypeManager'); $view = $services->get('ViewRenderer'); + $eventManager = $this->getEventManager(); + $criteria = Criteria::create()->where(Criteria::expr()->eq('isPublic', true)); + $args = $eventManager->prepareArgs(['resource' => $resource, 'criteria' => $criteria]); + $event = new Event('api.get_fulltext_text.value_criteria', $this, $args); + $eventManager->triggerEvent($event); + $criteria = $args['criteria']; + $texts = []; foreach ($resource->getValues()->matching($criteria) as $value) { $valueRepresentation = new ValueRepresentation($value, $services); @@ -685,7 +735,17 @@ public function getFulltextText($resource) // Add value annotation text, if any. $valueAnnotation = $value->getValueAnnotation(); if ($valueAnnotation) { - foreach ($valueAnnotation->getValues()->matching($criteria) as $value) { + $valueAnnotationCriteria = Criteria::create()->where(Criteria::expr()->eq('isPublic', true)); + $args = $eventManager->prepareArgs([ + 'resource' => $resource, + 'value' => $value, + 'criteria' => $valueAnnotationCriteria, + ]); + $event = new Event('api.get_fulltext_text.value_annotation_criteria', $this, $args); + $eventManager->triggerEvent($event); + $valueAnnotationCriteria = $args['criteria']; + + foreach ($valueAnnotation->getValues()->matching($valueAnnotationCriteria) as $value) { $valueRepresentation = new ValueRepresentation($value, $services); $texts[] = $dataTypes->getForExtract($value)->getFulltextText($view, $valueRepresentation); } diff --git a/application/src/Api/Adapter/AssetAdapter.php b/application/src/Api/Adapter/AssetAdapter.php index a19ea2f190..9cf4d64854 100644 --- a/application/src/Api/Adapter/AssetAdapter.php +++ b/application/src/Api/Adapter/AssetAdapter.php @@ -9,8 +9,6 @@ class AssetAdapter extends AbstractEntityAdapter { - const ALLOWED_MEDIA_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/svg', 'image/svgz', 'image/svg+xml']; - protected $sortFields = [ 'id' => 'id', 'media_type' => 'mediaType', @@ -81,7 +79,8 @@ public function hydrate(Request $request, EntityInterface $entity, ErrorStore $e } $tempFile->setSourceName($fileData['file']['name']); - $validator = new Validator(self::ALLOWED_MEDIA_TYPES); + $config = $this->getServiceLocator()->get('Config'); + $validator = new Validator($config['api_assets']['allowed_media_types'], $config['api_assets']['allowed_extensions']); if (!$validator->validate($tempFile, $errorStore)) { return; } diff --git a/application/src/Api/Adapter/MediaAdapter.php b/application/src/Api/Adapter/MediaAdapter.php index a3779ff706..d16f4e5a21 100644 --- a/application/src/Api/Adapter/MediaAdapter.php +++ b/application/src/Api/Adapter/MediaAdapter.php @@ -4,6 +4,7 @@ use Doctrine\ORM\QueryBuilder; use Omeka\Api\Request; use Omeka\Media\Ingester\MutableIngesterInterface; +use Omeka\Media\Renderer\FulltextSearchableInterface; use Omeka\Entity\EntityInterface; use Omeka\Entity\Item; use Omeka\Media\Ingester\Fallback; @@ -200,4 +201,16 @@ public function preprocessBatchUpdate(array $data, Request $request) return $data; } + + public function getFulltextText($resource) + { + $renderer = $this->getServiceLocator() + ->get('Omeka\Media\Renderer\Manager') + ->get($resource->getRenderer()); + $fulltextText = parent::getFulltextText($resource); + if ($renderer instanceof FulltextSearchableInterface) { + $fulltextText .= ' ' . $renderer->getFulltextText($this->getRepresentation($resource)); + } + return $fulltextText; + } } diff --git a/application/src/Api/Adapter/SitePageAdapter.php b/application/src/Api/Adapter/SitePageAdapter.php index e18600db6e..5a4fb6c83a 100644 --- a/application/src/Api/Adapter/SitePageAdapter.php +++ b/application/src/Api/Adapter/SitePageAdapter.php @@ -143,6 +143,14 @@ public function hydrate(Request $request, EntityInterface $entity, $entity->setIsPublic($request->getValue('o:is_public', true)); } + if ($this->shouldHydrate($request, 'o:layout')) { + $entity->setLayout($request->getValue('o:layout', null)); + } + + if ($this->shouldHydrate($request, 'o:layout_data')) { + $entity->setLayoutData($request->getValue('o:layout_data', null)); + } + $appendBlocks = $request->getOperation() === Request::UPDATE && $request->getOption('isPartial', false); $this->hydrateBlocks($blockData, $entity, $errorStore, $appendBlocks); $this->updateTimestamps($request, $entity); @@ -226,6 +234,7 @@ private function hydrateBlocks(array $blockData, SitePage $page, ErrorStore $err $block->setLayout($inputBlock['o:layout']); $block->setData($inputBlock['o:data']); + $block->setLayoutData($inputBlock['o:layout_data'] ?? null); // (Re-)order blocks by their order in the input $block->setPosition($position++); diff --git a/application/src/Api/Representation/AbstractResourceEntityRepresentation.php b/application/src/Api/Representation/AbstractResourceEntityRepresentation.php index 6f0cd1a4ad..ec2bc60d34 100644 --- a/application/src/Api/Representation/AbstractResourceEntityRepresentation.php +++ b/application/src/Api/Representation/AbstractResourceEntityRepresentation.php @@ -67,6 +67,8 @@ public function getJsonLdType() public function getJsonLd() { + $settings = $this->getServiceLocator()->get('Omeka\Settings'); + // Set the date time value objects. $dateTime = [ 'o:created' => [ @@ -109,8 +111,11 @@ public function getJsonLd() // According to the JSON-LD spec, the value of the @reverse key "MUST be // a JSON object containing members representing reverse properties." // Here, we include the key only if the resource has reverse properties. - $reverse = $this->subjectValuesForReverse(); - $reverse = $reverse ? ['@reverse' => $reverse] : []; + $reverse = []; + if (!$settings->get('disable_jsonld_reverse')) { + $reverse = $this->subjectValuesForReverse(); + $reverse = $reverse ? ['@reverse' => $reverse] : []; + } return array_merge( [ @@ -427,6 +432,19 @@ public function subjectValuesForReverse($propertyId = null, $resourceType = null return $subjectValues; } + /** + * Get the total count of this resource's subject values. + * + * @param int|string|null $propertyId Filter by property ID + * @param string|null $resourceType Filter by resource type + * @param int|null $siteId Filter by site ID + * @return int + */ + public function subjectValueTotalCount($propertyId = null, $resourceType = null, $siteId = null) + { + return $this->getAdapter()->getSubjectValueTotalCount($this->resource, $propertyId, $resourceType, $siteId); + } + /** * Get value representations where this resource is the RDF subject. * @@ -515,7 +533,7 @@ public function displayValues(array $options = []) * The should follow the pattern laid out in * AbstractResourceEntityAdapter::getSubjectValuesQueryBuilder(). If a * $resourceProperty isn't passed or is invalid, the default is all - * properties for the "items" resource type. + * properties for the current resource type. * * @param array $options * @return string @@ -528,10 +546,34 @@ public function displaySubjectValues(array $options = []) $viewName = $options['viewName'] ?? 'common/linked-resources'; $page = $options['page'] ?? null; $perPage = $options['perPage'] ?? null; - $resourceProperty = $options['resourceProperty'] ?? null; $siteId = $options['siteId'] ?? null; - $resourceType = 'items'; + $subjectValuePropertiesItems = $adapter->getSubjectValueProperties($this->resource, 'items', $siteId); + $subjectValuePropertiesItemSets = $adapter->getSubjectValueProperties($this->resource, 'item_sets', $siteId); + $subjectValuePropertiesMedia = $adapter->getSubjectValueProperties($this->resource, 'media', $siteId); + + if (!$subjectValuePropertiesItems && !$subjectValuePropertiesItemSets && !$subjectValuePropertiesMedia) { + // This resource has no subject values; + return null; + } + + $resourcePropertiesAll = [ + 'items' => $subjectValuePropertiesItems, + 'item_sets' => $subjectValuePropertiesItemSets, + 'media' => $subjectValuePropertiesMedia, + ]; + // Find the default resource property by detecting the first resource + // type that has properties. + $defaultResourceProperty = null; + foreach ($resourcePropertiesAll as $resourceType => $resourceProperties) { + if ($resourceProperties) { + $defaultResourceProperty = sprintf('%s:', $resourceType); + break; + } + } + $resourceProperty = $options['resourceProperty'] ?? $defaultResourceProperty; + + $resourceType = $adapter->getResourceName(); $propertyId = null; if ($resourceProperty && false !== strpos($resourceProperty, ':')) { // Derive the resource type and property ID from $resourceProperty. @@ -539,18 +581,7 @@ public function displaySubjectValues(array $options = []) } $totalCount = $adapter->getSubjectValueTotalCount($this->resource, $propertyId, $resourceType, $siteId); - if (!$totalCount) { - return; - } $subjectValues = $this->subjectValues($page, $perPage, $propertyId, $resourceType, $siteId); - if (!$subjectValues) { - return; - } - $resourcePropertiesAll = [ - 'items' => $adapter->getSubjectValueProperties($this->resource, 'items', $siteId), - 'item_sets' => $adapter->getSubjectValueProperties($this->resource, 'item_sets', $siteId), - 'media' => $adapter->getSubjectValueProperties($this->resource, 'media', $siteId), - ]; $partial = $this->getViewHelper('partial'); return $partial($viewName, [ diff --git a/application/src/Api/Representation/SitePageBlockRepresentation.php b/application/src/Api/Representation/SitePageBlockRepresentation.php index eaa470df6a..dcc941107b 100644 --- a/application/src/Api/Representation/SitePageBlockRepresentation.php +++ b/application/src/Api/Representation/SitePageBlockRepresentation.php @@ -29,6 +29,7 @@ public function jsonSerialize(): array return [ 'o:layout' => $this->layout(), 'o:data' => $this->data(), + 'o:layout_data' => $this->layoutData(), 'o:attachment' => $this->attachments(), ]; } @@ -79,6 +80,27 @@ public function dataValue($key, $default = null) return $data[$key] ?? $default; } + /** + * Get block layout data by key. + * + * @param string $key The layout data key + * @param mixed $default Return this if key does not exist + * @return mixed + */ + public function layoutDataValue($key, $default = null) + { + $layoutData = $this->block->getLayoutData(); + return $layoutData[$key] ?? $default; + } + + /** + * @return array + */ + public function layoutData() + { + return $this->block->getLayoutData(); + } + public function attachments() { $attachments = []; diff --git a/application/src/Api/Representation/SitePageRepresentation.php b/application/src/Api/Representation/SitePageRepresentation.php index 96b87cde50..1d00bcc85a 100644 --- a/application/src/Api/Representation/SitePageRepresentation.php +++ b/application/src/Api/Representation/SitePageRepresentation.php @@ -25,6 +25,8 @@ public function getJsonLd() 'o:slug' => $this->slug(), 'o:title' => $this->title(), 'o:is_public' => $this->isPublic(), + 'o:layout' => $this->layout(), + 'o:layout_data' => $this->layoutData() ?? [], 'o:block' => $this->blocks(), 'o:site' => $this->site()->getReference(), 'o:created' => $created, @@ -72,6 +74,35 @@ public function isPublic() return $this->resource->isPublic(); } + /** + * @return ?string + */ + public function layout() + { + return $this->resource->getLayout(); + } + + /** + * @return ?array + */ + public function layoutData() + { + return $this->resource->getLayoutData(); + } + + /** + * Get layout data by key. + * + * @param string $key The layout data key + * @param mixed $default Return this if key does not exist + * @return mixed + */ + public function layoutDataValue($key, $default = null) + { + $layoutData = $this->resource->getLayoutData(); + return $layoutData[$key] ?? $default; + } + /** * Get the blocks assigned to this page. * diff --git a/application/src/Controller/Admin/SystemInfoController.php b/application/src/Controller/Admin/SystemInfoController.php index 9304ce6167..c16e4c9b95 100644 --- a/application/src/Controller/Admin/SystemInfoController.php +++ b/application/src/Controller/Admin/SystemInfoController.php @@ -82,6 +82,7 @@ private function getSystemInfo() 'Version' => sprintf('%s %s %s', php_uname('s'), php_uname('r'), php_uname('m')), ], 'Modules' => [], + 'Free space' => [], 'Paths' => [ 'PHP CLI path' => sprintf( '%s %s', @@ -124,6 +125,25 @@ private function getSystemInfo() } } + $freeSpaceSystem = disk_free_space('.'); + $info['Free space']['System'] = $this->formatSpace($freeSpaceSystem); + $freeSpaceFilesDir = $this->getDirFiles(); + if ($freeSpaceFilesDir) { + $freeSpaceFiles = disk_free_space($freeSpaceFilesDir); + if ($freeSpaceFiles !== $freeSpaceSystem) { + $info['Free space']['Local files'] = $this->formatSpace($freeSpaceFiles); + } + // Manage the case where directory "original" is mounted separately. + $freeSpaceOriginal = disk_free_space($freeSpaceFilesDir . '/original'); + if ($freeSpaceFiles !== $freeSpaceOriginal) { + $info['Free space']['Local files (original)'] = $this->formatSpace($freeSpaceOriginal); + } + } + $freeSpaceTemp = disk_free_space($this->getDirTemp()); + if ($freeSpaceTemp !== $freeSpaceSystem) { + $info['Free space']['Temp dir'] = $this->formatSpace($freeSpaceTemp); + } + return $info; } @@ -171,4 +191,23 @@ public function getImagemagickPath() { return sprintf('%s/convert', $this->getImagemagickDir()); } + + protected function getDirFiles(): ?string + { + $fileStore = $this->config['service_manager']['aliases']['Omeka\File\Store']; + if ($fileStore === 'Omeka\File\Store\Local') { + return $this->config['file_store']['local']['base_path'] ?: (OMEKA_PATH . '/files'); + } + return null; + } + + protected function getDirTemp(): ?string + { + return $this->config['temp_dir'] ?: sys_get_temp_dir(); + } + + protected function formatSpace($bytes): string + { + return sprintf('%1$.1f GiB', $bytes / (1024 * 1024 * 1024)); + } } diff --git a/application/src/Controller/Admin/UserController.php b/application/src/Controller/Admin/UserController.php index 8bbdf05edf..56844d59cb 100644 --- a/application/src/Controller/Admin/UserController.php +++ b/application/src/Controller/Admin/UserController.php @@ -8,6 +8,7 @@ use Omeka\Form\UserForm; use Omeka\Mvc\Exception; use Omeka\Stdlib\Message; +use Laminas\Mail\Exception\ExceptionInterface as MailException; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; @@ -110,7 +111,12 @@ public function addAction() $response = $this->api($form)->create('users', $formData['user-information']); if ($response) { $user = $response->getContent()->getEntity(); - $this->mailer()->sendUserActivation($user); + try { + $this->mailer()->sendUserActivation($user); + } catch (MailException $e) { + $this->logger()->err((string) $e); + $this->messenger()->addWarning('Unable to send user activation email.'); // @translate + } $message = new Message( 'User successfully created. %s', // @translate sprintf( @@ -139,6 +145,11 @@ public function editAction() $readResponse = $this->api()->read('users', $id); $user = $readResponse->getContent(); $userEntity = $user->getEntity(); + + if (!$this->userIsAllowed($userEntity, 'update')) { + throw new Exception\PermissionDeniedException; + } + $currentUser = $userEntity === $this->identity(); $keys = $userEntity->getKeys(); @@ -241,7 +252,7 @@ public function editAction() if ($keyPersisted) { $message = new Message( - 'API key successfully created.

    Here is your key ID and credential for access to the API. WARNING: "key_credential" will be unretrievable after you navigate away from this page.

    key_identity: %1$s
    key_credential: %2$s', // @translate + 'API key successfully created.

    Here is your key ID and credential for access to the API. WARNING: "key_credential" will be unretrievable after you navigate away from this page.

    key_identity=%1$s
    key_credential=%2$s', // @translate $keyId, $keyCredential ); $message->setEscapeHtml(false); diff --git a/application/src/Controller/Admin/VocabularyController.php b/application/src/Controller/Admin/VocabularyController.php index 4b3adbef4d..4d4bc5965f 100644 --- a/application/src/Controller/Admin/VocabularyController.php +++ b/application/src/Controller/Admin/VocabularyController.php @@ -1,7 +1,6 @@ getForm(VocabularyForm::class, ['include_namespace' => true]); - + $form = $this->getForm(VocabularyForm::class); $request = $this->getRequest(); if ($request->isPost()) { $post = array_merge_recursive( @@ -74,45 +72,39 @@ public function importAction() $form->setData($post); if ($form->isValid()) { $data = $form->getData(); + $strategy = null; + $options = [ + 'format' => $data['vocabulary-file']['format'], + 'lang' => $data['vocabulary-advanced']['lang'], + 'label_property' => $data['vocabulary-advanced']['label_property'], + 'comment_property' => $data['vocabulary-advanced']['comment_property'], + ]; + if ('upload' === $data['vocabulary-file']['import_type']) { + $strategy = 'file'; + $options['file'] = $data['vocabulary-file']['file']['tmp_name']; + } elseif ('url' === $data['vocabulary-file']['import_type']) { + $strategy = 'url'; + $options['url'] = $data['vocabulary-file']['url']; + } try { - $strategy = null; - $options = [ - 'format' => $data['vocabulary-file']['format'], - 'lang' => $data['vocabulary-advanced']['lang'], - 'label_property' => $data['vocabulary-advanced']['label_property'], - 'comment_property' => $data['vocabulary-advanced']['comment_property'], - ]; - if (\UPLOAD_ERR_OK === $data['vocabulary-file']['file']['error']) { - $strategy = 'file'; - $options['file'] = $data['vocabulary-file']['file']['tmp_name']; - } elseif ($data['vocabulary-file']['url']) { - $strategy = 'url'; - $options['url'] = $data['vocabulary-file']['url']; - } else { - throw new ValidationException($this->translate('Must provide a vocabulary file or a vocabulary URL')); - } $response = $this->rdfImporter->import($strategy, $data['vocabulary-info'], $options); - if ($response) { - $message = new Message( - 'Vocabulary successfully imported. %s', // @translate - sprintf( - '%s', - htmlspecialchars($this->url()->fromRoute(null, [], true)), - $this->translate('Import another vocabulary?') - )); - $message->setEscapeHtml(false); - $this->messenger()->addSuccess($message); - return $this->redirect()->toRoute(null, ['action' => 'browse'], true); - } - } catch (ValidationException $e) { + $message = new Message( + 'Vocabulary successfully imported. %s', // @translate + sprintf('%s', htmlspecialchars($this->url()->fromRoute(null, [], true)), $this->translate('Import another vocabulary?')) + ); + $message->setEscapeHtml(false); + $this->messenger()->addSuccess($message); + return $this->redirect()->toRoute(null, ['action' => 'browse'], true); + } catch (\Exception $e) { $messages = []; - // A message may be thrown directly from the RDF importer. if ($e->getMessage()) { $messages[] = $e->getMessage(); } // Messages may be thrown from the API via the importer. - foreach ($e->getErrorStore()->getErrors() as $message) { - $messages[] = $message; + if (method_exists($e, 'getErrorStore')) { + foreach ($e->getErrorStore()->getErrors() as $message) { + $messages[] = $message; + } } $this->messenger()->addErrors($messages); } @@ -120,7 +112,6 @@ public function importAction() $this->messenger()->addFormErrors($form); } } - $view = new ViewModel; $view->setVariable('form', $form); return $view; @@ -128,24 +119,21 @@ public function importAction() public function editAction() { - $form = $this->getForm(VocabularyForm::class); $vocabulary = $this->api()->read('vocabularies', $this->params('id'))->getContent(); - + $form = $this->getForm(VocabularyForm::class, ['vocabulary' => $vocabulary]); if ($vocabulary->isPermanent()) { throw new Exception\PermissionDeniedException('Cannot edit a permanent vocabulary'); } - $data = [ 'vocabulary-info' => [ 'o:label' => $vocabulary->label(), 'o:comment' => $vocabulary->comment(), + 'o:namespace_uri' => $vocabulary->namespaceUri(), ], ]; $form->setData($data); - $view = new ViewModel; $view->setVariable('vocabulary', $vocabulary); - $request = $this->getRequest(); if ($request->isPost()) { $post = array_merge_recursive( @@ -156,7 +144,6 @@ public function editAction() if ($form->isValid()) { $data = $form->getData(); $response = $this->api($form)->update('vocabularies', $this->params('id'), $data['vocabulary-info'], [], ['isPartial' => true]); - $strategy = null; $options = [ 'format' => $data['vocabulary-file']['format'], @@ -164,31 +151,32 @@ public function editAction() 'label_property' => $data['vocabulary-advanced']['label_property'], 'comment_property' => $data['vocabulary-advanced']['comment_property'], ]; - if (\UPLOAD_ERR_OK === $data['vocabulary-file']['file']['error']) { + if ('upload' === $data['vocabulary-file']['import_type']) { $strategy = 'file'; $options['file'] = $data['vocabulary-file']['file']['tmp_name']; - } elseif ($data['vocabulary-file']['url']) { + } elseif ('url' === $data['vocabulary-file']['import_type']) { $strategy = 'url'; $options['url'] = $data['vocabulary-file']['url']; } - - if (null !== $strategy) { - $this->messenger()->addSuccess('Please review these changes before you accept them.'); // @translate + if (null === $strategy) { + $this->messenger()->addSuccess('Vocabulary successfully updated'); // @translate + return $this->redirect()->toRoute(null, ['action' => 'browse'], true); + } + try { $diff = $this->rdfImporter->getDiff($strategy, $vocabulary->namespaceUri(), $options); + $this->messenger()->addSuccess('Please review these changes before you accept them.'); // @translate $form = $this->getForm(VocabularyUpdateForm::class); $form->setAttribute('action', $this->url()->fromRoute(null, ['action' => 'update'], true)); $form->get('diff')->setValue(json_encode($diff)); $view->setVariable('diff', $diff); $view->setTemplate('omeka/admin/vocabulary/update'); - } else { - $this->messenger()->addSuccess('Vocabulary successfully updated'); // @translate - return $this->redirect()->toRoute(null, ['action' => 'browse'], true); + } catch (\Exception $e) { + $this->messenger()->addError($e->getMessage()); } } else { $this->messenger()->addFormErrors($form); } } - $view->setVariable('form', $form); return $view; } diff --git a/application/src/Controller/LoginController.php b/application/src/Controller/LoginController.php index 9d55faacc9..f6a025ec69 100644 --- a/application/src/Controller/LoginController.php +++ b/application/src/Controller/LoginController.php @@ -7,6 +7,7 @@ use Omeka\Form\ActivateForm; use Omeka\Form\ForgotPasswordForm; use Laminas\Authentication\AuthenticationService; +use Laminas\Mail\Exception\ExceptionInterface as MailException; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\Session\Container; use Laminas\View\Model\ViewModel; @@ -60,7 +61,10 @@ public function loginAction() if ($redirectUrl = $session->offsetGet('redirect_url')) { return $this->redirect()->toUrl($redirectUrl); } - return $this->redirect()->toRoute('admin'); + if ($this->userIsAllowed('Omeka\Controller\Admin\Index', 'browse')) { + return $this->redirect()->toRoute('admin'); + } + return $this->redirect()->toRoute('top'); } else { $this->messenger()->addError('Email or password is invalid'); // @translate } @@ -163,7 +167,12 @@ public function forgotPasswordAction() $this->entityManager->remove($passwordCreation); $this->entityManager->flush(); } - $this->mailer()->sendResetPassword($user); + try { + $this->mailer()->sendResetPassword($user); + } catch (MailException $e) { + $this->logger()->err((string) $e); + $this->messenger()->addWarning('Unable to send password reset email.'); // @translate + } } $this->messenger()->addSuccess('Check your email for instructions on how to reset your password'); // @translate return $this->redirect()->toRoute('login'); diff --git a/application/src/Controller/Site/PageController.php b/application/src/Controller/Site/PageController.php index 3040240815..c3b23ef91a 100644 --- a/application/src/Controller/Site/PageController.php +++ b/application/src/Controller/Site/PageController.php @@ -3,9 +3,17 @@ use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; +use Omeka\Site\Theme\Theme; class PageController extends AbstractActionController { + protected $currentTheme; + + public function __construct(Theme $currentTheme) + { + $this->currentTheme = $currentTheme; + } + public function browseAction() { $this->setBrowseDefaults('created'); @@ -41,6 +49,16 @@ public function showAction() $view->setVariable('pageBodyClass', $pageBodyClass); $view->setVariable('displayNavigation', true); + // Set the configured page template, if any. + $templateName = $page->layoutDataValue('template_name'); + if ($templateName) { + // Verify that the current theme provides this template. + $config = $this->currentTheme->getConfigSpec(); + if (isset($config['page_templates'][$templateName])) { + $view->setTemplate(sprintf('common/page-template/%s', $templateName)); + } + } + $contentView = clone $view; $contentView->setTemplate('omeka/site/page/content'); $contentView->setVariable('pageViewModel', $view); diff --git a/application/src/Controller/SiteAdmin/IndexController.php b/application/src/Controller/SiteAdmin/IndexController.php index 1b5366443b..7b4d04cb55 100644 --- a/application/src/Controller/SiteAdmin/IndexController.php +++ b/application/src/Controller/SiteAdmin/IndexController.php @@ -152,6 +152,7 @@ public function addPageAction() $formData = $form->getData(); $formData['o:site']['o:id'] = $site->id(); $formData['o:is_public'] = !empty($post['o:is_public']); + $formData['o:layout_data']['template_name'] = $post['template_name']; $response = $this->api($form)->create('site_pages', $formData); if ($response) { $page = $response->getContent(); diff --git a/application/src/Controller/SiteAdmin/PageController.php b/application/src/Controller/SiteAdmin/PageController.php index 525c823f0a..24c7984321 100644 --- a/application/src/Controller/SiteAdmin/PageController.php +++ b/application/src/Controller/SiteAdmin/PageController.php @@ -1,6 +1,8 @@ pages(); $form = $this->getForm(SitePageForm::class); - $form->setData($page->jsonSerialize()); + $pageData = $page->jsonSerialize(); + $form->setData($pageData); if ($this->getRequest()->isPost()) { $post = $this->params()->fromPost(); + // Prepare block layout data. + foreach ($post['o:block'] as $key => $blockData) { + $post['o:block'][$key]['o:layout_data'] = json_decode($blockData['o:layout_data'], true); + } $form->setData($post); if ($form->isValid()) { $response = $this->api($form)->update('site_pages', $page->id(), $post); @@ -36,11 +43,21 @@ public function editAction() } } + // Populate the page layout data fieldset. + $pageLayoutDataForm = $this->getForm(PageLayoutDataForm::class); + $pageLayoutDataFormData = []; + foreach ($pageData['o:layout_data'] as $key => $value) { + $pageLayoutDataFormData[sprintf('o:layout_data[%s]', $key)] = $value; + } + $pageLayoutDataForm->setData($pageLayoutDataFormData); + $view = new ViewModel; $view->setVariable('site', $site); $view->setVariable('sitePages', $sitePages); $view->setVariable('page', $page); $view->setVariable('form', $form); + $view->setVariable('pageLayoutDataForm', $pageLayoutDataForm); + $view->setVariable('blockLayoutDataForm', $this->getForm(BlockLayoutDataForm::class)); return $view; } diff --git a/application/src/Db/Event/Subscriber/Entity.php b/application/src/Db/Event/Subscriber/Entity.php index 75bb7fcc14..dc368a893a 100644 --- a/application/src/Db/Event/Subscriber/Entity.php +++ b/application/src/Db/Event/Subscriber/Entity.php @@ -2,6 +2,7 @@ namespace Omeka\Db\Event\Subscriber; use Doctrine\Common\EventSubscriber; +use Doctrine\Common\Util\ClassUtils; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Events as DoctrineEvent; use Omeka\Entity\Resource as OmekaResource; @@ -106,7 +107,7 @@ public function postUpdate(LifecycleEventArgs $args) protected function trigger($eventName, LifecycleEventArgs $args) { $entity = $args->getEntity(); - $identifiers = [get_class($entity)]; + $identifiers = [ClassUtils::getClass($entity)]; if ($entity instanceof OmekaResource) { // Add the identifier for a generic resource entity. $identifiers[] = 'Omeka\Entity\Resource'; diff --git a/application/src/Entity/Resource.php b/application/src/Entity/Resource.php index e71ab1cb08..390b1985d8 100644 --- a/application/src/Entity/Resource.php +++ b/application/src/Entity/Resource.php @@ -12,6 +12,19 @@ * @Entity * @InheritanceType("JOINED") * @DiscriminatorColumn(name="resource_type", type="string") + * @Table( + * indexes={ + * @Index( + * name="title", + * columns={"title"}, + * options={"lengths":{190}} + * ), + * @Index( + * name="is_public", + * columns={"is_public"} + * ) + * } + * ) * * @see \Omeka\Db\Event\Listener\ResourceDiscriminatorMap */ diff --git a/application/src/Entity/SitePage.php b/application/src/Entity/SitePage.php index c2dcf64dec..68e7fceb63 100644 --- a/application/src/Entity/SitePage.php +++ b/application/src/Entity/SitePage.php @@ -11,6 +11,12 @@ * @UniqueConstraint( * columns={"site_id", "slug"} * ) + * }, + * indexes={ + * @Index( + * name="is_public", + * columns={"is_public"} + * ) * } * ) */ @@ -38,6 +44,16 @@ class SitePage extends AbstractEntity */ protected $isPublic = true; + /** + * @Column(type="string", nullable=true) + */ + protected $layout; + + /** + * @Column(type="json", nullable=true) + */ + protected $layoutData; + /** * @ManyToOne(targetEntity="Site", inversedBy="pages") * @JoinColumn(nullable=false) @@ -105,6 +121,26 @@ public function isPublic() return (bool) $this->isPublic; } + public function setLayout($layout) + { + $this->layout = $layout; + } + + public function getLayout() + { + return $this->layout; + } + + public function setLayoutData($layoutData) + { + $this->layoutData = $layoutData; + } + + public function getLayoutData() + { + return $this->layoutData; + } + public function setSite(Site $site) { $this->site = $site; diff --git a/application/src/Entity/SitePageBlock.php b/application/src/Entity/SitePageBlock.php index f039f82a9c..5a681c0e74 100644 --- a/application/src/Entity/SitePageBlock.php +++ b/application/src/Entity/SitePageBlock.php @@ -33,6 +33,11 @@ class SitePageBlock extends AbstractEntity */ protected $data; + /** + * @Column(type="json", nullable=true) + */ + protected $layoutData; + /** * @Column(type="integer") */ @@ -95,6 +100,16 @@ public function getPosition() return $this->position; } + public function setLayoutData($layoutData) + { + $this->layoutData = $layoutData; + } + + public function getLayoutData() + { + return $this->layoutData; + } + public function setPage(SitePage $page) { $this->page = $page; diff --git a/application/src/Entity/Value.php b/application/src/Entity/Value.php index f62e503c6b..436463943b 100644 --- a/application/src/Entity/Value.php +++ b/application/src/Entity/Value.php @@ -7,7 +7,8 @@ * @Entity * @Table(name="`value`", indexes={ * @Index(name="`value`", columns={"`value`"}, options={"lengths":{190}}), - * @Index(name="`uri`", columns={"`uri`"}, options={"lengths":{190}}) + * @Index(name="`uri`", columns={"`uri`"}, options={"lengths":{190}}), + * @Index(name="is_public", columns={"is_public"}) * }) */ class Value extends AbstractEntity diff --git a/application/src/File/Downloader.php b/application/src/File/Downloader.php index 74199c2bab..1aff5512b8 100644 --- a/application/src/File/Downloader.php +++ b/application/src/File/Downloader.php @@ -73,6 +73,7 @@ public function download($uri, ErrorStore $errorStore = null) ); $errorStore->addError('download', $message); } + $tempFile->delete(); return false; } } @@ -87,6 +88,7 @@ public function download($uri, ErrorStore $errorStore = null) $errorStore->addError('download', $message); } $this->logger->err($message); + $tempFile->delete(); return false; } diff --git a/application/src/File/Uploader.php b/application/src/File/Uploader.php index 34f84361f4..d50150f79e 100644 --- a/application/src/File/Uploader.php +++ b/application/src/File/Uploader.php @@ -48,6 +48,7 @@ public function upload(array $fileData, ErrorStore $errorStore = null) $errorStore->addError('upload', $message); } } + $tempFile->delete(); return false; } $fileInput->getValue(); diff --git a/application/src/Form/BlockLayoutDataForm.php b/application/src/Form/BlockLayoutDataForm.php new file mode 100644 index 0000000000..1f3ea46d82 --- /dev/null +++ b/application/src/Form/BlockLayoutDataForm.php @@ -0,0 +1,132 @@ +viewHelpers->get('escapeHtml'); + $translate = $this->viewHelpers->get('translate'); + + // No need for CSRF protection on what is essentially a fieldset. + $this->remove('csrf'); + + // Get block templates configured by the current theme, if any. + $config = $this->currentTheme->getConfigSpec(); + $blockTemplates = []; + if (isset($config['block_templates']) && is_array($config['block_templates'])) { + $blockTemplates = $config['block_templates']; + } + // Build select options for every block layout that has templates. + $valueOptions = []; + foreach ($blockTemplates as $layoutName => $templates) { + $valueOptions[$layoutName] = ''; + foreach ($templates as $templateName => $templateLabel) { + $valueOptions[$layoutName] .= sprintf( + '', + $escapeHtml($templateName), + $escapeHtml($translate($templateLabel)) + ); + } + } + $this->add([ + 'type' => 'select', + 'name' => 'template_name', + 'options' => [ + 'label' => 'Template', + 'value_options' => [], + ], + 'attributes' => [ + 'id' => 'block-layout-data-template-name', + 'data-block-templates' => json_encode($blockTemplates), + 'data-empty-option' => sprintf('', $translate('Default')), + 'data-value-options' => json_encode($valueOptions), + 'data-key' => 'template_name', + ], + ]); + $this->add([ + 'name' => 'class', + 'type' => 'text', + 'options' => [ + 'label' => 'Class', // @translate + ], + 'attributes' => [ + 'id' => 'block-layout-data-class', + 'data-key' => 'class', + ], + ]); + $this->add([ + 'name' => 'alignment', + 'type' => 'select', + 'options' => [ + 'label' => 'Alignment', // @translate + 'empty_option' => 'Default', // @translate + 'value_options' => [ + 'left' => 'Float left', // @translate + 'right' => 'Float right', // @translate + 'center' => 'Center', // @translate + ], + ], + 'attributes' => [ + 'id' => 'block-layout-data-alignment', + 'data-key' => 'alignment', + ], + ]); + $this->add([ + 'name' => 'background', + 'type' => 'Omeka\Form\Element\Background', + 'options' => [ + 'label' => 'Background', + ], + ]); + $this->add([ + 'name' => 'min_height', + 'type' => 'number', + 'options' => [ + 'label' => 'Minimum height', // @translate + ], + 'attributes' => [ + 'id' => 'block-layout-data-min-height', + 'data-key' => 'min_height', + 'min' => '0', + ], + ]); + + /** + * Modules can add elements to this fieldset using the form.add_elements + * event. They can opt-in to automatically populate and apply the values + * by adding a "data-key" attribute containing the corresponding block + * layout data key. Elements that need more complex handling must attach + * to the following JS events on the document: + * - o:prepare-block-layout-data + * - o:apply-block-layout-data + */ + $event = new Event('form.add_elements', $this); + $this->getEventManager()->triggerEvent($event); + + // Note that we don't trigger form.add_input_filters because JS handles + // validation. + } + + public function setCurrentTheme(Theme $currentTheme) + { + $this->currentTheme = $currentTheme; + } + + public function setViewHelpers(HelperPluginManager $viewHelpers) + { + $this->viewHelpers = $viewHelpers; + } +} diff --git a/application/src/Form/Element/AbstractVocabularyMemberSelect.php b/application/src/Form/Element/AbstractVocabularyMemberSelect.php index 7d40cd3ce4..4f5d282466 100644 --- a/application/src/Form/Element/AbstractVocabularyMemberSelect.php +++ b/application/src/Form/Element/AbstractVocabularyMemberSelect.php @@ -70,6 +70,7 @@ public function getValueOptions(): array } elseif ('resource_classes' === $resourceName) { $attributes['data-resource-class-id'] = $member->id(); } + $attributes['title'] = $member->term(); $option = [ 'label' => $member->label(), 'value' => $termAsValue ? $member->term() : $member->id(), diff --git a/application/src/Form/Element/ArrayTextarea.php b/application/src/Form/Element/ArrayTextarea.php index 61414c2f2f..16ec8f32a4 100644 --- a/application/src/Form/Element/ArrayTextarea.php +++ b/application/src/Form/Element/ArrayTextarea.php @@ -121,7 +121,7 @@ protected function stringToList($string) */ protected function fixEndOfLine($string) { - return str_replace(["\r\n", "\n\r", "\r"], ["\n", "\n", "\n"], $string); + return str_replace(["\r\n", "\n\r", "\r"], ["\n", "\n", "\n"], (string) $string); } /** diff --git a/application/src/Form/Element/Background.php b/application/src/Form/Element/Background.php new file mode 100644 index 0000000000..214475c33a --- /dev/null +++ b/application/src/Form/Element/Background.php @@ -0,0 +1,78 @@ +imageAssetElement = (new OmekaElement\Asset('background_image_asset')) + ->setAttributes([ + 'id' => 'block-layout-data-background-image-asset', + 'data-key' => 'background_image_asset', + ]); + + $this->positionYElement = (new LaminasElement\Select('background_position_y')) + ->setEmptyOption('Default') // @translate + ->setValueOptions([ + 'top' => 'Top', // @translate + 'center' => 'Center', // @translate + 'bottom' => 'Bottom', // @translate + ]) + ->setAttributes([ + 'id' => 'block-layout-data-background-position-y', + 'data-key' => 'background_position_y', + ]); + + $this->positionXElement = (new LaminasElement\Select('background_position_x')) + ->setEmptyOption('Default') // @translate + ->setValueOptions([ + 'left' => 'Left', // @translate + 'center' => 'Center', // @translate + 'right' => 'Right', // @translate + ]) + ->setAttributes([ + 'id' => 'block-layout-data-background-position-x', + 'data-key' => 'background_position_x', + ]); + $this->sizeElement = (new LaminasElement\Select('background_size')) + ->setEmptyOption('Default') // @translate + ->setValueOptions([ + 'cover' => 'Cover', // @translate + 'contain' => 'Contain', // @translate + ]) + ->setAttributes([ + 'id' => 'block-layout-data-background-size', + 'data-key' => 'background_size', + ]); + } + + public function getImageAssetElement() + { + return $this->imageAssetElement; + } + + public function getPositionYElement() + { + return $this->positionYElement; + } + + public function getPositionXElement() + { + return $this->positionXElement; + } + + public function getSizeElement() + { + return $this->sizeElement; + } +} diff --git a/application/src/Form/Element/PropertySelect.php b/application/src/Form/Element/PropertySelect.php index daad72b61b..a882c05fd3 100644 --- a/application/src/Form/Element/PropertySelect.php +++ b/application/src/Form/Element/PropertySelect.php @@ -44,6 +44,7 @@ public function getValueOptions(): array 'attributes' => [ 'data-term' => $property->term(), 'data-property-id' => $property->id(), + 'title' => $property->term(), ], ]; } diff --git a/application/src/Form/PageLayoutDataForm.php b/application/src/Form/PageLayoutDataForm.php new file mode 100644 index 0000000000..7d8b9f3c07 --- /dev/null +++ b/application/src/Form/PageLayoutDataForm.php @@ -0,0 +1,73 @@ +remove('csrf'); + + $config = $this->currentTheme->getConfigSpec(); + $valueOptions = []; + if (isset($config['page_templates']) && is_array($config['page_templates'])) { + $valueOptions = $config['page_templates']; + } + $this->add([ + 'type' => 'select', + 'name' => 'o:layout_data[template_name]', + 'options' => [ + 'label' => 'Template', + 'empty_option' => 'Default', // @translate + 'value_options' => $valueOptions, + ], + 'attributes' => [ + 'id' => 'template-name', + ], + ]); + $this->add([ + 'type' => 'number', + 'name' => 'o:layout_data[grid_column_gap]', + 'options' => [ + 'label' => 'Column gap', + ], + 'attributes' => [ + 'id' => 'page-layout-grid-column-gap-input', + 'value' => '10', + 'min' => 0, + ], + ]); + $this->add([ + 'type' => 'number', + 'name' => 'o:layout_data[grid_row_gap]', + 'options' => [ + 'label' => 'Row gap', + ], + 'attributes' => [ + 'id' => 'page-layout-grid-row-gap-input', + 'value' => '10', + 'min' => 0, + ], + ]); + + $event = new Event('form.add_elements', $this); + $this->getEventManager()->triggerEvent($event); + + // Note that we don't trigger form.add_input_filters because JS handles + // validation. + } + + public function setCurrentTheme(Theme $currentTheme) + { + $this->currentTheme = $currentTheme; + } +} diff --git a/application/src/Form/ResourceBatchUpdateForm.php b/application/src/Form/ResourceBatchUpdateForm.php index 051425342e..81cf70ad0a 100644 --- a/application/src/Form/ResourceBatchUpdateForm.php +++ b/application/src/Form/ResourceBatchUpdateForm.php @@ -367,7 +367,7 @@ public function preprocessData() if (isset($data['clear_property_values'])) { $preData['remove']['clear_property_values'] = $data['clear_property_values']; } - if (isset($data['set_value_visibility'])) { + if (!empty($data['set_value_visibility'])) { $preData['remove']['set_value_visibility'] = $data['set_value_visibility']; } if (!empty($data['clear_language'])) { diff --git a/application/src/Form/SettingForm.php b/application/src/Form/SettingForm.php index 67fcced0eb..9e7b98f45c 100644 --- a/application/src/Form/SettingForm.php +++ b/application/src/Form/SettingForm.php @@ -64,6 +64,7 @@ class SettingForm extends Form 'image/pjpeg', 'image/png', 'image/tiff', + 'image/webp', 'image/x-icon', // text/* 'text/css', @@ -91,8 +92,8 @@ class SettingForm extends Form 'mp2', 'mp3', 'mp4', 'mpa', 'mpe', 'mpeg', 'mpg', 'mpp', 'odb', 'odc', 'odf', 'odg', 'odp', 'ods', 'odt', 'ogg', 'opus', 'pdf', 'png', 'pot', 'pps', 'ppt', 'pptx', 'qt', 'ra', 'ram', 'rtf', 'rtx', 'swf', 'tar', 'tif', - 'tiff', 'txt', 'wav', 'wax', 'webm', 'wma', 'wmv', 'wmx', 'wri', 'xla', 'xls', - 'xlsx', 'xlt', 'xlw', 'zip', + 'tiff', 'txt', 'wav', 'wax', 'webm', 'webp', 'wma', 'wmv', 'wmx', 'wri', 'xla', + 'xls', 'xlsx', 'xlt', 'xlw', 'zip', ]; /** @@ -104,6 +105,9 @@ public function init() { $this->setOption('element_groups', [ 'general' => 'General', // @translate + 'display' => 'Display', // @translate + 'editing' => 'Editing', // @translate + 'search' => 'Search', // @translate 'security' => 'Security', // @translate ]); @@ -154,11 +158,69 @@ public function init() ], ]); + $this->add([ + 'name' => 'locale', + 'type' => 'Omeka\Form\Element\LocaleSelect', + 'options' => [ + 'element_group' => 'general', + 'label' => 'Locale', // @translate + 'info' => 'Global locale/language code for all interfaces.', // @translate + ], + 'attributes' => [ + 'value' => $this->settings->get('locale'), + 'class' => 'chosen-select', + 'id' => 'locale', + ], + ]); + + $this->add([ + 'name' => 'version_notifications', + 'type' => 'Checkbox', + 'options' => [ + 'element_group' => 'general', + 'label' => 'Enable version notifications', // @translate + 'info' => 'Enable notifications when a new version of Omeka S, modules, or themes are available.', // @translate + ], + 'attributes' => [ + 'value' => $this->settings->get('version_notifications'), + 'id' => 'version_notifications', + ], + ]); + + $this->add([ + 'type' => 'checkbox', + 'name' => 'disable_jsonld_reverse', + 'options' => [ + 'element_group' => 'general', + 'label' => 'Disable JSON-LD @reverse', // @translate + 'info' => 'Disable JSON-LD reverse properties in the API output for resources.', // @translate + ], + 'attributes' => [ + 'value' => $this->settings->get('disable_jsonld_reverse'), + 'id' => 'disable-jsonld-reverse', + ], + ]); + + $this->add([ + 'name' => 'favicon', + 'type' => 'Omeka\Form\Element\Asset', + 'options' => [ + 'element_group' => 'general', + 'label' => 'Favicon', // @translate + ], + 'attributes' => [ + 'value' => $this->settings->get('favicon'), + 'id' => 'favicon', + ], + ]); + + // Display element group + $this->add([ 'name' => 'pagination_per_page', 'type' => 'Text', 'options' => [ - 'element_group' => 'general', + 'element_group' => 'display', 'label' => 'Results per page', // @translate 'info' => 'The maximum number of results per page on browse pages.', // @translate ], @@ -173,7 +235,7 @@ public function init() 'name' => 'property_label_information', 'type' => 'Select', 'options' => [ - 'element_group' => 'general', + 'element_group' => 'display', 'label' => 'Property label information', // @translate 'info' => 'The additional information that accompanies labels on resource pages.', // @translate 'value_options' => [ @@ -192,7 +254,7 @@ public function init() 'name' => 'default_site', 'type' => SiteSelect::class, 'options' => [ - 'element_group' => 'general', + 'element_group' => 'display', 'label' => 'Default site', // @translate 'info' => 'Select which site should appear when users go to the front page of the installation.', // @translate 'empty_option' => '', @@ -206,40 +268,11 @@ public function init() ], ]); - $this->add([ - 'name' => 'locale', - 'type' => 'Omeka\Form\Element\LocaleSelect', - 'options' => [ - 'element_group' => 'general', - 'label' => 'Locale', // @translate - 'info' => 'Global locale/language code for all interfaces.', // @translate - ], - 'attributes' => [ - 'value' => $this->settings->get('locale'), - 'class' => 'chosen-select', - 'id' => 'locale', - ], - ]); - - $this->add([ - 'name' => 'version_notifications', - 'type' => 'Checkbox', - 'options' => [ - 'element_group' => 'general', - 'label' => 'Enable version notifications', // @translate - 'info' => 'Enable notifications when a new version of Omeka S, modules, or themes are available.', // @translate - ], - 'attributes' => [ - 'value' => $this->settings->get('version_notifications'), - 'id' => 'version_notifications', - ], - ]); - $this->add([ 'name' => 'disable_jsonld_embed', 'type' => 'Checkbox', 'options' => [ - 'element_group' => 'general', + 'element_group' => 'display', 'label' => 'Disable JSON-LD embed', // @translate 'info' => 'By default, Omeka embeds JSON-LD in resource browse and show pages for the purpose of machine-readable metadata discovery. Check this to disable embedding.', // @translate ], @@ -249,11 +282,13 @@ public function init() ], ]); + // Editing element group + $this->add([ 'name' => 'default_to_private', 'type' => 'Checkbox', 'options' => [ - 'element_group' => 'general', + 'element_group' => 'editing', 'label' => 'Default content visibility to Private', // @translate 'info' => 'If checked, all items, item sets and sites newly created will have their visibility set to private by default.', // @translate ], @@ -267,7 +302,7 @@ public function init() 'name' => 'value_languages', 'type' => ArrayTextarea::class, 'options' => [ - 'element_group' => 'general', + 'element_group' => 'editing', 'label' => 'Suggested languages for values', // @translate 'info' => 'List of languages to facilitate filling of the values in the resource form. List them one by line. The label displayed for a language may be appended with a "=".', // @translate 'as_key_value' => true, @@ -282,7 +317,7 @@ public function init() 'name' => 'media_alt_text_property', 'type' => PropertySelect::class, 'options' => [ - 'element_group' => 'general', + 'element_group' => 'editing', 'label' => 'Media alt text property', // @translate 'info' => 'Media property to use as alt text if no alt text is explicitly set.', // @translate 'empty_option' => '[None]', // @translate @@ -295,11 +330,13 @@ public function init() ], ]); + // Search element group + $this->add([ 'name' => 'index_fulltext_search', 'type' => 'Checkbox', 'options' => [ - 'element_group' => 'general', + 'element_group' => 'search', 'label' => 'Index full-text search', // @translate ], 'attributes' => [ diff --git a/application/src/Form/SitePageForm.php b/application/src/Form/SitePageForm.php index 757e1adbf0..9f5e36c3af 100644 --- a/application/src/Form/SitePageForm.php +++ b/application/src/Form/SitePageForm.php @@ -2,9 +2,12 @@ namespace Omeka\Form; use Laminas\Form\Form; +use Omeka\Site\Theme\Theme; class SitePageForm extends Form { + protected $currentTheme; + public function init() { $this->setAttribute('id', 'site-page-form'); @@ -40,5 +43,12 @@ public function init() ], ]); } + + $inputFilter = $this->getInputFilter(); + } + + public function setCurrentTheme(Theme $currentTheme) + { + $this->currentTheme = $currentTheme; } } diff --git a/application/src/Form/SiteSettingsForm.php b/application/src/Form/SiteSettingsForm.php index 9bdfb58b13..97f7f74356 100644 --- a/application/src/Form/SiteSettingsForm.php +++ b/application/src/Form/SiteSettingsForm.php @@ -80,24 +80,6 @@ public function init() 'value' => $settings->get('show_page_pagination', true), ], ]); - $this->add([ - 'name' => 'property_label_information', - 'type' => 'Select', - 'options' => [ - 'element_group' => 'general', - 'label' => 'Property label information', // @translate - 'info' => 'The additional information that accompanies labels on resource pages.', // @translate - 'value_options' => [ - 'none' => 'None', // @translate - 'vocab' => 'Show Vocabulary', // @translate - 'term' => 'Show Term', // @translate - ], - ], - 'attributes' => [ - 'id' => 'property_label_information', - 'value' => $settings->get('property_label_information', 'none'), - ], - ]); $this->add([ 'name' => 'show_user_bar', 'type' => 'radio', @@ -127,6 +109,35 @@ public function init() 'id' => 'disable_jsonld_embed', ], ]); + $this->add([ + 'name' => 'favicon', + 'type' => 'Omeka\Form\Element\Asset', + 'options' => [ + 'element_group' => 'general', + 'label' => 'Favicon', // @translate + ], + 'attributes' => [ + 'value' => $settings->get('favicon'), + 'id' => 'favicon', + ], + ]); + $this->add([ + 'name' => 'subnav_display', + 'type' => 'select', + 'options' => [ + 'element_group' => 'general', + 'label' => 'Page subnavigation display', // @translate + 'empty_option' => 'Hide on leaf pages (default)', // @translate + 'value_options' => [ + 'hide' => 'Hide on all pages', // @translate + 'show' => 'Show on all pages', // @translate + ], + ], + 'attributes' => [ + 'value' => $settings->get('subnav_display'), + 'id' => 'disable_jsonld_embed', + ], + ]); // Language section $this->add([ @@ -265,6 +276,24 @@ public function init() 'value' => (bool) $settings->get('show_attached_pages', true), ], ]); + $this->add([ + 'name' => 'property_label_information', + 'type' => 'Select', + 'options' => [ + 'element_group' => 'show', + 'label' => 'Property label information', // @translate + 'info' => 'The additional information that accompanies labels on resource pages.', // @translate + 'value_options' => [ + 'none' => 'None', // @translate + 'vocab' => 'Show Vocabulary', // @translate + 'term' => 'Show Term', // @translate + ], + ], + 'attributes' => [ + 'id' => 'property_label_information', + 'value' => $settings->get('property_label_information', 'none'), + ], + ]); $this->add([ 'name' => 'show_value_annotations', 'type' => 'select', @@ -403,6 +432,10 @@ public function init() 'name' => 'locale', 'allow_empty' => true, ]); + $inputFilter->add([ + 'name' => 'subnav_display', + 'allow_empty' => true, + ]); $inputFilter->add([ 'name' => 'pagination_per_page', 'required' => false, diff --git a/application/src/Form/View/Helper/FormBackground.php b/application/src/Form/View/Helper/FormBackground.php new file mode 100644 index 0000000000..f850f8748b --- /dev/null +++ b/application/src/Form/View/Helper/FormBackground.php @@ -0,0 +1,18 @@ +render($element); + } + + public function render(ElementInterface $element) + { + return $this->getView()->partial('common/background-form', ['element' => $element]); + } +} diff --git a/application/src/Form/VocabularyForm.php b/application/src/Form/VocabularyForm.php index 2ffe9fe75f..7dbf799991 100644 --- a/application/src/Form/VocabularyForm.php +++ b/application/src/Form/VocabularyForm.php @@ -5,8 +5,10 @@ class VocabularyForm extends Form { + protected $translator; + protected $options = [ - 'include_namespace' => false, + 'vocabulary' => null, ]; public function __construct($name = null, $options = []) @@ -16,6 +18,8 @@ public function __construct($name = null, $options = []) public function init() { + $vocabulary = $this->getOption('vocabulary'); + $this->setAttribute('id', 'vocabulary-form'); $this->add([ 'name' => 'vocabulary-info', 'type' => 'fieldset', @@ -61,19 +65,23 @@ public function init() 'id' => 'o:comment', ], ]); - if ($this->getOption('include_namespace')) { - $this->get('vocabulary-info')->add([ - 'name' => 'o:namespace_uri', - 'type' => 'text', - 'options' => [ - 'label' => 'Namespace URI', // @translate - 'info' => 'Enter the unique namespace URI used to identify the classes and properties of the vocabulary.', // @translate - ], - 'attributes' => [ - 'required' => true, - 'id' => 'o:namespace_uri', - ], - ]); + $this->get('vocabulary-info')->add([ + 'name' => 'o:namespace_uri', + 'type' => 'text', + 'options' => [ + 'label' => 'Namespace URI', // @translate + 'info' => 'Enter the unique namespace URI used to identify the classes and properties of the vocabulary.', // @translate + ], + 'attributes' => [ + 'required' => true, + 'id' => 'o:namespace_uri', + 'placeholder' => $vocabulary ? $vocabulary->namespaceUri() : null, + 'data-confirm-ends-with' => $this->translator->translate('The namespace URI you entered does not end with a / or #, as is normally expected for namespace URIs. Would you like to save anyway?'), + 'data-confirm-change' => $this->translator->translate('The namespace URI you entered does not match the saved namespace URI. Would you like to save anyway?'), + 'data-original-namespace-uri' => $vocabulary ? $vocabulary->namespaceUri() : null, + ], + ]); + if (!$vocabulary) { $this->get('vocabulary-info')->add([ 'name' => 'o:prefix', 'type' => 'text', @@ -87,26 +95,41 @@ public function init() ], ]); } + $this->get('vocabulary-file')->add([ + 'name' => 'import_type', + 'type' => 'radio', + 'options' => [ + 'label' => 'Import type', // @translate + 'value_options' => [ + 'upload' => 'Upload', // @translate + 'url' => 'URL', // @translate + ], + ], + 'attributes' => [ + 'value' => 'upload', + 'class' => 'import-type-select', + ], + ]); $this->get('vocabulary-file')->add([ 'name' => 'file', 'type' => 'file', 'options' => [ - 'label' => 'Vocabulary file', // @translate - 'info' => 'Choose a RDF vocabulary file. You must choose a file or enter a URL below.', // @translate + 'label' => 'File upload', // @translate + 'info' => 'Choose a RDF vocabulary file.', // @translate ], 'attributes' => [ - 'id' => 'file', + 'id' => 'file-upload', ], ]); $this->get('vocabulary-file')->add([ 'name' => 'url', 'type' => 'url', 'options' => [ - 'label' => 'Vocabulary URL', // @translate - 'info' => 'Enter a RDF vocabulary URL. You must enter a URL or choose a file above.', // @translate + 'label' => 'File URL', // @translate + 'info' => 'Enter a URL to a RDF vocabulary file.', // @translate ], 'attributes' => [ - 'id' => 'url', + 'id' => 'file-url', ], ]); $this->get('vocabulary-file')->add([ @@ -120,6 +143,10 @@ public function init() 'ntriples' => 'N-Triples (.nt)', // @translate 'rdfxml' => 'RDF/XML (.rdf)', // @translate 'turtle' => 'Turtle (.ttl)', // @translate + [ + 'value' => 'turtle', + 'label' => 'Notation3 (.n3)', // @translate + ], ], ], 'attributes' => [ @@ -182,4 +209,9 @@ public function init() ], ]); } + + public function setTranslator($translator) + { + $this->translator = $translator; + } } diff --git a/application/src/Installation/Task/AddDefaultSettingsTask.php b/application/src/Installation/Task/AddDefaultSettingsTask.php index e691c4b7c1..97c5e09c6d 100644 --- a/application/src/Installation/Task/AddDefaultSettingsTask.php +++ b/application/src/Installation/Task/AddDefaultSettingsTask.php @@ -14,6 +14,7 @@ class AddDefaultSettingsTask implements TaskInterface 'media_type_whitelist' => SettingForm::MEDIA_TYPE_WHITELIST, 'extension_whitelist' => SettingForm::EXTENSION_WHITELIST, 'version_notifications' => '1', + 'use_htmlpurifier' => '1', ]; public function perform(Installer $installer) diff --git a/application/src/Job/IndexFulltextSearch.php b/application/src/Job/IndexFulltextSearch.php index a30dff6d65..8b1dd235e6 100644 --- a/application/src/Job/IndexFulltextSearch.php +++ b/application/src/Job/IndexFulltextSearch.php @@ -2,6 +2,7 @@ namespace Omeka\Job; use Omeka\Api\Adapter\FulltextSearchableInterface; +use Omeka\Api\Adapter\ResourceAdapter; use Omeka\Api\Adapter\ValueAnnotationAdapter; class IndexFulltextSearch extends AbstractJob @@ -14,12 +15,23 @@ public function perform() $services = $this->getServiceLocator(); $api = $services->get('Omeka\ApiManager'); $em = $services->get('Omeka\EntityManager'); + $conn = $services->get('Omeka\Connection'); $fulltext = $services->get('Omeka\FulltextSearch'); $adapters = $services->get('Omeka\ApiAdapterManager'); + + // First delete all rows from the fulltext table to clear out the + // resources that don't belong. + $conn->executeStatement('DELETE FROM `fulltext_search`'); + + // Then iterate through all resource types and index the ones that are + // fulltext searchable. Note that we don't index "resource" and "value + // annotation" resources. foreach ($adapters->getRegisteredNames() as $adapterName) { $adapter = $adapters->get($adapterName); if ($adapter instanceof FulltextSearchableInterface - && !($adapter instanceof ValueAnnotationAdapter)) { + && !($adapter instanceof ResourceAdapter) + && !($adapter instanceof ValueAnnotationAdapter) + ) { $page = 1; do { if ($this->shouldStop()) { diff --git a/application/src/Media/Ingester/Upload.php b/application/src/Media/Ingester/Upload.php index 2f8a43da5e..1f609901e8 100644 --- a/application/src/Media/Ingester/Upload.php +++ b/application/src/Media/Ingester/Upload.php @@ -5,7 +5,6 @@ use Omeka\Entity\Media; use Omeka\File\Uploader; use Omeka\Stdlib\ErrorStore; -use Laminas\Form\Element\File; use Laminas\View\Renderer\PhpRenderer; class Upload implements IngesterInterface @@ -64,16 +63,24 @@ public function ingest(Media $media, Request $request, ErrorStore $errorStore) public function form(PhpRenderer $view, array $options = []) { - $fileInput = new File('file[__index__]'); - $fileInput->setOptions([ - 'label' => 'Upload file', // @translate - 'info' => $view->uploadLimit(), - ]); - $fileInput->setAttributes([ - 'id' => 'media-file-input-__index__', - 'required' => true, - ]); - $field = $view->formRow($fileInput); - return $field . ''; + $infoTemplate = ' +
    +
    +
    +
    '; + return ' +
    +
    + + +
    +
    ' . $view->uploadLimit() . '
    +
    +
    +
    + + +
    +
    '; } } diff --git a/application/src/Media/Renderer/FulltextSearchableInterface.php b/application/src/Media/Renderer/FulltextSearchableInterface.php new file mode 100644 index 0000000000..5b0d5a10cb --- /dev/null +++ b/application/src/Media/Renderer/FulltextSearchableInterface.php @@ -0,0 +1,15 @@ +mediaData(); return $data['html']; } + + public function getFulltextText(MediaRepresentation $media) + { + $data = $media->mediaData(); + return strip_tags($data['html']); + } } diff --git a/application/src/Mvc/Controller/Plugin/FallbackSettings.php b/application/src/Mvc/Controller/Plugin/FallbackSettings.php new file mode 100644 index 0000000000..76f978c3cf --- /dev/null +++ b/application/src/Mvc/Controller/Plugin/FallbackSettings.php @@ -0,0 +1,20 @@ +fallbackSettings = $fallbackSettings; + } + + public function __invoke() + { + return $this->fallbackSettings; + } +} diff --git a/application/src/Mvc/Controller/Plugin/Paginator.php b/application/src/Mvc/Controller/Plugin/Paginator.php index 3f5496d5f0..ce4ebd204e 100644 --- a/application/src/Mvc/Controller/Plugin/Paginator.php +++ b/application/src/Mvc/Controller/Plugin/Paginator.php @@ -36,7 +36,6 @@ public function __invoke($totalCount, $currentPage = null, $perPage = null, $par { // Fetch variables from the query if none provided. $query = $this->getController()->getRequest()->getQuery(); - $query->set('sort_by', (!isset($query['sort_by_default']) && isset($query['sort_by'])) ? $query['sort_by'] : ''); $currentPage = $currentPage ?: $query->get('page', $currentPage); $perPage = $perPage ?: $query->get('per_page', $perPage); diff --git a/application/src/Mvc/Controller/Plugin/SetBrowseDefaults.php b/application/src/Mvc/Controller/Plugin/SetBrowseDefaults.php index 724f2084a7..0d5b7b1540 100644 --- a/application/src/Mvc/Controller/Plugin/SetBrowseDefaults.php +++ b/application/src/Mvc/Controller/Plugin/SetBrowseDefaults.php @@ -19,6 +19,7 @@ class SetBrowseDefaults extends AbstractPlugin public function __invoke($sortBy, $sortOrder = 'desc', $page = 1) { $query = $this->getController()->getRequest()->getQuery(); + // Set the sort_by_default flag if the request doesn't pass a sort_by. $query->set('sort_by_default', (null === $query->get('sort_by') || '' === $query->get('sort_by')) ? '' : null); $query->set('sort_by', $query->get('sort_by', $sortBy)); $query->set('sort_order', $query->get('sort_order', $sortOrder)); diff --git a/application/src/Mvc/MvcListeners.php b/application/src/Mvc/MvcListeners.php index 8c773ca316..785cb56e15 100644 --- a/application/src/Mvc/MvcListeners.php +++ b/application/src/Mvc/MvcListeners.php @@ -260,7 +260,7 @@ public function redirectToLogin(MvcEvent $event) public function authenticateApiKey(MvcEvent $event) { $routeMatch = $event->getRouteMatch(); - if (!$routeMatch->getParam('__API__')) { + if (!$routeMatch->getParam('__KEYAUTH__')) { // This is not an API request. return; } diff --git a/application/src/Mvc/Status.php b/application/src/Mvc/Status.php index 91548bd5fe..75d0c18801 100644 --- a/application/src/Mvc/Status.php +++ b/application/src/Mvc/Status.php @@ -22,6 +22,11 @@ class Status */ protected $isApiRequest; + /** + * @var bool + */ + protected $isKeyauthRequest; + /** * @var bool */ @@ -105,6 +110,20 @@ public function isApiRequest() return $this->isApiRequest; } + /** + * Check whether the current HTTP request requires key authentication (api). + * + * @return bool + */ + public function isKeyauthRequest() + { + if (isset($this->isKeyauthRequest)) { + return $this->isKeyauthRequest; + } + $this->isKeyauthRequest = (bool) $this->getRouteParam('__KEYAUTH__'); + return $this->isKeyauthRequest; + } + /** * Check whether the current HTTP request is an admin request. * diff --git a/application/src/Service/AuthenticationServiceFactory.php b/application/src/Service/AuthenticationServiceFactory.php index 2088b3dbac..1c4b3b2aa6 100644 --- a/application/src/Service/AuthenticationServiceFactory.php +++ b/application/src/Service/AuthenticationServiceFactory.php @@ -36,8 +36,8 @@ public function __invoke(ContainerInterface $serviceLocator, $requestedName, arr }); } else { $userRepository = $entityManager->getRepository('Omeka\Entity\User'); - if ($status->isApiRequest()) { - // Authenticate using key for API requests. + if ($status->isKeyauthRequest()) { + // Authenticate using key for requests that require key authentication. $keyRepository = $entityManager->getRepository('Omeka\Entity\ApiKey'); $storage = new DoctrineWrapper(new NonPersistent, $userRepository); $adapter = new KeyAdapter($keyRepository, $entityManager); diff --git a/application/src/Service/Controller/Site/PageControllerFactory.php b/application/src/Service/Controller/Site/PageControllerFactory.php new file mode 100644 index 0000000000..e850b67660 --- /dev/null +++ b/application/src/Service/Controller/Site/PageControllerFactory.php @@ -0,0 +1,15 @@ +get('Omeka\Site\ThemeManager')->getCurrentTheme(); + return new PageController($currentTheme); + } +} diff --git a/application/src/Service/ControllerPlugin/FallbackSettingsFactory.php b/application/src/Service/ControllerPlugin/FallbackSettingsFactory.php new file mode 100644 index 0000000000..0fc2dd9ccd --- /dev/null +++ b/application/src/Service/ControllerPlugin/FallbackSettingsFactory.php @@ -0,0 +1,14 @@ +get('Omeka\Settings\Fallback')); + } +} diff --git a/application/src/Service/Delegator/FormElementDelegatorFactory.php b/application/src/Service/Delegator/FormElementDelegatorFactory.php index 1d6301443b..d1848bb5c5 100644 --- a/application/src/Service/Delegator/FormElementDelegatorFactory.php +++ b/application/src/Service/Delegator/FormElementDelegatorFactory.php @@ -22,6 +22,7 @@ public function __invoke(ContainerInterface $container, $name, $formElement->addClass('Omeka\Form\Element\Query', 'formQuery'); $formElement->addClass('Omeka\Form\Element\Columns', 'formColumns'); $formElement->addClass('Omeka\Form\Element\BrowseDefaults', 'formBrowseDefaults'); + $formElement->addClass('Omeka\Form\Element\Background', 'formBackground'); return $formElement; } } diff --git a/application/src/Service/Delegator/FormSelectDelegatorFactory.php b/application/src/Service/Delegator/FormSelectDelegatorFactory.php index fffed49a50..2c73fbc8b8 100644 --- a/application/src/Service/Delegator/FormSelectDelegatorFactory.php +++ b/application/src/Service/Delegator/FormSelectDelegatorFactory.php @@ -10,6 +10,7 @@ public function __invoke(ContainerInterface $container, $name, callable $callback, array $options = null ) { $formSelect = $callback(); + $formSelect->addTranslatableAttribute('aria-label'); // The data-placeholder attribute is used by Chosen to display default // field text. This will make sure that attribute is translated. $formSelect->addTranslatableAttribute('data-placeholder'); diff --git a/application/src/Service/EntityManagerFactory.php b/application/src/Service/EntityManagerFactory.php index e25e67b30d..0ad7164b21 100644 --- a/application/src/Service/EntityManagerFactory.php +++ b/application/src/Service/EntityManagerFactory.php @@ -81,7 +81,14 @@ public function __invoke(ContainerInterface $serviceLocator, $requestedName, arr $emConfig->addFilter($name, $className); } - // Add user defined functions. + // Add custom data types. + foreach ($config['entity_manager']['data_types'] as $name => $className) { + if (!Type::hasType($name)) { + Type::addType($name, $className); + } + } + + // Add custom functions. $emConfig->setCustomNumericFunctions($config['entity_manager']['functions']['numeric']); $emConfig->setCustomStringFunctions($config['entity_manager']['functions']['string']); $emConfig->setCustomDatetimeFunctions($config['entity_manager']['functions']['datetime']); @@ -102,6 +109,7 @@ public function __invoke(ContainerInterface $serviceLocator, $requestedName, arr new ResourceDiscriminatorMap($config['entity_manager']['resource_discriminator_map']) ); $em->getEventManager()->addEventSubscriber(new Entity($serviceLocator->get('EventManager'))); + // Instantiate the visibility filters and inject the service locator. $em->getFilters()->enable('resource_visibility'); $em->getFilters()->getFilter('resource_visibility')->setServiceLocator($serviceLocator); @@ -110,11 +118,6 @@ public function __invoke(ContainerInterface $serviceLocator, $requestedName, arr $em->getFilters()->enable('site_page_visibility'); $em->getFilters()->getFilter('site_page_visibility')->setServiceLocator($serviceLocator); - // Register a custom mapping type for an IP address. - if (!Type::hasType('ip_address')) { - Type::addType('ip_address', 'Omeka\Db\Type\IpAddress'); - } - return $em; } } diff --git a/application/src/Service/Form/BlockLayoutDataFormFactory.php b/application/src/Service/Form/BlockLayoutDataFormFactory.php new file mode 100644 index 0000000000..eeefb7861f --- /dev/null +++ b/application/src/Service/Form/BlockLayoutDataFormFactory.php @@ -0,0 +1,17 @@ +setCurrentTheme($services->get('Omeka\Site\ThemeManager')->getCurrentTheme()); + $form->setViewHelpers($services->get('ViewHelperManager')); + return $form; + } +} diff --git a/application/src/Service/Form/PageLayoutDataFormFactory.php b/application/src/Service/Form/PageLayoutDataFormFactory.php new file mode 100644 index 0000000000..687e3940cf --- /dev/null +++ b/application/src/Service/Form/PageLayoutDataFormFactory.php @@ -0,0 +1,16 @@ +setCurrentTheme($services->get('Omeka\Site\ThemeManager')->getCurrentTheme()); + return $form; + } +} diff --git a/application/src/Service/Form/SitePageFormFactory.php b/application/src/Service/Form/SitePageFormFactory.php new file mode 100644 index 0000000000..032000a36a --- /dev/null +++ b/application/src/Service/Form/SitePageFormFactory.php @@ -0,0 +1,16 @@ +setCurrentTheme($services->get('Omeka\Site\ThemeManager')->getCurrentTheme()); + return $form; + } +} diff --git a/application/src/Service/Form/UserBatchUpdateFormFactory.php b/application/src/Service/Form/UserBatchUpdateFormFactory.php index 0be06430d1..e289380783 100644 --- a/application/src/Service/Form/UserBatchUpdateFormFactory.php +++ b/application/src/Service/Form/UserBatchUpdateFormFactory.php @@ -9,7 +9,7 @@ class UserBatchUpdateFormFactory implements FactoryInterface { public function __invoke(ContainerInterface $services, $requestedName, array $options = null) { - $form = new UserBatchUpdateForm(null, $options); + $form = new UserBatchUpdateForm(null, $options ?? []); $form->setEventManager($services->get('EventManager')); return $form; } diff --git a/application/src/Service/Form/VocabularyFormFactory.php b/application/src/Service/Form/VocabularyFormFactory.php new file mode 100644 index 0000000000..d09dfcf7b1 --- /dev/null +++ b/application/src/Service/Form/VocabularyFormFactory.php @@ -0,0 +1,17 @@ +setTranslator($services->get('MvcTranslator')); + $form->setOption('vocabulary', $options['vocabulary'] ?? null); + return $form; + } +} diff --git a/application/src/Service/FulltextSearchFactory.php b/application/src/Service/FulltextSearchFactory.php index 2c8a705ebb..34cfd27755 100644 --- a/application/src/Service/FulltextSearchFactory.php +++ b/application/src/Service/FulltextSearchFactory.php @@ -9,6 +9,6 @@ class FulltextSearchFactory implements FactoryInterface { public function __invoke(ContainerInterface $services, $requestedName, array $options = null) { - return new FulltextSearch($services->get('Omeka\EntityManager')); + return new FulltextSearch($services->get('Omeka\Connection')); } } diff --git a/application/src/Service/Settings/FallbackSettingsFactory.php b/application/src/Service/Settings/FallbackSettingsFactory.php new file mode 100644 index 0000000000..2d8763dda4 --- /dev/null +++ b/application/src/Service/Settings/FallbackSettingsFactory.php @@ -0,0 +1,18 @@ +get('Omeka\Settings'), + $serviceLocator->get('Omeka\Settings\Site'), + $serviceLocator->get('Omeka\Settings\User') + ); + } +} diff --git a/application/src/Service/ViewApiJsonRendererFactory.php b/application/src/Service/ViewApiJsonRendererFactory.php new file mode 100644 index 0000000000..2e0e15814d --- /dev/null +++ b/application/src/Service/ViewApiJsonRendererFactory.php @@ -0,0 +1,17 @@ +get('EventManager'); + $jsonRenderer = new ApiJsonRenderer($eventManager); + return $jsonRenderer; + } +} diff --git a/application/src/Service/ViewApiJsonStrategyFactory.php b/application/src/Service/ViewApiJsonStrategyFactory.php index feae4a6bb1..9d6b84c1b8 100644 --- a/application/src/Service/ViewApiJsonStrategyFactory.php +++ b/application/src/Service/ViewApiJsonStrategyFactory.php @@ -22,7 +22,8 @@ class ViewApiJsonStrategyFactory implements FactoryInterface public function __invoke(ContainerInterface $serviceLocator, $requestedName, array $options = null) { $jsonRenderer = $serviceLocator->get('Omeka\ViewApiJsonRenderer'); - $jsonStrategy = new ApiJsonStrategy($jsonRenderer); + $eventManager = $serviceLocator->get('EventManager'); + $jsonStrategy = new ApiJsonStrategy($jsonRenderer, $eventManager); return $jsonStrategy; } } diff --git a/application/src/Service/ViewHelper/BlockLayoutFactory.php b/application/src/Service/ViewHelper/BlockLayoutFactory.php index fbbfae1abd..caa7ca1465 100644 --- a/application/src/Service/ViewHelper/BlockLayoutFactory.php +++ b/application/src/Service/ViewHelper/BlockLayoutFactory.php @@ -18,6 +18,10 @@ class BlockLayoutFactory implements FactoryInterface */ public function __invoke(ContainerInterface $services, $requestedName, array $options = null) { - return new BlockLayout($services->get('Omeka\BlockLayoutManager')); + return new BlockLayout( + $services->get('Omeka\BlockLayoutManager'), + $services->get('EventManager'), + $services->get('Omeka\Site\ThemeManager')->getCurrentTheme() + ); } } diff --git a/application/src/Service/ViewHelper/FallbackSettingFactory.php b/application/src/Service/ViewHelper/FallbackSettingFactory.php new file mode 100644 index 0000000000..bdbf321b37 --- /dev/null +++ b/application/src/Service/ViewHelper/FallbackSettingFactory.php @@ -0,0 +1,15 @@ +get('Omeka\Settings\Fallback')); + } +} diff --git a/application/src/Service/ViewHelper/PageLayoutFactory.php b/application/src/Service/ViewHelper/PageLayoutFactory.php new file mode 100644 index 0000000000..8855aa5f88 --- /dev/null +++ b/application/src/Service/ViewHelper/PageLayoutFactory.php @@ -0,0 +1,15 @@ +get('EventManager')); + } +} diff --git a/application/src/Settings/FallbackSettings.php b/application/src/Settings/FallbackSettings.php new file mode 100644 index 0000000000..a9da298aad --- /dev/null +++ b/application/src/Settings/FallbackSettings.php @@ -0,0 +1,56 @@ +settings = $settings; + $this->siteSettings = $siteSettings; + $this->userSettings = $userSettings; + } + + /** + * Get a setting prioritized by source. + * + * Can select from the following sources: global, site, user. + * + * @param string $id The setting ID + * @param array $sources An array of setting sources in fallback order + * @param mixed $default The default value + * @return mixed + */ + public function get($id, array $sources, $default = null) + { + $setting = null; + foreach (array_unique($sources) as $source) { + switch ($source) { + case 'global': + $setting = $this->settings->get($id); + break; + case 'site': + try { + $setting = $this->siteSettings->get($id); + } catch (\Exception $e) { + // Not in a site context + } + break; + case 'user': + try { + $setting = $this->userSettings->get($id); + } catch (\Exception $e) { + // No authenticated user + } + break; + } + if (!(null === $setting || '' === $setting)) { + return $setting; + } + } + return $default; + } +} diff --git a/application/src/Site/BlockLayout/Asset.php b/application/src/Site/BlockLayout/Asset.php index 9b479b8ca6..95fde12417 100644 --- a/application/src/Site/BlockLayout/Asset.php +++ b/application/src/Site/BlockLayout/Asset.php @@ -7,10 +7,9 @@ use Omeka\Api\Representation\SitePageBlockRepresentation; use Omeka\Entity\SitePageBlock; use Omeka\Stdlib\ErrorStore; -use Laminas\Form\Element\Select; use Laminas\View\Renderer\PhpRenderer; -class Asset extends AbstractBlockLayout +class Asset extends AbstractBlockLayout implements TemplateableBlockLayoutInterface { public function getLabel() { @@ -28,31 +27,6 @@ public function onHydrate(SitePageBlock $block, ErrorStore $errorStore) $block->setData($data); } - public function alignmentClassSelect(PhpRenderer $view, SitePageBlockRepresentation $block = null - ) { - $alignmentLabels = [ - 'default', // @translate - 'float left', // @translate - 'float right', // @translate - 'center', // @translate - ]; - $alignmentValues = [ - 'default', // @translate - 'left', // @translate - 'right', // @translate - 'center', // @translate - ]; - $alignment = $block ? $block->dataValue('alignment', 'default') : 'default'; - $select = new Select('o:block[__blockIndex__][o:data][alignment]'); - $select->setValueOptions(array_combine($alignmentValues, $alignmentLabels))->setValue($alignment); - $selectLabel = 'Alignment'; // @translate - $select->setAttributes(['title' => $selectLabel, 'aria-label' => $selectLabel]); - $html = '
    '; - $html .= '
    '; - $html .= '
    ' . $view->formSelect($select) . '
    '; - return $html; - } - public function prepareAssetAttachments(PhpRenderer $view, $blockData, SiteRepresentation $site) { $attachments = []; @@ -93,27 +67,22 @@ public function form(PhpRenderer $view, SiteRepresentation $site, SitePageRepres $apiUrl = $site->apiUrl(); $blockData = ($block) ? $block->data() : ''; $attachments = $this->prepareAssetAttachments($view, $blockData, $site); - $alignmentClassSelect = $this->alignmentClassSelect($view, $block); return $view->partial('common/asset-block-form', [ 'block' => $blockData, 'siteId' => $siteId, 'apiUrl' => $apiUrl, 'attachments' => $attachments, - 'alignmentClassSelect' => $alignmentClassSelect, ]); } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/asset') { $blockData = ($block) ? $block->data() : ''; $site = $view->site; $attachments = $this->prepareAssetAttachments($view, $blockData, $site); - $customClass = $block->dataValue('className'); - $alignment = $block->dataValue('alignment'); - return $view->partial('common/block-layout/asset', [ - 'attachments' => $attachments, - 'className' => $customClass, - 'alignment' => $alignment, + return $view->partial($templateViewScript, [ + 'block' => $block, + 'attachments' => $attachments, ]); } } diff --git a/application/src/Site/BlockLayout/BrowsePreview.php b/application/src/Site/BlockLayout/BrowsePreview.php index fad3ff0ea7..02099c117b 100644 --- a/application/src/Site/BlockLayout/BrowsePreview.php +++ b/application/src/Site/BlockLayout/BrowsePreview.php @@ -9,7 +9,7 @@ use Laminas\Form\Form; use Laminas\View\Renderer\PhpRenderer; -class BrowsePreview extends AbstractBlockLayout +class BrowsePreview extends AbstractBlockLayout implements TemplateableBlockLayoutInterface { public function getLabel() { @@ -123,7 +123,7 @@ public function form(PhpRenderer $view, SiteRepresentation $site, return $view->formCollection($form); } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/browse-preview') { $resourceType = $block->dataValue('resource_type', 'items'); @@ -162,7 +162,8 @@ public function render(PhpRenderer $view, SitePageBlockRepresentation $block) 'media' => 'media', ]; - return $view->partial('common/block-layout/browse-preview', [ + return $view->partial($templateViewScript, [ + 'block' => $block, 'resourceType' => $resourceTypes[$resourceType], 'resources' => $resources, 'heading' => $block->dataValue('heading'), diff --git a/application/src/Site/BlockLayout/Html.php b/application/src/Site/BlockLayout/Html.php index e51b8efec8..158e7b4359 100644 --- a/application/src/Site/BlockLayout/Html.php +++ b/application/src/Site/BlockLayout/Html.php @@ -11,7 +11,7 @@ use Laminas\Form\Form; use Laminas\View\Renderer\PhpRenderer; -class Html extends AbstractBlockLayout +class Html extends AbstractBlockLayout implements TemplateableBlockLayoutInterface { /** * @var HtmlPurifier @@ -42,35 +42,17 @@ public function form(PhpRenderer $view, SiteRepresentation $site, $form = new Form(); $html = new Element\Textarea("o:block[__blockIndex__][o:data][html]"); $html->setAttribute('class', 'block-html full wysiwyg'); - $divClass = new Element\Text("o:block[__blockIndex__][o:data][divclass]"); - $divClass->setOptions([ - 'label' => 'Class', // @translate - 'info' => 'Optional CSS class for styling HTML.', // @translate - ]); if ($block) { $html->setValue($block->dataValue('html')); - $divClass->setValue($block->dataValue('divclass')); } $form->add($html); - $form->add($divClass); return $view->formCollection($form); } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/html') { - $htmlBlock = $block->dataValue('html', ''); - $divClass = $view->escapeHtml($block->dataValue('divclass')); - if (!empty($divClass)) { - //wrap HTML in div with specified class, if present - $htmlFinal = '
    '; - $htmlFinal .= $htmlBlock; - $htmlFinal .= '
    '; - } else { - $htmlFinal = $htmlBlock; - } - - return $htmlFinal; + return $view->partial($templateViewScript, ['block' => $block]); } public function getFulltextText(PhpRenderer $view, SitePageBlockRepresentation $block) diff --git a/application/src/Site/BlockLayout/ItemShowcase.php b/application/src/Site/BlockLayout/ItemShowcase.php index 7fd8a47d35..9a1fd57aa8 100644 --- a/application/src/Site/BlockLayout/ItemShowcase.php +++ b/application/src/Site/BlockLayout/ItemShowcase.php @@ -6,7 +6,7 @@ use Omeka\Api\Representation\SitePageBlockRepresentation; use Laminas\View\Renderer\PhpRenderer; -class ItemShowcase extends AbstractBlockLayout +class ItemShowcase extends AbstractBlockLayout implements TemplateableBlockLayoutInterface { public function getLabel() { @@ -28,7 +28,7 @@ public function form(PhpRenderer $view, SiteRepresentation $site, return $html; } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/item-showcase') { $attachments = $block->attachments(); if (!$attachments) { @@ -37,7 +37,7 @@ public function render(PhpRenderer $view, SitePageBlockRepresentation $block) $thumbnailType = $block->dataValue('thumbnail_type', 'square'); $showTitleOption = $block->dataValue('show_title_option', 'item_title'); - return $view->partial('common/block-layout/item-showcase', [ + return $view->partial($templateViewScript, [ 'block' => $block, 'attachments' => $attachments, 'thumbnailType' => $thumbnailType, diff --git a/application/src/Site/BlockLayout/ItemWithMetadata.php b/application/src/Site/BlockLayout/ItemWithMetadata.php index 8f398fd6f0..dbe23e55e2 100644 --- a/application/src/Site/BlockLayout/ItemWithMetadata.php +++ b/application/src/Site/BlockLayout/ItemWithMetadata.php @@ -6,7 +6,7 @@ use Omeka\Api\Representation\SitePageBlockRepresentation; use Laminas\View\Renderer\PhpRenderer; -class ItemWithMetadata extends AbstractBlockLayout +class ItemWithMetadata extends AbstractBlockLayout implements TemplateableBlockLayoutInterface { public function getLabel() { @@ -19,14 +19,15 @@ public function form(PhpRenderer $view, SiteRepresentation $site, return $view->blockAttachmentsForm($block, true); } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/item-with-metadata') { $attachments = $block->attachments(); if (!$attachments) { return 'No item selected'; // @translate } - return $view->partial('common/block-layout/item-with-metadata', [ + return $view->partial($templateViewScript, [ + 'block' => $block, 'attachments' => $attachments, ]); } diff --git a/application/src/Site/BlockLayout/LineBreak.php b/application/src/Site/BlockLayout/LineBreak.php index 9c03dbc0be..534417a1d7 100644 --- a/application/src/Site/BlockLayout/LineBreak.php +++ b/application/src/Site/BlockLayout/LineBreak.php @@ -7,7 +7,7 @@ use Omeka\Api\Representation\SitePageBlockRepresentation; use Laminas\View\Renderer\PhpRenderer; -class LineBreak extends AbstractBlockLayout +class LineBreak extends AbstractBlockLayout implements TemplateableBlockLayoutInterface { public function getLabel() { @@ -20,11 +20,9 @@ public function form(PhpRenderer $view, SiteRepresentation $site, return $this->breakTypeSelect($view, $site, $block); } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/line-break') { - $breakType = $block->dataValue('break_type'); - - return "
    "; + return $view->partial($templateViewScript, ['block' => $block]); } public function breakTypeSelect(PhpRenderer $view, SiteRepresentation $site, diff --git a/application/src/Site/BlockLayout/ListOfPages.php b/application/src/Site/BlockLayout/ListOfPages.php index 53b82c72fb..125f3aa38d 100644 --- a/application/src/Site/BlockLayout/ListOfPages.php +++ b/application/src/Site/BlockLayout/ListOfPages.php @@ -9,7 +9,7 @@ use Laminas\Form\Element\Hidden; use Laminas\View\Renderer\PhpRenderer; -class ListOfPages extends AbstractBlockLayout +class ListOfPages extends AbstractBlockLayout implements TemplateableBlockLayoutInterface { /** * @var LinkManager @@ -64,7 +64,7 @@ public function form(PhpRenderer $view, SiteRepresentation $site, return $html; } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/list-of-pages') { $nodes = json_decode($block->dataValue('pagelist'), true); if (!is_array($nodes)) { @@ -73,7 +73,8 @@ public function render(PhpRenderer $view, SitePageBlockRepresentation $block) $pageTree = $this->getPageNodeURLs($nodes, $block); - return $view->partial('common/block-layout/list-of-pages', [ + return $view->partial($templateViewScript, [ + 'block' => $block, 'pageList' => $pageTree, ]); } diff --git a/application/src/Site/BlockLayout/ListOfSites.php b/application/src/Site/BlockLayout/ListOfSites.php index a9bb6f5025..098d80bb19 100644 --- a/application/src/Site/BlockLayout/ListOfSites.php +++ b/application/src/Site/BlockLayout/ListOfSites.php @@ -8,7 +8,7 @@ use Laminas\Form\Form; use Laminas\View\Renderer\PhpRenderer; -class ListOfSites extends AbstractBlockLayout +class ListOfSites extends AbstractBlockLayout implements TemplateableBlockLayoutInterface { protected $defaults = [ 'sort' => 'alpha', @@ -112,7 +112,7 @@ public function form(PhpRenderer $view, SiteRepresentation $site, return $view->formCollection($form, false); } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/list-of-sites') { $sort = $block->dataValue('sort', $this->defaults['sort']); $limit = $block->dataValue('limit', $this->defaults['limit']); @@ -157,7 +157,8 @@ public function render(PhpRenderer $view, SitePageBlockRepresentation $block) $sites = $response->getContent(); - return $view->partial('common/block-layout/list-of-sites', [ + return $view->partial($templateViewScript, [ + 'block' => $block, 'sites' => $sites, 'pagination' => $pagination, 'summaries' => $summaries, diff --git a/application/src/Site/BlockLayout/Media.php b/application/src/Site/BlockLayout/Media.php index 83008d506e..d831ec1596 100644 --- a/application/src/Site/BlockLayout/Media.php +++ b/application/src/Site/BlockLayout/Media.php @@ -1,13 +1,12 @@

    ' . $view->translate('Options') . '

    '; $html .= '
    '; $html .= $view->blockThumbnailTypeSelect($block); - $html .= $this->alignmentClassSelect($view, $block); $html .= $view->blockShowTitleSelect($block); $html .= '
    '; return $html; } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/file') { $attachments = $block->attachments(); if (!$attachments) { return ''; } - $alignmentClass = $block->dataValue('alignment', 'left'); $thumbnailType = $block->dataValue('thumbnail_type', 'square'); $linkType = $view->siteSetting('attachment_link_type', 'item'); $showTitleOption = $block->dataValue('show_title_option', 'item_title'); - return $view->partial('common/block-layout/file', [ + return $view->partial($templateViewScript, [ 'block' => $block, 'attachments' => $attachments, - 'alignmentClass' => $alignmentClass, 'thumbnailType' => $thumbnailType, 'link' => $linkType, 'showTitleOption' => $showTitleOption, ]); } - - public function alignmentClassSelect(PhpRenderer $view, - SitePageBlockRepresentation $block = null - ) { - $alignmentLabels = ['float left', 'float right', 'center']; - $alignmentValues = ['left', 'right', 'center']; - $alignment = $block ? $block->dataValue('alignment', 'left') : 'left'; - $select = new Select('o:block[__blockIndex__][o:data][alignment]'); - $select->setValueOptions(array_combine($alignmentValues, $alignmentLabels))->setValue($alignment); - $selectLabel = 'Alignment'; // @translate - $select->setAttributes(['title' => $selectLabel, 'aria-label' => $selectLabel]); - $html = '
    '; - $html .= '
    '; - $html .= '
    ' . $view->formSelect($select) . '
    '; - return $html; - } } diff --git a/application/src/Site/BlockLayout/Oembed.php b/application/src/Site/BlockLayout/Oembed.php index 47723b6b2e..474cd73274 100644 --- a/application/src/Site/BlockLayout/Oembed.php +++ b/application/src/Site/BlockLayout/Oembed.php @@ -9,7 +9,7 @@ use Laminas\Form; use Laminas\View\Renderer\PhpRenderer; -class Oembed extends AbstractBlockLayout +class Oembed extends AbstractBlockLayout implements TemplateableBlockLayoutInterface { protected $oembed; @@ -118,9 +118,12 @@ public function form(PhpRenderer $view, SiteRepresentation $site, SitePageRepres ); } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/oembed') { - $data = $block->data() + $this->defaultData; - return sprintf('
    %s
    ', $this->oembed->renderOembed($view, $data['oembed'])); + return $view->partial($templateViewScript, [ + 'block' => $block, + 'oembed' => $this->oembed, + 'data' => $block->data() + $this->defaultData, + ]); } } diff --git a/application/src/Site/BlockLayout/PageDateTime.php b/application/src/Site/BlockLayout/PageDateTime.php index 6cdb274840..b7c912a005 100644 --- a/application/src/Site/BlockLayout/PageDateTime.php +++ b/application/src/Site/BlockLayout/PageDateTime.php @@ -7,7 +7,7 @@ use Laminas\Form; use Laminas\View\Renderer\PhpRenderer; -class PageDateTime extends AbstractBlockLayout +class PageDateTime extends AbstractBlockLayout implements TemplateableBlockLayoutInterface { protected $defaultData = [ 'display' => 'created_modified', @@ -72,9 +72,9 @@ public function form(PhpRenderer $view, SiteRepresentation $site, SitePageRepres return $view->formCollection($form, false); } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/page-date-time') { - return $view->partial('common/block-layout/page-date-time', [ + return $view->partial($templateViewScript, [ 'block' => $block, ]); } diff --git a/application/src/Site/BlockLayout/PageTitle.php b/application/src/Site/BlockLayout/PageTitle.php index 5efc4bf113..90c235072d 100644 --- a/application/src/Site/BlockLayout/PageTitle.php +++ b/application/src/Site/BlockLayout/PageTitle.php @@ -6,7 +6,7 @@ use Omeka\Api\Representation\SitePageBlockRepresentation; use Laminas\View\Renderer\PhpRenderer; -class PageTitle extends AbstractBlockLayout +class PageTitle extends AbstractBlockLayout implements TemplateableBlockLayoutInterface { public function getLabel() { @@ -19,9 +19,10 @@ public function form(PhpRenderer $view, SiteRepresentation $site, return $view->escapeHtml($page->title()); } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/page-title') { - return $view->partial('common/block-layout/page-title', [ + return $view->partial($templateViewScript, [ + 'block' => $block, 'pageTitle' => $block->page()->title(), ]); } diff --git a/application/src/Site/BlockLayout/TableOfContents.php b/application/src/Site/BlockLayout/TableOfContents.php index c4ff544d80..5d80c44cef 100644 --- a/application/src/Site/BlockLayout/TableOfContents.php +++ b/application/src/Site/BlockLayout/TableOfContents.php @@ -8,7 +8,7 @@ use Laminas\Form\Element\Number; use Laminas\View\Renderer\PhpRenderer; -class TableOfContents extends AbstractBlockLayout +class TableOfContents extends AbstractBlockLayout implements TemplateableBlockLayoutInterface { public function getLabel() { @@ -33,7 +33,7 @@ public function form(PhpRenderer $view, SiteRepresentation $site, return $html; } - public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + public function render(PhpRenderer $view, SitePageBlockRepresentation $block, $templateViewScript = 'common/block-layout/table-of-contents') { $view->pageViewModel->setVariable('displayNavigation', false); @@ -55,7 +55,7 @@ public function render(PhpRenderer $view, SitePageBlockRepresentation $block) $depth = $block->dataValue('depth', 1); - return $view->partial('common/block-layout/table-of-contents', [ + return $view->partial($templateViewScript, [ 'block' => $block, 'subNav' => $subNav, 'maxDepth' => $depth - 1, diff --git a/application/src/Site/BlockLayout/TemplateableBlockLayoutInterface.php b/application/src/Site/BlockLayout/TemplateableBlockLayoutInterface.php new file mode 100644 index 0000000000..f513cb13da --- /dev/null +++ b/application/src/Site/BlockLayout/TemplateableBlockLayoutInterface.php @@ -0,0 +1,10 @@ + 'uri', 'uri' => $data['url'], + 'target' => (isset($data['target_blank']) && $data['target_blank']) ? '_blank' : null, + ]; } @@ -48,6 +50,7 @@ public function toJstree(array $data, SiteRepresentation $site) return [ 'label' => $data['label'], 'url' => $data['url'], + 'target_blank' => $data['target_blank'] ?? false, ]; } } diff --git a/application/src/Site/ResourcePageBlockLayout/Manager.php b/application/src/Site/ResourcePageBlockLayout/Manager.php index b89afdb215..8461eefbf5 100644 --- a/application/src/Site/ResourcePageBlockLayout/Manager.php +++ b/application/src/Site/ResourcePageBlockLayout/Manager.php @@ -33,6 +33,7 @@ class Manager extends AbstractPluginManager ], 'media' => [ 'main' => [ + 'mediaRender', 'values', ], ], diff --git a/application/src/Stdlib/Environment.php b/application/src/Stdlib/Environment.php index c45cc2f95f..2c935e575a 100644 --- a/application/src/Stdlib/Environment.php +++ b/application/src/Stdlib/Environment.php @@ -14,13 +14,15 @@ class Environment /** * The MySQL minimum version + * @see https://dev.mysql.com/doc/relnotes/mysql/5.7/en/ */ - const MYSQL_MINIMUM_VERSION = '5.6.4'; + const MYSQL_MINIMUM_VERSION = '5.7.9'; /** * The MariaDB minimum version + * @see https://mariadb.com/kb/en/changes-improvements-in-mariadb-10-2/#list-of-all-mariadb-102-releases */ - const MARIADB_MINIMUM_VERSION = '10.0.5'; + const MARIADB_MINIMUM_VERSION = '10.2.6'; /** * The required PHP extensions diff --git a/application/src/Stdlib/FulltextSearch.php b/application/src/Stdlib/FulltextSearch.php index 2b72426f9e..8ec27a56f0 100644 --- a/application/src/Stdlib/FulltextSearch.php +++ b/application/src/Stdlib/FulltextSearch.php @@ -4,15 +4,15 @@ use Omeka\Api\Adapter\AdapterInterface; use Omeka\Api\Adapter\FulltextSearchableInterface; use Omeka\Api\ResourceInterface; -use Omeka\Entity\FulltextSearch as FulltextSearchEntity; +use PDO; class FulltextSearch { - protected $em; + protected $conn; - public function __construct($em) + public function __construct($conn) { - $this->em = $em; + $this->conn = $conn; } /** @@ -26,21 +26,26 @@ public function save(ResourceInterface $resource, AdapterInterface $adapter) if (!($adapter instanceof FulltextSearchableInterface)) { return; } - $searchId = $resource->getId(); - $searchResource = $adapter->getResourceName(); - $search = $this->em->find( - 'Omeka\Entity\FulltextSearch', - ['id' => $searchId, 'resource' => $searchResource] - ); - if (!$search) { - $search = new FulltextSearchEntity($searchId, $searchResource); - $this->em->persist($search); - } - $search->setOwner($adapter->getFulltextOwner($resource)); - $search->setIsPublic($adapter->getFulltextIsPublic($resource)); - $search->setTitle($adapter->getFulltextTitle($resource)); - $search->setText($adapter->getFulltextText($resource)); - $this->em->flush($search); + $resourceId = $resource->getId(); + $resourceName = $adapter->getResourceName(); + $owner = $adapter->getFulltextOwner($resource); + $ownerId = $owner ? $owner->getId() : null; + + $sql = 'INSERT INTO `fulltext_search` ( + `id`, `resource`, `owner_id`, `is_public`, `title`, `text` + ) VALUES ( + :id, :resource, :owner_id, :is_public, :title, :text + ) ON DUPLICATE KEY UPDATE + `owner_id` = :owner_id, `is_public` = :is_public, `title` = :title, `text` = :text'; + $stmt = $this->conn->prepare($sql); + + $stmt->bindValue('id', $resourceId, PDO::PARAM_INT); + $stmt->bindValue('resource', $resourceName, PDO::PARAM_STR); + $stmt->bindValue('owner_id', $ownerId, PDO::PARAM_INT); + $stmt->bindValue('is_public', $adapter->getFulltextIsPublic($resource), PDO::PARAM_BOOL); + $stmt->bindValue('title', $adapter->getFulltextTitle($resource), PDO::PARAM_STR); + $stmt->bindValue('text', $adapter->getFulltextText($resource), PDO::PARAM_STR); + $stmt->executeStatement(); } /** @@ -54,14 +59,13 @@ public function delete($resourceId, AdapterInterface $adapter) if (!($adapter instanceof FulltextSearchableInterface)) { return; } - $searchResource = $adapter->getResourceName(); - $search = $this->em->find( - 'Omeka\Entity\FulltextSearch', - ['id' => $resourceId, 'resource' => $searchResource] - ); - if ($search) { - $this->em->remove($search); - $this->em->flush($search); - } + $resourceName = $adapter->getResourceName(); + + $sql = 'DELETE FROM `fulltext_search` WHERE `id` = :id AND `resource` = :resource'; + $stmt = $this->conn->prepare($sql); + + $stmt->bindValue('id', $resourceId, PDO::PARAM_INT); + $stmt->bindValue('resource', $resourceName, PDO::PARAM_STR); + $stmt->executeStatement(); } } diff --git a/application/src/Stdlib/RdfImporter.php b/application/src/Stdlib/RdfImporter.php index 1e40934232..8b53ddfdf7 100644 --- a/application/src/Stdlib/RdfImporter.php +++ b/application/src/Stdlib/RdfImporter.php @@ -99,12 +99,12 @@ public function getMembers($strategy, $namespaceUri, array $options = []) } $file = $options['file']; if (!is_readable($file)) { - throw new ValidationException('File not readable.'); + throw new ValidationException('Could not read vocabulary file.'); } try { $graph->parseFile($file, $options['format'], $namespaceUri); } catch (\EasyRdf\Exception $e) { - throw new ValidationException($e->getMessage(), $e->getCode(), $e); + throw new ValidationException('Could not parse vocabulary file.'); } break; case 'url': @@ -115,7 +115,7 @@ public function getMembers($strategy, $namespaceUri, array $options = []) try { $graph->load($options['url'], $options['format']); } catch (\EasyRdf\Exception $e) { - throw new ValidationException($e->getMessage(), $e->getCode(), $e); + throw new ValidationException('Could not load vocabulary from URL.'); } break; default: @@ -335,8 +335,7 @@ protected function getMembersOfTypes(RdfGraph $graph, array $types, foreach ($types as $type) { foreach ($graph->allOfType($type) as $resource) { // The resource must be a local member of the vocabulary. - $output = strncmp($resource->getUri(), $namespaceUri, strlen($namespaceUri)); - if (0 === $output) { + if ($resource->getUri() === $namespaceUri . $resource->localName()) { $members[$resource->localName()] = [ 'label' => $this->getLabel($resource, $labelProperty, $lang, $resource->localName()), 'comment' => $this->getComment($resource, $commentProperty, $lang), diff --git a/application/src/View/Helper/BlockLayout.php b/application/src/View/Helper/BlockLayout.php index a9ffab4e55..31851737c4 100644 --- a/application/src/View/Helper/BlockLayout.php +++ b/application/src/View/Helper/BlockLayout.php @@ -5,6 +5,10 @@ use Omeka\Api\Representation\SitePageRepresentation; use Omeka\Api\Representation\SitePageBlockRepresentation; use Omeka\Site\BlockLayout\Manager as BlockLayoutManager; +use Omeka\Site\BlockLayout\TemplateableBlockLayoutInterface; +use Omeka\Site\Theme\Theme; +use Laminas\EventManager\Event; +use Laminas\EventManager\EventManager; use Laminas\View\Helper\AbstractHelper; /** @@ -22,9 +26,15 @@ class BlockLayout extends AbstractHelper */ protected $manager; - public function __construct(BlockLayoutManager $manager) + protected $eventManager; + + protected $currentTheme; + + public function __construct(BlockLayoutManager $manager, EventManager $eventManager, ?Theme $currentTheme) { $this->manager = $manager; + $this->eventManager = $eventManager; + $this->currentTheme = $currentTheme; } /** @@ -86,11 +96,13 @@ public function form($layout, SiteRepresentation $site = null, ) { $view = $this->getView(); $block = null; + $layoutData = []; if ($layout instanceof SitePageBlockRepresentation) { $block = $layout; $layout = $block->layout(); $page = $block->page(); $site = $page->site(); + $layoutData = $block->layoutData(); } $partialName = $partialName ?: self::PARTIAL_NAME; return $view->partial( @@ -98,6 +110,7 @@ public function form($layout, SiteRepresentation $site = null, [ 'layout' => $layout, 'layoutLabel' => $this->getLayoutLabel($layout), + 'layoutData' => $layoutData, 'blockContent' => $this->manager->get($layout)->form($this->getView(), $site, $page, $block), ] ); @@ -121,6 +134,123 @@ public function prepareRender($layout) */ public function render(SitePageBlockRepresentation $block) { - return $this->manager->get($block->layout())->render($this->getView(), $block); + $view = $this->getView(); + + // Allow modules to add classes for styling the layout. + $eventArgs = $this->eventManager->prepareArgs(['classes' => []]); + $this->eventManager->triggerEvent(new Event('block_layout.classes', $block, $eventArgs)); + $classes = $eventArgs['classes']; + + // Allow modules to add inline styles for styling the layout. + $eventArgs = $this->eventManager->prepareArgs(['inline_styles' => []]); + $this->eventManager->triggerEvent(new Event('block_layout.inline_styles', $block, $eventArgs)); + $inlineStyles = $eventArgs['inline_styles']; + + // Add classes and inline styles, if any. + $class = $block->layoutDataValue('class'); + if (is_string($class) && '' !== trim($class)) { + $classes[] = $class; + } + $alignment = $block->layoutDataValue('alignment'); + switch ($alignment) { + case 'left': + $classes[] = 'block-layout-alignment-left'; + break; + case 'right': + $classes[] = 'block-layout-alignment-right'; + break; + case 'center': + $classes[] = 'block-layout-alignment-center'; + break; + default: + // No alignment + } + $backgroundImageAsset = $block->layoutDataValue('background_image_asset'); + if ($backgroundImageAsset) { + $asset = $view->api()->searchOne('assets', ['id' => $backgroundImageAsset])->getContent(); + if ($asset) { + $inlineStyles[] = sprintf('background-image: url("%s");', $view->escapeCss($asset->assetUrl())); + } + } + $backgroundPositionY = $block->layoutDataValue('background_position_y'); + if ($backgroundPositionY) { + switch ($backgroundPositionY) { + case 'top': + $classes[] = 'block-layout-background-position-y-top'; + break; + case 'center': + $classes[] = 'block-layout-background-position-y-center'; + break; + case 'bottom': + $classes[] = 'block-layout-background-position-y-bottom'; + break; + default: + // No background position Y + } + } + $backgroundPositionX = $block->layoutDataValue('background_position_x'); + if ($backgroundPositionX) { + switch ($backgroundPositionX) { + case 'left': + $classes[] = 'block-layout-background-position-x-left'; + break; + case 'center': + $classes[] = 'block-layout-background-position-x-center'; + break; + case 'right': + $classes[] = 'block-layout-background-position-x-right'; + break; + default: + // No background position X + } + } + $backgroundSize = $block->layoutDataValue('background_size'); + if ($backgroundSize) { + switch ($backgroundSize) { + case 'cover': + $classes[] = 'block-layout-background-size-cover'; + break; + case 'contain': + $classes[] = 'block-layout-background-size-contain'; + break; + default: + // No background size + } + } + $minHeight = $block->layoutDataValue('min_height'); + if ($minHeight) { + $inlineStyles[] = sprintf('min-height: %spx', (int) $minHeight); + } + + $view = $this->getView(); + $blockLayout = $this->manager->get($block->layout()); + + // Set the configured block template, if any. + $templateName = $block->layoutDataValue('template_name'); + $templateViewScript = null; + if ($templateName && $blockLayout instanceof TemplateableBlockLayoutInterface) { + // Verify that the current theme provides this template. + $config = $this->currentTheme->getConfigSpec(); + if (isset($config['block_templates'][$block->layout()][$templateName])) { + $templateViewScript = sprintf('common/block-template/%s', $templateName); + } + } + + // Wrap block markup in a div only if the layout declares special + // styling via classes or inline styles. + if ($classes || $inlineStyles) { + return sprintf( + '
    %s
    ', + $view->escapeHtml(implode(' ', $classes)), + $view->escapeHtml(implode(' ', $inlineStyles)), + $templateViewScript + ? $blockLayout->render($this->getView(), $block, $templateViewScript) + : $blockLayout->render($this->getView(), $block) + ); + } + + return $templateViewScript + ? $blockLayout->render($this->getView(), $block, $templateViewScript) + : $blockLayout->render($this->getView(), $block); } } diff --git a/application/src/View/Helper/BlockThumbnailTypeSelect.php b/application/src/View/Helper/BlockThumbnailTypeSelect.php index ee39f45e62..3cdfcf4f4d 100644 --- a/application/src/View/Helper/BlockThumbnailTypeSelect.php +++ b/application/src/View/Helper/BlockThumbnailTypeSelect.php @@ -39,7 +39,7 @@ public function __invoke(SitePageBlockRepresentation $block = null) $type = $block->dataValue('thumbnail_type'); } - $selectLabel = $view->translate('Thumbnail type'); + $selectLabel = 'Thumbnail type'; // @translate $select = new Select('o:block[__blockIndex__][o:data][thumbnail_type]'); $select->setValueOptions(array_combine($this->thumbnailTypes, $this->thumbnailTypes))->setValue($type); $select->setAttributes(['title' => $selectLabel, 'aria-label' => $selectLabel]); diff --git a/application/src/View/Helper/Browse.php b/application/src/View/Helper/Browse.php index 2be2e19316..3ae49c2ed1 100644 --- a/application/src/View/Helper/Browse.php +++ b/application/src/View/Helper/Browse.php @@ -51,12 +51,14 @@ public function renderSortSelector($resourceTypeOrSortConfig) : string return ''; } $query = $view->params()->fromQuery(); - if (isset($query['fulltext_search']) && '' !== trim($query['fulltext_search'])) { + $isFulltextSearch = (isset($query['fulltext_search']) && '' !== trim($query['fulltext_search'])); + if ($isFulltextSearch) { + // Add "Relevance" to sort_by if this is a fulltext search. $sortConfig[''] = 'Relevance'; // @translate } $args = [ 'sortConfig' => $sortConfig, - 'sortByQuery' => isset($query['sort_by_default']) ? '' : $view->params()->fromQuery('sort_by'), + 'sortByQuery' => (isset($query['sort_by_default']) && $isFulltextSearch) ? '' : $view->params()->fromQuery('sort_by'), 'sortOrderQuery' => $view->params()->fromQuery('sort_order'), ]; $args = $view->trigger('view.sort-selector', $args, true); diff --git a/application/src/View/Helper/FallbackSetting.php b/application/src/View/Helper/FallbackSetting.php new file mode 100644 index 0000000000..7900ac2d58 --- /dev/null +++ b/application/src/View/Helper/FallbackSetting.php @@ -0,0 +1,20 @@ +fallbackSettings = $fallbackSettings; + } + + public function __invoke($id, array $sources, $default = null) + { + return $this->fallbackSettings->get($id, $sources, $default); + } +} diff --git a/application/src/View/Helper/LightGalleryOutput.php b/application/src/View/Helper/LightGalleryOutput.php index 4d4a607948..b711e88373 100644 --- a/application/src/View/Helper/LightGalleryOutput.php +++ b/application/src/View/Helper/LightGalleryOutput.php @@ -51,8 +51,8 @@ public function __invoke($files = null) if (isset($file['tracks'])) { foreach ($file['tracks'] as $key => $track) { $label = $track->displayTitle(); - $srclang = ($track->value('Dublin Core, Language')) ? $track->value('dcterms:language') : ''; - $type = ($track->value('Dublin Core, Type')) ? $track->value('dcterms:type') : 'captions'; + $srclang = (string) $track->value('dcterms:language', ['default' => '']); + $type = (string) $track->value('dcterms:type', ['default' => 'captions']); $videoSrcObject['tracks'][$key]['src'] = $track->originalUrl(); $videoSrcObject['tracks'][$key]['label'] = $label; $videoSrcObject['tracks'][$key]['srclang'] = $srclang; diff --git a/application/src/View/Helper/PageLayout.php b/application/src/View/Helper/PageLayout.php new file mode 100644 index 0000000000..0013787df5 --- /dev/null +++ b/application/src/View/Helper/PageLayout.php @@ -0,0 +1,89 @@ +eventManager = $eventManager; + } + + public function render(SitePageRepresentation $page) + { + $view = $this->getView(); + + // Allow modules to add classes for styling the layout. + $eventArgs = $this->eventManager->prepareArgs(['classes' => []]); + $this->eventManager->triggerEvent(new Event('page_layout.classes', $page, $eventArgs)); + $classes = $eventArgs['classes']; + + // Allow modules to add inline styles for styling the layout. + $eventArgs = $this->eventManager->prepareArgs(['inline_styles' => []]); + $this->eventManager->triggerEvent(new Event('page_layout.inline_styles', $page, $eventArgs)); + $inlineStyles = $eventArgs['inline_styles']; + + // Prepare the page layout. + switch ($page->layout()) { + case 'grid': + $view->headLink()->appendStylesheet($view->assetUrl('css/page-grid.css', 'Omeka')); + $classes[] = 'page-layout-grid'; + $inlineStyles[] = sprintf( + 'grid-template-columns: repeat(%s, 1fr);', + (int) $page->layoutDataValue('grid_columns') + ); + $inlineStyles[] = sprintf( + 'column-gap: %spx;', + (int) $page->layoutDataValue('grid_column_gap', 10) + ); + $inlineStyles[] = sprintf( + 'row-gap: %spx;', + (int) $page->layoutDataValue('grid_row_gap', 10) + ); + break; + case '': + default: + $classes[] = 'page-layout-normal'; + break; + } + echo sprintf( + '
    ', + $view->escapeHtml(implode(' ', $classes)), + $view->escapeHtml(implode(' ', $inlineStyles)) + ); + $layouts = []; + foreach ($page->blocks() as $block) { + if (!array_key_exists($block->layout(), $layouts)) { + // Prepare render only once per block layout type. + $layouts[$block->layout()] = null; + $view->blockLayout()->prepareRender($block->layout()); + } + // Render each block according to page layout. + switch ($page->layout()) { + case 'grid': + $gridColumns = (int) $page->layoutDataValue('grid_columns'); + $blockLayoutData = $block->layoutData(); + $getValidPosition = fn ($columnPosition) => in_array($columnPosition, ['auto',...range(1, $gridColumns)]) ? $columnPosition : 'auto'; + $getValidSpan = fn ($columnSpan) => in_array($columnSpan, range(1, $gridColumns)) ? $columnSpan : $gridColumns; + echo sprintf( + '
    %s
    ', + $getValidPosition($blockLayoutData['grid_column_position'] ?? 'auto'), + $getValidSpan($blockLayoutData['grid_column_span'] ?? $gridColumns), + $view->blockLayout()->render($block) + ); + break; + case '': + default: + echo $view->blockLayout()->render($block); + break; + } + } + echo '
    '; + } +} diff --git a/application/src/View/Helper/Pagination.php b/application/src/View/Helper/Pagination.php index 1a9f762114..b767c22d47 100644 --- a/application/src/View/Helper/Pagination.php +++ b/application/src/View/Helper/Pagination.php @@ -128,6 +128,12 @@ protected function getUrl($page) { $query = $this->getView()->params()->fromQuery(); $query['page'] = (int) $page; + if (isset($query['sort_by_default'])) { + // Do not emit sort_by if the sort_by_default flag is set. + unset($query['sort_by']); + } + // Do not emit the sort_by_default flag + unset($query['sort_by_default']); $options = ['query' => $query]; if (is_string($this->fragment)) { $options['fragment'] = $this->fragment; diff --git a/application/src/View/Helper/SearchFilters.php b/application/src/View/Helper/SearchFilters.php index 3928501d8e..aa928dc946 100644 --- a/application/src/View/Helper/SearchFilters.php +++ b/application/src/View/Helper/SearchFilters.php @@ -218,16 +218,19 @@ public function __invoke($partialName = null, array $query = null) case 'id': $filterLabel = $translate('ID'); + // Avoid a deprecated issue, so convert ids as string. $ids = $value; - if (is_string($ids) || is_int($ids)) { - $ids = false === strpos($ids, ',') ? [$ids] : explode(',', $ids); - } elseif (!is_array($ids)) { + if (is_int($ids)) { + $ids = [(string) $ids]; + } elseif (is_string($ids)) { + $ids = strpos($ids, ',') === false ? [$ids] : explode(',', $ids); + } elseif (is_array($ids)) { + $ids = array_map('strval', $ids); + } else { $ids = []; } $ids = array_map('trim', $ids); - $ids = array_filter($ids, function ($id) { - return !($id === null || $id === ''); - }); + $ids = array_filter($ids, 'strlen'); $filters[$filterLabel][] = implode(', ', $ids); break; } diff --git a/application/src/View/Helper/SortMedia.php b/application/src/View/Helper/SortMedia.php index 838e155d7c..3a44d15fc9 100644 --- a/application/src/View/Helper/SortMedia.php +++ b/application/src/View/Helper/SortMedia.php @@ -8,7 +8,7 @@ class SortMedia extends AbstractHelper public function __invoke($files = null) { $sortedMedia = []; - $whitelist = ['image/bmp', 'image/gif', 'image/jpeg', 'image/png', 'image/svg+xml', 'video/flv', 'video/x-flv', 'video/mp4', 'video/m4v', + $whitelist = ['image/bmp', 'image/gif', 'image/jpeg', 'image/png', 'image/svg+xml', 'image/webp', 'video/flv', 'video/x-flv', 'video/mp4', 'video/m4v', 'video/webm', 'video/wmv', 'video/quicktime', 'application/pdf', ]; $html5videos = []; $mediaCount = 0; diff --git a/application/src/View/Renderer/ApiJsonRenderer.php b/application/src/View/Renderer/ApiJsonRenderer.php index e2e58e3abe..605c6445cd 100644 --- a/application/src/View/Renderer/ApiJsonRenderer.php +++ b/application/src/View/Renderer/ApiJsonRenderer.php @@ -2,8 +2,8 @@ namespace Omeka\View\Renderer; use Omeka\Api\Exception\ValidationException; -use Omeka\Api\Representation\RepresentationInterface; use Omeka\Api\Response; +use Laminas\EventManager\EventManager; use Laminas\Json\Json; use Laminas\View\Renderer\JsonRenderer; @@ -17,16 +17,18 @@ class ApiJsonRenderer extends JsonRenderer */ protected $hasJsonpCallback = false; - /** - * @var array The JSON-LD context - */ - protected $context; - /** * @var string The output format */ protected $format; + protected $eventManager; + + public function __construct(EventManager $eventManager) + { + $this->eventManager = $eventManager; + } + /** * Return whether the response is JSONP * @@ -41,6 +43,11 @@ public function hasJsonpCallback() return $this->hasJsonpCallback; } + public function setHasJsonpCallback(bool $hasJsonpCallback) + { + $this->hasJsonpCallback = $hasJsonpCallback; + } + public function render($model, $values = null) { $response = $model->getApiResponse(); @@ -61,82 +68,17 @@ public function render($model, $values = null) return null; } - // Render a format that is not JSON-LD, if requested. - if ('jsonld' !== $this->format) { - // Render a single representation (get). - if ($payload instanceof RepresentationInterface) { - $jsonLd = $this->getJsonLdWithContext($payload); - return $this->serializeJsonLdToFormat($jsonLd, $this->format); - } - // Render multiple representations (getList); - if (is_array($payload) && isset($payload[0]) && $payload[0] instanceof RepresentationInterface) { - $jsonLd = []; - foreach ($payload as $representation) { - $jsonLd[] = $this->getJsonLdWithContext($representation); - } - return $this->serializeJsonLdToFormat($jsonLd, $this->format); - } - } - $output = parent::render($payload); - if ($payload instanceof RepresentationInterface) { - $eventManager = $payload->getEventManager(); - $args = $eventManager->prepareArgs(['jsonLd' => $output]); - $eventManager->trigger('rep.resource.json_output', $payload, $args); - $output = $args['jsonLd']; - } - - if (null !== $model->getOption('pretty_print')) { - // Pretty print the JSON. - $output = Json::prettyPrint($output); - } - - $jsonpCallback = (string) $model->getOption('callback'); - if (!empty($jsonpCallback)) { - // Wrap the JSON in a JSONP callback. Normally this would be done - // via `$this->setJsonpCallback()` but we don't want to pass the - // wrapped string to `rep.resource.json_output` handlers. - $output = sprintf('%s(%s);', $jsonpCallback, $output); - $this->hasJsonpCallback = true; - } - - return $output; - } - - /** - * Get the JSON-LD array of a representation, adding the @context. - * - * @param RepresentationInterface $representation - * @return array - */ - public function getJsonLdWithContext(RepresentationInterface $representation) - { - // Add the @context by encoding the output as JSON, then decoding to an array. - $eventManager = $representation->getEventManager(); - $jsonLd = Json::decode(Json::encode($representation), true); - if (!$this->context) { - // Get the JSON-LD @context - $args = $eventManager->prepareArgs(['context' => []]); - $eventManager->trigger('api.context', null, $args); - $this->context = $args['context']; - } - $jsonLd['@context'] = $this->context; - return $jsonLd; - } - - /** - * Serialize JSON-LD to another format. - * - * @param array $jsonLd - * @param string $format - * @param string - */ - public function serializeJsonLdToFormat(array $jsonLd, string $format) - { - $graph = new \EasyRdf\Graph; - $graph->parse(Json::encode($jsonLd), 'jsonld'); - return $graph->serialise($format); + // Allow modules to return custom output. + $args = $this->eventManager->prepareArgs([ + 'model' => $model, + 'payload' => $payload, + 'format' => $this->format, + 'output' => $output, + ]); + $this->eventManager->trigger('api.output.serialize', $this, $args); + return $args['output']; } /** diff --git a/application/src/View/Strategy/ApiJsonStrategy.php b/application/src/View/Strategy/ApiJsonStrategy.php index 95aa311a82..62d50addfb 100644 --- a/application/src/View/Strategy/ApiJsonStrategy.php +++ b/application/src/View/Strategy/ApiJsonStrategy.php @@ -8,6 +8,7 @@ use Omeka\Mvc\Exception as MvcException; use Omeka\View\Model\ApiJsonModel; use Omeka\View\Renderer\ApiJsonRenderer; +use Laminas\EventManager\EventManager; use Laminas\View\Strategy\JsonStrategy; use Laminas\View\ViewEvent; @@ -27,14 +28,18 @@ class ApiJsonStrategy extends JsonStrategy 'jsonld' => 'application/ld+json', ]; + protected $eventManager; + /** * Constructor, sets the renderer object * - * @param \Omeka\View\Renderer\ApiJsonRenderer + * @param ApiJsonRenderer + * @param EventManager */ - public function __construct(ApiJsonRenderer $renderer) + public function __construct(ApiJsonRenderer $renderer, EventManager $eventManager) { $this->renderer = $renderer; + $this->eventManager = $eventManager; } public function selectRenderer(ViewEvent $e) @@ -128,6 +133,11 @@ protected function getStatusCodeForException(\Exception $exception = null) */ protected function getFormat(ApiJsonModel $model) { + // Allow modules to register formats. + $args = $this->eventManager->prepareArgs(['formats' => $this->formats]); + $this->eventManager->trigger('api.output.formats', $this, $args); + $this->formats = $args['formats']; + // Prioritize the "format" query parameter. $format = $model->getOption('format'); if (array_key_exists($format, $this->formats)) { diff --git a/application/test/OmekaTest/View/Renderer/ApiJsonRendererTest.php b/application/test/OmekaTest/View/Renderer/ApiJsonRendererTest.php index 34c46ba656..6f80a6a67f 100644 --- a/application/test/OmekaTest/View/Renderer/ApiJsonRendererTest.php +++ b/application/test/OmekaTest/View/Renderer/ApiJsonRendererTest.php @@ -9,6 +9,19 @@ class ApiJsonRendererTest extends TestCase { + protected $eventManager; + + public function setUp(): void + { + $this->eventManager = $this->createMock('Laminas\EventManager\EventManager'); + $this->eventManager->expects($this->any()) + ->method('prepareArgs') + ->will($this->returnCallback(function ($arg) { + return $arg; + }) + ); + } + public function testRendererUsesApiResponse() { $testValue = ['test' => 'foo']; @@ -22,7 +35,7 @@ public function testRendererUsesApiResponse() ->method('getApiResponse') ->will($this->returnValue($response)); - $renderer = new ApiJsonRenderer; + $renderer = new ApiJsonRenderer($this->eventManager); $this->assertEquals(Json::encode($testValue), $renderer->render($model)); } @@ -38,7 +51,7 @@ public function testRendererPassesOnNullResponse() ->method('getApiResponse') ->will($this->returnValue($response)); - $renderer = new ApiJsonRenderer; + $renderer = new ApiJsonRenderer($this->eventManager); $this->assertEquals(null, $renderer->render($model)); } @@ -57,7 +70,7 @@ public function testRendererShowsErrors() ->method('getException') ->will($this->returnValue($exception)); - $renderer = new ApiJsonRenderer; + $renderer = new ApiJsonRenderer($this->eventManager); $this->assertEquals(Json::encode(['errors' => ['foo' => ['bar']]]), $renderer->render($model)); } } diff --git a/application/test/OmekaTest/View/Strategy/ApiJsonStrategyTest.php b/application/test/OmekaTest/View/Strategy/ApiJsonStrategyTest.php index b67e93d935..87e651d166 100644 --- a/application/test/OmekaTest/View/Strategy/ApiJsonStrategyTest.php +++ b/application/test/OmekaTest/View/Strategy/ApiJsonStrategyTest.php @@ -11,14 +11,22 @@ class ApiJsonStrategyTest extends TestCase { public $renderer; + public $eventManager; public $strategy; public $event; public function setUp(): void { $this->renderer = $this->createMock('Omeka\View\Renderer\ApiJsonRenderer'); - - $this->strategy = new ApiJsonStrategy($this->renderer); + $this->eventManager = $this->createMock('Laminas\EventManager\EventManager'); + $this->eventManager->expects($this->any()) + ->method('prepareArgs') + ->will($this->returnCallback(function ($arg) { + return $arg; + }) + ); + + $this->strategy = new ApiJsonStrategy($this->renderer, $this->eventManager); $this->event = new ViewEvent; $httpResponse = new HttpResponse; diff --git a/application/view/common/advanced-search.phtml b/application/view/common/advanced-search.phtml index 748094ad16..a5db20092b 100644 --- a/application/view/common/advanced-search.phtml +++ b/application/view/common/advanced-search.phtml @@ -20,6 +20,7 @@ $addPartial = function($partial) use (&$partials, $partialExcludelist) { } }; +$addPartial('common/advanced-search/sort'); $addPartial('common/advanced-search/fulltext'); $addPartial('common/advanced-search/properties'); $addPartial('common/advanced-search/resource-class'); @@ -48,7 +49,6 @@ if ($this->status()->isSiteRequest()) { $addPartial('common/advanced-search/resource-template-restrict'); } $addPartial('common/advanced-search/ids'); -$addPartial('common/advanced-search/sort'); $filterResults = $this->trigger( 'view.advanced_search', diff --git a/application/view/common/advanced-search/has-media.phtml b/application/view/common/advanced-search/has-media.phtml index ae8dd02972..47c161eddc 100644 --- a/application/view/common/advanced-search/has-media.phtml +++ b/application/view/common/advanced-search/has-media.phtml @@ -1,11 +1,12 @@ setLabel($this->translate('Search by media presence')) +$element + ->setLabel('Search by media presence') // @translate ->setValueOptions([ - '1' => $this->translate('Has media'), - '0' => $this->translate('Has no media'), + '1' => 'Has media', // @translate + '0' => 'Has no media', // @translate ]) - ->setEmptyOption($this->translate('Select media presence…')) - ->setValue($query['has_media'] ?? ''); + ->setEmptyOption('Select media presence…') // @translate + ->setValue($query['has_media'] ?? '') + ->setAttribute('id', 'has_media'); echo $this->formRow($element); -?> diff --git a/application/view/common/advanced-search/item-sets.phtml b/application/view/common/advanced-search/item-sets.phtml index 0cd2dfa3ae..80a157e2f9 100644 --- a/application/view/common/advanced-search/item-sets.phtml +++ b/application/view/common/advanced-search/item-sets.phtml @@ -38,7 +38,7 @@ if ($this->status()->isSiteRequest()) { $selectOptions = []; } ?> -
    +
    hyperlink('', '#', ['class' => 'expand', 'title' => $translate('Expand')]); ?> @@ -50,7 +50,7 @@ if ($this->status()->isSiteRequest()) {
    - @@ -59,7 +59,7 @@ if ($this->status()->isSiteRequest()) { 'attributes' => [ 'value' => $itemSet['id'], 'class' => 'item-set-select', - 'aria-labelledby' => 'by-item-set-label' + 'aria-labelledby' => 'by-item-set-label', ], 'options' => $selectOptions, ]); ?> diff --git a/application/view/common/advanced-search/owner.phtml b/application/view/common/advanced-search/owner.phtml index 52ee33e923..1ae168bb62 100644 --- a/application/view/common/advanced-search/owner.phtml +++ b/application/view/common/advanced-search/owner.phtml @@ -16,4 +16,3 @@ ]); ?>
    - diff --git a/application/view/common/advanced-search/properties.phtml b/application/view/common/advanced-search/properties.phtml index 9a16d16513..55cea9165f 100644 --- a/application/view/common/advanced-search/properties.phtml +++ b/application/view/common/advanced-search/properties.phtml @@ -55,7 +55,7 @@ if ($this->status()->isSiteRequest()) { $stem = "property[$index]"; ?>
    - @@ -63,8 +63,8 @@ if ($this->status()->isSiteRequest()) { 'name' => $stem . '[property]', 'attributes' => [ 'class' => 'query-property', - 'value' => isset($property['property']) ? $property['property'] : null, - 'aria-label' => $translate('Property'), + 'value' => $property['property'] ?? null, + 'aria-label' => 'Property', // @translate ], 'options' => [ 'empty_option' => '[Any Property]', // @translate diff --git a/application/view/common/advanced-search/sort.phtml b/application/view/common/advanced-search/sort.phtml index b739ad42de..39d9cf603d 100644 --- a/application/view/common/advanced-search/sort.phtml +++ b/application/view/common/advanced-search/sort.phtml @@ -16,15 +16,17 @@ switch ($resourceType) { $sortConfig = $this->browse()->getBrowseService()->getSortConfig($sortConfigContext, $sortConfigResourceType); $sortBy = new Element\Select('sort_by'); -$sortBy->setEmptyOption($this->translate('Select sort by…')); +$sortBy->setAttribute('aria-label', 'Sort by'); // @translate +$sortBy->setEmptyOption('Select sort by…'); // @translate $sortBy->setValueOptions($sortConfig); $sortBy->setValue((!isset($query['sort_by_default']) && isset($query['sort_by'])) ? $query['sort_by'] : ''); $sortOrder = new Element\Select('sort_order'); -$sortOrder->setEmptyOption($this->translate('Select sort order…')); +$sortOrder->setAttribute('aria-label', 'Sort order'); // @translate +$sortOrder->setEmptyOption('Select sort order…'); // @translate $sortOrder->setValueOptions([ - 'asc' => $this->translate('Ascending'), - 'desc' => $this->translate('Descending'), + 'asc' => 'Ascending', // @translate + 'desc' => 'Descending', // @translate ]); $sortOrder->setValue($query['sort_order'] ?? ''); ?> diff --git a/application/view/common/advanced-search/visibility.phtml b/application/view/common/advanced-search/visibility.phtml index 5c21fd8eba..5919dae363 100644 --- a/application/view/common/advanced-search/visibility.phtml +++ b/application/view/common/advanced-search/visibility.phtml @@ -1,11 +1,11 @@ setLabel($this->translate('Search by visibility')) +$element->setLabel('Search by visibility') // @translate ->setValueOptions([ - '1' => $this->translate('Public'), - '0' => $this->translate('Not public'), + '1' => 'Public', // @translate + '0' => 'Not public', // @translate ]) - ->setEmptyOption($this->translate('Select visibility…')) - ->setValue($query['is_public'] ?? ''); + ->setEmptyOption('Select visibility…') // @translate + ->setValue($query['is_public'] ?? '') + ->setAttribute('id', 'is_public'); echo $this->formRow($element); -?> diff --git a/application/view/common/asset-block-form.phtml b/application/view/common/asset-block-form.phtml index b423b2e096..554d89b842 100644 --- a/application/view/common/asset-block-form.phtml +++ b/application/view/common/asset-block-form.phtml @@ -23,7 +23,7 @@ $attachmentRowTemplate = '
    - id()) : ''; $page = (array_key_exists('page', $attachment)) ? $attachment['page'] : null; @@ -54,18 +54,3 @@ $attachmentRowTemplate = '
    - -

    -
    -
    -
    -
    - -
    -
    - - -
    -
    - -
    diff --git a/application/view/common/background-form.phtml b/application/view/common/background-form.phtml new file mode 100644 index 0000000000..45758c183e --- /dev/null +++ b/application/view/common/background-form.phtml @@ -0,0 +1,7 @@ +formElement($element->getImageAssetElement()); ?> +translate('Vertical anchor position'); ?> +formElement($element->getPositionYElement()); ?> +translate('Horizontal anchor position'); ?> +formElement($element->getPositionXElement()); ?> +translate('Size'); ?> +formElement($element->getSizeElement()); ?> diff --git a/application/view/common/block-layout.phtml b/application/view/common/block-layout.phtml index db3e26e7f2..2971e41aaf 100644 --- a/application/view/common/block-layout.phtml +++ b/application/view/common/block-layout.phtml @@ -1,21 +1,47 @@ plugin('translate'); $escape = $this->plugin('escapeHtml'); + +$layoutGridColumnPositionOptions = ['auto' => $translate('Auto placement')]; +foreach (range(1, 12) as $value) { + $layoutGridColumnPositionOptions[$value] = sprintf($translate('Position %s'), $value); +} +$layoutGridColumnSpanOptions = []; +foreach (range(1, 12) as $value) { + $layoutGridColumnSpanOptions[$value] = sprintf($translate('Span %s'), $value); +} +$layoutGridColumnPosition = $layoutData['grid_column_position'] ?? 'auto'; +$layoutGridColumnSpan = $layoutData['grid_column_span'] ?? '12'; ?> -
    +
    + + + +
      +
    • +
    • +
    • +
    • -
    • -
    +
    diff --git a/application/view/common/block-layout/asset.phtml b/application/view/common/block-layout/asset.phtml index 8340c99e66..4830b40be9 100644 --- a/application/view/common/block-layout/asset.phtml +++ b/application/view/common/block-layout/asset.phtml @@ -1,6 +1,6 @@ plugin('escapeHtml'); ?> -
    +
    diff --git a/application/view/common/block-layout/browse-preview.phtml b/application/view/common/block-layout/browse-preview.phtml index 1582673cd5..60c4e7118a 100644 --- a/application/view/common/block-layout/browse-preview.phtml +++ b/application/view/common/block-layout/browse-preview.phtml @@ -6,7 +6,7 @@ $thumbnail = $this->plugin('thumbnail');
    heading): ?> -

    heading; ?>

    +

    heading); ?>

      diff --git a/application/view/common/block-layout/file.phtml b/application/view/common/block-layout/file.phtml index 6db7f13a6d..1c709e8088 100644 --- a/application/view/common/block-layout/file.phtml +++ b/application/view/common/block-layout/file.phtml @@ -1,4 +1,4 @@ -
      +
      attachments as $attachment): ?>
      diff --git a/application/view/common/block-layout/html.phtml b/application/view/common/block-layout/html.phtml new file mode 100644 index 0000000000..fcca1c7ff5 --- /dev/null +++ b/application/view/common/block-layout/html.phtml @@ -0,0 +1 @@ +dataValue('html', ''); ?> diff --git a/application/view/common/block-layout/line-break.phtml b/application/view/common/block-layout/line-break.phtml new file mode 100644 index 0000000000..c6c90b3ff7 --- /dev/null +++ b/application/view/common/block-layout/line-break.phtml @@ -0,0 +1 @@ +
      '>
      diff --git a/application/view/common/block-layout/oembed.phtml b/application/view/common/block-layout/oembed.phtml new file mode 100644 index 0000000000..e85df9d738 --- /dev/null +++ b/application/view/common/block-layout/oembed.phtml @@ -0,0 +1 @@ +
      renderOembed($this, $data['oembed']); ?>
      diff --git a/application/view/common/linked-resources.phtml b/application/view/common/linked-resources.phtml index 80d0ded73d..72cf01cc25 100644 --- a/application/view/common/linked-resources.phtml +++ b/application/view/common/linked-resources.phtml @@ -55,7 +55,7 @@ $resourcePropertiesSelect->setValueOptions($valueOptions); formElement($resourcePropertiesSelect); ?>
      - $perPage) ? $pagination : ''; ?> +
      diff --git a/application/view/common/navigation-link-form/url.phtml b/application/view/common/navigation-link-form/url.phtml index 38b5579ad9..21235b73c4 100644 --- a/application/view/common/navigation-link-form/url.phtml +++ b/application/view/common/navigation-link-form/url.phtml @@ -3,7 +3,15 @@ $translate = $this->plugin('translate'); $escape = $this->plugin('escapeHtml'); $label = isset($data['label']) && '' !== trim($data['label']) ? $data['label'] : null; $url = isset($data['url']) && '' !== trim($data['url']) ? $data['url'] : null; +$targetBlank = isset($data['target_blank']) ? (bool) $data['target_blank'] : false; ?> + diff --git a/application/view/common/pagination.phtml b/application/view/common/pagination.phtml index cdd7d9b809..d921cfecbc 100644 --- a/application/view/common/pagination.phtml +++ b/application/view/common/pagination.phtml @@ -1,10 +1,17 @@ plugin('translate'); + +// Do not emit the sort_by_default flag. +$removeQueries = ['page', 'sort_by_default']; +if (isset($query['sort_by_default'])) { + // Do not emit sort_by if the sort_by_default flag is set. + $removeQueries[] = 'sort_by'; +} ?>
      '; ?> +
      +
      @@ -77,6 +79,7 @@ $templateUri = '
      +