Changeset 3322139
- Timestamp:
- 07/04/2025 07:24:49 AM (5 months ago)
- Location:
- jobbnorge-block
- Files:
-
- 32 added
- 49 edited
- 1 copied
-
assets/blueprints/blueprint.json (modified) (3 diffs)
-
tags/2.2.0 (copied) (copied from jobbnorge-block/trunk)
-
tags/2.2.0/CHANGELOG.md (modified) (1 diff)
-
tags/2.2.0/README.md (modified) (1 diff)
-
tags/2.2.0/build/block.json (modified) (2 diffs)
-
tags/2.2.0/build/editor.asset.php (added)
-
tags/2.2.0/build/editor.css (added)
-
tags/2.2.0/build/editor.js (added)
-
tags/2.2.0/build/init.asset.php (modified) (1 diff)
-
tags/2.2.0/build/init.css (modified) (1 diff)
-
tags/2.2.0/build/init.js (modified) (1 diff)
-
tags/2.2.0/build/pagination.asset.php (added)
-
tags/2.2.0/build/pagination.js (added)
-
tags/2.2.0/build/style-init.css (modified) (1 diff)
-
tags/2.2.0/build/style.asset.php (added)
-
tags/2.2.0/build/style.js (added)
-
tags/2.2.0/debug-grid.html (added)
-
tags/2.2.0/design.md (added)
-
tags/2.2.0/grid-test.html (added)
-
tags/2.2.0/languages/wp-jobbnorge-block-en_US-5847f2cef22ef3cae0e9359a7a5dd2ec.json (modified) (2 diffs)
-
tags/2.2.0/languages/wp-jobbnorge-block-en_US-bb1d7dea005e67527e728d4801f74b61.json (modified) (2 diffs)
-
tags/2.2.0/languages/wp-jobbnorge-block-en_US.mo (modified) (previous)
-
tags/2.2.0/languages/wp-jobbnorge-block-en_US.po (modified) (2 diffs)
-
tags/2.2.0/languages/wp-jobbnorge-block-nb_NO-5847f2cef22ef3cae0e9359a7a5dd2ec.json (modified) (2 diffs)
-
tags/2.2.0/languages/wp-jobbnorge-block-nb_NO-bb1d7dea005e67527e728d4801f74b61.json (modified) (2 diffs)
-
tags/2.2.0/languages/wp-jobbnorge-block-nb_NO.mo (modified) (previous)
-
tags/2.2.0/languages/wp-jobbnorge-block-nb_NO.po (modified) (3 diffs)
-
tags/2.2.0/languages/wp-jobbnorge-block.pot (modified) (2 diffs)
-
tags/2.2.0/package-lock.json (modified) (2 diffs)
-
tags/2.2.0/package.json (modified) (1 diff)
-
tags/2.2.0/readme.txt (modified) (2 diffs)
-
tags/2.2.0/src/block.json (modified) (2 diffs)
-
tags/2.2.0/src/edit.js (modified) (2 diffs)
-
tags/2.2.0/src/editor.scss (modified) (4 diffs)
-
tags/2.2.0/src/pagination.js (added)
-
tags/2.2.0/src/style.scss (modified) (5 diffs)
-
tags/2.2.0/status-check.php (added)
-
tags/2.2.0/test-enqueue.php (added)
-
tags/2.2.0/test-grid-functionality.php (added)
-
tags/2.2.0/verify-grid-fix.php (added)
-
tags/2.2.0/webpack.config.js (added)
-
tags/2.2.0/wp-jobb-norge.php (modified) (21 diffs)
-
trunk/CHANGELOG.md (modified) (1 diff)
-
trunk/README.md (modified) (1 diff)
-
trunk/build/block.json (modified) (2 diffs)
-
trunk/build/editor.asset.php (added)
-
trunk/build/editor.css (added)
-
trunk/build/editor.js (added)
-
trunk/build/init.asset.php (modified) (1 diff)
-
trunk/build/init.css (modified) (1 diff)
-
trunk/build/init.js (modified) (1 diff)
-
trunk/build/pagination.asset.php (added)
-
trunk/build/pagination.js (added)
-
trunk/build/style-init.css (modified) (1 diff)
-
trunk/build/style.asset.php (added)
-
trunk/build/style.js (added)
-
trunk/debug-grid.html (added)
-
trunk/design.md (added)
-
trunk/grid-test.html (added)
-
trunk/languages/wp-jobbnorge-block-en_US-5847f2cef22ef3cae0e9359a7a5dd2ec.json (modified) (2 diffs)
-
trunk/languages/wp-jobbnorge-block-en_US-bb1d7dea005e67527e728d4801f74b61.json (modified) (2 diffs)
-
trunk/languages/wp-jobbnorge-block-en_US.mo (modified) (previous)
-
trunk/languages/wp-jobbnorge-block-en_US.po (modified) (2 diffs)
-
trunk/languages/wp-jobbnorge-block-nb_NO-5847f2cef22ef3cae0e9359a7a5dd2ec.json (modified) (2 diffs)
-
trunk/languages/wp-jobbnorge-block-nb_NO-bb1d7dea005e67527e728d4801f74b61.json (modified) (2 diffs)
-
trunk/languages/wp-jobbnorge-block-nb_NO.mo (modified) (previous)
-
trunk/languages/wp-jobbnorge-block-nb_NO.po (modified) (3 diffs)
-
trunk/languages/wp-jobbnorge-block.pot (modified) (2 diffs)
-
trunk/package-lock.json (modified) (2 diffs)
-
trunk/package.json (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/src/block.json (modified) (2 diffs)
-
trunk/src/edit.js (modified) (2 diffs)
-
trunk/src/editor.scss (modified) (4 diffs)
-
trunk/src/pagination.js (added)
-
trunk/src/style.scss (modified) (5 diffs)
-
trunk/status-check.php (added)
-
trunk/test-enqueue.php (added)
-
trunk/test-grid-functionality.php (added)
-
trunk/verify-grid-fix.php (added)
-
trunk/webpack.config.js (added)
-
trunk/wp-jobb-norge.php (modified) (21 diffs)
Legend:
- Unmodified
- Added
- Removed
-
jobbnorge-block/assets/blueprints/blueprint.json
r3019435 r3322139 1 1 { 2 2 "$schema": "https://playground.wordpress.net/blueprint-schema.json", 3 "landingPage": "\/wp-admin\/post.php?post=2&action=edit", 3 "_comment1": "This is the landing page URL, Also see the runPHP step below", 4 "landingPage": "/wp-admin/post.php?post=2&action=edit", 5 "_comment2": "These are the preferred versions for PHP and WordPress", 4 6 "preferredVersions": { 5 7 "php": "8.1", 6 8 "wp": "latest" 7 9 }, 10 "_comment3": "These are the PHP extension bundles", 8 11 "phpExtensionBundles": [ 12 "_comment3.1": "kitchen-sink = gd, mbstring, iconv, openssl, libxml, xml, dom, simplexml, xmlreader and xmlwriter", 9 13 "kitchen-sink" 10 14 ], 15 "_comment4": "These are the features", 11 16 "features": { 17 "_comment4.1": "Network access is required. The plugin needs access to the Jobbnorge API", 12 18 "networking": true 13 19 }, 20 "_comment5": "These are the steps", 14 21 "steps": [ 15 22 { 23 "_comment5.1": "This is the login step", 16 24 "step": "login", 17 25 "username": "admin", … … 19 27 }, 20 28 { 29 "_comment5.2": "This is the plugin installation step", 21 30 "step": "installPlugin", 22 31 "pluginZipFile": { 23 "resource": "wordpress.org \/plugins",32 "resource": "wordpress.org/plugins", 24 33 "slug": "jobbnorge-block" 25 34 }, … … 29 38 }, 30 39 { 40 "_comment5.3": "Use wp_update_post. post ID 2 exists (default sample page), I updated it with my content and made it my landing page", 31 41 "step": "runPHP", 32 42 "code": "<?php require '/wordpress/wp-load.php'; wp_update_post( array('ID' => 2, 'post_title' => 'Jobbnorge','post_content' => '<!-- wp:dss/jobbnorge {\"employerID\":\"1981,1992,1980,2770,1989,1994,1986,1984,1985,1987,1996,1988,1982,1983,1995,1993,1991\"} /-->' ) );" -
jobbnorge-block/tags/2.2.0/CHANGELOG.md
r3003492 r3322139 1 # Cangelog 1 # Changelog 2 3 ## 2.2.0 4 5 * **NEW**: Add frontend pagination support with AJAX loading 6 * **NEW**: Add pagination controls (enable/disable, jobs per page setting) 7 * **ENHANCEMENT**: Upgrade to Jobbnorge API v3 for better performance 8 * **ENHANCEMENT**: Implement PHP-based pagination to work around API limitations with employer filtering 9 * **ENHANCEMENT**: Add responsive grid layout that adapts to screen size 10 * **ENHANCEMENT**: Improve cache key logic to include pagination and layout parameters 11 * **ENHANCEMENT**: Add loading states and error handling for pagination 12 * **ENHANCEMENT**: Separate frontend and admin CSS loading for better performance 13 * **FIX**: Fix CSS class naming conflicts that prevented grid view from working on frontend 14 * **FIX**: Resolve frontend style loading issues 15 * **DEVELOPER**: Add comprehensive webpack build configuration for multiple entry points 16 * **DEVELOPER**: Add pagination JavaScript with proper AJAX handling and nonce security 2 17 3 18 ## 2.1.5 -
jobbnorge-block/tags/2.2.0/README.md
r3002720 r3322139 5 5 > Also available at https://wordpress.org/plugins/jobbnorge-block/ 6 6 7 7 8 This WordPress plugin adds a block to the Gutenberg editor that displays a list of jobs from Jobbnorge. 8 9 9 See:[Features](#features) | [Installation](#installation) | [Use](#use) | [Filters](#filters) | [Styling](#styling) | [License](#license) | [Changelog](CHANGELOG.md)10 **See:** [Live Preview](https://playground.wordpress.net/?plugin=jobbnorge-block&blueprint-url=https://wordpress.org/plugins/wp-json/plugins/v1/plugin/jobbnorge-block/blueprint.json) | [Features](#features) | [Installation](#installation) | [Use](#use) | [Filters](#filters) | [Styling](#styling) | [License](#license) | [Changelog](CHANGELOG.md) 10 11 12 <p> </p> 11 13 12 14 <img src=".wordpress-org/jobbnorge.gif"> -
jobbnorge-block/tags/2.2.0/build/block.json
r3003492 r3322139 3 3 "apiVersion": 2, 4 4 "name": "dss/jobbnorge", 5 "version": "2. 1.5",5 "version": "2.2.0", 6 6 "title": "Jobbnorge", 7 7 "category": "widgets", … … 63 63 "type": "number", 64 64 "default": 55 65 }, 66 "enablePagination": { 67 "type": "boolean", 68 "default": true 69 }, 70 "jobsPerPage": { 71 "type": "number", 72 "default": 10 65 73 } 66 74 }, 67 75 "textdomain": "wp-jobbnorge-block", 68 76 "editorScript": "file:init.js", 69 "editorStyle": "file:editor. scss",70 "style": "file:style .scss"77 "editorStyle": "file:editor.css", 78 "style": "file:style-init.css" 71 79 } -
jobbnorge-block/tags/2.2.0/build/init.asset.php
r3003492 r3322139 1 <?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-server-side-render'), 'version' => ' 4d2818abc3875b8f27f4');1 <?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-server-side-render'), 'version' => '7c82361092d9d86c438b'); -
jobbnorge-block/tags/2.2.0/build/init.css
r2853882 r3322139 1 .wp-block-dss-jobbnorge li a>div{display:inline}.wp-block-dss-jobbnorge__placeholder-form{align-items:stretch;display:flex}.wp-block-dss-jobbnorge__placeholder-form>*{margin-bottom:8px}@media(min-width:782px){.wp-block-dss-jobbnorge__placeholder-form>*{margin-bottom:0}}.wp-block-dss-jobbnorge__placeholder-input{align-items:stretch;display:flex;flex-grow:1}.wp-block-dss-jobbnorge__placeholder-input .components-base-control__field{align-items:stretch;display:flex;flex-grow:1;margin:0 8px 0 0} 1 .wp-block-dss-jobbnorge li a>div{display:inline}.wp-block-dss-jobbnorge__placeholder-form{align-items:stretch;display:flex}.wp-block-dss-jobbnorge__placeholder-form>*{margin-bottom:8px}@media(min-width:782px){.wp-block-dss-jobbnorge__placeholder-form>*{margin-bottom:0}}.wp-block-dss-jobbnorge__placeholder-input{align-items:stretch;display:flex;flex-grow:1}.wp-block-dss-jobbnorge__placeholder-input .components-base-control__field{align-items:stretch;display:flex;flex-grow:1;margin:0 8px 0 0}ul.wp-block-dss-jobbnorge{list-style:none;padding:0}ul.wp-block-dss-jobbnorge.wp-block-dss-jobbnorge{box-sizing:border-box}ul.wp-block-dss-jobbnorge li{margin:0 0 1em}ul.wp-block-dss-jobbnorge.is-grid{display:flex;flex-wrap:wrap;list-style:none;padding:0}ul.wp-block-dss-jobbnorge.is-grid li{margin:0 1em 1em 0;width:100%}@media(min-width:600px){ul.wp-block-dss-jobbnorge.columns-2 li{width:calc(50% - 1em)}ul.wp-block-dss-jobbnorge.columns-3 li{width:calc(33.33333% - 1em)}ul.wp-block-dss-jobbnorge.columns-4 li{width:calc(25% - 1em)}ul.wp-block-dss-jobbnorge.columns-5 li{width:calc(20% - 1em)}ul.wp-block-dss-jobbnorge.columns-6 li{width:calc(16.66667% - 1em)}} -
jobbnorge-block/tags/2.2.0/build/init.js
r3003492 r3322139 1 !function(){"use strict";var e,o={938:function(e,o,t){var l=window.React,n=window.wp.primitives,r=(0,l.createElement)(n.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,l.createElement)(n.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})),a=window.wp.blocks,i=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":2,"name":"dss/jobbnorge","version":"2.1.5","title":"Jobbnorge","category":"widgets","icon":"people","description":"Retrieve and display job listings from Jobbnorge.no","keywords":["jobbnorge","jobbnorge.no"],"supports":{"html":false},"attributes":{"columns":{"type":"number","default":3},"blockLayout":{"type":"string","default":"list"},"employerID":{"type":"string","default":""},"noJobsMessage":{"type":"string","default":""},"orderBy":{"type":"string","default":"Deadline"},"itemsToShow":{"type":"number","default":5},"displayEmployer":{"type":"boolean","default":false},"displayExcerpt":{"type":"boolean","default":true},"displayDeadline":{"type":"boolean","default":false},"displayScope":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":true},"excerptLength":{"type":"number","default":55}},"textdomain":"wp-jobbnorge-block","editorScript":"file:init.js","editorStyle":"file:editor.scss","style":"file:style.scss"}'),c=window.wp.blockEditor,s=window.wp.components,b=window.wp.element,p=(0,l.createElement)(n.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,l.createElement)(n.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})),d=(0,l.createElement)(n.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},(0,l.createElement)(n.Path,{d:"M4 4v1.5h16V4H4zm8 8.5h8V11h-8v1.5zM4 20h16v-1.5H4V20zm4-8c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2z"})),m=(0,l.createElement)(n.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,l.createElement)(n.Path,{d:"m3 5c0-1.10457.89543-2 2-2h13.5c1.1046 0 2 .89543 2 2v13.5c0 1.1046-.8954 2-2 2h-13.5c-1.10457 0-2-.8954-2-2zm2-.5h6v6.5h-6.5v-6c0-.27614.22386-.5.5-.5zm-.5 8v6c0 .2761.22386.5.5.5h6v-6.5zm8 0v6.5h6c.2761 0 .5-.2239.5-.5v-6zm0-8v6.5h6.5v-6c0-.27614-.2239-.5-.5-.5z",fillRule:"evenodd",clipRule:"evenodd"})),u=window.wp.i18n,g=window.wp.serverSideRender,w=t.n(g);const{name:v}=i;(e=>{const{metadata:o,settings:t,name:l}=e;(0,a.registerBlockType)({name:l,...o},t)})({name:v,metadata:i,settings:{icon:r,example:{attributes:{employerID:"123[, 456, 789]"}},edit:function({attributes:e,setAttributes:o}){const[t,n]=(0,b.useState)(!e.employerID),{blockLayout:a,columns:i,displayScope:g,displayDate:v,displayEmployer:y,displayExcerpt:h,employerID:f,itemsToShow:k,noJobsMessage:_,orderBy:E}=e;function j(t){return()=>{const l=e[t];o({[t]:!l})}}const C=(0,c.useBlockProps)();var x;if(t)return(0,l.createElement)("div",{...C},(0,l.createElement)(s.Placeholder,{icon:r,label:"Jobbnorge"},(0,l.createElement)("form",{onSubmit:function(e){e.preventDefault(),f&&(o({employerID:f}),n(!1))},className:"wp-block-dss-jobbnorge__placeholder-form"},window.wpJobbnorgeBlock&&window.wpJobbnorgeBlock.employers?(0,l.createElement)(s.SelectControl,{multiple:!0,value:f.split(","),onChange:e=>o({employerID:e.toString()}),options:(null!==(x=wpJobbnorgeBlock.employers)&&void 0!==x?x:[]).map((e=>{var o;return{label:e.label,value:e.value,disabled:null!==(o=e?.disabled)&&void 0!==o&&o}})),className:"wp-block-dss-jobbnorge__placeholder-input",help:(0,u.__)("Select employers to display. Ctrl-click (Windows) or Cmd-click (Mac) to select multiple employers. Shift-click to select a range of employers.","wp-jobbnorge-block"),__nextHasNoMarginBottom:!0}):(0,l.createElement)(s.TextControl,{placeholder:(0,u.__)("Employer ID [,id2, id3, ..]","wp-jobbnorge-block"),value:f,onChange:e=>o({employerID:e}),className:"wp-block-dss-jobbnorge__placeholder-input"}),(0,l.createElement)(s.Button,{variant:"primary",type:"submit"},(0,u.__)("Save","wp-jobbnorge-block")))));const S=[{icon:p,title:(0,u.__)("Edit Jobbnorge URL","wp-jobbnorge-block"),onClick:()=>n(!0)},{icon:d,title:(0,u.__)("List view","wp-jobbnorge-block"),onClick:()=>o({blockLayout:"list"}),isActive:"list"===a},{icon:m,title:(0,u.__)("Grid view","wp-jobbnorge-block"),onClick:()=>o({blockLayout:"grid"}),isActive:"grid"===a}];return(0,l.createElement)(l.Fragment,null,(0,l.createElement)(c.BlockControls,null,(0,l.createElement)(s.ToolbarGroup,{controls:S})),(0,l.createElement)(c.InspectorControls,null,(0,l.createElement)(s.PanelBody,{title:(0,u.__)("Settings","wp-jobbnorge-block")},(0,l.createElement)(s.RangeControl,{__nextHasNoMarginBottom:!0,label:(0,u.__)("Number of items","wp-jobbnorge-block"),value:k,onChange:e=>o({itemsToShow:e}),min:1,max:100,required:!0}),f.includes(",")&&(0,l.createElement)(s.RadioControl,{label:(0,u.__)("Order by","wp-jobbnorge-block"),selected:E,options:[{label:(0,u.__)("Deadline","wp-jobbnorge-block"),value:"Deadline"},{label:(0,u.__)("Employer","wp-jobbnorge-block"),value:"Employer"}],onChange:e=>o({orderBy:e})}),(0,l.createElement)(s.TextareaControl,{label:(0,u.__)("No jobs found message","wp-jobbnorge-block"),help:(0,u.__)("Message to display if no jobs are found","wp-jobbnorge-block"),value:_||(0,u.__)("There are no jobs at this time.","wp-jobbnorge-block"),onChange:e=>o({noJobsMessage:e})})),(0,l.createElement)(s.PanelBody,{title:(0,u.__)("Item","wp-jobbnorge-block")},(0,l.createElement)(s.ToggleControl,{label:(0,u.__)("Display employer","wp-jobbnorge-block"),checked:y,onChange:j("displayEmployer")}),(0,l.createElement)(s.ToggleControl,{label:(0,u.__)("Display excerpt","wp-jobbnorge-block"),checked:h,onChange:j("displayExcerpt")}),(0,l.createElement)(s.ToggleControl,{label:(0,u.__)("Display deadline","wp-jobbnorge-block"),checked:v,onChange:j("displayDate")}),(0,l.createElement)(s.ToggleControl,{label:(0,u.__)("Display scope","wp-jobbnorge-block"),checked:g,onChange:j("displayScope")})),"grid"===a&&(0,l.createElement)(s.PanelBody,{title:(0,u.__)("Grid view","wp-jobbnorge-block")},(0,l.createElement)(s.RangeControl,{__nextHasNoMarginBottom:!0,label:(0,u.__)("Columns","wp-jobbnorge-block"),value:i,onChange:e=>o({columns:e}),min:2,max:6,required:!0}))),(0,l.createElement)("div",{...C},(0,l.createElement)(s.Disabled,null,(0,l.createElement)(w(),{block:"dss/jobbnorge",attributes:e,httpMethod:"POST"}))))}}})}},t={};function l(e){var n=t[e];if(void 0!==n)return n.exports;var r=t[e]={exports:{}};return o[e](r,r.exports,l),r.exports}l.m=o,e=[],l.O=function(o,t,n,r){if(!t){var a=1/0;for(b=0;b<e.length;b++){t=e[b][0],n=e[b][1],r=e[b][2];for(var i=!0,c=0;c<t.length;c++)(!1&r||a>=r)&&Object.keys(l.O).every((function(e){return l.O[e](t[c])}))?t.splice(c--,1):(i=!1,r<a&&(a=r));if(i){e.splice(b--,1);var s=n();void 0!==s&&(o=s)}}return o}r=r||0;for(var b=e.length;b>0&&e[b-1][2]>r;b--)e[b]=e[b-1];e[b]=[t,n,r]},l.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(o,{a:o}),o},l.d=function(e,o){for(var t in o)l.o(o,t)&&!l.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},l.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},function(){var e={410:0,308:0};l.O.j=function(o){return 0===e[o]};var o=function(o,t){var n,r,a=t[0],i=t[1],c=t[2],s=0;if(a.some((function(o){return 0!==e[o]}))){for(n in i)l.o(i,n)&&(l.m[n]=i[n]);if(c)var b=c(l)}for(o&&o(t);s<a.length;s++)r=a[s],l.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return l.O(b)},t=self.webpackChunkjobbnorge_block=self.webpackChunkjobbnorge_block||[];t.forEach(o.bind(null,0)),t.push=o.bind(null,t.push.bind(t))}();var n=l.O(void 0,[308],(function(){return l(938)}));n=l.O(n)}();1 !function(){"use strict";var e,o={938:function(e,o,t){var n=window.React,l=window.wp.primitives,r=(0,n.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(l.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})),a=window.wp.blocks,i=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":2,"name":"dss/jobbnorge","version":"2.2.0","title":"Jobbnorge","category":"widgets","icon":"people","description":"Retrieve and display job listings from Jobbnorge.no","keywords":["jobbnorge","jobbnorge.no"],"supports":{"html":false},"attributes":{"columns":{"type":"number","default":3},"blockLayout":{"type":"string","default":"list"},"employerID":{"type":"string","default":""},"noJobsMessage":{"type":"string","default":""},"orderBy":{"type":"string","default":"Deadline"},"itemsToShow":{"type":"number","default":5},"displayEmployer":{"type":"boolean","default":false},"displayExcerpt":{"type":"boolean","default":true},"displayDeadline":{"type":"boolean","default":false},"displayScope":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":true},"excerptLength":{"type":"number","default":55},"enablePagination":{"type":"boolean","default":true},"jobsPerPage":{"type":"number","default":10}},"textdomain":"wp-jobbnorge-block","editorScript":"file:init.js","editorStyle":"file:editor.css","style":"file:style-init.css"}'),c=window.wp.blockEditor,b=window.wp.components,s=window.wp.element,p=(0,n.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(l.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})),d=(0,n.createElement)(l.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},(0,n.createElement)(l.Path,{d:"M4 4v1.5h16V4H4zm8 8.5h8V11h-8v1.5zM4 20h16v-1.5H4V20zm4-8c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2z"})),m=(0,n.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(l.Path,{d:"m3 5c0-1.10457.89543-2 2-2h13.5c1.1046 0 2 .89543 2 2v13.5c0 1.1046-.8954 2-2 2h-13.5c-1.10457 0-2-.8954-2-2zm2-.5h6v6.5h-6.5v-6c0-.27614.22386-.5.5-.5zm-.5 8v6c0 .2761.22386.5.5.5h6v-6.5zm8 0v6.5h6c.2761 0 .5-.2239.5-.5v-6zm0-8v6.5h6.5v-6c0-.27614-.2239-.5-.5-.5z",fillRule:"evenodd",clipRule:"evenodd"})),u=window.wp.i18n,g=window.wp.serverSideRender,w=t.n(g);const{name:h}=i;(e=>{const{metadata:o,settings:t,name:n}=e;(0,a.registerBlockType)({name:n,...o},t)})({name:h,metadata:i,settings:{icon:r,example:{attributes:{employerID:"123[, 456, 789]"}},edit:function({attributes:e,setAttributes:o}){const[t,l]=(0,s.useState)(!e.employerID),{blockLayout:a,columns:i,displayScope:g,displayDate:h,displayEmployer:y,displayExcerpt:v,employerID:f,itemsToShow:_,noJobsMessage:k,orderBy:j,enablePagination:E,jobsPerPage:C}=e;function x(t){return()=>{const n=e[t];o({[t]:!n})}}const S=(0,c.useBlockProps)();var B;if(t)return(0,n.createElement)("div",{...S},(0,n.createElement)(b.Placeholder,{icon:r,label:"Jobbnorge"},(0,n.createElement)("form",{onSubmit:function(e){e.preventDefault(),f&&(o({employerID:f}),l(!1))},className:"wp-block-dss-jobbnorge__placeholder-form"},window.wpJobbnorgeBlock&&window.wpJobbnorgeBlock.employers?(0,n.createElement)(b.SelectControl,{multiple:!0,value:f.split(","),onChange:e=>o({employerID:e.toString()}),options:(null!==(B=wpJobbnorgeBlock.employers)&&void 0!==B?B:[]).map((e=>{var o;return{label:e.label,value:e.value,disabled:null!==(o=e?.disabled)&&void 0!==o&&o}})),className:"wp-block-dss-jobbnorge__placeholder-input",help:(0,u.__)("Select employers to display. Ctrl-click (Windows) or Cmd-click (Mac) to select multiple employers. Shift-click to select a range of employers.","wp-jobbnorge-block"),__nextHasNoMarginBottom:!0}):(0,n.createElement)(b.TextControl,{placeholder:(0,u.__)("Employer ID [,id2, id3, ..]","wp-jobbnorge-block"),value:f,onChange:e=>o({employerID:e}),className:"wp-block-dss-jobbnorge__placeholder-input"}),(0,n.createElement)(b.Button,{variant:"primary",type:"submit"},(0,u.__)("Save","wp-jobbnorge-block")))));const D=[{icon:p,title:(0,u.__)("Edit Jobbnorge URL","wp-jobbnorge-block"),onClick:()=>l(!0)},{icon:d,title:(0,u.__)("List view","wp-jobbnorge-block"),onClick:()=>o({blockLayout:"list"}),isActive:"list"===a},{icon:m,title:(0,u.__)("Grid view","wp-jobbnorge-block"),onClick:()=>o({blockLayout:"grid"}),isActive:"grid"===a}];return(0,n.createElement)(n.Fragment,null,(0,n.createElement)(c.BlockControls,null,(0,n.createElement)(b.ToolbarGroup,{controls:D})),(0,n.createElement)(c.InspectorControls,null,(0,n.createElement)(b.PanelBody,{title:(0,u.__)("Settings","wp-jobbnorge-block")},(0,n.createElement)(b.ToggleControl,{label:(0,u.__)("Enable pagination","wp-jobbnorge-block"),help:(0,u.__)("When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown.","wp-jobbnorge-block"),checked:E,onChange:e=>o({enablePagination:e})}),!E&&(0,n.createElement)(b.RangeControl,{__nextHasNoMarginBottom:!0,label:(0,u.__)("Number of items","wp-jobbnorge-block"),value:_,onChange:e=>o({itemsToShow:e}),min:1,max:100,required:!0}),E&&(0,n.createElement)(b.RangeControl,{__nextHasNoMarginBottom:!0,label:(0,u.__)("Jobs per page","wp-jobbnorge-block"),value:C,onChange:e=>o({jobsPerPage:e}),min:1,max:50,required:!0}),f.includes(",")&&(0,n.createElement)(b.RadioControl,{label:(0,u.__)("Order by","wp-jobbnorge-block"),selected:j,options:[{label:(0,u.__)("Deadline","wp-jobbnorge-block"),value:"Deadline"},{label:(0,u.__)("Employer","wp-jobbnorge-block"),value:"Employer"}],onChange:e=>o({orderBy:e})}),(0,n.createElement)(b.TextareaControl,{label:(0,u.__)("No jobs found message","wp-jobbnorge-block"),help:(0,u.__)("Message to display if no jobs are found","wp-jobbnorge-block"),value:k||(0,u.__)("There are no jobs at this time.","wp-jobbnorge-block"),onChange:e=>o({noJobsMessage:e})})),(0,n.createElement)(b.PanelBody,{title:(0,u.__)("Item","wp-jobbnorge-block")},(0,n.createElement)(b.ToggleControl,{label:(0,u.__)("Display employer","wp-jobbnorge-block"),checked:y,onChange:x("displayEmployer")}),(0,n.createElement)(b.ToggleControl,{label:(0,u.__)("Display excerpt","wp-jobbnorge-block"),checked:v,onChange:x("displayExcerpt")}),(0,n.createElement)(b.ToggleControl,{label:(0,u.__)("Display deadline","wp-jobbnorge-block"),checked:h,onChange:x("displayDate")}),(0,n.createElement)(b.ToggleControl,{label:(0,u.__)("Display scope","wp-jobbnorge-block"),checked:g,onChange:x("displayScope")})),"grid"===a&&(0,n.createElement)(b.PanelBody,{title:(0,u.__)("Grid view","wp-jobbnorge-block")},(0,n.createElement)(b.RangeControl,{__nextHasNoMarginBottom:!0,label:(0,u.__)("Columns","wp-jobbnorge-block"),value:i,onChange:e=>o({columns:e}),min:2,max:6,required:!0}))),(0,n.createElement)("div",{...S},(0,n.createElement)(b.Disabled,null,(0,n.createElement)(w(),{block:"dss/jobbnorge",attributes:e,httpMethod:"POST"}))))}}})}},t={};function n(e){var l=t[e];if(void 0!==l)return l.exports;var r=t[e]={exports:{}};return o[e](r,r.exports,n),r.exports}n.m=o,e=[],n.O=function(o,t,l,r){if(!t){var a=1/0;for(s=0;s<e.length;s++){t=e[s][0],l=e[s][1],r=e[s][2];for(var i=!0,c=0;c<t.length;c++)(!1&r||a>=r)&&Object.keys(n.O).every((function(e){return n.O[e](t[c])}))?t.splice(c--,1):(i=!1,r<a&&(a=r));if(i){e.splice(s--,1);var b=l();void 0!==b&&(o=b)}}return o}r=r||0;for(var s=e.length;s>0&&e[s-1][2]>r;s--)e[s]=e[s-1];e[s]=[t,l,r]},n.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(o,{a:o}),o},n.d=function(e,o){for(var t in o)n.o(o,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},n.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},function(){var e={410:0,308:0};n.O.j=function(o){return 0===e[o]};var o=function(o,t){var l,r,a=t[0],i=t[1],c=t[2],b=0;if(a.some((function(o){return 0!==e[o]}))){for(l in i)n.o(i,l)&&(n.m[l]=i[l]);if(c)var s=c(n)}for(o&&o(t);b<a.length;b++)r=a[b],n.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return n.O(s)},t=self.webpackChunkjobbnorge_block=self.webpackChunkjobbnorge_block||[];t.forEach(o.bind(null,0)),t.push=o.bind(null,t.push.bind(t))}();var l=n.O(void 0,[308],(function(){return n(938)}));l=n.O(l)}(); -
jobbnorge-block/tags/2.2.0/build/style-init.css
r2997962 r3322139 1 ul.wp-block-dss-jobbnorge{list-style:none;padding:0}ul.wp-block-dss-jobbnorge.wp-block-dss-jobbnorge{box-sizing:border-box}ul.wp-block-dss-jobbnorge.alignleft{margin-right:2em}ul.wp-block-dss-jobbnorge.alignright{margin-left:2em}ul.wp-block-dss-jobbnorge li{margin:0 0 1em}ul.wp-block-dss-jobbnorge.is-grid{display:flex;flex-wrap:wrap;list-style:none;padding:0}ul.wp-block-dss-jobbnorge.is-grid li{margin:0 1em 1em 0;width:100%}@media(min-width:600px){ul.wp-block-dss-jobbnorge.columns-2 li{width:calc(50% - 1em)}ul.wp-block-dss-jobbnorge.columns-3 li{width:calc(33.33333% - 1em)}ul.wp-block-dss-jobbnorge.columns-4 li{width:calc(25% - 1em)}ul.wp-block-dss-jobbnorge.columns-5 li{width:calc(20% - 1em)}ul.wp-block-dss-jobbnorge.columns-6 li{width:calc(16.66667% - 1em)}}.wp-block-dss-jobbnorge__item-title{font-size:1.125em;font-weight:600;margin:0 0 .25em}.wp-block-dss-jobbnorge__item-meta{margin:0 0 .25em;padding:0}.wp-block-dss-jobbnorge__item-deadline,.wp-block-dss-jobbnorge__item-employer,.wp-block-dss-jobbnorge__item-scope{display:block;font-size:.8125em;font-weight:600} 1 ul.wp-block-dss-jobbnorge{list-style:none;padding:0}ul.wp-block-dss-jobbnorge.wp-block-dss-jobbnorge{box-sizing:border-box}ul.wp-block-dss-jobbnorge.alignleft{margin-right:2em}ul.wp-block-dss-jobbnorge.alignright{margin-left:2em}ul.wp-block-dss-jobbnorge li{margin:0 0 1em}ul.wp-block-dss-jobbnorge.is-grid{display:flex;flex-wrap:wrap;list-style:none;padding:0}ul.wp-block-dss-jobbnorge.is-grid li{margin:0 1em 1em 0;width:100%}@media(min-width:600px){ul.wp-block-dss-jobbnorge.columns-2 li{width:calc(50% - 1em)}ul.wp-block-dss-jobbnorge.columns-3 li{width:calc(33.33333% - 1em)}ul.wp-block-dss-jobbnorge.columns-4 li{width:calc(25% - 1em)}ul.wp-block-dss-jobbnorge.columns-5 li{width:calc(20% - 1em)}ul.wp-block-dss-jobbnorge.columns-6 li{width:calc(16.66667% - 1em)}}.wp-block-dss-jobbnorge__item-title{font-size:1.125em;font-weight:600;margin:0 0 .25em}.wp-block-dss-jobbnorge__item-meta{margin:0 0 .25em;padding:0}.wp-block-dss-jobbnorge__item-deadline,.wp-block-dss-jobbnorge__item-employer,.wp-block-dss-jobbnorge__item-scope{display:block;font-size:.8125em;font-weight:600}.wp-block-dss-jobbnorge__pagination{border-top:1px solid #e0e0e0;display:flex;flex-direction:column;gap:1rem;margin-top:2rem;padding:1rem 0}@media(min-width:600px){.wp-block-dss-jobbnorge__pagination{align-items:center;flex-direction:row;justify-content:space-between}}.wp-block-dss-jobbnorge__pagination-info{color:#666;font-size:.875rem;margin:0}.wp-block-dss-jobbnorge__pagination-controls{align-items:center;display:flex;gap:.5rem}.wp-block-dss-jobbnorge__pagination-controls button{background:#fff;border:1px solid #ddd;border-radius:4px;cursor:pointer;font-size:.875rem;padding:.5rem 1rem;transition:all .2s ease}.wp-block-dss-jobbnorge__pagination-controls button:hover:not(:disabled){background:#f5f5f5;border-color:#999}.wp-block-dss-jobbnorge__pagination-controls button:disabled{cursor:not-allowed;opacity:.5}.wp-block-dss-jobbnorge__pagination-controls .wp-block-dss-jobbnorge__pagination-info{color:#333;font-size:.875rem;margin:0 .5rem}.wp-block-dss-jobbnorge__loading{opacity:.6;pointer-events:none}.wp-block-dss-jobbnorge__loading:after{animation:spin 1s linear infinite;border:2px solid #ccc;border-radius:50%;border-top-color:#333;content:"";height:20px;left:50%;margin:-10px 0 0 -10px;position:absolute;top:50%;width:20px}.wp-block-dss-jobbnorge__error{background:#ffebe8;border:1px solid #d63638;border-radius:4px;color:#d63638;margin:1rem 0;padding:.75rem}.wp-block-dss-jobbnorge__error p{margin:0}@keyframes spin{to{transform:rotate(1turn)}} -
jobbnorge-block/tags/2.2.0/languages/wp-jobbnorge-block-en_US-5847f2cef22ef3cae0e9359a7a5dd2ec.json
r3002720 r3322139 1 1 { 2 2 "translation-revision-date": "YEAR-MO-DA HO:MI+ZONE", 3 "generator": "WP-CLI\/2. 9.0",3 "generator": "WP-CLI\/2.12.0", 4 4 "source": "build\/init.js", 5 5 "domain": "messages", … … 35 35 "" 36 36 ], 37 "Enable pagination": [ 38 "" 39 ], 40 "When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown.": [ 41 "" 42 ], 37 43 "Number of items": [ 44 "" 45 ], 46 "Jobs per page": [ 38 47 "" 39 48 ], -
jobbnorge-block/tags/2.2.0/languages/wp-jobbnorge-block-en_US-bb1d7dea005e67527e728d4801f74b61.json
r3002720 r3322139 1 1 { 2 2 "translation-revision-date": "YEAR-MO-DA HO:MI+ZONE", 3 "generator": "WP-CLI\/2. 9.0",3 "generator": "WP-CLI\/2.12.0", 4 4 "source": "src\/edit.js", 5 5 "domain": "messages", … … 35 35 "" 36 36 ], 37 "Enable pagination": [ 38 "" 39 ], 40 "When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown.": [ 41 "" 42 ], 37 43 "Number of items": [ 44 "" 45 ], 46 "Jobs per page": [ 38 47 "" 39 48 ], -
jobbnorge-block/tags/2.2.0/languages/wp-jobbnorge-block-en_US.po
r3002720 r3322139 1 # Copyright (C) 202 3PerS1 # Copyright (C) 2025 PerS 2 2 # This file is distributed under the GPL-2.0-or-later. 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Jobbnorge Block 2. 1.4\n"5 "Project-Id-Version: Jobbnorge Block 2.2.0\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/jobbnorge-block\n" 7 7 "Last-Translator: Per Søderlind <[email protected]\n" … … 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 202 3-11-28T12:11:37+00:00\n"12 "POT-Creation-Date: 2025-07-03T21:16:21+00:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 "X-Generator: WP-CLI 2. 9.0\n"14 "X-Generator: WP-CLI 2.12.0\n" 15 15 "X-Domain: wp-jobbnorge-block\n" 16 16 17 17 #. Plugin Name of the plugin 18 #: wp-jobb-norge.php 18 19 msgid "Jobbnorge Block" 19 20 msgstr "" 20 21 21 22 #. Plugin URI of the plugin 23 #: wp-jobb-norge.php 22 24 msgid "https://wordpress.org/plugins/jobbnorge-block/" 23 25 msgstr "" 24 26 25 27 #. Description of the plugin 28 #: wp-jobb-norge.php 26 29 msgid "Retrieve and display job listings from Jobbnorge.no" 27 30 msgstr "" 28 31 29 32 #. Author of the plugin 33 #: wp-jobb-norge.php 30 34 msgid "PerS" 31 35 msgstr "" 32 36 33 #: wp-jobb-norge.php:1 5937 #: wp-jobb-norge.php:181 34 38 msgid "Invalid ID" 35 39 msgstr "" 36 40 37 #: wp-jobb-norge.php: 18141 #: wp-jobb-norge.php:212 38 42 msgid "Error connecting to Jobbnorge.no" 39 43 msgstr "" 40 44 41 #: wp-jobb-norge.php: 19545 #: wp-jobb-norge.php:251 42 46 msgid "No jobs found" 43 47 msgstr "" 44 48 45 #: wp-jobb-norge.php:2 0549 #: wp-jobb-norge.php:261 46 50 msgid "(no title)" 47 51 msgstr "" 48 52 49 #: wp-jobb-norge.php:2 2650 #: build/init.js:1 51 #: src/edit.js:1 6053 #: wp-jobb-norge.php:282 54 #: build/init.js:1 55 #: src/edit.js:181 52 56 msgid "Employer" 53 57 msgstr "" 54 58 55 #: wp-jobb-norge.php:2 2759 #: wp-jobb-norge.php:283 56 60 msgid "Scope" 57 61 msgstr "" 58 62 59 #: wp-jobb-norge.php: 28263 #: wp-jobb-norge.php:345 60 64 msgid "Read more" 61 65 msgstr "" 62 66 63 #: wp-jobb-norge.php: 35367 #: wp-jobb-norge.php:416 64 68 msgid "Deadline:" 65 69 msgstr "" 66 70 67 #: build/init.js:1 68 #: src/edit.js:95 71 #: wp-jobb-norge.php:556 72 msgid "Job listings pagination" 73 msgstr "" 74 75 #: wp-jobb-norge.php:562 76 #, php-format 77 msgid "Showing %d-%d of %d jobs" 78 msgstr "" 79 80 #: wp-jobb-norge.php:577 81 #: wp-jobb-norge.php:582 82 msgid "Previous" 83 msgstr "" 84 85 #: wp-jobb-norge.php:590 86 #, php-format 87 msgid "Page %d of %d" 88 msgstr "" 89 90 #: wp-jobb-norge.php:601 91 #: wp-jobb-norge.php:606 92 msgid "Next" 93 msgstr "" 94 95 #: build/init.js:1 96 #: src/edit.js:97 69 97 msgid "Select employers to display. Ctrl-click (Windows) or Cmd-click (Mac) to select multiple employers. Shift-click to select a range of employers." 70 98 msgstr "" 71 99 72 100 #: build/init.js:1 73 #: src/edit.js:10 3101 #: src/edit.js:105 74 102 msgid "Employer ID [,id2, id3, ..]" 75 103 msgstr "" 76 104 77 105 #: build/init.js:1 78 #: src/edit.js:11 0106 #: src/edit.js:112 79 107 msgid "Save" 80 108 msgstr "" 81 109 82 110 #: build/init.js:1 83 #: src/edit.js:12 1111 #: src/edit.js:123 84 112 msgid "Edit Jobbnorge URL" 85 113 msgstr "" 86 114 87 115 #: build/init.js:1 88 #: src/edit.js:12 6116 #: src/edit.js:128 89 117 msgid "List view" 90 118 msgstr "" 91 119 92 120 #: build/init.js:1 93 #: src/edit.js:132 121 #: src/edit.js:134 122 #: src/edit.js:216 123 msgid "Grid view" 124 msgstr "" 125 126 #: build/init.js:1 127 #: src/edit.js:146 128 msgid "Settings" 129 msgstr "" 130 131 #: build/init.js:1 132 #: src/edit.js:148 133 msgid "Enable pagination" 134 msgstr "" 135 136 #: build/init.js:1 137 #: src/edit.js:149 138 msgid "When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown." 139 msgstr "" 140 141 #: build/init.js:1 142 #: src/edit.js:156 143 msgid "Number of items" 144 msgstr "" 145 146 #: build/init.js:1 147 #: src/edit.js:167 148 msgid "Jobs per page" 149 msgstr "" 150 151 #: build/init.js:1 152 #: src/edit.js:177 153 msgid "Order by" 154 msgstr "" 155 156 #: build/init.js:1 157 #: src/edit.js:180 158 msgid "Deadline" 159 msgstr "" 160 161 #: build/init.js:1 162 #: src/edit.js:187 163 msgid "No jobs found message" 164 msgstr "" 165 166 #: build/init.js:1 167 #: src/edit.js:188 168 msgid "Message to display if no jobs are found" 169 msgstr "" 170 171 #: build/init.js:1 172 #: src/edit.js:189 173 msgid "There are no jobs at this time." 174 msgstr "" 175 176 #: build/init.js:1 177 #: src/edit.js:193 178 msgid "Item" 179 msgstr "" 180 181 #: build/init.js:1 94 182 #: src/edit.js:195 95 msgid "Grid view"96 msgstr ""97 98 #: build/init.js:199 #: src/edit.js:144100 msgid "Settings"101 msgstr ""102 103 #: build/init.js:1104 #: src/edit.js:147105 msgid "Number of items"106 msgstr ""107 108 #: build/init.js:1109 #: src/edit.js:156110 msgid "Order by"111 msgstr ""112 113 #: build/init.js:1114 #: src/edit.js:159115 msgid "Deadline"116 msgstr ""117 118 #: build/init.js:1119 #: src/edit.js:166120 msgid "No jobs found message"121 msgstr ""122 123 #: build/init.js:1124 #: src/edit.js:167125 msgid "Message to display if no jobs are found"126 msgstr ""127 128 #: build/init.js:1129 #: src/edit.js:168130 msgid "There are no jobs at this time."131 msgstr ""132 133 #: build/init.js:1134 #: src/edit.js:172135 msgid "Item"136 msgstr ""137 138 #: build/init.js:1139 #: src/edit.js:174140 183 msgid "Display employer" 141 184 msgstr "" 142 185 143 186 #: build/init.js:1 144 #: src/edit.js: 179187 #: src/edit.js:200 145 188 msgid "Display excerpt" 146 189 msgstr "" 147 190 148 191 #: build/init.js:1 149 #: src/edit.js: 184192 #: src/edit.js:205 150 193 msgid "Display deadline" 151 194 msgstr "" 152 195 153 196 #: build/init.js:1 154 #: src/edit.js: 189197 #: src/edit.js:210 155 198 msgid "Display scope" 156 199 msgstr "" 157 200 158 201 #: build/init.js:1 159 #: src/edit.js: 198202 #: src/edit.js:219 160 203 msgid "Columns" 161 204 msgstr "" -
jobbnorge-block/tags/2.2.0/languages/wp-jobbnorge-block-nb_NO-5847f2cef22ef3cae0e9359a7a5dd2ec.json
r3002720 r3322139 1 1 { 2 "translation-revision-date": "202 3-11-28 13:09+0100",3 "generator": "WP-CLI\/2. 9.0",2 "translation-revision-date": "2025-07-03 23:16+0200", 3 "generator": "WP-CLI\/2.12.0", 4 4 "source": "build\/init.js", 5 5 "domain": "messages", … … 35 35 "Innstillinger" 36 36 ], 37 "Enable pagination": [ 38 "Aktiver paginering" 39 ], 40 "When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown.": [ 41 "N\u00e5r denne funksjonen er aktivert, vises alle jobber med pagineringskontroller. N\u00e5r den er deaktivert, vises bare det angitte antallet jobber." 42 ], 37 43 "Number of items": [ 38 44 "Antall oppf\u00f8ringer" 45 ], 46 "Jobs per page": [ 47 "Jobber per side" 39 48 ], 40 49 "Order by": [ -
jobbnorge-block/tags/2.2.0/languages/wp-jobbnorge-block-nb_NO-bb1d7dea005e67527e728d4801f74b61.json
r3002720 r3322139 1 1 { 2 "translation-revision-date": "202 3-11-28 13:09+0100",3 "generator": "WP-CLI\/2. 9.0",2 "translation-revision-date": "2025-07-03 23:16+0200", 3 "generator": "WP-CLI\/2.12.0", 4 4 "source": "src\/edit.js", 5 5 "domain": "messages", … … 35 35 "Innstillinger" 36 36 ], 37 "Enable pagination": [ 38 "Aktiver paginering" 39 ], 40 "When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown.": [ 41 "N\u00e5r denne funksjonen er aktivert, vises alle jobber med pagineringskontroller. N\u00e5r den er deaktivert, vises bare det angitte antallet jobber." 42 ], 37 43 "Number of items": [ 38 44 "Antall oppf\u00f8ringer" 45 ], 46 "Jobs per page": [ 47 "Jobber per side" 39 48 ], 40 49 "Order by": [ -
jobbnorge-block/tags/2.2.0/languages/wp-jobbnorge-block-nb_NO.po
r3002720 r3322139 5 5 "Project-Id-Version: Jobbnorge Block 0.1.0\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/jobbnorge-block\n" 7 "POT-Creation-Date: 202 3-11-28T11:53:20+00:00\n"8 "PO-Revision-Date: 202 3-11-28 13:09+0100\n"7 "POT-Creation-Date: 2025-07-03T21:00:36+00:00\n" 8 "PO-Revision-Date: 2025-07-03 23:16+0200\n" 9 9 "Last-Translator: Per Søderlind <[email protected]>\n" 10 10 "Language-Team: \n" … … 13 13 "Content-Type: text/plain; charset=UTF-8\n" 14 14 "Content-Transfer-Encoding: 8bit\n" 15 "X-Generator: Poedit 3. 4.1\n"15 "X-Generator: Poedit 3.6\n" 16 16 "X-Domain: wp-jobbnorge-block\n" 17 17 18 18 #. Plugin Name of the plugin 19 #: wp-jobb-norge.php 19 20 msgid "Jobbnorge Block" 20 21 msgstr "Jobbnorge-blokken" 21 22 22 23 #. Plugin URI of the plugin 24 #: wp-jobb-norge.php 23 25 msgid "https://wordpress.org/plugins/jobbnorge-block/" 24 26 msgstr "https://wordpress.org/plugins/jobbnorge-block/" 25 27 26 28 #. Description of the plugin 29 #: wp-jobb-norge.php 27 30 msgid "Retrieve and display job listings from Jobbnorge.no" 28 31 msgstr "Hente og vise stillingsannonser fra Jobbnorge.no" 29 32 30 33 #. Author of the plugin 34 #: wp-jobb-norge.php 31 35 msgid "PerS" 32 36 msgstr "PerS" 33 37 34 #: wp-jobb-norge.php:1 5938 #: wp-jobb-norge.php:181 35 39 msgid "Invalid ID" 36 40 msgstr "Ugyldig ID" 37 41 38 #: wp-jobb-norge.php: 18142 #: wp-jobb-norge.php:212 39 43 msgid "Error connecting to Jobbnorge.no" 40 44 msgstr "Feil ved tilkobling til Jobbnorge.no" 41 45 42 #: wp-jobb-norge.php: 19546 #: wp-jobb-norge.php:251 43 47 msgid "No jobs found" 44 48 msgstr "Ingen jobber funnet" 45 49 46 #: wp-jobb-norge.php:2 0550 #: wp-jobb-norge.php:261 47 51 msgid "(no title)" 48 52 msgstr "(ingen tittel)" 49 53 50 #: wp-jobb-norge.php:2 26 build/init.js:1 src/edit.js:16054 #: wp-jobb-norge.php:282 build/init.js:1 src/edit.js:181 51 55 msgid "Employer" 52 56 msgstr "Arbeidsgiver" 53 57 54 #: wp-jobb-norge.php:2 2758 #: wp-jobb-norge.php:283 55 59 msgid "Scope" 56 60 msgstr "Omfang" 57 61 58 #: wp-jobb-norge.php: 28262 #: wp-jobb-norge.php:345 59 63 msgid "Read more" 60 64 msgstr "Les mer" 61 65 62 #: wp-jobb-norge.php: 35366 #: wp-jobb-norge.php:416 63 67 msgid "Deadline:" 64 68 msgstr "Søknadsfrist:" 65 69 66 #: build/init.js:1 src/edit.js:95 70 #: wp-jobb-norge.php:556 71 msgid "Job listings pagination" 72 msgstr "Paginering av stillingsannonser" 73 74 #: wp-jobb-norge.php:562 75 #, php-format 76 msgid "Showing %d-%d of %d jobs" 77 msgstr "Viser %d-%d av %d jobber" 78 79 #: wp-jobb-norge.php:577 wp-jobb-norge.php:582 80 msgid "Previous" 81 msgstr "Forrige" 82 83 #: wp-jobb-norge.php:590 84 #, php-format 85 msgid "Page %d of %d" 86 msgstr "Side %d av %d" 87 88 #: wp-jobb-norge.php:601 wp-jobb-norge.php:606 89 msgid "Next" 90 msgstr "Neste" 91 92 #: build/init.js:1 src/edit.js:97 67 93 msgid "" 68 94 "Select employers to display. Ctrl-click (Windows) or Cmd-click (Mac) to " … … 73 99 "arbeidsgivere." 74 100 75 #: build/init.js:1 src/edit.js:10 3101 #: build/init.js:1 src/edit.js:105 76 102 msgid "Employer ID [,id2, id3, ..]" 77 103 msgstr "Arbeidsgiver-ID [,id2, id3, ...]" 78 104 79 #: build/init.js:1 src/edit.js:11 0105 #: build/init.js:1 src/edit.js:112 80 106 msgid "Save" 81 107 msgstr "Lagre" 82 108 83 #: build/init.js:1 src/edit.js:12 1109 #: build/init.js:1 src/edit.js:123 84 110 msgid "Edit Jobbnorge URL" 85 111 msgstr "Rediger Jobbnorge URL" 86 112 87 #: build/init.js:1 src/edit.js:12 6113 #: build/init.js:1 src/edit.js:128 88 114 msgid "List view" 89 115 msgstr "Listevisning" 90 116 91 #: build/init.js:1 src/edit.js:13 2 src/edit.js:195117 #: build/init.js:1 src/edit.js:134 src/edit.js:216 92 118 msgid "Grid view" 93 119 msgstr "Rutemønster" 94 120 95 #: build/init.js:1 src/edit.js:14 4121 #: build/init.js:1 src/edit.js:146 96 122 msgid "Settings" 97 123 msgstr "Innstillinger" 98 124 99 #: build/init.js:1 src/edit.js:147 125 #: build/init.js:1 src/edit.js:148 126 msgid "Enable pagination" 127 msgstr "Aktiver paginering" 128 129 #: build/init.js:1 src/edit.js:149 130 msgid "" 131 "When enabled, all jobs will be displayed with pagination controls. When " 132 "disabled, only the specified number of jobs will be shown." 133 msgstr "" 134 "Når denne funksjonen er aktivert, vises alle jobber med " 135 "pagineringskontroller. Når den er deaktivert, vises bare det angitte " 136 "antallet jobber." 137 138 #: build/init.js:1 src/edit.js:156 100 139 msgid "Number of items" 101 140 msgstr "Antall oppføringer" 102 141 103 #: build/init.js:1 src/edit.js:156 142 #: build/init.js:1 src/edit.js:167 143 msgid "Jobs per page" 144 msgstr "Jobber per side" 145 146 #: build/init.js:1 src/edit.js:177 104 147 msgid "Order by" 105 148 msgstr "Sorter etter" 106 149 107 #: build/init.js:1 src/edit.js:1 59150 #: build/init.js:1 src/edit.js:180 108 151 msgid "Deadline" 109 152 msgstr "Søknadsfrist" 110 153 111 #: build/init.js:1 src/edit.js:1 66154 #: build/init.js:1 src/edit.js:187 112 155 msgid "No jobs found message" 113 156 msgstr "Ingen jobber funnet melding" 114 157 115 #: build/init.js:1 src/edit.js:1 67158 #: build/init.js:1 src/edit.js:188 116 159 msgid "Message to display if no jobs are found" 117 160 msgstr "Melding som vises hvis ingen jobber er funnet" 118 161 119 #: build/init.js:1 src/edit.js:1 68162 #: build/init.js:1 src/edit.js:189 120 163 msgid "There are no jobs at this time." 121 164 msgstr "Det er for tiden ingen ledige stillinger." 122 165 123 #: build/init.js:1 src/edit.js:1 72166 #: build/init.js:1 src/edit.js:193 124 167 msgid "Item" 125 168 msgstr "Element" 126 169 127 #: build/init.js:1 src/edit.js:1 74170 #: build/init.js:1 src/edit.js:195 128 171 msgid "Display employer" 129 172 msgstr "Vis arbeidsgiver" 130 173 131 #: build/init.js:1 src/edit.js: 179174 #: build/init.js:1 src/edit.js:200 132 175 msgid "Display excerpt" 133 176 msgstr "Vis utdrag" 134 177 135 #: build/init.js:1 src/edit.js: 184178 #: build/init.js:1 src/edit.js:205 136 179 msgid "Display deadline" 137 180 msgstr "Vis søknadsfrist" 138 181 139 #: build/init.js:1 src/edit.js: 189182 #: build/init.js:1 src/edit.js:210 140 183 msgid "Display scope" 141 184 msgstr "Vis omfang" 142 185 143 #: build/init.js:1 src/edit.js: 198186 #: build/init.js:1 src/edit.js:219 144 187 msgid "Columns" 145 188 msgstr "Kolonner" -
jobbnorge-block/tags/2.2.0/languages/wp-jobbnorge-block.pot
r3002720 r3322139 1 # Copyright (C) 202 3PerS1 # Copyright (C) 2025 PerS 2 2 # This file is distributed under the GPL-2.0-or-later. 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Jobbnorge Block 2. 1.4\n"5 "Project-Id-Version: Jobbnorge Block 2.2.0\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/jobbnorge-block\n" 7 7 "Last-Translator: Per Søderlind <[email protected]\n" … … 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 202 3-11-28T12:11:37+00:00\n"12 "POT-Creation-Date: 2025-07-03T21:16:21+00:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 "X-Generator: WP-CLI 2. 9.0\n"14 "X-Generator: WP-CLI 2.12.0\n" 15 15 "X-Domain: wp-jobbnorge-block\n" 16 16 17 17 #. Plugin Name of the plugin 18 #: wp-jobb-norge.php 18 19 msgid "Jobbnorge Block" 19 20 msgstr "" 20 21 21 22 #. Plugin URI of the plugin 23 #: wp-jobb-norge.php 22 24 msgid "https://wordpress.org/plugins/jobbnorge-block/" 23 25 msgstr "" 24 26 25 27 #. Description of the plugin 28 #: wp-jobb-norge.php 26 29 msgid "Retrieve and display job listings from Jobbnorge.no" 27 30 msgstr "" 28 31 29 32 #. Author of the plugin 33 #: wp-jobb-norge.php 30 34 msgid "PerS" 31 35 msgstr "" 32 36 33 #: wp-jobb-norge.php:1 5937 #: wp-jobb-norge.php:181 34 38 msgid "Invalid ID" 35 39 msgstr "" 36 40 37 #: wp-jobb-norge.php: 18141 #: wp-jobb-norge.php:212 38 42 msgid "Error connecting to Jobbnorge.no" 39 43 msgstr "" 40 44 41 #: wp-jobb-norge.php: 19545 #: wp-jobb-norge.php:251 42 46 msgid "No jobs found" 43 47 msgstr "" 44 48 45 #: wp-jobb-norge.php:2 0549 #: wp-jobb-norge.php:261 46 50 msgid "(no title)" 47 51 msgstr "" 48 52 49 #: wp-jobb-norge.php:2 2650 #: build/init.js:1 51 #: src/edit.js:1 6053 #: wp-jobb-norge.php:282 54 #: build/init.js:1 55 #: src/edit.js:181 52 56 msgid "Employer" 53 57 msgstr "" 54 58 55 #: wp-jobb-norge.php:2 2759 #: wp-jobb-norge.php:283 56 60 msgid "Scope" 57 61 msgstr "" 58 62 59 #: wp-jobb-norge.php: 28263 #: wp-jobb-norge.php:345 60 64 msgid "Read more" 61 65 msgstr "" 62 66 63 #: wp-jobb-norge.php: 35367 #: wp-jobb-norge.php:416 64 68 msgid "Deadline:" 65 69 msgstr "" 66 70 67 #: build/init.js:1 68 #: src/edit.js:95 71 #: wp-jobb-norge.php:556 72 msgid "Job listings pagination" 73 msgstr "" 74 75 #: wp-jobb-norge.php:562 76 #, php-format 77 msgid "Showing %d-%d of %d jobs" 78 msgstr "" 79 80 #: wp-jobb-norge.php:577 81 #: wp-jobb-norge.php:582 82 msgid "Previous" 83 msgstr "" 84 85 #: wp-jobb-norge.php:590 86 #, php-format 87 msgid "Page %d of %d" 88 msgstr "" 89 90 #: wp-jobb-norge.php:601 91 #: wp-jobb-norge.php:606 92 msgid "Next" 93 msgstr "" 94 95 #: build/init.js:1 96 #: src/edit.js:97 69 97 msgid "Select employers to display. Ctrl-click (Windows) or Cmd-click (Mac) to select multiple employers. Shift-click to select a range of employers." 70 98 msgstr "" 71 99 72 100 #: build/init.js:1 73 #: src/edit.js:10 3101 #: src/edit.js:105 74 102 msgid "Employer ID [,id2, id3, ..]" 75 103 msgstr "" 76 104 77 105 #: build/init.js:1 78 #: src/edit.js:11 0106 #: src/edit.js:112 79 107 msgid "Save" 80 108 msgstr "" 81 109 82 110 #: build/init.js:1 83 #: src/edit.js:12 1111 #: src/edit.js:123 84 112 msgid "Edit Jobbnorge URL" 85 113 msgstr "" 86 114 87 115 #: build/init.js:1 88 #: src/edit.js:12 6116 #: src/edit.js:128 89 117 msgid "List view" 90 118 msgstr "" 91 119 92 120 #: build/init.js:1 93 #: src/edit.js:132 121 #: src/edit.js:134 122 #: src/edit.js:216 123 msgid "Grid view" 124 msgstr "" 125 126 #: build/init.js:1 127 #: src/edit.js:146 128 msgid "Settings" 129 msgstr "" 130 131 #: build/init.js:1 132 #: src/edit.js:148 133 msgid "Enable pagination" 134 msgstr "" 135 136 #: build/init.js:1 137 #: src/edit.js:149 138 msgid "When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown." 139 msgstr "" 140 141 #: build/init.js:1 142 #: src/edit.js:156 143 msgid "Number of items" 144 msgstr "" 145 146 #: build/init.js:1 147 #: src/edit.js:167 148 msgid "Jobs per page" 149 msgstr "" 150 151 #: build/init.js:1 152 #: src/edit.js:177 153 msgid "Order by" 154 msgstr "" 155 156 #: build/init.js:1 157 #: src/edit.js:180 158 msgid "Deadline" 159 msgstr "" 160 161 #: build/init.js:1 162 #: src/edit.js:187 163 msgid "No jobs found message" 164 msgstr "" 165 166 #: build/init.js:1 167 #: src/edit.js:188 168 msgid "Message to display if no jobs are found" 169 msgstr "" 170 171 #: build/init.js:1 172 #: src/edit.js:189 173 msgid "There are no jobs at this time." 174 msgstr "" 175 176 #: build/init.js:1 177 #: src/edit.js:193 178 msgid "Item" 179 msgstr "" 180 181 #: build/init.js:1 94 182 #: src/edit.js:195 95 msgid "Grid view"96 msgstr ""97 98 #: build/init.js:199 #: src/edit.js:144100 msgid "Settings"101 msgstr ""102 103 #: build/init.js:1104 #: src/edit.js:147105 msgid "Number of items"106 msgstr ""107 108 #: build/init.js:1109 #: src/edit.js:156110 msgid "Order by"111 msgstr ""112 113 #: build/init.js:1114 #: src/edit.js:159115 msgid "Deadline"116 msgstr ""117 118 #: build/init.js:1119 #: src/edit.js:166120 msgid "No jobs found message"121 msgstr ""122 123 #: build/init.js:1124 #: src/edit.js:167125 msgid "Message to display if no jobs are found"126 msgstr ""127 128 #: build/init.js:1129 #: src/edit.js:168130 msgid "There are no jobs at this time."131 msgstr ""132 133 #: build/init.js:1134 #: src/edit.js:172135 msgid "Item"136 msgstr ""137 138 #: build/init.js:1139 #: src/edit.js:174140 183 msgid "Display employer" 141 184 msgstr "" 142 185 143 186 #: build/init.js:1 144 #: src/edit.js: 179187 #: src/edit.js:200 145 188 msgid "Display excerpt" 146 189 msgstr "" 147 190 148 191 #: build/init.js:1 149 #: src/edit.js: 184192 #: src/edit.js:205 150 193 msgid "Display deadline" 151 194 msgstr "" 152 195 153 196 #: build/init.js:1 154 #: src/edit.js: 189197 #: src/edit.js:210 155 198 msgid "Display scope" 156 199 msgstr "" 157 200 158 201 #: build/init.js:1 159 #: src/edit.js: 198202 #: src/edit.js:219 160 203 msgid "Columns" 161 204 msgstr "" -
jobbnorge-block/tags/2.2.0/package-lock.json
r3003492 r3322139 1 1 { 2 2 "name": "jobbnorge-block", 3 "version": "2. 1.5",3 "version": "2.2.0", 4 4 "lockfileVersion": 3, 5 5 "requires": true, … … 7 7 "": { 8 8 "name": "jobbnorge-block", 9 "version": "2. 1.5",9 "version": "2.2.0", 10 10 "license": "GPL-2.0-or-later", 11 11 "dependencies": { -
jobbnorge-block/tags/2.2.0/package.json
r3003492 r3322139 1 1 { 2 2 "name": "jobbnorge-block", 3 "version": "2. 1.5",3 "version": "2.2.0", 4 4 "description": "Jobbnorge Block for WordPress Gutenberg", 5 5 "author": "Per Søderlind <[email protected]>", -
jobbnorge-block/tags/2.2.0/readme.txt
r3003492 r3322139 5 5 Requires at least: 5.9 6 6 Requires PHP: 7.4 7 Stable tag: 2. 1.57 Stable tag: 2.2.0 8 8 License: GPL-2.0-or-later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 104 104 == Changelog == 105 105 106 = 2.2.0 = 107 108 * NEW: Add frontend pagination support with AJAX loading 109 * NEW: Add pagination controls (enable/disable, jobs per page setting) 110 * ENHANCEMENT: Upgrade to Jobbnorge API v3 for better performance 111 * ENHANCEMENT: Implement PHP-based pagination to work around API limitations with employer filtering 112 * ENHANCEMENT: Add responsive grid layout that adapts to screen size 113 * ENHANCEMENT: Improve cache key logic to include pagination and layout parameters 114 * ENHANCEMENT: Add loading states and error handling for pagination 115 * ENHANCEMENT: Separate frontend and admin CSS loading for better performance 116 * FIX: Fix CSS class naming conflicts that prevented grid view from working on frontend 117 * FIX: Resolve frontend style loading issues 118 * DEVELOPER: Add comprehensive webpack build configuration for multiple entry points 119 * DEVELOPER: Add pagination JavaScript with proper AJAX handling and nonce security 120 106 121 = 2.1.5 = 107 122 -
jobbnorge-block/tags/2.2.0/src/block.json
r3003492 r3322139 3 3 "apiVersion": 2, 4 4 "name": "dss/jobbnorge", 5 "version": "2. 1.5",5 "version": "2.2.0", 6 6 "title": "Jobbnorge", 7 7 "category": "widgets", … … 63 63 "type": "number", 64 64 "default": 55 65 }, 66 "enablePagination": { 67 "type": "boolean", 68 "default": true 69 }, 70 "jobsPerPage": { 71 "type": "number", 72 "default": 10 65 73 } 66 74 }, 67 75 "textdomain": "wp-jobbnorge-block", 68 76 "editorScript": "file:init.js", 69 "editorStyle": "file:editor. scss",70 "style": "file:style .scss"77 "editorStyle": "file:editor.css", 78 "style": "file:style-init.css" 71 79 } -
jobbnorge-block/tags/2.2.0/src/edit.js
r3002720 r3322139 52 52 noJobsMessage, 53 53 orderBy, 54 enablePagination, 55 jobsPerPage, 54 56 } = attributes; 55 57 … … 143 145 <InspectorControls> 144 146 <PanelBody title={__('Settings', 'wp-jobbnorge-block')}> 145 <RangeControl 146 __nextHasNoMarginBottom 147 label={__('Number of items', 'wp-jobbnorge-block')} 148 value={itemsToShow} 149 onChange={(value) => setAttributes({ itemsToShow: value })} 150 min={DEFAULT_MIN_ITEMS} 151 max={DEFAULT_MAX_ITEMS} 152 required 153 /> 147 <ToggleControl 148 label={__('Enable pagination', 'wp-jobbnorge-block')} 149 help={__('When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown.', 'wp-jobbnorge-block')} 150 checked={enablePagination} 151 onChange={(value) => setAttributes({ enablePagination: value })} 152 /> 153 {!enablePagination && ( 154 <RangeControl 155 __nextHasNoMarginBottom 156 label={__('Number of items', 'wp-jobbnorge-block')} 157 value={itemsToShow} 158 onChange={(value) => setAttributes({ itemsToShow: value })} 159 min={DEFAULT_MIN_ITEMS} 160 max={DEFAULT_MAX_ITEMS} 161 required 162 /> 163 )} 164 {enablePagination && ( 165 <RangeControl 166 __nextHasNoMarginBottom 167 label={__('Jobs per page', 'wp-jobbnorge-block')} 168 value={jobsPerPage} 169 onChange={(value) => setAttributes({ jobsPerPage: value })} 170 min={1} 171 max={50} 172 required 173 /> 174 )} 154 175 {employerID.includes(',') && ( 155 176 <RadioControl -
jobbnorge-block/tags/2.2.0/src/editor.scss
r2853882 r3322139 1 1 $break-medium: 782px; 2 $break-small: 600px; 2 3 $grid-unit: 8px; 3 4 $grid-unit-10: 1 * $grid-unit; // 8px … … 9 10 } 10 11 11 .wp-block-dss-jobbnorge li a > div { 12 @mixin break-small() { 13 @media (min-width: #{ ($break-small) }) { 14 @content; 15 } 16 } 17 18 .wp-block-dss-jobbnorge li a>div { 12 19 display: inline; 13 20 } … … 17 24 align-items: stretch; 18 25 19 > * {26 >* { 20 27 margin-bottom: $grid-unit-10; 21 28 } 22 29 23 30 @include break-medium() { 24 > * {31 >* { 25 32 margin-bottom: 0; 26 33 } 27 34 } 28 35 } 29 30 31 36 32 37 .wp-block-dss-jobbnorge__placeholder-input { … … 43 48 } 44 49 } 50 51 // Grid styles for the editor 52 ul.wp-block-dss-jobbnorge { 53 list-style: none; 54 padding: 0; 55 56 &.wp-block-dss-jobbnorge { 57 box-sizing: border-box; 58 } 59 60 li { 61 margin: 0 0 1em 0; 62 } 63 64 &.is-grid { 65 display: flex; 66 flex-wrap: wrap; 67 padding: 0; 68 list-style: none; 69 70 li { 71 margin: 0 1em 1em 0; 72 width: 100%; 73 } 74 } 75 76 @include break-small { 77 @for $i from 2 through 6 { 78 &.columns-#{ $i } li { 79 width: calc((100% / #{ $i }) - 1em); 80 } 81 } 82 } 83 } -
jobbnorge-block/tags/2.2.0/src/style.scss
r2997962 r3322139 8 8 9 9 10 ul.wp-block-dss-jobbnorge { // The ul is needed for specificity to override the reset styles in the editor. 10 ul.wp-block-dss-jobbnorge { 11 // The ul is needed for specificity to override the reset styles in the editor. 11 12 list-style: none; 12 13 padding: 0; … … 21 22 margin-right: 2em; 22 23 } 24 23 25 &.alignright { 24 26 /*rtl:ignore*/ 25 27 margin-left: 2em; 26 28 } 29 27 30 li { 28 31 margin: 0 0 1em 0; 29 32 } 33 30 34 &.is-grid { 31 35 display: flex; … … 43 47 @for $i from 2 through 6 { 44 48 &.columns-#{ $i } li { 45 width: calc(( 100% / #{ $i }) - 1em);49 width: calc((100% / #{ $i }) - 1em); 46 50 } 47 51 } … … 63 67 .wp-block-dss-jobbnorge__item-employer, 64 68 .wp-block-dss-jobbnorge__item-deadline, 65 .wp-block-dss-jobbnorge__item-scope {69 .wp-block-dss-jobbnorge__item-scope { 66 70 display: block; 67 71 font-weight: 600; … … 69 73 } 70 74 75 // Pagination styles 76 .wp-block-dss-jobbnorge { 77 &__pagination { 78 display: flex; 79 flex-direction: column; 80 gap: 1rem; 81 margin-top: 2rem; 82 padding: 1rem 0; 83 border-top: 1px solid #e0e0e0; 84 85 @include break-small { 86 flex-direction: row; 87 justify-content: space-between; 88 align-items: center; 89 } 90 } 91 92 &__pagination-info { 93 font-size: 0.875rem; 94 color: #666; 95 margin: 0; 96 } 97 98 &__pagination-controls { 99 display: flex; 100 gap: 0.5rem; 101 align-items: center; 102 103 button { 104 padding: 0.5rem 1rem; 105 border: 1px solid #ddd; 106 background: white; 107 cursor: pointer; 108 border-radius: 4px; 109 font-size: 0.875rem; 110 transition: all 0.2s ease; 111 112 &:hover:not(:disabled) { 113 background: #f5f5f5; 114 border-color: #999; 115 } 116 117 &:disabled { 118 opacity: 0.5; 119 cursor: not-allowed; 120 } 121 } 122 123 .wp-block-dss-jobbnorge__pagination-info { 124 font-size: 0.875rem; 125 color: #333; 126 margin: 0 0.5rem; 127 } 128 } 129 130 // Loading state 131 &__loading { 132 opacity: 0.6; 133 pointer-events: none; 134 135 &::after { 136 content: ''; 137 position: absolute; 138 top: 50%; 139 left: 50%; 140 width: 20px; 141 height: 20px; 142 margin: -10px 0 0 -10px; 143 border: 2px solid #ccc; 144 border-top-color: #333; 145 border-radius: 50%; 146 animation: spin 1s linear infinite; 147 } 148 } 149 150 // Error message 151 &__error { 152 margin: 1rem 0; 153 padding: 0.75rem; 154 background: #ffebe8; 155 border: 1px solid #d63638; 156 border-radius: 4px; 157 color: #d63638; 158 159 p { 160 margin: 0; 161 } 162 } 163 } 164 165 @keyframes spin { 166 to { 167 transform: rotate(360deg); 168 } 169 } -
jobbnorge-block/tags/2.2.0/wp-jobb-norge.php
r3003492 r3322139 6 6 * Requires at least: 5.9 7 7 * Requires PHP: 7.0 8 * Version: 2. 1.58 * Version: 2.2.0 9 9 * Author: PerS 10 10 * License: GPL-2.0-or-later … … 36 36 add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\dss_jobbnorge_enqueue_scripts' ); 37 37 38 // Add the 'dss_jobbnorge_enqueue_ scripts' function to the 'wp_enqueue_scripts' action hook.38 // Add the 'dss_jobbnorge_enqueue_frontend_styles' function to the 'wp_enqueue_scripts' action hook. 39 39 // This function will be called when scripts and styles are enqueued for the front end of the site. 40 add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\dss_jobbnorge_enqueue_ scripts' );40 add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\dss_jobbnorge_enqueue_frontend_styles' ); 41 41 42 42 // Load the plugin's text domain for internationalization. … … 50 50 register_block_type( 51 51 __DIR__ . '/build', 52 [ 52 [ 53 53 'render_callback' => __NAMESPACE__ . '\render_block_dss_jobbnorge', 54 54 ] … … 81 81 // If it does, require it and merge its dependencies with the existing ones. 82 82 $file = require $deps_file; 83 $jsdeps = array_merge( $jsdeps, $file[ 'dependencies'] );83 $jsdeps = array_merge( $jsdeps, $file[ 'dependencies' ] ); 84 84 // Also, set the version to the one from the file. 85 $version = $file[ 'version'];85 $version = $file[ 'version' ]; 86 86 } 87 87 … … 92 92 wp_enqueue_style( 'dss-jobbnorge-admin' ); 93 93 } 94 95 // Register and enqueue a CSS file for the public view.96 wp_register_style( 'dss-jobbnorge', plugin_dir_url( __FILE__ ) . 'build/style-init.css', [], $version );97 wp_enqueue_style( 'dss-jobbnorge' );98 94 99 95 // Set translations for the script. … … 118 114 'dss-jobbnorge-editor-script', 119 115 'wpJobbnorgeBlock', 120 [ 116 [ 121 117 'employers' => $employers, 122 118 ] … … 126 122 127 123 /** 124 * Enqueue frontend styles for the block 125 * 126 * @return void 127 */ 128 function dss_jobbnorge_enqueue_frontend_styles(): void { 129 // Define the path to the dependencies file. 130 $deps_file = plugin_dir_path( __FILE__ ) . 'build/init.asset.php'; 131 132 // Initialize version number. 133 $version = wp_rand(); 134 135 // Check if the dependencies file exists. 136 if ( file_exists( $deps_file ) ) { 137 // If it does, require it and get the version. 138 $file = require $deps_file; 139 $version = $file[ 'version' ]; 140 } 141 142 // Register and enqueue a CSS file for the public view. 143 wp_register_style( 'dss-jobbnorge', plugin_dir_url( __FILE__ ) . 'build/style-init.css', [], $version ); 144 wp_enqueue_style( 'dss-jobbnorge' ); 145 } 146 147 /** 128 148 * Renders the `jobbnorge` block on server. 129 149 * … … 137 157 $attributes = wp_parse_args( 138 158 $attributes, 139 [ 140 'employerID' => '', 141 'displayEmployer' => false, 142 'displayDate' => true, 143 'displayDeadline' => false, 144 'displayScope' => false, 145 'displayExcerpt' => true, 146 'excerptLength' => 55, 147 'blockLayout' => 'list', 148 'orderBy' => 'Deadline', 149 'columns' => 3, 150 'itemsToShow' => 5, 159 [ 160 'employerID' => '', 161 'displayEmployer' => false, 162 'displayDate' => true, 163 'displayDeadline' => false, 164 'displayScope' => false, 165 'displayExcerpt' => true, 166 'excerptLength' => 55, 167 'blockLayout' => 'list', 168 'orderBy' => 'Deadline', 169 'columns' => 3, 170 'itemsToShow' => 5, 171 'enablePagination' => true, 172 'jobsPerPage' => 10, 151 173 ] 152 174 ); 153 175 154 176 // Convert employer IDs to an array and trim whitespace. 155 $arr_ids = array_map( 'trim', explode( ',', $attributes[ 'employerID'] ) );177 $arr_ids = array_map( 'trim', explode( ',', $attributes[ 'employerID' ] ) ); 156 178 157 179 // Check if all IDs are numeric. If not, return an error message. … … 160 182 } 161 183 162 // Construct the API URL. 163 $jobbnorge_api_url = 'https://publicapi.jobbnorge.no/v2/Jobs?abroad=false&orderBy=' . $attributes['orderBy']; 184 // Get current page for pagination 185 $current_page = isset( $_GET[ 'jobbnorge_page' ] ) ? max( 1, intval( $_GET[ 'jobbnorge_page' ] ) ) : 1; 186 187 // Determine items per page based on pagination setting 188 $items_per_page = $attributes[ 'enablePagination' ] ? $attributes[ 'jobsPerPage' ] : $attributes[ 'itemsToShow' ]; 189 190 // Construct the API URL for v3 191 // NOTE: API v3 pagination doesn't work correctly with employer filtering 192 // So we fetch all jobs for the employers and paginate in PHP 193 $jobbnorge_api_url = 'https://publicapi.jobbnorge.no/v3/Jobs?abroad=false&orderBy=' . $attributes[ 'orderBy' ]; 164 194 165 195 // Add each employer ID to the API URL. … … 171 201 $cache = new \Jobbnorge_CacheHandler( $cache_path ); 172 202 173 $cache_key = md5( $jobbnorge_api_url ); 174 $expiration = apply_filters( 'jobbnorge_cache_time', 30 * MINUTE_IN_SECONDS ); 175 $body = $cache->get( $cache_key, $expiration ); 176 177 if ( false === $body ) { 203 // Cache key based on employer IDs and settings, not pagination 204 $cache_key = md5( $jobbnorge_api_url ); 205 $expiration = apply_filters( 'jobbnorge_cache_time', 30 * MINUTE_IN_SECONDS ); 206 $response_data = $cache->get( $cache_key, $expiration ); 207 208 if ( false === $response_data ) { 178 209 $response = wp_remote_get( $jobbnorge_api_url ); 179 210 … … 182 213 } 183 214 184 $body = wp_remote_retrieve_body( $response ); 185 $cache->set( $cache_key, $body ); 186 } 187 188 // Decode the JSON response and limit the number of items. 189 $items = json_decode( $body, true ); 190 // Just get desired number of items. 191 $items = array_slice( $items, 0, $attributes['itemsToShow'] ); 215 $body = wp_remote_retrieve_body( $response ); 216 $response_data = json_decode( $body, true ); 217 $cache->set( $cache_key, $response_data ); 218 } 219 220 // Debug: Log the API response structure 221 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { 222 error_log( 'Jobbnorge API URL: ' . $jobbnorge_api_url ); 223 error_log( 'Jobbnorge API Response: ' . print_r( $response_data, true ) ); 224 } 225 // Handle v3 API response structure 226 $all_items = isset( $response_data[ 'jobs' ] ) ? $response_data[ 'jobs' ] : $response_data; 227 $total_jobs = count( $all_items ); 228 229 // Debug: Log the items array 230 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { 231 error_log( 'Items count: ' . count( $all_items ) ); 232 error_log( 'Total jobs: ' . $total_jobs ); 233 if ( ! empty( $all_items ) ) { 234 error_log( 'First item: ' . print_r( $all_items[ 0 ], true ) ); 235 } 236 } 237 238 // Implement pagination in PHP since API pagination doesn't work with employer filtering 239 if ( $attributes[ 'enablePagination' ] && $total_jobs > 0 ) { 240 // Calculate pagination 241 $start_index = ( $current_page - 1 ) * $attributes[ 'jobsPerPage' ]; 242 $items = array_slice( $all_items, $start_index, $attributes[ 'jobsPerPage' ] ); 243 } else { 244 // For non-paginated, limit to itemsToShow 245 $items = array_slice( $all_items, 0, $attributes[ 'itemsToShow' ] ); 246 $total_jobs = count( $items ); // Update total for non-paginated display 247 } 192 248 193 249 // If there are no items, return an error message. … … 202 258 foreach ( $items as $item ) { 203 259 // Sanitize and format the title. 204 $title = esc_html( trim( wp_strip_all_tags( $item[ 'title'] ) ) );260 $title = esc_html( trim( wp_strip_all_tags( $item[ 'title' ] ) ) ); 205 261 $title = empty( $title ) ? __( '(no title)', 'wp-jobbnorge-block' ) : $title; 206 262 207 263 // Sanitize the link. 208 $link = esc_url( $item[ 'link'] );264 $link = esc_url( $item[ 'link' ] ); 209 265 // If there's a link, wrap the title in an anchor tag. 210 266 $title = $link ? "<a href='{$link}'>{$title}</a>" : $title; … … 216 272 $deadline = ''; 217 273 // If the displayDate attribute is true and the item has a deadline, format the deadline. 218 if ( $attributes[ 'displayDate'] && isset( $item['deadline'] ) ) {219 $deadline = format_deadline( $item[ 'deadline'] );274 if ( $attributes[ 'displayDate' ] && isset( $item[ 'deadline' ] ) ) { 275 $deadline = format_deadline( $item[ 'deadline' ] ); 220 276 } 221 277 … … 238 294 } 239 295 240 // Initialize an array for the classnames. 241 $classnames = []; 242 243 // If the blockLayout attribute is 'grid', add the 'is-grid' and 'columns-' classes. 244 if ( 'grid' === $attributes['blockLayout'] ) { 245 add_classname( $classnames, $attributes, 'blockLayout', 'is-grid' ); 246 add_classname( $classnames, $attributes, 'columns', 'columns-' . $attributes['columns'] ); 247 } 248 249 // Add the 'has-' classes based on the display attributes. 250 add_classname( $classnames, $attributes, 'displayEmployer', 'has-employer' ); 251 add_classname( $classnames, $attributes, 'displayDate', 'has-dates' ); 252 add_classname( $classnames, $attributes, 'displayDeadline', 'has-deadline' ); 253 add_classname( $classnames, $attributes, 'displayScope', 'has-scope' ); 254 add_classname( $classnames, $attributes, 'displayExcerpt', 'has-excerpts' ); 255 256 // Get the block wrapper attributes and add the classnames to it. 257 $wrapper_attributes = get_block_wrapper_attributes( [ 'class' => implode( ' ', $classnames ) ] ); 296 // Get the block wrapper attributes (without grid classes) 297 $wrapper_classes = []; 298 add_classname( $wrapper_classes, $attributes, 'displayEmployer', 'has-employer' ); 299 add_classname( $wrapper_classes, $attributes, 'displayDate', 'has-dates' ); 300 add_classname( $wrapper_classes, $attributes, 'displayDeadline', 'has-deadline' ); 301 add_classname( $wrapper_classes, $attributes, 'displayScope', 'has-scope' ); 302 add_classname( $wrapper_classes, $attributes, 'displayExcerpt', 'has-excerpts' ); 303 304 $wrapper_attributes = get_block_wrapper_attributes( [ 305 'class' => implode( ' ', $wrapper_classes ), 306 'data-attributes' => esc_attr( json_encode( $attributes ) ), 307 ] ); 308 309 // Generate the ul classes (including grid classes) 310 $ul_classes = [ 'wp-block-dss-jobbnorge' ]; 311 if ( 'grid' === $attributes[ 'blockLayout' ] ) { 312 $ul_classes[] = 'is-grid'; 313 $ul_classes[] = 'columns-' . $attributes[ 'columns' ]; 314 } 315 316 // Generate pagination controls if enabled 317 $pagination_html = ''; 318 if ( $attributes[ 'enablePagination' ] && count( $all_items ) > $attributes[ 'jobsPerPage' ] ) { 319 $pagination_html = generate_pagination_controls( $current_page, count( $all_items ), $attributes[ 'jobsPerPage' ], $attributes ); 320 } 258 321 259 322 // Return the final HTML string, wrapping the list items in an unordered list. 260 return sprintf( '< ul %s>%s</ul>', $wrapper_attributes, $list_items);323 return sprintf( '<div %s><ul class="%s">%s</ul>%s</div>', $wrapper_attributes, esc_attr( implode( ' ', $ul_classes ) ), $list_items, $pagination_html ); 261 324 } 262 325 … … 273 336 274 337 // If the displayExcerpt attribute is true and the item has a summary, format the excerpt. 275 if ( $attributes[ 'displayExcerpt'] && isset( $item['summary'] ) ) {338 if ( $attributes[ 'displayExcerpt' ] && isset( $item[ 'summary' ] ) ) { 276 339 // Decode the HTML entities in the summary. 277 $excerpt = html_entity_decode( $item[ 'summary'], ENT_QUOTES, get_option( 'blog_charset' ) );340 $excerpt = html_entity_decode( $item[ 'summary' ], ENT_QUOTES, get_option( 'blog_charset' ) ); 278 341 // Trim the excerpt to the excerptLength and escape it for safe use in HTML output. 279 $excerpt = esc_attr( wp_trim_words( $excerpt, $attributes[ 'excerptLength'], '' ) );342 $excerpt = esc_attr( wp_trim_words( $excerpt, $attributes[ 'excerptLength' ], '' ) ); 280 343 281 344 // Format the read more link. 282 $read_more = sprintf( ' ... <a href="%s">%s</a>', esc_url( $item[ 'link'] ), __( 'Read more', 'wp-jobbnorge-block' ) );345 $read_more = sprintf( ' ... <a href="%s">%s</a>', esc_url( $item[ 'link' ] ), __( 'Read more', 'wp-jobbnorge-block' ) ); 283 346 284 347 // Add the excerpt and read more link to the result string, wrapped in a div. … … 338 401 // Format the date according to the site's date format. 339 402 $str_date = date_i18n( get_option( 'date_format' ), $date ); 340 } catch ( \Exception $e) {403 } catch (\Exception $e) { 341 404 // If there's an exception, fallback to the original date. 342 405 $str_date = $deadline_date; … … 348 411 return sprintf( 349 412 '<time datetime="%1$s" class="wp-block-dss-jobbnorge__item-deadline">%2$s %3$s</time> ', 350 // If there's a parsed date, use it for the datetime attribute. Otherwise, leave it empty.413 // If there's a parsed date, use it for the datetime attribute. Otherwise, leave it empty. 351 414 ( $date ) ? esc_attr( wp_date( 'c', $date ) ) : '', 352 415 // Translate the 'Deadline:' string. … … 406 469 function parse_date_fallback( $deadline_date ) { 407 470 // Define an array of month names in Norwegian. 408 $str_months = [ 471 $str_months = [ 409 472 'januar', 410 473 'februar', … … 422 485 423 486 // Define an array of month numbers. 424 $num_months = [ 487 $num_months = [ 425 488 '01', 426 489 '02', … … 448 511 449 512 // Return a Unix timestamp for the date. 450 return mktime( 0, 0, 0, $dato_arr[ 2], $dato_arr[1], $dato_arr[3] );513 return mktime( 0, 0, 0, $dato_arr[ 2 ], $dato_arr[ 1 ], $dato_arr[ 3 ] ); 451 514 } 452 515 … … 466 529 } 467 530 } 531 532 /** 533 * Generates pagination controls for the job listings. 534 * 535 * @param int $current_page The current page number. 536 * @param int $total_jobs The total number of jobs. 537 * @param int $jobs_per_page The number of jobs per page. 538 * @param array $attributes The block attributes. 539 * @return string The pagination HTML. 540 */ 541 function generate_pagination_controls( $current_page, $total_jobs, $jobs_per_page, $attributes ) { 542 $total_pages = ceil( $total_jobs / $jobs_per_page ); 543 544 if ( $total_pages <= 1 ) { 545 return ''; 546 } 547 548 $prev_page = max( 1, $current_page - 1 ); 549 $next_page = min( $total_pages, $current_page + 1 ); 550 551 // Calculate result range 552 $start_item = ( ( $current_page - 1 ) * $jobs_per_page ) + 1; 553 $end_item = min( $current_page * $jobs_per_page, $total_jobs ); 554 555 // Generate pagination HTML 556 $pagination_html = '<nav class="wp-block-dss-jobbnorge__pagination" role="navigation" aria-label="' . esc_attr__( 'Job listings pagination', 'wp-jobbnorge-block' ) . '">'; 557 558 // Results info 559 $pagination_html .= sprintf( 560 '<div class="wp-block-dss-jobbnorge__pagination-info">%s</div>', 561 sprintf( 562 esc_html__( 'Showing %d-%d of %d jobs', 'wp-jobbnorge-block' ), 563 $start_item, 564 $end_item, 565 $total_jobs 566 ) 567 ); 568 569 // Pagination controls 570 $pagination_html .= '<div class="wp-block-dss-jobbnorge__pagination-controls">'; 571 572 // Previous button 573 if ( $current_page > 1 ) { 574 $pagination_html .= sprintf( 575 '<button type="button" class="wp-block-dss-jobbnorge__pagination-prev" data-page="%d">%s</button>', 576 $prev_page, 577 esc_html__( 'Previous', 'wp-jobbnorge-block' ) 578 ); 579 } else { 580 $pagination_html .= sprintf( 581 '<button type="button" class="wp-block-dss-jobbnorge__pagination-prev" disabled>%s</button>', 582 esc_html__( 'Previous', 'wp-jobbnorge-block' ) 583 ); 584 } 585 586 // Page info 587 $pagination_html .= sprintf( 588 '<span class="wp-block-dss-jobbnorge__pagination-info">%s</span>', 589 sprintf( 590 esc_html__( 'Page %d of %d', 'wp-jobbnorge-block' ), 591 $current_page, 592 $total_pages 593 ) 594 ); 595 596 // Next button 597 if ( $current_page < $total_pages ) { 598 $pagination_html .= sprintf( 599 '<button type="button" class="wp-block-dss-jobbnorge__pagination-next" data-page="%d">%s</button>', 600 $next_page, 601 esc_html__( 'Next', 'wp-jobbnorge-block' ) 602 ); 603 } else { 604 $pagination_html .= sprintf( 605 '<button type="button" class="wp-block-dss-jobbnorge__pagination-next" disabled>%s</button>', 606 esc_html__( 'Next', 'wp-jobbnorge-block' ) 607 ); 608 } 609 610 $pagination_html .= '</div>'; 611 $pagination_html .= '</nav>'; 612 613 return $pagination_html; 614 } 615 616 /** 617 * Register AJAX endpoints for pagination. 618 */ 619 add_action( 'wp_ajax_jobbnorge_get_jobs', __NAMESPACE__ . '\handle_ajax_get_jobs' ); 620 add_action( 'wp_ajax_nopriv_jobbnorge_get_jobs', __NAMESPACE__ . '\handle_ajax_get_jobs' ); 621 622 /** 623 * Handle AJAX request for paginated job listings. 624 */ 625 function handle_ajax_get_jobs() { 626 // Verify nonce 627 if ( ! wp_verify_nonce( $_POST[ 'nonce' ], 'jobbnorge_pagination_nonce' ) ) { 628 wp_die( 'Security check failed' ); 629 } 630 631 // Get and sanitize parameters 632 $page = isset( $_POST[ 'page' ] ) ? max( 1, intval( $_POST[ 'page' ] ) ) : 1; 633 $attributes = isset( $_POST[ 'attributes' ] ) ? json_decode( stripslashes( $_POST[ 'attributes' ] ), true ) : []; 634 635 // Validate attributes 636 if ( empty( $attributes ) || ! is_array( $attributes ) ) { 637 wp_send_json_error( 'Invalid attributes' ); 638 } 639 640 // Set current page in GET superglobal for compatibility 641 $_GET[ 'jobbnorge_page' ] = $page; 642 643 // Generate the job listings HTML 644 $html = render_block_dss_jobbnorge( $attributes ); 645 646 // Return JSON response 647 wp_send_json_success( [ 'html' => $html ] ); 648 } 649 650 /** 651 * Enqueue frontend JavaScript for pagination. 652 */ 653 function enqueue_pagination_script() { 654 // Check if the block is being used on the current page 655 if ( ! has_block( 'dss/jobbnorge' ) ) { 656 return; 657 } 658 659 // Define the path to the pagination dependencies file. 660 $deps_file = plugin_dir_path( __FILE__ ) . 'build/pagination.asset.php'; 661 662 // Initialize an array for JavaScript dependencies and a random version number. 663 $jsdeps = []; 664 $version = wp_rand(); 665 666 // Check if the dependencies file exists. 667 if ( file_exists( $deps_file ) ) { 668 // If it does, require it and merge its dependencies with the existing ones. 669 $file = require $deps_file; 670 $jsdeps = array_merge( $jsdeps, $file[ 'dependencies' ] ); 671 // Also, set the version to the one from the file. 672 $version = $file[ 'version' ]; 673 } 674 675 wp_enqueue_script( 676 'jobbnorge-pagination', 677 plugin_dir_url( __FILE__ ) . 'build/pagination.js', 678 $jsdeps, 679 $version, 680 true 681 ); 682 683 // Localize script with AJAX URL and nonce 684 wp_localize_script( 685 'jobbnorge-pagination', 686 'jobbnorgeAjax', 687 [ 688 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 689 'nonce' => wp_create_nonce( 'jobbnorge_pagination_nonce' ), 690 ] 691 ); 692 } 693 694 // Hook into wp_enqueue_scripts to add pagination script 695 add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\enqueue_pagination_script' ); -
jobbnorge-block/trunk/CHANGELOG.md
r3003492 r3322139 1 # Cangelog 1 # Changelog 2 3 ## 2.2.0 4 5 * **NEW**: Add frontend pagination support with AJAX loading 6 * **NEW**: Add pagination controls (enable/disable, jobs per page setting) 7 * **ENHANCEMENT**: Upgrade to Jobbnorge API v3 for better performance 8 * **ENHANCEMENT**: Implement PHP-based pagination to work around API limitations with employer filtering 9 * **ENHANCEMENT**: Add responsive grid layout that adapts to screen size 10 * **ENHANCEMENT**: Improve cache key logic to include pagination and layout parameters 11 * **ENHANCEMENT**: Add loading states and error handling for pagination 12 * **ENHANCEMENT**: Separate frontend and admin CSS loading for better performance 13 * **FIX**: Fix CSS class naming conflicts that prevented grid view from working on frontend 14 * **FIX**: Resolve frontend style loading issues 15 * **DEVELOPER**: Add comprehensive webpack build configuration for multiple entry points 16 * **DEVELOPER**: Add pagination JavaScript with proper AJAX handling and nonce security 2 17 3 18 ## 2.1.5 -
jobbnorge-block/trunk/README.md
r3002720 r3322139 5 5 > Also available at https://wordpress.org/plugins/jobbnorge-block/ 6 6 7 7 8 This WordPress plugin adds a block to the Gutenberg editor that displays a list of jobs from Jobbnorge. 8 9 9 See:[Features](#features) | [Installation](#installation) | [Use](#use) | [Filters](#filters) | [Styling](#styling) | [License](#license) | [Changelog](CHANGELOG.md)10 **See:** [Live Preview](https://playground.wordpress.net/?plugin=jobbnorge-block&blueprint-url=https://wordpress.org/plugins/wp-json/plugins/v1/plugin/jobbnorge-block/blueprint.json) | [Features](#features) | [Installation](#installation) | [Use](#use) | [Filters](#filters) | [Styling](#styling) | [License](#license) | [Changelog](CHANGELOG.md) 10 11 12 <p> </p> 11 13 12 14 <img src=".wordpress-org/jobbnorge.gif"> -
jobbnorge-block/trunk/build/block.json
r3003492 r3322139 3 3 "apiVersion": 2, 4 4 "name": "dss/jobbnorge", 5 "version": "2. 1.5",5 "version": "2.2.0", 6 6 "title": "Jobbnorge", 7 7 "category": "widgets", … … 63 63 "type": "number", 64 64 "default": 55 65 }, 66 "enablePagination": { 67 "type": "boolean", 68 "default": true 69 }, 70 "jobsPerPage": { 71 "type": "number", 72 "default": 10 65 73 } 66 74 }, 67 75 "textdomain": "wp-jobbnorge-block", 68 76 "editorScript": "file:init.js", 69 "editorStyle": "file:editor. scss",70 "style": "file:style .scss"77 "editorStyle": "file:editor.css", 78 "style": "file:style-init.css" 71 79 } -
jobbnorge-block/trunk/build/init.asset.php
r3003492 r3322139 1 <?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-server-side-render'), 'version' => ' 4d2818abc3875b8f27f4');1 <?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-server-side-render'), 'version' => '7c82361092d9d86c438b'); -
jobbnorge-block/trunk/build/init.css
r2853882 r3322139 1 .wp-block-dss-jobbnorge li a>div{display:inline}.wp-block-dss-jobbnorge__placeholder-form{align-items:stretch;display:flex}.wp-block-dss-jobbnorge__placeholder-form>*{margin-bottom:8px}@media(min-width:782px){.wp-block-dss-jobbnorge__placeholder-form>*{margin-bottom:0}}.wp-block-dss-jobbnorge__placeholder-input{align-items:stretch;display:flex;flex-grow:1}.wp-block-dss-jobbnorge__placeholder-input .components-base-control__field{align-items:stretch;display:flex;flex-grow:1;margin:0 8px 0 0} 1 .wp-block-dss-jobbnorge li a>div{display:inline}.wp-block-dss-jobbnorge__placeholder-form{align-items:stretch;display:flex}.wp-block-dss-jobbnorge__placeholder-form>*{margin-bottom:8px}@media(min-width:782px){.wp-block-dss-jobbnorge__placeholder-form>*{margin-bottom:0}}.wp-block-dss-jobbnorge__placeholder-input{align-items:stretch;display:flex;flex-grow:1}.wp-block-dss-jobbnorge__placeholder-input .components-base-control__field{align-items:stretch;display:flex;flex-grow:1;margin:0 8px 0 0}ul.wp-block-dss-jobbnorge{list-style:none;padding:0}ul.wp-block-dss-jobbnorge.wp-block-dss-jobbnorge{box-sizing:border-box}ul.wp-block-dss-jobbnorge li{margin:0 0 1em}ul.wp-block-dss-jobbnorge.is-grid{display:flex;flex-wrap:wrap;list-style:none;padding:0}ul.wp-block-dss-jobbnorge.is-grid li{margin:0 1em 1em 0;width:100%}@media(min-width:600px){ul.wp-block-dss-jobbnorge.columns-2 li{width:calc(50% - 1em)}ul.wp-block-dss-jobbnorge.columns-3 li{width:calc(33.33333% - 1em)}ul.wp-block-dss-jobbnorge.columns-4 li{width:calc(25% - 1em)}ul.wp-block-dss-jobbnorge.columns-5 li{width:calc(20% - 1em)}ul.wp-block-dss-jobbnorge.columns-6 li{width:calc(16.66667% - 1em)}} -
jobbnorge-block/trunk/build/init.js
r3003492 r3322139 1 !function(){"use strict";var e,o={938:function(e,o,t){var l=window.React,n=window.wp.primitives,r=(0,l.createElement)(n.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,l.createElement)(n.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})),a=window.wp.blocks,i=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":2,"name":"dss/jobbnorge","version":"2.1.5","title":"Jobbnorge","category":"widgets","icon":"people","description":"Retrieve and display job listings from Jobbnorge.no","keywords":["jobbnorge","jobbnorge.no"],"supports":{"html":false},"attributes":{"columns":{"type":"number","default":3},"blockLayout":{"type":"string","default":"list"},"employerID":{"type":"string","default":""},"noJobsMessage":{"type":"string","default":""},"orderBy":{"type":"string","default":"Deadline"},"itemsToShow":{"type":"number","default":5},"displayEmployer":{"type":"boolean","default":false},"displayExcerpt":{"type":"boolean","default":true},"displayDeadline":{"type":"boolean","default":false},"displayScope":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":true},"excerptLength":{"type":"number","default":55}},"textdomain":"wp-jobbnorge-block","editorScript":"file:init.js","editorStyle":"file:editor.scss","style":"file:style.scss"}'),c=window.wp.blockEditor,s=window.wp.components,b=window.wp.element,p=(0,l.createElement)(n.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,l.createElement)(n.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})),d=(0,l.createElement)(n.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},(0,l.createElement)(n.Path,{d:"M4 4v1.5h16V4H4zm8 8.5h8V11h-8v1.5zM4 20h16v-1.5H4V20zm4-8c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2z"})),m=(0,l.createElement)(n.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,l.createElement)(n.Path,{d:"m3 5c0-1.10457.89543-2 2-2h13.5c1.1046 0 2 .89543 2 2v13.5c0 1.1046-.8954 2-2 2h-13.5c-1.10457 0-2-.8954-2-2zm2-.5h6v6.5h-6.5v-6c0-.27614.22386-.5.5-.5zm-.5 8v6c0 .2761.22386.5.5.5h6v-6.5zm8 0v6.5h6c.2761 0 .5-.2239.5-.5v-6zm0-8v6.5h6.5v-6c0-.27614-.2239-.5-.5-.5z",fillRule:"evenodd",clipRule:"evenodd"})),u=window.wp.i18n,g=window.wp.serverSideRender,w=t.n(g);const{name:v}=i;(e=>{const{metadata:o,settings:t,name:l}=e;(0,a.registerBlockType)({name:l,...o},t)})({name:v,metadata:i,settings:{icon:r,example:{attributes:{employerID:"123[, 456, 789]"}},edit:function({attributes:e,setAttributes:o}){const[t,n]=(0,b.useState)(!e.employerID),{blockLayout:a,columns:i,displayScope:g,displayDate:v,displayEmployer:y,displayExcerpt:h,employerID:f,itemsToShow:k,noJobsMessage:_,orderBy:E}=e;function j(t){return()=>{const l=e[t];o({[t]:!l})}}const C=(0,c.useBlockProps)();var x;if(t)return(0,l.createElement)("div",{...C},(0,l.createElement)(s.Placeholder,{icon:r,label:"Jobbnorge"},(0,l.createElement)("form",{onSubmit:function(e){e.preventDefault(),f&&(o({employerID:f}),n(!1))},className:"wp-block-dss-jobbnorge__placeholder-form"},window.wpJobbnorgeBlock&&window.wpJobbnorgeBlock.employers?(0,l.createElement)(s.SelectControl,{multiple:!0,value:f.split(","),onChange:e=>o({employerID:e.toString()}),options:(null!==(x=wpJobbnorgeBlock.employers)&&void 0!==x?x:[]).map((e=>{var o;return{label:e.label,value:e.value,disabled:null!==(o=e?.disabled)&&void 0!==o&&o}})),className:"wp-block-dss-jobbnorge__placeholder-input",help:(0,u.__)("Select employers to display. Ctrl-click (Windows) or Cmd-click (Mac) to select multiple employers. Shift-click to select a range of employers.","wp-jobbnorge-block"),__nextHasNoMarginBottom:!0}):(0,l.createElement)(s.TextControl,{placeholder:(0,u.__)("Employer ID [,id2, id3, ..]","wp-jobbnorge-block"),value:f,onChange:e=>o({employerID:e}),className:"wp-block-dss-jobbnorge__placeholder-input"}),(0,l.createElement)(s.Button,{variant:"primary",type:"submit"},(0,u.__)("Save","wp-jobbnorge-block")))));const S=[{icon:p,title:(0,u.__)("Edit Jobbnorge URL","wp-jobbnorge-block"),onClick:()=>n(!0)},{icon:d,title:(0,u.__)("List view","wp-jobbnorge-block"),onClick:()=>o({blockLayout:"list"}),isActive:"list"===a},{icon:m,title:(0,u.__)("Grid view","wp-jobbnorge-block"),onClick:()=>o({blockLayout:"grid"}),isActive:"grid"===a}];return(0,l.createElement)(l.Fragment,null,(0,l.createElement)(c.BlockControls,null,(0,l.createElement)(s.ToolbarGroup,{controls:S})),(0,l.createElement)(c.InspectorControls,null,(0,l.createElement)(s.PanelBody,{title:(0,u.__)("Settings","wp-jobbnorge-block")},(0,l.createElement)(s.RangeControl,{__nextHasNoMarginBottom:!0,label:(0,u.__)("Number of items","wp-jobbnorge-block"),value:k,onChange:e=>o({itemsToShow:e}),min:1,max:100,required:!0}),f.includes(",")&&(0,l.createElement)(s.RadioControl,{label:(0,u.__)("Order by","wp-jobbnorge-block"),selected:E,options:[{label:(0,u.__)("Deadline","wp-jobbnorge-block"),value:"Deadline"},{label:(0,u.__)("Employer","wp-jobbnorge-block"),value:"Employer"}],onChange:e=>o({orderBy:e})}),(0,l.createElement)(s.TextareaControl,{label:(0,u.__)("No jobs found message","wp-jobbnorge-block"),help:(0,u.__)("Message to display if no jobs are found","wp-jobbnorge-block"),value:_||(0,u.__)("There are no jobs at this time.","wp-jobbnorge-block"),onChange:e=>o({noJobsMessage:e})})),(0,l.createElement)(s.PanelBody,{title:(0,u.__)("Item","wp-jobbnorge-block")},(0,l.createElement)(s.ToggleControl,{label:(0,u.__)("Display employer","wp-jobbnorge-block"),checked:y,onChange:j("displayEmployer")}),(0,l.createElement)(s.ToggleControl,{label:(0,u.__)("Display excerpt","wp-jobbnorge-block"),checked:h,onChange:j("displayExcerpt")}),(0,l.createElement)(s.ToggleControl,{label:(0,u.__)("Display deadline","wp-jobbnorge-block"),checked:v,onChange:j("displayDate")}),(0,l.createElement)(s.ToggleControl,{label:(0,u.__)("Display scope","wp-jobbnorge-block"),checked:g,onChange:j("displayScope")})),"grid"===a&&(0,l.createElement)(s.PanelBody,{title:(0,u.__)("Grid view","wp-jobbnorge-block")},(0,l.createElement)(s.RangeControl,{__nextHasNoMarginBottom:!0,label:(0,u.__)("Columns","wp-jobbnorge-block"),value:i,onChange:e=>o({columns:e}),min:2,max:6,required:!0}))),(0,l.createElement)("div",{...C},(0,l.createElement)(s.Disabled,null,(0,l.createElement)(w(),{block:"dss/jobbnorge",attributes:e,httpMethod:"POST"}))))}}})}},t={};function l(e){var n=t[e];if(void 0!==n)return n.exports;var r=t[e]={exports:{}};return o[e](r,r.exports,l),r.exports}l.m=o,e=[],l.O=function(o,t,n,r){if(!t){var a=1/0;for(b=0;b<e.length;b++){t=e[b][0],n=e[b][1],r=e[b][2];for(var i=!0,c=0;c<t.length;c++)(!1&r||a>=r)&&Object.keys(l.O).every((function(e){return l.O[e](t[c])}))?t.splice(c--,1):(i=!1,r<a&&(a=r));if(i){e.splice(b--,1);var s=n();void 0!==s&&(o=s)}}return o}r=r||0;for(var b=e.length;b>0&&e[b-1][2]>r;b--)e[b]=e[b-1];e[b]=[t,n,r]},l.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(o,{a:o}),o},l.d=function(e,o){for(var t in o)l.o(o,t)&&!l.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},l.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},function(){var e={410:0,308:0};l.O.j=function(o){return 0===e[o]};var o=function(o,t){var n,r,a=t[0],i=t[1],c=t[2],s=0;if(a.some((function(o){return 0!==e[o]}))){for(n in i)l.o(i,n)&&(l.m[n]=i[n]);if(c)var b=c(l)}for(o&&o(t);s<a.length;s++)r=a[s],l.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return l.O(b)},t=self.webpackChunkjobbnorge_block=self.webpackChunkjobbnorge_block||[];t.forEach(o.bind(null,0)),t.push=o.bind(null,t.push.bind(t))}();var n=l.O(void 0,[308],(function(){return l(938)}));n=l.O(n)}();1 !function(){"use strict";var e,o={938:function(e,o,t){var n=window.React,l=window.wp.primitives,r=(0,n.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(l.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})),a=window.wp.blocks,i=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":2,"name":"dss/jobbnorge","version":"2.2.0","title":"Jobbnorge","category":"widgets","icon":"people","description":"Retrieve and display job listings from Jobbnorge.no","keywords":["jobbnorge","jobbnorge.no"],"supports":{"html":false},"attributes":{"columns":{"type":"number","default":3},"blockLayout":{"type":"string","default":"list"},"employerID":{"type":"string","default":""},"noJobsMessage":{"type":"string","default":""},"orderBy":{"type":"string","default":"Deadline"},"itemsToShow":{"type":"number","default":5},"displayEmployer":{"type":"boolean","default":false},"displayExcerpt":{"type":"boolean","default":true},"displayDeadline":{"type":"boolean","default":false},"displayScope":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":true},"excerptLength":{"type":"number","default":55},"enablePagination":{"type":"boolean","default":true},"jobsPerPage":{"type":"number","default":10}},"textdomain":"wp-jobbnorge-block","editorScript":"file:init.js","editorStyle":"file:editor.css","style":"file:style-init.css"}'),c=window.wp.blockEditor,b=window.wp.components,s=window.wp.element,p=(0,n.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(l.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})),d=(0,n.createElement)(l.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},(0,n.createElement)(l.Path,{d:"M4 4v1.5h16V4H4zm8 8.5h8V11h-8v1.5zM4 20h16v-1.5H4V20zm4-8c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2z"})),m=(0,n.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(l.Path,{d:"m3 5c0-1.10457.89543-2 2-2h13.5c1.1046 0 2 .89543 2 2v13.5c0 1.1046-.8954 2-2 2h-13.5c-1.10457 0-2-.8954-2-2zm2-.5h6v6.5h-6.5v-6c0-.27614.22386-.5.5-.5zm-.5 8v6c0 .2761.22386.5.5.5h6v-6.5zm8 0v6.5h6c.2761 0 .5-.2239.5-.5v-6zm0-8v6.5h6.5v-6c0-.27614-.2239-.5-.5-.5z",fillRule:"evenodd",clipRule:"evenodd"})),u=window.wp.i18n,g=window.wp.serverSideRender,w=t.n(g);const{name:h}=i;(e=>{const{metadata:o,settings:t,name:n}=e;(0,a.registerBlockType)({name:n,...o},t)})({name:h,metadata:i,settings:{icon:r,example:{attributes:{employerID:"123[, 456, 789]"}},edit:function({attributes:e,setAttributes:o}){const[t,l]=(0,s.useState)(!e.employerID),{blockLayout:a,columns:i,displayScope:g,displayDate:h,displayEmployer:y,displayExcerpt:v,employerID:f,itemsToShow:_,noJobsMessage:k,orderBy:j,enablePagination:E,jobsPerPage:C}=e;function x(t){return()=>{const n=e[t];o({[t]:!n})}}const S=(0,c.useBlockProps)();var B;if(t)return(0,n.createElement)("div",{...S},(0,n.createElement)(b.Placeholder,{icon:r,label:"Jobbnorge"},(0,n.createElement)("form",{onSubmit:function(e){e.preventDefault(),f&&(o({employerID:f}),l(!1))},className:"wp-block-dss-jobbnorge__placeholder-form"},window.wpJobbnorgeBlock&&window.wpJobbnorgeBlock.employers?(0,n.createElement)(b.SelectControl,{multiple:!0,value:f.split(","),onChange:e=>o({employerID:e.toString()}),options:(null!==(B=wpJobbnorgeBlock.employers)&&void 0!==B?B:[]).map((e=>{var o;return{label:e.label,value:e.value,disabled:null!==(o=e?.disabled)&&void 0!==o&&o}})),className:"wp-block-dss-jobbnorge__placeholder-input",help:(0,u.__)("Select employers to display. Ctrl-click (Windows) or Cmd-click (Mac) to select multiple employers. Shift-click to select a range of employers.","wp-jobbnorge-block"),__nextHasNoMarginBottom:!0}):(0,n.createElement)(b.TextControl,{placeholder:(0,u.__)("Employer ID [,id2, id3, ..]","wp-jobbnorge-block"),value:f,onChange:e=>o({employerID:e}),className:"wp-block-dss-jobbnorge__placeholder-input"}),(0,n.createElement)(b.Button,{variant:"primary",type:"submit"},(0,u.__)("Save","wp-jobbnorge-block")))));const D=[{icon:p,title:(0,u.__)("Edit Jobbnorge URL","wp-jobbnorge-block"),onClick:()=>l(!0)},{icon:d,title:(0,u.__)("List view","wp-jobbnorge-block"),onClick:()=>o({blockLayout:"list"}),isActive:"list"===a},{icon:m,title:(0,u.__)("Grid view","wp-jobbnorge-block"),onClick:()=>o({blockLayout:"grid"}),isActive:"grid"===a}];return(0,n.createElement)(n.Fragment,null,(0,n.createElement)(c.BlockControls,null,(0,n.createElement)(b.ToolbarGroup,{controls:D})),(0,n.createElement)(c.InspectorControls,null,(0,n.createElement)(b.PanelBody,{title:(0,u.__)("Settings","wp-jobbnorge-block")},(0,n.createElement)(b.ToggleControl,{label:(0,u.__)("Enable pagination","wp-jobbnorge-block"),help:(0,u.__)("When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown.","wp-jobbnorge-block"),checked:E,onChange:e=>o({enablePagination:e})}),!E&&(0,n.createElement)(b.RangeControl,{__nextHasNoMarginBottom:!0,label:(0,u.__)("Number of items","wp-jobbnorge-block"),value:_,onChange:e=>o({itemsToShow:e}),min:1,max:100,required:!0}),E&&(0,n.createElement)(b.RangeControl,{__nextHasNoMarginBottom:!0,label:(0,u.__)("Jobs per page","wp-jobbnorge-block"),value:C,onChange:e=>o({jobsPerPage:e}),min:1,max:50,required:!0}),f.includes(",")&&(0,n.createElement)(b.RadioControl,{label:(0,u.__)("Order by","wp-jobbnorge-block"),selected:j,options:[{label:(0,u.__)("Deadline","wp-jobbnorge-block"),value:"Deadline"},{label:(0,u.__)("Employer","wp-jobbnorge-block"),value:"Employer"}],onChange:e=>o({orderBy:e})}),(0,n.createElement)(b.TextareaControl,{label:(0,u.__)("No jobs found message","wp-jobbnorge-block"),help:(0,u.__)("Message to display if no jobs are found","wp-jobbnorge-block"),value:k||(0,u.__)("There are no jobs at this time.","wp-jobbnorge-block"),onChange:e=>o({noJobsMessage:e})})),(0,n.createElement)(b.PanelBody,{title:(0,u.__)("Item","wp-jobbnorge-block")},(0,n.createElement)(b.ToggleControl,{label:(0,u.__)("Display employer","wp-jobbnorge-block"),checked:y,onChange:x("displayEmployer")}),(0,n.createElement)(b.ToggleControl,{label:(0,u.__)("Display excerpt","wp-jobbnorge-block"),checked:v,onChange:x("displayExcerpt")}),(0,n.createElement)(b.ToggleControl,{label:(0,u.__)("Display deadline","wp-jobbnorge-block"),checked:h,onChange:x("displayDate")}),(0,n.createElement)(b.ToggleControl,{label:(0,u.__)("Display scope","wp-jobbnorge-block"),checked:g,onChange:x("displayScope")})),"grid"===a&&(0,n.createElement)(b.PanelBody,{title:(0,u.__)("Grid view","wp-jobbnorge-block")},(0,n.createElement)(b.RangeControl,{__nextHasNoMarginBottom:!0,label:(0,u.__)("Columns","wp-jobbnorge-block"),value:i,onChange:e=>o({columns:e}),min:2,max:6,required:!0}))),(0,n.createElement)("div",{...S},(0,n.createElement)(b.Disabled,null,(0,n.createElement)(w(),{block:"dss/jobbnorge",attributes:e,httpMethod:"POST"}))))}}})}},t={};function n(e){var l=t[e];if(void 0!==l)return l.exports;var r=t[e]={exports:{}};return o[e](r,r.exports,n),r.exports}n.m=o,e=[],n.O=function(o,t,l,r){if(!t){var a=1/0;for(s=0;s<e.length;s++){t=e[s][0],l=e[s][1],r=e[s][2];for(var i=!0,c=0;c<t.length;c++)(!1&r||a>=r)&&Object.keys(n.O).every((function(e){return n.O[e](t[c])}))?t.splice(c--,1):(i=!1,r<a&&(a=r));if(i){e.splice(s--,1);var b=l();void 0!==b&&(o=b)}}return o}r=r||0;for(var s=e.length;s>0&&e[s-1][2]>r;s--)e[s]=e[s-1];e[s]=[t,l,r]},n.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(o,{a:o}),o},n.d=function(e,o){for(var t in o)n.o(o,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},n.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},function(){var e={410:0,308:0};n.O.j=function(o){return 0===e[o]};var o=function(o,t){var l,r,a=t[0],i=t[1],c=t[2],b=0;if(a.some((function(o){return 0!==e[o]}))){for(l in i)n.o(i,l)&&(n.m[l]=i[l]);if(c)var s=c(n)}for(o&&o(t);b<a.length;b++)r=a[b],n.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return n.O(s)},t=self.webpackChunkjobbnorge_block=self.webpackChunkjobbnorge_block||[];t.forEach(o.bind(null,0)),t.push=o.bind(null,t.push.bind(t))}();var l=n.O(void 0,[308],(function(){return n(938)}));l=n.O(l)}(); -
jobbnorge-block/trunk/build/style-init.css
r2997962 r3322139 1 ul.wp-block-dss-jobbnorge{list-style:none;padding:0}ul.wp-block-dss-jobbnorge.wp-block-dss-jobbnorge{box-sizing:border-box}ul.wp-block-dss-jobbnorge.alignleft{margin-right:2em}ul.wp-block-dss-jobbnorge.alignright{margin-left:2em}ul.wp-block-dss-jobbnorge li{margin:0 0 1em}ul.wp-block-dss-jobbnorge.is-grid{display:flex;flex-wrap:wrap;list-style:none;padding:0}ul.wp-block-dss-jobbnorge.is-grid li{margin:0 1em 1em 0;width:100%}@media(min-width:600px){ul.wp-block-dss-jobbnorge.columns-2 li{width:calc(50% - 1em)}ul.wp-block-dss-jobbnorge.columns-3 li{width:calc(33.33333% - 1em)}ul.wp-block-dss-jobbnorge.columns-4 li{width:calc(25% - 1em)}ul.wp-block-dss-jobbnorge.columns-5 li{width:calc(20% - 1em)}ul.wp-block-dss-jobbnorge.columns-6 li{width:calc(16.66667% - 1em)}}.wp-block-dss-jobbnorge__item-title{font-size:1.125em;font-weight:600;margin:0 0 .25em}.wp-block-dss-jobbnorge__item-meta{margin:0 0 .25em;padding:0}.wp-block-dss-jobbnorge__item-deadline,.wp-block-dss-jobbnorge__item-employer,.wp-block-dss-jobbnorge__item-scope{display:block;font-size:.8125em;font-weight:600} 1 ul.wp-block-dss-jobbnorge{list-style:none;padding:0}ul.wp-block-dss-jobbnorge.wp-block-dss-jobbnorge{box-sizing:border-box}ul.wp-block-dss-jobbnorge.alignleft{margin-right:2em}ul.wp-block-dss-jobbnorge.alignright{margin-left:2em}ul.wp-block-dss-jobbnorge li{margin:0 0 1em}ul.wp-block-dss-jobbnorge.is-grid{display:flex;flex-wrap:wrap;list-style:none;padding:0}ul.wp-block-dss-jobbnorge.is-grid li{margin:0 1em 1em 0;width:100%}@media(min-width:600px){ul.wp-block-dss-jobbnorge.columns-2 li{width:calc(50% - 1em)}ul.wp-block-dss-jobbnorge.columns-3 li{width:calc(33.33333% - 1em)}ul.wp-block-dss-jobbnorge.columns-4 li{width:calc(25% - 1em)}ul.wp-block-dss-jobbnorge.columns-5 li{width:calc(20% - 1em)}ul.wp-block-dss-jobbnorge.columns-6 li{width:calc(16.66667% - 1em)}}.wp-block-dss-jobbnorge__item-title{font-size:1.125em;font-weight:600;margin:0 0 .25em}.wp-block-dss-jobbnorge__item-meta{margin:0 0 .25em;padding:0}.wp-block-dss-jobbnorge__item-deadline,.wp-block-dss-jobbnorge__item-employer,.wp-block-dss-jobbnorge__item-scope{display:block;font-size:.8125em;font-weight:600}.wp-block-dss-jobbnorge__pagination{border-top:1px solid #e0e0e0;display:flex;flex-direction:column;gap:1rem;margin-top:2rem;padding:1rem 0}@media(min-width:600px){.wp-block-dss-jobbnorge__pagination{align-items:center;flex-direction:row;justify-content:space-between}}.wp-block-dss-jobbnorge__pagination-info{color:#666;font-size:.875rem;margin:0}.wp-block-dss-jobbnorge__pagination-controls{align-items:center;display:flex;gap:.5rem}.wp-block-dss-jobbnorge__pagination-controls button{background:#fff;border:1px solid #ddd;border-radius:4px;cursor:pointer;font-size:.875rem;padding:.5rem 1rem;transition:all .2s ease}.wp-block-dss-jobbnorge__pagination-controls button:hover:not(:disabled){background:#f5f5f5;border-color:#999}.wp-block-dss-jobbnorge__pagination-controls button:disabled{cursor:not-allowed;opacity:.5}.wp-block-dss-jobbnorge__pagination-controls .wp-block-dss-jobbnorge__pagination-info{color:#333;font-size:.875rem;margin:0 .5rem}.wp-block-dss-jobbnorge__loading{opacity:.6;pointer-events:none}.wp-block-dss-jobbnorge__loading:after{animation:spin 1s linear infinite;border:2px solid #ccc;border-radius:50%;border-top-color:#333;content:"";height:20px;left:50%;margin:-10px 0 0 -10px;position:absolute;top:50%;width:20px}.wp-block-dss-jobbnorge__error{background:#ffebe8;border:1px solid #d63638;border-radius:4px;color:#d63638;margin:1rem 0;padding:.75rem}.wp-block-dss-jobbnorge__error p{margin:0}@keyframes spin{to{transform:rotate(1turn)}} -
jobbnorge-block/trunk/languages/wp-jobbnorge-block-en_US-5847f2cef22ef3cae0e9359a7a5dd2ec.json
r3002720 r3322139 1 1 { 2 2 "translation-revision-date": "YEAR-MO-DA HO:MI+ZONE", 3 "generator": "WP-CLI\/2. 9.0",3 "generator": "WP-CLI\/2.12.0", 4 4 "source": "build\/init.js", 5 5 "domain": "messages", … … 35 35 "" 36 36 ], 37 "Enable pagination": [ 38 "" 39 ], 40 "When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown.": [ 41 "" 42 ], 37 43 "Number of items": [ 44 "" 45 ], 46 "Jobs per page": [ 38 47 "" 39 48 ], -
jobbnorge-block/trunk/languages/wp-jobbnorge-block-en_US-bb1d7dea005e67527e728d4801f74b61.json
r3002720 r3322139 1 1 { 2 2 "translation-revision-date": "YEAR-MO-DA HO:MI+ZONE", 3 "generator": "WP-CLI\/2. 9.0",3 "generator": "WP-CLI\/2.12.0", 4 4 "source": "src\/edit.js", 5 5 "domain": "messages", … … 35 35 "" 36 36 ], 37 "Enable pagination": [ 38 "" 39 ], 40 "When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown.": [ 41 "" 42 ], 37 43 "Number of items": [ 44 "" 45 ], 46 "Jobs per page": [ 38 47 "" 39 48 ], -
jobbnorge-block/trunk/languages/wp-jobbnorge-block-en_US.po
r3002720 r3322139 1 # Copyright (C) 202 3PerS1 # Copyright (C) 2025 PerS 2 2 # This file is distributed under the GPL-2.0-or-later. 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Jobbnorge Block 2. 1.4\n"5 "Project-Id-Version: Jobbnorge Block 2.2.0\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/jobbnorge-block\n" 7 7 "Last-Translator: Per Søderlind <[email protected]\n" … … 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 202 3-11-28T12:11:37+00:00\n"12 "POT-Creation-Date: 2025-07-03T21:16:21+00:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 "X-Generator: WP-CLI 2. 9.0\n"14 "X-Generator: WP-CLI 2.12.0\n" 15 15 "X-Domain: wp-jobbnorge-block\n" 16 16 17 17 #. Plugin Name of the plugin 18 #: wp-jobb-norge.php 18 19 msgid "Jobbnorge Block" 19 20 msgstr "" 20 21 21 22 #. Plugin URI of the plugin 23 #: wp-jobb-norge.php 22 24 msgid "https://wordpress.org/plugins/jobbnorge-block/" 23 25 msgstr "" 24 26 25 27 #. Description of the plugin 28 #: wp-jobb-norge.php 26 29 msgid "Retrieve and display job listings from Jobbnorge.no" 27 30 msgstr "" 28 31 29 32 #. Author of the plugin 33 #: wp-jobb-norge.php 30 34 msgid "PerS" 31 35 msgstr "" 32 36 33 #: wp-jobb-norge.php:1 5937 #: wp-jobb-norge.php:181 34 38 msgid "Invalid ID" 35 39 msgstr "" 36 40 37 #: wp-jobb-norge.php: 18141 #: wp-jobb-norge.php:212 38 42 msgid "Error connecting to Jobbnorge.no" 39 43 msgstr "" 40 44 41 #: wp-jobb-norge.php: 19545 #: wp-jobb-norge.php:251 42 46 msgid "No jobs found" 43 47 msgstr "" 44 48 45 #: wp-jobb-norge.php:2 0549 #: wp-jobb-norge.php:261 46 50 msgid "(no title)" 47 51 msgstr "" 48 52 49 #: wp-jobb-norge.php:2 2650 #: build/init.js:1 51 #: src/edit.js:1 6053 #: wp-jobb-norge.php:282 54 #: build/init.js:1 55 #: src/edit.js:181 52 56 msgid "Employer" 53 57 msgstr "" 54 58 55 #: wp-jobb-norge.php:2 2759 #: wp-jobb-norge.php:283 56 60 msgid "Scope" 57 61 msgstr "" 58 62 59 #: wp-jobb-norge.php: 28263 #: wp-jobb-norge.php:345 60 64 msgid "Read more" 61 65 msgstr "" 62 66 63 #: wp-jobb-norge.php: 35367 #: wp-jobb-norge.php:416 64 68 msgid "Deadline:" 65 69 msgstr "" 66 70 67 #: build/init.js:1 68 #: src/edit.js:95 71 #: wp-jobb-norge.php:556 72 msgid "Job listings pagination" 73 msgstr "" 74 75 #: wp-jobb-norge.php:562 76 #, php-format 77 msgid "Showing %d-%d of %d jobs" 78 msgstr "" 79 80 #: wp-jobb-norge.php:577 81 #: wp-jobb-norge.php:582 82 msgid "Previous" 83 msgstr "" 84 85 #: wp-jobb-norge.php:590 86 #, php-format 87 msgid "Page %d of %d" 88 msgstr "" 89 90 #: wp-jobb-norge.php:601 91 #: wp-jobb-norge.php:606 92 msgid "Next" 93 msgstr "" 94 95 #: build/init.js:1 96 #: src/edit.js:97 69 97 msgid "Select employers to display. Ctrl-click (Windows) or Cmd-click (Mac) to select multiple employers. Shift-click to select a range of employers." 70 98 msgstr "" 71 99 72 100 #: build/init.js:1 73 #: src/edit.js:10 3101 #: src/edit.js:105 74 102 msgid "Employer ID [,id2, id3, ..]" 75 103 msgstr "" 76 104 77 105 #: build/init.js:1 78 #: src/edit.js:11 0106 #: src/edit.js:112 79 107 msgid "Save" 80 108 msgstr "" 81 109 82 110 #: build/init.js:1 83 #: src/edit.js:12 1111 #: src/edit.js:123 84 112 msgid "Edit Jobbnorge URL" 85 113 msgstr "" 86 114 87 115 #: build/init.js:1 88 #: src/edit.js:12 6116 #: src/edit.js:128 89 117 msgid "List view" 90 118 msgstr "" 91 119 92 120 #: build/init.js:1 93 #: src/edit.js:132 121 #: src/edit.js:134 122 #: src/edit.js:216 123 msgid "Grid view" 124 msgstr "" 125 126 #: build/init.js:1 127 #: src/edit.js:146 128 msgid "Settings" 129 msgstr "" 130 131 #: build/init.js:1 132 #: src/edit.js:148 133 msgid "Enable pagination" 134 msgstr "" 135 136 #: build/init.js:1 137 #: src/edit.js:149 138 msgid "When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown." 139 msgstr "" 140 141 #: build/init.js:1 142 #: src/edit.js:156 143 msgid "Number of items" 144 msgstr "" 145 146 #: build/init.js:1 147 #: src/edit.js:167 148 msgid "Jobs per page" 149 msgstr "" 150 151 #: build/init.js:1 152 #: src/edit.js:177 153 msgid "Order by" 154 msgstr "" 155 156 #: build/init.js:1 157 #: src/edit.js:180 158 msgid "Deadline" 159 msgstr "" 160 161 #: build/init.js:1 162 #: src/edit.js:187 163 msgid "No jobs found message" 164 msgstr "" 165 166 #: build/init.js:1 167 #: src/edit.js:188 168 msgid "Message to display if no jobs are found" 169 msgstr "" 170 171 #: build/init.js:1 172 #: src/edit.js:189 173 msgid "There are no jobs at this time." 174 msgstr "" 175 176 #: build/init.js:1 177 #: src/edit.js:193 178 msgid "Item" 179 msgstr "" 180 181 #: build/init.js:1 94 182 #: src/edit.js:195 95 msgid "Grid view"96 msgstr ""97 98 #: build/init.js:199 #: src/edit.js:144100 msgid "Settings"101 msgstr ""102 103 #: build/init.js:1104 #: src/edit.js:147105 msgid "Number of items"106 msgstr ""107 108 #: build/init.js:1109 #: src/edit.js:156110 msgid "Order by"111 msgstr ""112 113 #: build/init.js:1114 #: src/edit.js:159115 msgid "Deadline"116 msgstr ""117 118 #: build/init.js:1119 #: src/edit.js:166120 msgid "No jobs found message"121 msgstr ""122 123 #: build/init.js:1124 #: src/edit.js:167125 msgid "Message to display if no jobs are found"126 msgstr ""127 128 #: build/init.js:1129 #: src/edit.js:168130 msgid "There are no jobs at this time."131 msgstr ""132 133 #: build/init.js:1134 #: src/edit.js:172135 msgid "Item"136 msgstr ""137 138 #: build/init.js:1139 #: src/edit.js:174140 183 msgid "Display employer" 141 184 msgstr "" 142 185 143 186 #: build/init.js:1 144 #: src/edit.js: 179187 #: src/edit.js:200 145 188 msgid "Display excerpt" 146 189 msgstr "" 147 190 148 191 #: build/init.js:1 149 #: src/edit.js: 184192 #: src/edit.js:205 150 193 msgid "Display deadline" 151 194 msgstr "" 152 195 153 196 #: build/init.js:1 154 #: src/edit.js: 189197 #: src/edit.js:210 155 198 msgid "Display scope" 156 199 msgstr "" 157 200 158 201 #: build/init.js:1 159 #: src/edit.js: 198202 #: src/edit.js:219 160 203 msgid "Columns" 161 204 msgstr "" -
jobbnorge-block/trunk/languages/wp-jobbnorge-block-nb_NO-5847f2cef22ef3cae0e9359a7a5dd2ec.json
r3002720 r3322139 1 1 { 2 "translation-revision-date": "202 3-11-28 13:09+0100",3 "generator": "WP-CLI\/2. 9.0",2 "translation-revision-date": "2025-07-03 23:16+0200", 3 "generator": "WP-CLI\/2.12.0", 4 4 "source": "build\/init.js", 5 5 "domain": "messages", … … 35 35 "Innstillinger" 36 36 ], 37 "Enable pagination": [ 38 "Aktiver paginering" 39 ], 40 "When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown.": [ 41 "N\u00e5r denne funksjonen er aktivert, vises alle jobber med pagineringskontroller. N\u00e5r den er deaktivert, vises bare det angitte antallet jobber." 42 ], 37 43 "Number of items": [ 38 44 "Antall oppf\u00f8ringer" 45 ], 46 "Jobs per page": [ 47 "Jobber per side" 39 48 ], 40 49 "Order by": [ -
jobbnorge-block/trunk/languages/wp-jobbnorge-block-nb_NO-bb1d7dea005e67527e728d4801f74b61.json
r3002720 r3322139 1 1 { 2 "translation-revision-date": "202 3-11-28 13:09+0100",3 "generator": "WP-CLI\/2. 9.0",2 "translation-revision-date": "2025-07-03 23:16+0200", 3 "generator": "WP-CLI\/2.12.0", 4 4 "source": "src\/edit.js", 5 5 "domain": "messages", … … 35 35 "Innstillinger" 36 36 ], 37 "Enable pagination": [ 38 "Aktiver paginering" 39 ], 40 "When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown.": [ 41 "N\u00e5r denne funksjonen er aktivert, vises alle jobber med pagineringskontroller. N\u00e5r den er deaktivert, vises bare det angitte antallet jobber." 42 ], 37 43 "Number of items": [ 38 44 "Antall oppf\u00f8ringer" 45 ], 46 "Jobs per page": [ 47 "Jobber per side" 39 48 ], 40 49 "Order by": [ -
jobbnorge-block/trunk/languages/wp-jobbnorge-block-nb_NO.po
r3002720 r3322139 5 5 "Project-Id-Version: Jobbnorge Block 0.1.0\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/jobbnorge-block\n" 7 "POT-Creation-Date: 202 3-11-28T11:53:20+00:00\n"8 "PO-Revision-Date: 202 3-11-28 13:09+0100\n"7 "POT-Creation-Date: 2025-07-03T21:00:36+00:00\n" 8 "PO-Revision-Date: 2025-07-03 23:16+0200\n" 9 9 "Last-Translator: Per Søderlind <[email protected]>\n" 10 10 "Language-Team: \n" … … 13 13 "Content-Type: text/plain; charset=UTF-8\n" 14 14 "Content-Transfer-Encoding: 8bit\n" 15 "X-Generator: Poedit 3. 4.1\n"15 "X-Generator: Poedit 3.6\n" 16 16 "X-Domain: wp-jobbnorge-block\n" 17 17 18 18 #. Plugin Name of the plugin 19 #: wp-jobb-norge.php 19 20 msgid "Jobbnorge Block" 20 21 msgstr "Jobbnorge-blokken" 21 22 22 23 #. Plugin URI of the plugin 24 #: wp-jobb-norge.php 23 25 msgid "https://wordpress.org/plugins/jobbnorge-block/" 24 26 msgstr "https://wordpress.org/plugins/jobbnorge-block/" 25 27 26 28 #. Description of the plugin 29 #: wp-jobb-norge.php 27 30 msgid "Retrieve and display job listings from Jobbnorge.no" 28 31 msgstr "Hente og vise stillingsannonser fra Jobbnorge.no" 29 32 30 33 #. Author of the plugin 34 #: wp-jobb-norge.php 31 35 msgid "PerS" 32 36 msgstr "PerS" 33 37 34 #: wp-jobb-norge.php:1 5938 #: wp-jobb-norge.php:181 35 39 msgid "Invalid ID" 36 40 msgstr "Ugyldig ID" 37 41 38 #: wp-jobb-norge.php: 18142 #: wp-jobb-norge.php:212 39 43 msgid "Error connecting to Jobbnorge.no" 40 44 msgstr "Feil ved tilkobling til Jobbnorge.no" 41 45 42 #: wp-jobb-norge.php: 19546 #: wp-jobb-norge.php:251 43 47 msgid "No jobs found" 44 48 msgstr "Ingen jobber funnet" 45 49 46 #: wp-jobb-norge.php:2 0550 #: wp-jobb-norge.php:261 47 51 msgid "(no title)" 48 52 msgstr "(ingen tittel)" 49 53 50 #: wp-jobb-norge.php:2 26 build/init.js:1 src/edit.js:16054 #: wp-jobb-norge.php:282 build/init.js:1 src/edit.js:181 51 55 msgid "Employer" 52 56 msgstr "Arbeidsgiver" 53 57 54 #: wp-jobb-norge.php:2 2758 #: wp-jobb-norge.php:283 55 59 msgid "Scope" 56 60 msgstr "Omfang" 57 61 58 #: wp-jobb-norge.php: 28262 #: wp-jobb-norge.php:345 59 63 msgid "Read more" 60 64 msgstr "Les mer" 61 65 62 #: wp-jobb-norge.php: 35366 #: wp-jobb-norge.php:416 63 67 msgid "Deadline:" 64 68 msgstr "Søknadsfrist:" 65 69 66 #: build/init.js:1 src/edit.js:95 70 #: wp-jobb-norge.php:556 71 msgid "Job listings pagination" 72 msgstr "Paginering av stillingsannonser" 73 74 #: wp-jobb-norge.php:562 75 #, php-format 76 msgid "Showing %d-%d of %d jobs" 77 msgstr "Viser %d-%d av %d jobber" 78 79 #: wp-jobb-norge.php:577 wp-jobb-norge.php:582 80 msgid "Previous" 81 msgstr "Forrige" 82 83 #: wp-jobb-norge.php:590 84 #, php-format 85 msgid "Page %d of %d" 86 msgstr "Side %d av %d" 87 88 #: wp-jobb-norge.php:601 wp-jobb-norge.php:606 89 msgid "Next" 90 msgstr "Neste" 91 92 #: build/init.js:1 src/edit.js:97 67 93 msgid "" 68 94 "Select employers to display. Ctrl-click (Windows) or Cmd-click (Mac) to " … … 73 99 "arbeidsgivere." 74 100 75 #: build/init.js:1 src/edit.js:10 3101 #: build/init.js:1 src/edit.js:105 76 102 msgid "Employer ID [,id2, id3, ..]" 77 103 msgstr "Arbeidsgiver-ID [,id2, id3, ...]" 78 104 79 #: build/init.js:1 src/edit.js:11 0105 #: build/init.js:1 src/edit.js:112 80 106 msgid "Save" 81 107 msgstr "Lagre" 82 108 83 #: build/init.js:1 src/edit.js:12 1109 #: build/init.js:1 src/edit.js:123 84 110 msgid "Edit Jobbnorge URL" 85 111 msgstr "Rediger Jobbnorge URL" 86 112 87 #: build/init.js:1 src/edit.js:12 6113 #: build/init.js:1 src/edit.js:128 88 114 msgid "List view" 89 115 msgstr "Listevisning" 90 116 91 #: build/init.js:1 src/edit.js:13 2 src/edit.js:195117 #: build/init.js:1 src/edit.js:134 src/edit.js:216 92 118 msgid "Grid view" 93 119 msgstr "Rutemønster" 94 120 95 #: build/init.js:1 src/edit.js:14 4121 #: build/init.js:1 src/edit.js:146 96 122 msgid "Settings" 97 123 msgstr "Innstillinger" 98 124 99 #: build/init.js:1 src/edit.js:147 125 #: build/init.js:1 src/edit.js:148 126 msgid "Enable pagination" 127 msgstr "Aktiver paginering" 128 129 #: build/init.js:1 src/edit.js:149 130 msgid "" 131 "When enabled, all jobs will be displayed with pagination controls. When " 132 "disabled, only the specified number of jobs will be shown." 133 msgstr "" 134 "Når denne funksjonen er aktivert, vises alle jobber med " 135 "pagineringskontroller. Når den er deaktivert, vises bare det angitte " 136 "antallet jobber." 137 138 #: build/init.js:1 src/edit.js:156 100 139 msgid "Number of items" 101 140 msgstr "Antall oppføringer" 102 141 103 #: build/init.js:1 src/edit.js:156 142 #: build/init.js:1 src/edit.js:167 143 msgid "Jobs per page" 144 msgstr "Jobber per side" 145 146 #: build/init.js:1 src/edit.js:177 104 147 msgid "Order by" 105 148 msgstr "Sorter etter" 106 149 107 #: build/init.js:1 src/edit.js:1 59150 #: build/init.js:1 src/edit.js:180 108 151 msgid "Deadline" 109 152 msgstr "Søknadsfrist" 110 153 111 #: build/init.js:1 src/edit.js:1 66154 #: build/init.js:1 src/edit.js:187 112 155 msgid "No jobs found message" 113 156 msgstr "Ingen jobber funnet melding" 114 157 115 #: build/init.js:1 src/edit.js:1 67158 #: build/init.js:1 src/edit.js:188 116 159 msgid "Message to display if no jobs are found" 117 160 msgstr "Melding som vises hvis ingen jobber er funnet" 118 161 119 #: build/init.js:1 src/edit.js:1 68162 #: build/init.js:1 src/edit.js:189 120 163 msgid "There are no jobs at this time." 121 164 msgstr "Det er for tiden ingen ledige stillinger." 122 165 123 #: build/init.js:1 src/edit.js:1 72166 #: build/init.js:1 src/edit.js:193 124 167 msgid "Item" 125 168 msgstr "Element" 126 169 127 #: build/init.js:1 src/edit.js:1 74170 #: build/init.js:1 src/edit.js:195 128 171 msgid "Display employer" 129 172 msgstr "Vis arbeidsgiver" 130 173 131 #: build/init.js:1 src/edit.js: 179174 #: build/init.js:1 src/edit.js:200 132 175 msgid "Display excerpt" 133 176 msgstr "Vis utdrag" 134 177 135 #: build/init.js:1 src/edit.js: 184178 #: build/init.js:1 src/edit.js:205 136 179 msgid "Display deadline" 137 180 msgstr "Vis søknadsfrist" 138 181 139 #: build/init.js:1 src/edit.js: 189182 #: build/init.js:1 src/edit.js:210 140 183 msgid "Display scope" 141 184 msgstr "Vis omfang" 142 185 143 #: build/init.js:1 src/edit.js: 198186 #: build/init.js:1 src/edit.js:219 144 187 msgid "Columns" 145 188 msgstr "Kolonner" -
jobbnorge-block/trunk/languages/wp-jobbnorge-block.pot
r3002720 r3322139 1 # Copyright (C) 202 3PerS1 # Copyright (C) 2025 PerS 2 2 # This file is distributed under the GPL-2.0-or-later. 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Jobbnorge Block 2. 1.4\n"5 "Project-Id-Version: Jobbnorge Block 2.2.0\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/jobbnorge-block\n" 7 7 "Last-Translator: Per Søderlind <[email protected]\n" … … 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 202 3-11-28T12:11:37+00:00\n"12 "POT-Creation-Date: 2025-07-03T21:16:21+00:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 "X-Generator: WP-CLI 2. 9.0\n"14 "X-Generator: WP-CLI 2.12.0\n" 15 15 "X-Domain: wp-jobbnorge-block\n" 16 16 17 17 #. Plugin Name of the plugin 18 #: wp-jobb-norge.php 18 19 msgid "Jobbnorge Block" 19 20 msgstr "" 20 21 21 22 #. Plugin URI of the plugin 23 #: wp-jobb-norge.php 22 24 msgid "https://wordpress.org/plugins/jobbnorge-block/" 23 25 msgstr "" 24 26 25 27 #. Description of the plugin 28 #: wp-jobb-norge.php 26 29 msgid "Retrieve and display job listings from Jobbnorge.no" 27 30 msgstr "" 28 31 29 32 #. Author of the plugin 33 #: wp-jobb-norge.php 30 34 msgid "PerS" 31 35 msgstr "" 32 36 33 #: wp-jobb-norge.php:1 5937 #: wp-jobb-norge.php:181 34 38 msgid "Invalid ID" 35 39 msgstr "" 36 40 37 #: wp-jobb-norge.php: 18141 #: wp-jobb-norge.php:212 38 42 msgid "Error connecting to Jobbnorge.no" 39 43 msgstr "" 40 44 41 #: wp-jobb-norge.php: 19545 #: wp-jobb-norge.php:251 42 46 msgid "No jobs found" 43 47 msgstr "" 44 48 45 #: wp-jobb-norge.php:2 0549 #: wp-jobb-norge.php:261 46 50 msgid "(no title)" 47 51 msgstr "" 48 52 49 #: wp-jobb-norge.php:2 2650 #: build/init.js:1 51 #: src/edit.js:1 6053 #: wp-jobb-norge.php:282 54 #: build/init.js:1 55 #: src/edit.js:181 52 56 msgid "Employer" 53 57 msgstr "" 54 58 55 #: wp-jobb-norge.php:2 2759 #: wp-jobb-norge.php:283 56 60 msgid "Scope" 57 61 msgstr "" 58 62 59 #: wp-jobb-norge.php: 28263 #: wp-jobb-norge.php:345 60 64 msgid "Read more" 61 65 msgstr "" 62 66 63 #: wp-jobb-norge.php: 35367 #: wp-jobb-norge.php:416 64 68 msgid "Deadline:" 65 69 msgstr "" 66 70 67 #: build/init.js:1 68 #: src/edit.js:95 71 #: wp-jobb-norge.php:556 72 msgid "Job listings pagination" 73 msgstr "" 74 75 #: wp-jobb-norge.php:562 76 #, php-format 77 msgid "Showing %d-%d of %d jobs" 78 msgstr "" 79 80 #: wp-jobb-norge.php:577 81 #: wp-jobb-norge.php:582 82 msgid "Previous" 83 msgstr "" 84 85 #: wp-jobb-norge.php:590 86 #, php-format 87 msgid "Page %d of %d" 88 msgstr "" 89 90 #: wp-jobb-norge.php:601 91 #: wp-jobb-norge.php:606 92 msgid "Next" 93 msgstr "" 94 95 #: build/init.js:1 96 #: src/edit.js:97 69 97 msgid "Select employers to display. Ctrl-click (Windows) or Cmd-click (Mac) to select multiple employers. Shift-click to select a range of employers." 70 98 msgstr "" 71 99 72 100 #: build/init.js:1 73 #: src/edit.js:10 3101 #: src/edit.js:105 74 102 msgid "Employer ID [,id2, id3, ..]" 75 103 msgstr "" 76 104 77 105 #: build/init.js:1 78 #: src/edit.js:11 0106 #: src/edit.js:112 79 107 msgid "Save" 80 108 msgstr "" 81 109 82 110 #: build/init.js:1 83 #: src/edit.js:12 1111 #: src/edit.js:123 84 112 msgid "Edit Jobbnorge URL" 85 113 msgstr "" 86 114 87 115 #: build/init.js:1 88 #: src/edit.js:12 6116 #: src/edit.js:128 89 117 msgid "List view" 90 118 msgstr "" 91 119 92 120 #: build/init.js:1 93 #: src/edit.js:132 121 #: src/edit.js:134 122 #: src/edit.js:216 123 msgid "Grid view" 124 msgstr "" 125 126 #: build/init.js:1 127 #: src/edit.js:146 128 msgid "Settings" 129 msgstr "" 130 131 #: build/init.js:1 132 #: src/edit.js:148 133 msgid "Enable pagination" 134 msgstr "" 135 136 #: build/init.js:1 137 #: src/edit.js:149 138 msgid "When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown." 139 msgstr "" 140 141 #: build/init.js:1 142 #: src/edit.js:156 143 msgid "Number of items" 144 msgstr "" 145 146 #: build/init.js:1 147 #: src/edit.js:167 148 msgid "Jobs per page" 149 msgstr "" 150 151 #: build/init.js:1 152 #: src/edit.js:177 153 msgid "Order by" 154 msgstr "" 155 156 #: build/init.js:1 157 #: src/edit.js:180 158 msgid "Deadline" 159 msgstr "" 160 161 #: build/init.js:1 162 #: src/edit.js:187 163 msgid "No jobs found message" 164 msgstr "" 165 166 #: build/init.js:1 167 #: src/edit.js:188 168 msgid "Message to display if no jobs are found" 169 msgstr "" 170 171 #: build/init.js:1 172 #: src/edit.js:189 173 msgid "There are no jobs at this time." 174 msgstr "" 175 176 #: build/init.js:1 177 #: src/edit.js:193 178 msgid "Item" 179 msgstr "" 180 181 #: build/init.js:1 94 182 #: src/edit.js:195 95 msgid "Grid view"96 msgstr ""97 98 #: build/init.js:199 #: src/edit.js:144100 msgid "Settings"101 msgstr ""102 103 #: build/init.js:1104 #: src/edit.js:147105 msgid "Number of items"106 msgstr ""107 108 #: build/init.js:1109 #: src/edit.js:156110 msgid "Order by"111 msgstr ""112 113 #: build/init.js:1114 #: src/edit.js:159115 msgid "Deadline"116 msgstr ""117 118 #: build/init.js:1119 #: src/edit.js:166120 msgid "No jobs found message"121 msgstr ""122 123 #: build/init.js:1124 #: src/edit.js:167125 msgid "Message to display if no jobs are found"126 msgstr ""127 128 #: build/init.js:1129 #: src/edit.js:168130 msgid "There are no jobs at this time."131 msgstr ""132 133 #: build/init.js:1134 #: src/edit.js:172135 msgid "Item"136 msgstr ""137 138 #: build/init.js:1139 #: src/edit.js:174140 183 msgid "Display employer" 141 184 msgstr "" 142 185 143 186 #: build/init.js:1 144 #: src/edit.js: 179187 #: src/edit.js:200 145 188 msgid "Display excerpt" 146 189 msgstr "" 147 190 148 191 #: build/init.js:1 149 #: src/edit.js: 184192 #: src/edit.js:205 150 193 msgid "Display deadline" 151 194 msgstr "" 152 195 153 196 #: build/init.js:1 154 #: src/edit.js: 189197 #: src/edit.js:210 155 198 msgid "Display scope" 156 199 msgstr "" 157 200 158 201 #: build/init.js:1 159 #: src/edit.js: 198202 #: src/edit.js:219 160 203 msgid "Columns" 161 204 msgstr "" -
jobbnorge-block/trunk/package-lock.json
r3003492 r3322139 1 1 { 2 2 "name": "jobbnorge-block", 3 "version": "2. 1.5",3 "version": "2.2.0", 4 4 "lockfileVersion": 3, 5 5 "requires": true, … … 7 7 "": { 8 8 "name": "jobbnorge-block", 9 "version": "2. 1.5",9 "version": "2.2.0", 10 10 "license": "GPL-2.0-or-later", 11 11 "dependencies": { -
jobbnorge-block/trunk/package.json
r3003492 r3322139 1 1 { 2 2 "name": "jobbnorge-block", 3 "version": "2. 1.5",3 "version": "2.2.0", 4 4 "description": "Jobbnorge Block for WordPress Gutenberg", 5 5 "author": "Per Søderlind <[email protected]>", -
jobbnorge-block/trunk/readme.txt
r3003492 r3322139 5 5 Requires at least: 5.9 6 6 Requires PHP: 7.4 7 Stable tag: 2. 1.57 Stable tag: 2.2.0 8 8 License: GPL-2.0-or-later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 104 104 == Changelog == 105 105 106 = 2.2.0 = 107 108 * NEW: Add frontend pagination support with AJAX loading 109 * NEW: Add pagination controls (enable/disable, jobs per page setting) 110 * ENHANCEMENT: Upgrade to Jobbnorge API v3 for better performance 111 * ENHANCEMENT: Implement PHP-based pagination to work around API limitations with employer filtering 112 * ENHANCEMENT: Add responsive grid layout that adapts to screen size 113 * ENHANCEMENT: Improve cache key logic to include pagination and layout parameters 114 * ENHANCEMENT: Add loading states and error handling for pagination 115 * ENHANCEMENT: Separate frontend and admin CSS loading for better performance 116 * FIX: Fix CSS class naming conflicts that prevented grid view from working on frontend 117 * FIX: Resolve frontend style loading issues 118 * DEVELOPER: Add comprehensive webpack build configuration for multiple entry points 119 * DEVELOPER: Add pagination JavaScript with proper AJAX handling and nonce security 120 106 121 = 2.1.5 = 107 122 -
jobbnorge-block/trunk/src/block.json
r3003492 r3322139 3 3 "apiVersion": 2, 4 4 "name": "dss/jobbnorge", 5 "version": "2. 1.5",5 "version": "2.2.0", 6 6 "title": "Jobbnorge", 7 7 "category": "widgets", … … 63 63 "type": "number", 64 64 "default": 55 65 }, 66 "enablePagination": { 67 "type": "boolean", 68 "default": true 69 }, 70 "jobsPerPage": { 71 "type": "number", 72 "default": 10 65 73 } 66 74 }, 67 75 "textdomain": "wp-jobbnorge-block", 68 76 "editorScript": "file:init.js", 69 "editorStyle": "file:editor. scss",70 "style": "file:style .scss"77 "editorStyle": "file:editor.css", 78 "style": "file:style-init.css" 71 79 } -
jobbnorge-block/trunk/src/edit.js
r3002720 r3322139 52 52 noJobsMessage, 53 53 orderBy, 54 enablePagination, 55 jobsPerPage, 54 56 } = attributes; 55 57 … … 143 145 <InspectorControls> 144 146 <PanelBody title={__('Settings', 'wp-jobbnorge-block')}> 145 <RangeControl 146 __nextHasNoMarginBottom 147 label={__('Number of items', 'wp-jobbnorge-block')} 148 value={itemsToShow} 149 onChange={(value) => setAttributes({ itemsToShow: value })} 150 min={DEFAULT_MIN_ITEMS} 151 max={DEFAULT_MAX_ITEMS} 152 required 153 /> 147 <ToggleControl 148 label={__('Enable pagination', 'wp-jobbnorge-block')} 149 help={__('When enabled, all jobs will be displayed with pagination controls. When disabled, only the specified number of jobs will be shown.', 'wp-jobbnorge-block')} 150 checked={enablePagination} 151 onChange={(value) => setAttributes({ enablePagination: value })} 152 /> 153 {!enablePagination && ( 154 <RangeControl 155 __nextHasNoMarginBottom 156 label={__('Number of items', 'wp-jobbnorge-block')} 157 value={itemsToShow} 158 onChange={(value) => setAttributes({ itemsToShow: value })} 159 min={DEFAULT_MIN_ITEMS} 160 max={DEFAULT_MAX_ITEMS} 161 required 162 /> 163 )} 164 {enablePagination && ( 165 <RangeControl 166 __nextHasNoMarginBottom 167 label={__('Jobs per page', 'wp-jobbnorge-block')} 168 value={jobsPerPage} 169 onChange={(value) => setAttributes({ jobsPerPage: value })} 170 min={1} 171 max={50} 172 required 173 /> 174 )} 154 175 {employerID.includes(',') && ( 155 176 <RadioControl -
jobbnorge-block/trunk/src/editor.scss
r2853882 r3322139 1 1 $break-medium: 782px; 2 $break-small: 600px; 2 3 $grid-unit: 8px; 3 4 $grid-unit-10: 1 * $grid-unit; // 8px … … 9 10 } 10 11 11 .wp-block-dss-jobbnorge li a > div { 12 @mixin break-small() { 13 @media (min-width: #{ ($break-small) }) { 14 @content; 15 } 16 } 17 18 .wp-block-dss-jobbnorge li a>div { 12 19 display: inline; 13 20 } … … 17 24 align-items: stretch; 18 25 19 > * {26 >* { 20 27 margin-bottom: $grid-unit-10; 21 28 } 22 29 23 30 @include break-medium() { 24 > * {31 >* { 25 32 margin-bottom: 0; 26 33 } 27 34 } 28 35 } 29 30 31 36 32 37 .wp-block-dss-jobbnorge__placeholder-input { … … 43 48 } 44 49 } 50 51 // Grid styles for the editor 52 ul.wp-block-dss-jobbnorge { 53 list-style: none; 54 padding: 0; 55 56 &.wp-block-dss-jobbnorge { 57 box-sizing: border-box; 58 } 59 60 li { 61 margin: 0 0 1em 0; 62 } 63 64 &.is-grid { 65 display: flex; 66 flex-wrap: wrap; 67 padding: 0; 68 list-style: none; 69 70 li { 71 margin: 0 1em 1em 0; 72 width: 100%; 73 } 74 } 75 76 @include break-small { 77 @for $i from 2 through 6 { 78 &.columns-#{ $i } li { 79 width: calc((100% / #{ $i }) - 1em); 80 } 81 } 82 } 83 } -
jobbnorge-block/trunk/src/style.scss
r2997962 r3322139 8 8 9 9 10 ul.wp-block-dss-jobbnorge { // The ul is needed for specificity to override the reset styles in the editor. 10 ul.wp-block-dss-jobbnorge { 11 // The ul is needed for specificity to override the reset styles in the editor. 11 12 list-style: none; 12 13 padding: 0; … … 21 22 margin-right: 2em; 22 23 } 24 23 25 &.alignright { 24 26 /*rtl:ignore*/ 25 27 margin-left: 2em; 26 28 } 29 27 30 li { 28 31 margin: 0 0 1em 0; 29 32 } 33 30 34 &.is-grid { 31 35 display: flex; … … 43 47 @for $i from 2 through 6 { 44 48 &.columns-#{ $i } li { 45 width: calc(( 100% / #{ $i }) - 1em);49 width: calc((100% / #{ $i }) - 1em); 46 50 } 47 51 } … … 63 67 .wp-block-dss-jobbnorge__item-employer, 64 68 .wp-block-dss-jobbnorge__item-deadline, 65 .wp-block-dss-jobbnorge__item-scope {69 .wp-block-dss-jobbnorge__item-scope { 66 70 display: block; 67 71 font-weight: 600; … … 69 73 } 70 74 75 // Pagination styles 76 .wp-block-dss-jobbnorge { 77 &__pagination { 78 display: flex; 79 flex-direction: column; 80 gap: 1rem; 81 margin-top: 2rem; 82 padding: 1rem 0; 83 border-top: 1px solid #e0e0e0; 84 85 @include break-small { 86 flex-direction: row; 87 justify-content: space-between; 88 align-items: center; 89 } 90 } 91 92 &__pagination-info { 93 font-size: 0.875rem; 94 color: #666; 95 margin: 0; 96 } 97 98 &__pagination-controls { 99 display: flex; 100 gap: 0.5rem; 101 align-items: center; 102 103 button { 104 padding: 0.5rem 1rem; 105 border: 1px solid #ddd; 106 background: white; 107 cursor: pointer; 108 border-radius: 4px; 109 font-size: 0.875rem; 110 transition: all 0.2s ease; 111 112 &:hover:not(:disabled) { 113 background: #f5f5f5; 114 border-color: #999; 115 } 116 117 &:disabled { 118 opacity: 0.5; 119 cursor: not-allowed; 120 } 121 } 122 123 .wp-block-dss-jobbnorge__pagination-info { 124 font-size: 0.875rem; 125 color: #333; 126 margin: 0 0.5rem; 127 } 128 } 129 130 // Loading state 131 &__loading { 132 opacity: 0.6; 133 pointer-events: none; 134 135 &::after { 136 content: ''; 137 position: absolute; 138 top: 50%; 139 left: 50%; 140 width: 20px; 141 height: 20px; 142 margin: -10px 0 0 -10px; 143 border: 2px solid #ccc; 144 border-top-color: #333; 145 border-radius: 50%; 146 animation: spin 1s linear infinite; 147 } 148 } 149 150 // Error message 151 &__error { 152 margin: 1rem 0; 153 padding: 0.75rem; 154 background: #ffebe8; 155 border: 1px solid #d63638; 156 border-radius: 4px; 157 color: #d63638; 158 159 p { 160 margin: 0; 161 } 162 } 163 } 164 165 @keyframes spin { 166 to { 167 transform: rotate(360deg); 168 } 169 } -
jobbnorge-block/trunk/wp-jobb-norge.php
r3003492 r3322139 6 6 * Requires at least: 5.9 7 7 * Requires PHP: 7.0 8 * Version: 2. 1.58 * Version: 2.2.0 9 9 * Author: PerS 10 10 * License: GPL-2.0-or-later … … 36 36 add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\dss_jobbnorge_enqueue_scripts' ); 37 37 38 // Add the 'dss_jobbnorge_enqueue_ scripts' function to the 'wp_enqueue_scripts' action hook.38 // Add the 'dss_jobbnorge_enqueue_frontend_styles' function to the 'wp_enqueue_scripts' action hook. 39 39 // This function will be called when scripts and styles are enqueued for the front end of the site. 40 add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\dss_jobbnorge_enqueue_ scripts' );40 add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\dss_jobbnorge_enqueue_frontend_styles' ); 41 41 42 42 // Load the plugin's text domain for internationalization. … … 50 50 register_block_type( 51 51 __DIR__ . '/build', 52 [ 52 [ 53 53 'render_callback' => __NAMESPACE__ . '\render_block_dss_jobbnorge', 54 54 ] … … 81 81 // If it does, require it and merge its dependencies with the existing ones. 82 82 $file = require $deps_file; 83 $jsdeps = array_merge( $jsdeps, $file[ 'dependencies'] );83 $jsdeps = array_merge( $jsdeps, $file[ 'dependencies' ] ); 84 84 // Also, set the version to the one from the file. 85 $version = $file[ 'version'];85 $version = $file[ 'version' ]; 86 86 } 87 87 … … 92 92 wp_enqueue_style( 'dss-jobbnorge-admin' ); 93 93 } 94 95 // Register and enqueue a CSS file for the public view.96 wp_register_style( 'dss-jobbnorge', plugin_dir_url( __FILE__ ) . 'build/style-init.css', [], $version );97 wp_enqueue_style( 'dss-jobbnorge' );98 94 99 95 // Set translations for the script. … … 118 114 'dss-jobbnorge-editor-script', 119 115 'wpJobbnorgeBlock', 120 [ 116 [ 121 117 'employers' => $employers, 122 118 ] … … 126 122 127 123 /** 124 * Enqueue frontend styles for the block 125 * 126 * @return void 127 */ 128 function dss_jobbnorge_enqueue_frontend_styles(): void { 129 // Define the path to the dependencies file. 130 $deps_file = plugin_dir_path( __FILE__ ) . 'build/init.asset.php'; 131 132 // Initialize version number. 133 $version = wp_rand(); 134 135 // Check if the dependencies file exists. 136 if ( file_exists( $deps_file ) ) { 137 // If it does, require it and get the version. 138 $file = require $deps_file; 139 $version = $file[ 'version' ]; 140 } 141 142 // Register and enqueue a CSS file for the public view. 143 wp_register_style( 'dss-jobbnorge', plugin_dir_url( __FILE__ ) . 'build/style-init.css', [], $version ); 144 wp_enqueue_style( 'dss-jobbnorge' ); 145 } 146 147 /** 128 148 * Renders the `jobbnorge` block on server. 129 149 * … … 137 157 $attributes = wp_parse_args( 138 158 $attributes, 139 [ 140 'employerID' => '', 141 'displayEmployer' => false, 142 'displayDate' => true, 143 'displayDeadline' => false, 144 'displayScope' => false, 145 'displayExcerpt' => true, 146 'excerptLength' => 55, 147 'blockLayout' => 'list', 148 'orderBy' => 'Deadline', 149 'columns' => 3, 150 'itemsToShow' => 5, 159 [ 160 'employerID' => '', 161 'displayEmployer' => false, 162 'displayDate' => true, 163 'displayDeadline' => false, 164 'displayScope' => false, 165 'displayExcerpt' => true, 166 'excerptLength' => 55, 167 'blockLayout' => 'list', 168 'orderBy' => 'Deadline', 169 'columns' => 3, 170 'itemsToShow' => 5, 171 'enablePagination' => true, 172 'jobsPerPage' => 10, 151 173 ] 152 174 ); 153 175 154 176 // Convert employer IDs to an array and trim whitespace. 155 $arr_ids = array_map( 'trim', explode( ',', $attributes[ 'employerID'] ) );177 $arr_ids = array_map( 'trim', explode( ',', $attributes[ 'employerID' ] ) ); 156 178 157 179 // Check if all IDs are numeric. If not, return an error message. … … 160 182 } 161 183 162 // Construct the API URL. 163 $jobbnorge_api_url = 'https://publicapi.jobbnorge.no/v2/Jobs?abroad=false&orderBy=' . $attributes['orderBy']; 184 // Get current page for pagination 185 $current_page = isset( $_GET[ 'jobbnorge_page' ] ) ? max( 1, intval( $_GET[ 'jobbnorge_page' ] ) ) : 1; 186 187 // Determine items per page based on pagination setting 188 $items_per_page = $attributes[ 'enablePagination' ] ? $attributes[ 'jobsPerPage' ] : $attributes[ 'itemsToShow' ]; 189 190 // Construct the API URL for v3 191 // NOTE: API v3 pagination doesn't work correctly with employer filtering 192 // So we fetch all jobs for the employers and paginate in PHP 193 $jobbnorge_api_url = 'https://publicapi.jobbnorge.no/v3/Jobs?abroad=false&orderBy=' . $attributes[ 'orderBy' ]; 164 194 165 195 // Add each employer ID to the API URL. … … 171 201 $cache = new \Jobbnorge_CacheHandler( $cache_path ); 172 202 173 $cache_key = md5( $jobbnorge_api_url ); 174 $expiration = apply_filters( 'jobbnorge_cache_time', 30 * MINUTE_IN_SECONDS ); 175 $body = $cache->get( $cache_key, $expiration ); 176 177 if ( false === $body ) { 203 // Cache key based on employer IDs and settings, not pagination 204 $cache_key = md5( $jobbnorge_api_url ); 205 $expiration = apply_filters( 'jobbnorge_cache_time', 30 * MINUTE_IN_SECONDS ); 206 $response_data = $cache->get( $cache_key, $expiration ); 207 208 if ( false === $response_data ) { 178 209 $response = wp_remote_get( $jobbnorge_api_url ); 179 210 … … 182 213 } 183 214 184 $body = wp_remote_retrieve_body( $response ); 185 $cache->set( $cache_key, $body ); 186 } 187 188 // Decode the JSON response and limit the number of items. 189 $items = json_decode( $body, true ); 190 // Just get desired number of items. 191 $items = array_slice( $items, 0, $attributes['itemsToShow'] ); 215 $body = wp_remote_retrieve_body( $response ); 216 $response_data = json_decode( $body, true ); 217 $cache->set( $cache_key, $response_data ); 218 } 219 220 // Debug: Log the API response structure 221 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { 222 error_log( 'Jobbnorge API URL: ' . $jobbnorge_api_url ); 223 error_log( 'Jobbnorge API Response: ' . print_r( $response_data, true ) ); 224 } 225 // Handle v3 API response structure 226 $all_items = isset( $response_data[ 'jobs' ] ) ? $response_data[ 'jobs' ] : $response_data; 227 $total_jobs = count( $all_items ); 228 229 // Debug: Log the items array 230 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { 231 error_log( 'Items count: ' . count( $all_items ) ); 232 error_log( 'Total jobs: ' . $total_jobs ); 233 if ( ! empty( $all_items ) ) { 234 error_log( 'First item: ' . print_r( $all_items[ 0 ], true ) ); 235 } 236 } 237 238 // Implement pagination in PHP since API pagination doesn't work with employer filtering 239 if ( $attributes[ 'enablePagination' ] && $total_jobs > 0 ) { 240 // Calculate pagination 241 $start_index = ( $current_page - 1 ) * $attributes[ 'jobsPerPage' ]; 242 $items = array_slice( $all_items, $start_index, $attributes[ 'jobsPerPage' ] ); 243 } else { 244 // For non-paginated, limit to itemsToShow 245 $items = array_slice( $all_items, 0, $attributes[ 'itemsToShow' ] ); 246 $total_jobs = count( $items ); // Update total for non-paginated display 247 } 192 248 193 249 // If there are no items, return an error message. … … 202 258 foreach ( $items as $item ) { 203 259 // Sanitize and format the title. 204 $title = esc_html( trim( wp_strip_all_tags( $item[ 'title'] ) ) );260 $title = esc_html( trim( wp_strip_all_tags( $item[ 'title' ] ) ) ); 205 261 $title = empty( $title ) ? __( '(no title)', 'wp-jobbnorge-block' ) : $title; 206 262 207 263 // Sanitize the link. 208 $link = esc_url( $item[ 'link'] );264 $link = esc_url( $item[ 'link' ] ); 209 265 // If there's a link, wrap the title in an anchor tag. 210 266 $title = $link ? "<a href='{$link}'>{$title}</a>" : $title; … … 216 272 $deadline = ''; 217 273 // If the displayDate attribute is true and the item has a deadline, format the deadline. 218 if ( $attributes[ 'displayDate'] && isset( $item['deadline'] ) ) {219 $deadline = format_deadline( $item[ 'deadline'] );274 if ( $attributes[ 'displayDate' ] && isset( $item[ 'deadline' ] ) ) { 275 $deadline = format_deadline( $item[ 'deadline' ] ); 220 276 } 221 277 … … 238 294 } 239 295 240 // Initialize an array for the classnames. 241 $classnames = []; 242 243 // If the blockLayout attribute is 'grid', add the 'is-grid' and 'columns-' classes. 244 if ( 'grid' === $attributes['blockLayout'] ) { 245 add_classname( $classnames, $attributes, 'blockLayout', 'is-grid' ); 246 add_classname( $classnames, $attributes, 'columns', 'columns-' . $attributes['columns'] ); 247 } 248 249 // Add the 'has-' classes based on the display attributes. 250 add_classname( $classnames, $attributes, 'displayEmployer', 'has-employer' ); 251 add_classname( $classnames, $attributes, 'displayDate', 'has-dates' ); 252 add_classname( $classnames, $attributes, 'displayDeadline', 'has-deadline' ); 253 add_classname( $classnames, $attributes, 'displayScope', 'has-scope' ); 254 add_classname( $classnames, $attributes, 'displayExcerpt', 'has-excerpts' ); 255 256 // Get the block wrapper attributes and add the classnames to it. 257 $wrapper_attributes = get_block_wrapper_attributes( [ 'class' => implode( ' ', $classnames ) ] ); 296 // Get the block wrapper attributes (without grid classes) 297 $wrapper_classes = []; 298 add_classname( $wrapper_classes, $attributes, 'displayEmployer', 'has-employer' ); 299 add_classname( $wrapper_classes, $attributes, 'displayDate', 'has-dates' ); 300 add_classname( $wrapper_classes, $attributes, 'displayDeadline', 'has-deadline' ); 301 add_classname( $wrapper_classes, $attributes, 'displayScope', 'has-scope' ); 302 add_classname( $wrapper_classes, $attributes, 'displayExcerpt', 'has-excerpts' ); 303 304 $wrapper_attributes = get_block_wrapper_attributes( [ 305 'class' => implode( ' ', $wrapper_classes ), 306 'data-attributes' => esc_attr( json_encode( $attributes ) ), 307 ] ); 308 309 // Generate the ul classes (including grid classes) 310 $ul_classes = [ 'wp-block-dss-jobbnorge' ]; 311 if ( 'grid' === $attributes[ 'blockLayout' ] ) { 312 $ul_classes[] = 'is-grid'; 313 $ul_classes[] = 'columns-' . $attributes[ 'columns' ]; 314 } 315 316 // Generate pagination controls if enabled 317 $pagination_html = ''; 318 if ( $attributes[ 'enablePagination' ] && count( $all_items ) > $attributes[ 'jobsPerPage' ] ) { 319 $pagination_html = generate_pagination_controls( $current_page, count( $all_items ), $attributes[ 'jobsPerPage' ], $attributes ); 320 } 258 321 259 322 // Return the final HTML string, wrapping the list items in an unordered list. 260 return sprintf( '< ul %s>%s</ul>', $wrapper_attributes, $list_items);323 return sprintf( '<div %s><ul class="%s">%s</ul>%s</div>', $wrapper_attributes, esc_attr( implode( ' ', $ul_classes ) ), $list_items, $pagination_html ); 261 324 } 262 325 … … 273 336 274 337 // If the displayExcerpt attribute is true and the item has a summary, format the excerpt. 275 if ( $attributes[ 'displayExcerpt'] && isset( $item['summary'] ) ) {338 if ( $attributes[ 'displayExcerpt' ] && isset( $item[ 'summary' ] ) ) { 276 339 // Decode the HTML entities in the summary. 277 $excerpt = html_entity_decode( $item[ 'summary'], ENT_QUOTES, get_option( 'blog_charset' ) );340 $excerpt = html_entity_decode( $item[ 'summary' ], ENT_QUOTES, get_option( 'blog_charset' ) ); 278 341 // Trim the excerpt to the excerptLength and escape it for safe use in HTML output. 279 $excerpt = esc_attr( wp_trim_words( $excerpt, $attributes[ 'excerptLength'], '' ) );342 $excerpt = esc_attr( wp_trim_words( $excerpt, $attributes[ 'excerptLength' ], '' ) ); 280 343 281 344 // Format the read more link. 282 $read_more = sprintf( ' ... <a href="%s">%s</a>', esc_url( $item[ 'link'] ), __( 'Read more', 'wp-jobbnorge-block' ) );345 $read_more = sprintf( ' ... <a href="%s">%s</a>', esc_url( $item[ 'link' ] ), __( 'Read more', 'wp-jobbnorge-block' ) ); 283 346 284 347 // Add the excerpt and read more link to the result string, wrapped in a div. … … 338 401 // Format the date according to the site's date format. 339 402 $str_date = date_i18n( get_option( 'date_format' ), $date ); 340 } catch ( \Exception $e) {403 } catch (\Exception $e) { 341 404 // If there's an exception, fallback to the original date. 342 405 $str_date = $deadline_date; … … 348 411 return sprintf( 349 412 '<time datetime="%1$s" class="wp-block-dss-jobbnorge__item-deadline">%2$s %3$s</time> ', 350 // If there's a parsed date, use it for the datetime attribute. Otherwise, leave it empty.413 // If there's a parsed date, use it for the datetime attribute. Otherwise, leave it empty. 351 414 ( $date ) ? esc_attr( wp_date( 'c', $date ) ) : '', 352 415 // Translate the 'Deadline:' string. … … 406 469 function parse_date_fallback( $deadline_date ) { 407 470 // Define an array of month names in Norwegian. 408 $str_months = [ 471 $str_months = [ 409 472 'januar', 410 473 'februar', … … 422 485 423 486 // Define an array of month numbers. 424 $num_months = [ 487 $num_months = [ 425 488 '01', 426 489 '02', … … 448 511 449 512 // Return a Unix timestamp for the date. 450 return mktime( 0, 0, 0, $dato_arr[ 2], $dato_arr[1], $dato_arr[3] );513 return mktime( 0, 0, 0, $dato_arr[ 2 ], $dato_arr[ 1 ], $dato_arr[ 3 ] ); 451 514 } 452 515 … … 466 529 } 467 530 } 531 532 /** 533 * Generates pagination controls for the job listings. 534 * 535 * @param int $current_page The current page number. 536 * @param int $total_jobs The total number of jobs. 537 * @param int $jobs_per_page The number of jobs per page. 538 * @param array $attributes The block attributes. 539 * @return string The pagination HTML. 540 */ 541 function generate_pagination_controls( $current_page, $total_jobs, $jobs_per_page, $attributes ) { 542 $total_pages = ceil( $total_jobs / $jobs_per_page ); 543 544 if ( $total_pages <= 1 ) { 545 return ''; 546 } 547 548 $prev_page = max( 1, $current_page - 1 ); 549 $next_page = min( $total_pages, $current_page + 1 ); 550 551 // Calculate result range 552 $start_item = ( ( $current_page - 1 ) * $jobs_per_page ) + 1; 553 $end_item = min( $current_page * $jobs_per_page, $total_jobs ); 554 555 // Generate pagination HTML 556 $pagination_html = '<nav class="wp-block-dss-jobbnorge__pagination" role="navigation" aria-label="' . esc_attr__( 'Job listings pagination', 'wp-jobbnorge-block' ) . '">'; 557 558 // Results info 559 $pagination_html .= sprintf( 560 '<div class="wp-block-dss-jobbnorge__pagination-info">%s</div>', 561 sprintf( 562 esc_html__( 'Showing %d-%d of %d jobs', 'wp-jobbnorge-block' ), 563 $start_item, 564 $end_item, 565 $total_jobs 566 ) 567 ); 568 569 // Pagination controls 570 $pagination_html .= '<div class="wp-block-dss-jobbnorge__pagination-controls">'; 571 572 // Previous button 573 if ( $current_page > 1 ) { 574 $pagination_html .= sprintf( 575 '<button type="button" class="wp-block-dss-jobbnorge__pagination-prev" data-page="%d">%s</button>', 576 $prev_page, 577 esc_html__( 'Previous', 'wp-jobbnorge-block' ) 578 ); 579 } else { 580 $pagination_html .= sprintf( 581 '<button type="button" class="wp-block-dss-jobbnorge__pagination-prev" disabled>%s</button>', 582 esc_html__( 'Previous', 'wp-jobbnorge-block' ) 583 ); 584 } 585 586 // Page info 587 $pagination_html .= sprintf( 588 '<span class="wp-block-dss-jobbnorge__pagination-info">%s</span>', 589 sprintf( 590 esc_html__( 'Page %d of %d', 'wp-jobbnorge-block' ), 591 $current_page, 592 $total_pages 593 ) 594 ); 595 596 // Next button 597 if ( $current_page < $total_pages ) { 598 $pagination_html .= sprintf( 599 '<button type="button" class="wp-block-dss-jobbnorge__pagination-next" data-page="%d">%s</button>', 600 $next_page, 601 esc_html__( 'Next', 'wp-jobbnorge-block' ) 602 ); 603 } else { 604 $pagination_html .= sprintf( 605 '<button type="button" class="wp-block-dss-jobbnorge__pagination-next" disabled>%s</button>', 606 esc_html__( 'Next', 'wp-jobbnorge-block' ) 607 ); 608 } 609 610 $pagination_html .= '</div>'; 611 $pagination_html .= '</nav>'; 612 613 return $pagination_html; 614 } 615 616 /** 617 * Register AJAX endpoints for pagination. 618 */ 619 add_action( 'wp_ajax_jobbnorge_get_jobs', __NAMESPACE__ . '\handle_ajax_get_jobs' ); 620 add_action( 'wp_ajax_nopriv_jobbnorge_get_jobs', __NAMESPACE__ . '\handle_ajax_get_jobs' ); 621 622 /** 623 * Handle AJAX request for paginated job listings. 624 */ 625 function handle_ajax_get_jobs() { 626 // Verify nonce 627 if ( ! wp_verify_nonce( $_POST[ 'nonce' ], 'jobbnorge_pagination_nonce' ) ) { 628 wp_die( 'Security check failed' ); 629 } 630 631 // Get and sanitize parameters 632 $page = isset( $_POST[ 'page' ] ) ? max( 1, intval( $_POST[ 'page' ] ) ) : 1; 633 $attributes = isset( $_POST[ 'attributes' ] ) ? json_decode( stripslashes( $_POST[ 'attributes' ] ), true ) : []; 634 635 // Validate attributes 636 if ( empty( $attributes ) || ! is_array( $attributes ) ) { 637 wp_send_json_error( 'Invalid attributes' ); 638 } 639 640 // Set current page in GET superglobal for compatibility 641 $_GET[ 'jobbnorge_page' ] = $page; 642 643 // Generate the job listings HTML 644 $html = render_block_dss_jobbnorge( $attributes ); 645 646 // Return JSON response 647 wp_send_json_success( [ 'html' => $html ] ); 648 } 649 650 /** 651 * Enqueue frontend JavaScript for pagination. 652 */ 653 function enqueue_pagination_script() { 654 // Check if the block is being used on the current page 655 if ( ! has_block( 'dss/jobbnorge' ) ) { 656 return; 657 } 658 659 // Define the path to the pagination dependencies file. 660 $deps_file = plugin_dir_path( __FILE__ ) . 'build/pagination.asset.php'; 661 662 // Initialize an array for JavaScript dependencies and a random version number. 663 $jsdeps = []; 664 $version = wp_rand(); 665 666 // Check if the dependencies file exists. 667 if ( file_exists( $deps_file ) ) { 668 // If it does, require it and merge its dependencies with the existing ones. 669 $file = require $deps_file; 670 $jsdeps = array_merge( $jsdeps, $file[ 'dependencies' ] ); 671 // Also, set the version to the one from the file. 672 $version = $file[ 'version' ]; 673 } 674 675 wp_enqueue_script( 676 'jobbnorge-pagination', 677 plugin_dir_url( __FILE__ ) . 'build/pagination.js', 678 $jsdeps, 679 $version, 680 true 681 ); 682 683 // Localize script with AJAX URL and nonce 684 wp_localize_script( 685 'jobbnorge-pagination', 686 'jobbnorgeAjax', 687 [ 688 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 689 'nonce' => wp_create_nonce( 'jobbnorge_pagination_nonce' ), 690 ] 691 ); 692 } 693 694 // Hook into wp_enqueue_scripts to add pagination script 695 add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\enqueue_pagination_script' );
Note: See TracChangeset
for help on using the changeset viewer.