{"id":351931,"date":"2026-08-19T10:57:48","date_gmt":"2026-08-19T10:57:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/iq-jobs-manager\/"},"modified":"2026-08-19T10:57:23","modified_gmt":"2026-08-19T10:57:23","slug":"iq-jobs-manager","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/iq-jobs-manager\/","author":23546695,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"3.0.31","stable_tag":"3.0.31","tested":"7.0.4","requires":"5.9","requires_php":"7.4","requires_plugins":null,"header_name":"IQ Jobs Manager","header_author":"Iquester Solutions LLP","header_description":"Job openings CPT with an \"Apply\" modal + a persistent application form, application pipeline tracking, and CSV export. HR adds\/edits jobs from wp-admin; the Careers page updates automatically once you pick pages in Settings \u2014 no shortcodes required (shortcodes and blocks are also available if you'd rather place things manually).","assets_banners_color":"","last_updated":"2026-08-19 10:57:23","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/iquesters.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":51,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"3.0.31":{"tag":"3.0.31","author":"pritam02b","date":"2026-08-19 10:57:23"}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3654495,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128}},"assets_banners":[],"assets_blueprints":{},"all_blocks":{"iq-jobs-manager\/application-form":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"iq-jobs-manager\/application-form","title":"Job Application Form","category":"widgets","icon":"media-document","description":"The general job application form.","textdomain":"iq-jobs-manager","editorScript":"file:.\/editor.js"},"iq-jobs-manager\/job-listings":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"iq-jobs-manager\/job-listings","title":"Job Listings","category":"widgets","icon":"businessperson","description":"Job listing with search\/filter and Apply buttons.","textdomain":"iq-jobs-manager","editorScript":"file:.\/editor.js"}},"tagged_versions":["3.0.31"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[3197,16503,9023,9021],"plugin_category":[39],"plugin_contributors":[276488],"plugin_business_model":[],"class_list":["post-351931","plugin","type-plugin","status-publish","hentry","plugin_tags-applications","plugin_tags-careers","plugin_tags-jobs","plugin_tags-recruitment","plugin_category-business","plugin_contributors-pritam02b","plugin_committers-pritam02b"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/iq-jobs-manager\/assets\/icon-128x128.png?rev=3654495","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>IQ Jobs Manager adds a \"Job Opening\" post type with a simple classic-editor admin screen (title + one form for\nlocation, type, salary, deadline, etc. \u2014 no page-builder or block-editor knowledge required), a public Careers page\nyou set up by picking pages in Settings (no shortcodes to add), a secure application pipeline (resumes are never\nstored at a public URL and are only ever emailed as an attachment or downloaded through a login-gated link), and\nHR tools for tracking and exporting applications.<\/p>\n\n<h4>Displaying content on your site<\/h4>\n\n<p>Go to <strong>Job Openings &gt; Settings<\/strong> and pick a page for \"Job Listings Page\" and\/or \"General Application Form Page\".\nThe content appears there automatically \u2014 nothing to paste into the page editor.<\/p>\n\n<p>If you'd rather place things manually, two block-editor blocks are also available \u2014 \"Job Listings\" and \"Job\nApplication Form\" \u2014 searchable from the block inserter. The classic shortcodes still work too, for page builders or\nolder themes: <code>[career_jobs]<\/code> (job listing with Apply buttons) and <code>[career_form]<\/code> (the general application form).<\/p>\n\n<h4>Admin<\/h4>\n\n<ul>\n<li><strong>Job Openings &gt; Add New<\/strong> \u2014 HR fills in one form (description, location, type, experience, salary, openings,\nskills, deadline) and clicks Publish.<\/li>\n<li><strong>Job Openings &gt; Form Fields<\/strong> \u2014 toggle\/relabel which fields appear on the application form, and add custom\nfields (label + type \u2014 the internal field name is generated automatically).<\/li>\n<li><strong>Job Openings &gt; Settings<\/strong> \u2014 pick the Job Listings \/ Application Form pages, set the HR notification email, and\nconfigure uninstall data behavior.<\/li>\n<li><strong>Applications<\/strong> \u2014 view submissions, change status (New \/ Reviewed \/ Interview \/ Hired \/ Rejected), download\nresumes, export to CSV. Each application also records the applicant's IP address and browser (user agent) to\nhelp spot spam patterns.<\/li>\n<li><strong>Job Openings &gt; Analytics<\/strong> \u2014 page views, Apply clicks, submission attempts\/successes\/failures, overall and\nbroken down per job, over the last 7\/30\/90 days or all time.<\/li>\n<\/ul>\n\n<h3>External services<\/h3>\n\n<p>This plugin can optionally connect to Google reCAPTCHA to help protect the application forms (the Apply modal and\nthe general application form) from spam and automated submissions. It is <strong>off by default<\/strong> and only takes effect\nif you enable it and enter your own site key and secret key under Job Openings &gt; Settings &gt; reCAPTCHA.<\/p>\n\n<p>When enabled:<\/p>\n\n<ul>\n<li>The applicant's browser loads Google's reCAPTCHA script (<code>https:\/\/www.google.com\/recaptcha\/api.js<\/code>) so the\nwidget can render (v2) or a token can be generated (v3).<\/li>\n<li>When the applicant submits the form, the site sends the reCAPTCHA response token and the applicant's IP address\nto Google's verification endpoint (<code>https:\/\/www.google.com\/recaptcha\/api\/siteverify<\/code>) to confirm the submission\nwasn't automated.<\/li>\n<li>When an administrator saves a reCAPTCHA secret key in Settings, the site makes one request to the same Google\nendpoint to confirm the key is valid.<\/li>\n<\/ul>\n\n<p>This service is provided by Google LLC:\n<a href=\"https:\/\/policies.google.com\/terms\">Terms of Service<\/a> | <a href=\"https:\/\/policies.google.com\/privacy\">Privacy Policy<\/a><\/p>\n\n<p>No other third-party\/remote service is contacted by this plugin.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>iq-jobs-manager<\/code> folder to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate the plugin through the 'Plugins' menu in WordPress.<\/li>\n<li>Go to Job Openings &gt; Settings, set the HR notification email, and pick your Job Listings and Application Form\npages.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20need%20to%20add%20shortcodes%20to%20my%20pages%3F\"><h3>Do I need to add shortcodes to my pages?<\/h3><\/dt>\n<dd><p>No. Pick a \"Job Listings Page\" and\/or \"General Application Form Page\" in Job Openings &gt; Settings and the content\nappears there automatically. Shortcodes (<code>[career_jobs]<\/code>, <code>[career_form]<\/code>) and block-editor blocks are also\navailable if you'd rather place things manually.<\/p><\/dd>\n<dt id=\"where%20are%20submitted%20resumes%20stored%3F\"><h3>Where are submitted resumes stored?<\/h3><\/dt>\n<dd><p>In a private subfolder of your uploads directory (<code>wp-content\/uploads\/iqjoma-private-resumes\/<\/code>), under a randomly\ngenerated filename and blocked from direct access. Resumes are never given a public URL \u2014 they can only be\ndownloaded from wp-admin (Applications screen) by a logged-in Administrator via a capability- and nonce-checked\nlink, or received as an email attachment if HR notification emails are enabled.<\/p><\/dd>\n<dt id=\"who%20can%20see%20submitted%20applications%3F\"><h3>Who can see submitted applications?<\/h3><\/dt>\n<dd><p>Only Administrators, by default (not Editors, Authors, or Contributors), since applications contain applicant PII\n(name, email, phone, resume).<\/p><\/dd>\n<dt id=\"is%20google%20recaptcha%20required%3F\"><h3>Is Google reCAPTCHA required?<\/h3><\/dt>\n<dd><p>No. It's off by default. You can enable it (v2 checkbox or v3 invisible) from Job Openings &gt; Settings &gt; reCAPTCHA\nwith your own Google reCAPTCHA site\/secret keys. See \"External services\" below for what that sends to Google.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20my%20data%20if%20i%20delete%20the%20plugin%3F\"><h3>What happens to my data if I delete the plugin?<\/h3><\/dt>\n<dd><p>By default, nothing is deleted \u2014 job openings, applications, resumes, and settings are all kept. Deletion only\nhappens if you explicitly enable \"Delete data on uninstall\" in Settings before removing the plugin.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>3.0.31<\/h4>\n\n<ul>\n<li>Plugin Check: the custom application-field values array is inherently sanitized per-element further down (the\nright sanitizer depends on each field's configured type, known only inside that loop), so there's no single\nsanitizer that could apply at the point the array is first read \u2014 documented with an inline justification instead\nof restructuring further.<\/li>\n<\/ul>\n\n<h4>3.0.30<\/h4>\n\n<ul>\n<li>Re-ran Plugin Check after 3.0.29 and fixed what it still caught: a translators comment that had drifted away from\nits printf() call (a phpcs:ignore line got inserted between them), two wp_dropdown_pages() calls where a\nsingle-line ignore comment didn't reach the flagged values nested inside its multi-line array argument (now\nbracketed with phpcs:disable\/enable instead), a card_button_text field now sanitized once into a variable instead\nof re-reading $_POST across two branches, custom application-form field values now unslashed at the array level,\nand the CSV export date filters now read $_GET once per key instead of multiple times across a ternary.<\/li>\n<\/ul>\n\n<h4>3.0.29<\/h4>\n\n<ul>\n<li>Addressed the full Plugin Check report: a few remaining unescaped values (including one only reachable via\nprintf(), which the earlier manual review pass missed), several missing wp_unslash() calls, replaced direct\nfilesystem calls (unlink()\/rmdir()) in uninstall.php with WP_Filesystem, and prefixed uninstall.php's local\nvariables. Remaining Plugin Check warnings (custom-table direct queries, read-only GET filters without a nonce,\na couple of confirmed-safe false positives) are left in place with an inline explanation at each one rather than\nworked around, since none of them are real issues.<\/li>\n<\/ul>\n\n<h4>3.0.28<\/h4>\n\n<ul>\n<li>WordPress.org review follow-up: renamed the plugin's internal prefix (options, hooks, post types, script\/style\nhandles, meta box IDs, etc.) from the too-short \"cjm\"\/\"job\" to \"iqjoma\" throughout, to avoid collisions with other\nplugins. All dynamic output that reaches an echo\/print statement is now either escaped at the point of output or,\nwhere a helper method already escapes everything it builds internally (verified case by case), marked with an\ninline phpcs:ignore and a short justification instead of double-escaping already-safe HTML.<\/li>\n<li>Sites that already had this plugin active before 3.0.28 are migrated automatically and once, the first time this\nversion runs: existing settings, form field\/custom field config, the Analytics history table, published jobs, and\nsubmitted applications are all moved over to the new names. Nothing is deleted and no action is needed.<\/li>\n<\/ul>\n\n<h4>3.0.27<\/h4>\n\n<ul>\n<li>WordPress.org review follow-up: resumes now store under the uploads directory (via wp_upload_dir()) instead of a\nhardcoded wp-content path. The \"Powered by\" credit link now defaults off \u2014 site owners must explicitly opt in\nfrom Settings &gt; General. Inline admin CSS\/JS is now enqueued through wp_add_inline_style()\/wp_add_inline_script()\ninstead of being echoed directly. Nonce values are sanitized before verification. Removed the no-longer-needed\nload_plugin_textdomain() call. Fixed the header short description's shortcode wording to match the readme.<\/li>\n<\/ul>\n\n<h4>3.0.26<\/h4>\n\n<ul>\n<li>Fixed WordPress.org automated plugin-check failures: both block.json files now declare apiVersion 3 (required for\nthe WordPress 7.0+ iframed block editor), and the resume upload handler now moves the uploaded file via the\nWP_Filesystem API (with an explicit is_uploaded_file() check) instead of calling move_uploaded_file() directly.<\/li>\n<\/ul>\n\n<h4>3.0.25<\/h4>\n\n<ul>\n<li>WordPress.org submission prep: added a GPL license header to the plugin's main file, added External Services\nand FAQ sections to this readme, and removed a self-hosted-only \"View details\" popup that would have shadowed\nWordPress.org's own plugin info screen once listed there.<\/li>\n<li>The \"Powered by IQ Jobs Manager\" credit link (shown on the job listing, job detail, and application form pages)\nis now optional \u2014 toggle it off from Settings &gt; General. Was previously always shown with no way to disable it.<\/li>\n<li>Hardened CSV export against formula\/CSV injection: applicant-supplied values (name, message, custom field\nanswers) are now prefixed with a leading quote if they start with a character (=, +, -, @) that spreadsheet\napps could interpret as a formula when the export is opened.<\/li>\n<li>Number of Openings is now stored as a plain integer instead of free text.<\/li>\n<li>Minor: job posting structured data's deadline now uses UTC rather than the server's local timezone.<\/li>\n<\/ul>\n\n<h4>3.0.24<\/h4>\n\n<ul>\n<li>Fixed shared job links showing this plugin's own small \"Powered by\" logo in the link preview instead of the\nsite's own icon. Job posts have no featured image (no image field exists for them), so whatever generates the\npreview card was falling back to scanning the page and picking up our logo image instead. Jobs with no featured\nimage now report the site's own Site Icon (Settings &gt; General &gt; Site Icon) as their featured image, which is\nwhat virtually every SEO plugin\/sharing platform checks first.<\/li>\n<\/ul>\n\n<h4>3.0.23<\/h4>\n\n<ul>\n<li>Fixed the ID-prefixed job URL (e.g. \/jobs\/5433-growth-lead-job-25072026\/) 404ing right after a job was published,\neven though the plain slug URL worked. The rewrite rule that recognizes the ID-prefixed format is generic (any\nID + any slug) and normally only needs flushing once, but if a job got published before that flush had actually\nrun for this site (e.g. right after a plugin update), its URL would 404 until something else happened to trigger\na flush later. Now a flush also runs the moment a job is first published, closing that gap.<\/li>\n<\/ul>\n\n<h4>3.0.22<\/h4>\n\n<ul>\n<li>Settings page now tests the reCAPTCHA secret key against Google when you save (if reCAPTCHA is enabled and a\nsecret key is set), showing whether it looks valid or invalid right alongside the \"Settings saved\" notice.\nSettings are always saved regardless of the check result, so a typo doesn't cost you your other changes \u2014 you get\nclear feedback and a chance to fix it, instead of only finding out when a real applicant's submission fails.<\/li>\n<\/ul>\n\n<h4>3.0.21<\/h4>\n\n<ul>\n<li>Fixed the grid card's eye-icon badge not lining up with the title \u2014 it was absolutely positioned at a guessed\npixel offset rather than actually being measured against the title, so title length\/wrapping could throw the\nalignment off. Title and badge now share a flex row instead, keeping them level regardless.<\/li>\n<\/ul>\n\n<h4>3.0.20<\/h4>\n\n<ul>\n<li>Fixed the hero paragraph's margin-top (added last release) never actually applying when Elementor is active \u2014 the\nrule setting it used an \"h1 + p\" adjacent-sibling selector, but wrapping the heading in its own\n.elementor-widget-heading div (an earlier fix) put a div between the h1 and the paragraph in the DOM, silently\nbreaking that selector's match. It's now targeted by the paragraph's own class instead, which doesn't depend on\nexact DOM nesting.<\/li>\n<\/ul>\n\n<h4>3.0.19<\/h4>\n\n<ul>\n<li>Added margin-top: 20px to the hero paragraph text (the rule setting its margin already existed and was\nexplicitly zeroing out its top margin, so it needed updating directly there rather than a new rule elsewhere).<\/li>\n<\/ul>\n\n<h4>3.0.18<\/h4>\n\n<ul>\n<li>Increased the gap between the hero section and the filter bar below it to 10rem total \u2014 5rem of bottom padding on\nthe hero plus 5rem of top margin on the filter bar (kept as margin rather than padding on the filter bar itself,\nso its own compact pill shape isn't stretched out).<\/li>\n<\/ul>\n\n<h4>3.0.17<\/h4>\n\n<ul>\n<li>Increased the gap between the hero heading and the text below it from 16px to 20px.<\/li>\n<\/ul>\n\n<h4>3.0.16<\/h4>\n\n<ul>\n<li>Apply modal: the close \"x\" is now in a proper flex row with the title instead of being absolutely positioned in\nthe box's corner, so it's reliably vertically centered against the heading text rather than floating above it.<\/li>\n<li>Modal\/form container padding no longer shrinks on small screens \u2014 it now stays the same at every width.<\/li>\n<li>Added top spacing above the meta\/Apply row on the overview page on mobile.<\/li>\n<li>Removed the \"Share:\" label before the share icons.<\/li>\n<\/ul>\n\n<h4>3.0.15<\/h4>\n\n<ul>\n<li>Found the actual source of the recurring hover\/click color changes: the active theme (Astra) has its own global\n\"button:hover, button:focus\" rule that repaints background\/text\/border color on every plain  element\nsite-wide. Removing our own hover rules in earlier rounds wasn't enough \u2014 it just left nothing to stop that theme\nrule from taking over instead. All 5 of our buttons (copy-link, Apply, Submit, filter Search, modal close) now\nexplicitly pin their resting colors against it on hover\/focus\/active\/click, and Apply\/Submit no longer depend on\nthe theme's own \".button\" class for their color, so there's no more cascade-order gamble there either.<\/li>\n<\/ul>\n\n<h4>3.0.14<\/h4>\n\n<ul>\n<li>Fixed the Job Listings page hero heading still not matching other Elementor-built pages' heading weight\/spacing\/\ncolor. It was correctly picking up Elementor's site-wide default heading size, but not the bolder weight, tighter\nletter-spacing, and darker color other headings have \u2014 those come from a per-page Elementor override tied to that\nspecific page's own widget ID, which our heading (not a real Elementor-authored widget) has no way to match. Set\nthe same values directly instead.<\/li>\n<\/ul>\n\n<h4>3.0.13<\/h4>\n\n<ul>\n<li>Changed the filter bar's Search button from blue to yellow with dark text, matching the Apply button's color.<\/li>\n<li>Grid card corner badge's mobile top offset changed from 20px to 24px.<\/li>\n<\/ul>\n\n<h4>3.0.12<\/h4>\n\n<ul>\n<li>The blue circle on the Apply modal's close button on click wasn't fixed by the previous round's outline\/tap-\nhighlight reset \u2014 it's most likely the theme's own Bootstrap-style focus glow, which is a box-shadow ring, not an\noutline. Explicitly cleared box-shadow (and native button appearance) on the close button for every interaction\nstate (hover\/focus\/active).<\/li>\n<\/ul>\n\n<h4>3.0.11<\/h4>\n\n<ul>\n<li>Removed every hover-state color change on buttons (hero button, icon buttons\/share row, filter Search button, view\nbutton) \u2014 they're now visually static on hover\/click, no exceptions.<\/li>\n<li>Killed the mobile browser's own default blue tap-highlight\/focus flash on buttons (a WebKit default we'd never\nexplicitly turned off) \u2014 this is what was showing as a blue circle behind the Apply modal's close \"x\".<\/li>\n<li>Fixed the Apply modal: a long job title wrapping to two lines could run underneath the close \"x\" button since no\nspace was reserved for it; the heading now keeps clear of it. Increased the gap between form fields, and gave\ninputs slightly more breathing room (padding\/corner radius).<\/li>\n<\/ul>\n\n<h4>3.0.10<\/h4>\n\n<ul>\n<li>Fixed job card and list row titles (h5) also being subject to the active theme's own responsive heading rule at\nnarrower widths, same root cause as the hero heading fix in 3.0.9 \u2014 they now have an explicit font-size that\ncan't be overridden by it.<\/li>\n<li>The grid card's corner badge (the eye icon \/ \"Applications Closed\" label) now sits closer to the top on mobile\n(20px instead of 30px), matching the card's own reduced mobile padding.<\/li>\n<li>Fixed the \"Powered by\" line: only the icon links to iquesters.com now, not the whole \"Powered by ... Jobs\nManager\" line.<\/li>\n<\/ul>\n\n<h4>3.0.9<\/h4>\n\n<ul>\n<li>Fixed the Job Listings page hero heading picking up the active theme's generic mobile heading size instead of\nElementor's own heading typography when Elementor is active \u2014 the heading was using Elementor's CSS classes but\nwasn't wrapped in Elementor's own widget container, so Elementor's real (already-loaded) heading styles never\nactually matched it and the theme's own responsive \"h1\" rule won by default instead. It's now wrapped correctly\nso Elementor's own styling takes over as intended.<\/li>\n<li>The hero heading and text are now left-aligned on mobile instead of centered.<\/li>\n<li>Removed the green \"success\" background\/border the copy-link button switched to after a click \u2014 the \"Copied!\"\ntooltip already confirms the action, so the button itself no longer changes color.<\/li>\n<\/ul>\n\n<h4>3.0.7<\/h4>\n\n<ul>\n<li>Removed the \"|\" separator between meta items (location\/type\/salary, posted-date\/experience, list-row meta, card\nmeta) on small screens. No static CSS rule can tell where a flex row will actually wrap, so whenever only one\nitem ended up alone on its own line, it still showed a stray pipe next to nothing. Below 600px the pipes are\ndropped entirely \u2014 each item already has its own icon, so the spacing alone reads fine without them.<\/li>\n<li>Fixed a font-size mismatch on the overview page header: the location\/type\/salary row had no explicit font-size\n(inheriting the theme's default) while the posted-date\/experience row below it was set to 0.9em, so the two rows\nvisibly rendered at different sizes. Both now use the same 0.9em.<\/li>\n<\/ul>\n\n<h4>3.0.6<\/h4>\n\n<ul>\n<li>The \"Powered by [icon] Jobs Manager\" line shown on every plugin-rendered page now links to iquesters.com, the\nsame way \"Powered by WordPress\" links to wordpress.org.<\/li>\n<li>On the Plugins screen: the author is now \"Iquester Solutions LLP\" (linked to iquesters.com) instead of\n\"Custom\", and there's now a \"View details\" link next to it that opens the same details popup WordPress.org-hosted\nplugins get \u2014 this plugin isn't on WordPress.org, so that popup is now hand-built from this readme instead.<\/li>\n<\/ul>\n\n<h4>3.0.5<\/h4>\n\n<ul>\n<li>Fixed the \"|\" separator between meta items (location\/type\/salary, posted-date\/experience, list-row meta, card\nmeta) leaving a stray hanging \"|\" at the start of a wrapped line on narrow screens. It was baked onto the front\nof each item, so when an item wrapped onto a new line, its leading \"|\" wrapped with it and landed with nothing\nbefore it. It's now baked onto the end of each item instead (skipped on the last item), so it reads as normal\ntrailing punctuation at the end of the previous line instead of a stray mark starting the new one.<\/li>\n<\/ul>\n\n<h4>3.0.4<\/h4>\n\n<ul>\n<li>Openings + application deadline on the overview page now sit together under an \"Additional Information\" heading\nwith consistent spacing, instead of as two loose pills with inconsistent gaps between them.<\/li>\n<li>Copy-link button: the icon now recolors on hover (previously only the background changed), and clicking it shows\na small \"Copied!\" tooltip above the button instead of only updating the accessible label.<\/li>\n<li>Rebuilt the job filter bar's dropdown\/submit styling to look like one cohesive component instead of a native\nselect next to a theme-default button, and fixed a mobile layout bug where the search field could stretch to\n240px tall (flex-basis meant for width was being applied as a height once the bar switched to a column layout).\nOn mobile, the Type\/Location dropdowns now share one line instead of stacking one per row.<\/li>\n<\/ul>\n\n<h4>3.0.3<\/h4>\n\n<ul>\n<li>Fixed the overview page's meta rows (location\/type\/salary and posted-date\/experience) rendering in a different\nfont on mobile than desktop \u2014 some themes\/builders apply different responsive typography per breakpoint, which\nthis text was just inheriting; it now uses a fixed font stack instead.<\/li>\n<li>Reverted the mobile-only \"stack one item per line\" layout from the last release \u2014 it wasn't actually needed:\nthe \"|\" separator lives inside each item itself, so it already wraps together with its item instead of getting\nstranded. Mobile now wraps naturally (as many items as fit per line, \"|\" between each), same as desktop.<\/li>\n<\/ul>\n\n<h4>3.0.2<\/h4>\n\n<ul>\n<li>\"Openings\" on the overview page restyled as a quiet rounded badge, matching the \"Apply by ...\" tag next to it\ninstead of plain text. Also fixed a bug this surfaced: it shared a class with the meta-row items that get a\n\"|\" separator before them, which could incorrectly show a stray \"|\" in front of the badge.<\/li>\n<\/ul>\n\n<h4>3.0.1<\/h4>\n\n<ul>\n<li>Restored the job title being moved inside the detail card, and the \"|\" separators in the overview page's meta\nrows \u2014 both had been mistakenly removed in the previous release while fixing an unrelated loading flash. The\nflash is now fixed properly instead: the title move happens via a synchronous inline script positioned right\nafter the card in the page HTML (runs while the browser is still parsing, before that part of the page is\npainted) rather than a DOMContentLoaded listener (which only runs after the whole page has already rendered).<\/li>\n<li>Fixed the mobile bug that prompted the \"|\" removal properly this time: on narrow screens the meta rows now\nstack one item per line (so there's no wrap point for a separator to get stranded at) instead of losing the\nseparator on desktop too.<\/li>\n<\/ul>\n\n<h4>3.0.0<\/h4>\n\n<ul>\n<li>Added an Analytics dashboard (Job Openings &gt; Analytics): page views, Apply button clicks, submission attempts,\nsuccesses, and failures \u2014 overall and broken down per job, with a 7\/30\/90-day or all-time range selector.\nBacked by a new database table, not third-party analytics.<\/li>\n<li>Applications now record the applicant's IP address and browser (user agent), shown on the application's admin\ndetail screen and included in CSV exports, to help HR spot spam patterns (e.g. many submissions from one\nIP\/browser in a short window).<\/li>\n<li>Resume uploads are now validated more strictly, both client- and server-side: max 10 MB, and PDF\/Word only \u2014\nthe server-side check now sniffs actual file content, not just the file extension, and a rejected upload now\nshows a clear error instead of silently being dropped from the submission.<\/li>\n<\/ul>\n\n<h4>2.9.0<\/h4>\n\n<ul>\n<li>Fixed the job title going invisible for a moment on page load \u2014 a previous version hid it via CSS and only\nrevealed it after a script repositioned it, which looked broken (especially on a slow connection). The title\nnow just stays in the theme's normal position\/visibility at all times; no more hide\/move\/reveal.<\/li>\n<li>Plugin CSS\/JS (and the reCAPTCHA script, if enabled) now only load on pages that actually use this plugin's\nmarkup (the job overview page, the configured Job Listings\/Application Form pages, or any page\/post using the\nshortcodes or blocks manually) instead of on every page of the site.<\/li>\n<li>The reCAPTCHA script now loads with the <code>async<\/code> attribute \u2014 as a third-party, cross-origin script, this was a\nlikely real contributor to slow page loads when reCAPTCHA is enabled.<\/li>\n<\/ul>\n\n<h4>2.8.2<\/h4>\n\n<ul>\n<li>Removed the light blue focus\/click outline on the share icon buttons and the filter bar's search\/dropdown\nfields \u2014 both now use a neutral gray focus ring instead.<\/li>\n<\/ul>\n\n<h4>2.8.1<\/h4>\n\n<ul>\n<li>Removed the background and shadow from the job filter bar.<\/li>\n<\/ul>\n\n<h4>2.8.0<\/h4>\n\n<ul>\n<li>Fixed a mobile bug on the overview page where the top meta row (location\/type\/salary) and the posted-info row\ncould show a stray \"|\" separator stranded at the start of a wrapped line. Removed the \"|\" separator there\nentirely \u2014 each item already has its own icon, so it reads fine on plain spacing alone.<\/li>\n<li>\"Openings\" moved out of the top posted-info row and now shows after Required Skills further down the page.<\/li>\n<\/ul>\n\n<h4>2.7.6<\/h4>\n\n<ul>\n<li>List view meta (location\/type\/posted date) moved from the right side of the row to directly under the title,\ninstead of sitting alongside it.<\/li>\n<\/ul>\n\n<h4>2.7.5<\/h4>\n\n<ul>\n<li>List row corner radius reduced to 1rem (was 2rem, matching the grid card\/other surfaces).<\/li>\n<\/ul>\n\n<h4>2.7.4<\/h4>\n\n<ul>\n<li>List row meta now matches the grid card's styling: \"|\" separators (was \"\u2022\"), and the same muted color\/size for\nthe meta text \u2014 so both layouts read as one consistent design instead of two slightly different ones.<\/li>\n<\/ul>\n\n<h4>2.7.3<\/h4>\n\n<ul>\n<li>Grid card meta line: added the missing clock icon before the job type, added a \"Posted X ago\" item (matching\nthe list view), and switched the separator to \"|\" between all three items.<\/li>\n<li>Corner badge (the eye button) top offset increased to 30px.<\/li>\n<\/ul>\n\n<h4>2.7.2<\/h4>\n\n<ul>\n<li>Removed the \"Apply by ...\" deadline pill from listing cards (grid layout) \u2014 the excerpt already fills the\ncard, and the full deadline is one click away on the job's own page.<\/li>\n<li>Fixed a bug where a narrow grid card could wrap the location\/type meta line mid-separator, stranding the dot\nat the end of a line \u2014 location and type are now each a single unit that wraps as a whole.<\/li>\n<li>Fixed list rows showing the job type twice (once as a subtitle under the title, once in the meta row) when no\ndepartment taxonomy was set \u2014 the subtitle now only shows the department, since type is already in the meta row.<\/li>\n<li>Increased card\/row padding so content sits further from the (2rem) rounded corners.<\/li>\n<\/ul>\n\n<h4>2.7.1<\/h4>\n\n<ul>\n<li>Admin job form: the Responsibilities\/Requirements\/Benefits fields were relabeled to match what's actually\nshown on the job page (\"Key Responsibilities\", \"Preferred Qualifications\"), and each now has a persistent\nhelp note plus realistic example placeholders explaining that one line = one bullet point, instead of only a\nplaceholder hint that disappears once you start typing.<\/li>\n<\/ul>\n\n<h4>2.7.0<\/h4>\n\n<ul>\n<li>Added an Education field to the Job Details admin form, shown as its own section on the overview page.<\/li>\n<li>Overview page sections reordered: Key Responsibilities, Preferred Qualifications, Benefits, Required Skills,\nEducation, then the application deadline.<\/li>\n<li>Fixed the \"Copy link\" share button looking different from the other share icons \u2014 it's a <code>&lt;button&gt;<\/code> while the\nothers are <code>&lt;a&gt;<\/code> links, and browsers apply different default styling to each even with the same CSS class;\nadded explicit resets (outline, box-shadow, text-align, etc.) so all five share buttons render identically.<\/li>\n<li>Required Skills tags restyled to match the \"Apply by ...\" badge (same padding, muted background, size, and\nweight) instead of their own slightly different pill style.<\/li>\n<\/ul>\n\n<h4>2.6.5<\/h4>\n\n<ul>\n<li>Required Skills tags restyled to match the \"Apply by ...\" badge (same padding, muted background, size, and\nweight) instead of their own slightly different pill style.<\/li>\n<\/ul>\n\n<h4>2.6.4<\/h4>\n\n<ul>\n<li>Fixed the \"Copy link\" share button looking different from the other share icons \u2014 it's a <code>&lt;button&gt;<\/code> while the\nothers are <code>&lt;a&gt;<\/code> links, and browsers apply different default styling to each even with the same CSS class;\nadded explicit resets (outline, box-shadow, text-align, etc.) so all five share buttons render identically.<\/li>\n<\/ul>\n\n<h4>2.6.3<\/h4>\n\n<ul>\n<li>Fixed a flash where the job title briefly appeared in its original position before jumping into the detail\ncard on page load \u2014 it's now hidden until the script has already moved it (with a no-JS fallback so it's never\nleft invisible if JavaScript is disabled).<\/li>\n<li>Apply button text shortened from \"Apply for this Position\" to \"Apply\".<\/li>\n<\/ul>\n\n<h4>2.6.2<\/h4>\n\n<ul>\n<li>Overview page sections relabeled\/reordered to match the section structure used by major job portals, mapped\nonto our existing fields: Description -&gt; \"Overview\", Responsibilities -&gt; \"Key Responsibilities\" (now shown\nfirst), Skills -&gt; \"Required Skills\", Requirements -&gt; \"Preferred Qualifications\". Benefits is unchanged; there's\nno \"Required Experience\" or \"Education\" section since we don't collect those as separate fields.<\/li>\n<\/ul>\n\n<h4>2.6.1<\/h4>\n\n<ul>\n<li>The job title now moves inside the detail card (above the meta row) instead of sitting outside it above a plain\nwhite gap (best-effort, JS-driven \u2014 see the .entry-title caveat elsewhere in this file).<\/li>\n<li>Top meta row trimmed to location | type | salary with pipe separators; experience and openings moved down next\nto the \"Posted X ago\" line (also pipe-separated); the application deadline moved to sit right after Benefits\ninstead of in the top meta row.<\/li>\n<\/ul>\n\n<h4>2.6.0<\/h4>\n\n<ul>\n<li>Overview page redesigned toward the plain, flat layout used by major job portals (Naukri, LinkedIn, Indeed)\ninstead of a tinted\/elevated card: white background, simple dividers.<\/li>\n<li>The theme's author\/date byline above the job title is now hidden (best-effort \u2014 depends on the theme using a\ncommon class name for it).<\/li>\n<li>Apply now sits directly next to the meta info at the top (alongside a new \"Posted X ago \u00b7 N openings\" line),\nin the same position major job portals place their primary CTA. Share icons moved down to a footer row instead\nof competing with Apply for attention at the top.<\/li>\n<\/ul>\n\n<h4>2.5.0<\/h4>\n\n<ul>\n<li>Grid card CTA moved to a corner badge (top-right, like a bookmark icon) instead of a footer button, and the\neye icon itself dropped its circular background \u2014 it's now just a colored icon, no pill\/fill.<\/li>\n<li>Added a short auto-generated description snippet under the meta info on both the grid card and the list row.<\/li>\n<li>List rows now show a location and a clock icon next to location\/type (previously plain text only, for\nconsistency with the grid card's icon treatment).<\/li>\n<\/ul>\n\n<h4>2.4.3<\/h4>\n\n<ul>\n<li>All card-style surfaces (job cards, job rows, the overview page's detail card, the Apply modal\/general form,\nthe filter bar) now use a consistent 2rem border-radius.<\/li>\n<li>Application form field labels reduced to font-weight 500; form field (input\/textarea\/select) corners changed\nto 7px.<\/li>\n<\/ul>\n\n<h4>2.4.2<\/h4>\n\n<ul>\n<li>Grid listing card redesigned to cut icon clutter: one icon (location) instead of one per field, location\/type\nshown as plain dot-separated text, and the deadline shown as a quiet rounded tag instead of icon+sentence.\nAdded a subtle divider above the view button so it reads as an integrated footer rather than a floating element.<\/li>\n<\/ul>\n\n<h4>2.4.1<\/h4>\n\n<ul>\n<li>Replaced the default hero illustration (self-hosted SVG) with a bundled photo\n(assets\/image\/careers-hero-team-collaboration.webp). A custom image picked in Settings &gt; Hero Section still\noverrides it, same as before.<\/li>\n<\/ul>\n\n<h4>2.4.0<\/h4>\n\n<ul>\n<li>Replaced the \"View &amp; Apply\" text button on listing cards\/rows with a circular icon-only (eye) button. The\nconfigured button text (Settings &gt; Job Listings &gt; Apply Button Text) is kept as the accessible name\n(aria-label\/title) even though it's no longer shown visually.<\/li>\n<\/ul>\n\n<h4>2.3.3<\/h4>\n\n<ul>\n<li>Job overview page's detail card now uses a soft blue tint (#f5fcff) instead of plain white.<\/li>\n<li>Job listing rows\/cards now alternate between a soft cream (#fff6e0) and the same soft blue (#f5fcff) tint,\ninstead of all being plain white.<\/li>\n<\/ul>\n\n<h4>2.3.2<\/h4>\n\n<ul>\n<li>Overview page section headings (Skills, etc.) reduced to font-weight 500.<\/li>\n<li>The \"Back to Jobs\" link now moves above the page title instead of sitting below it \u2014 done via a small script\nsince the theme renders the title outside any area the plugin's PHP can reach (best-effort: relies on the\ntheme using the common \".entry-title\" class, same caveat as the existing title-sizing CSS rule).<\/li>\n<\/ul>\n\n<h4>2.3.1<\/h4>\n\n<ul>\n<li>Job filter bar redesigned in a Material style: filled pill-shaped search\/dropdown fields (no borders, soft grey\nfill that turns white with an accent focus ring), a search icon inside the search field, and the whole bar\ndistinguished by elevation (shadow) instead of a hard border.<\/li>\n<\/ul>\n\n<h4>2.3.0<\/h4>\n\n<ul>\n<li>Added a \"Back to Jobs\" link at the top of the job overview page, linking to whichever page is set as the Job\nListings Page in Settings (hidden if that setting isn't configured).<\/li>\n<li>Job URLs now include the post ID for clarity\/reference (e.g. \/jobs\/142-frontend-developer\/ instead of\n\/jobs\/frontend-developer\/). The old ID-less URLs keep working \u2014 this adds a URL pattern, it doesn't replace one.\nRewrite rules are flushed automatically once after this update, no manual Permalinks resave needed.<\/li>\n<\/ul>\n\n<h4>2.2.1<\/h4>\n\n<ul>\n<li>The Submit button now shows a spinner while an application is being sent, and is disabled to prevent double-submits.<\/li>\n<li>After submitting, the form fields are replaced with a clear success (checkmark) or error (cross) icon and message\ninstead of a small line of text under the form; the Apply modal then closes automatically a few seconds later\neither way, and the form is reset and ready again for the next visitor.<\/li>\n<\/ul>\n\n<h4>2.2.0<\/h4>\n\n<ul>\n<li>Added Google reCAPTCHA protection for the application forms (Apply modal + general application form) \u2014 choose\nv2 (\"I'm not a robot\" checkbox) or v3 (invisible, score-based) from the new Settings &gt; reCAPTCHA tab. Off by\ndefault until keys for the selected version are set.<\/li>\n<li>Job overview page redesigned: Apply and Share now sit together right under the job's meta info at the top of the\npage (instead of only at the bottom after scrolling), the description now has its own \"Description\" heading, and\nthe page uses a single elevated card instead of a plain content block.<\/li>\n<li>Listing and grid cards restyled with soft shadows and a hover lift instead of plain borders.<\/li>\n<li>All content headings (job titles, section headings, form headings) reduced to h5, keeping only the Hero heading\nas an h1; section heading weight reduced so it reads as a label rather than a shout.<\/li>\n<li>Removed the placeholder logo icon from list-layout rows.<\/li>\n<li>Added a Location filter (populated from whatever locations are actually in use) alongside Search\/Department\/Type,\nand restyled the whole filter bar.<\/li>\n<\/ul>\n\n<h4>2.1.1<\/h4>\n\n<ul>\n<li>Settings page reorganized into tabs (General \/ Job Listings \/ Hero Section) and gained a Hero Image picker\n(Media Library) with the original illustration kept as the fallback when no image is set.<\/li>\n<li>Fixed a bug where, if the Job Listings and General Application Form settings pointed at the same page, the\nlisting and the general form (each with their own \"Powered by\" footer) would both render on that page.<\/li>\n<li>Job listing rows now show location \/ type \/ posted date on a single line instead of stacked.<\/li>\n<li>Job overview page: section headings (Skills, Responsibilities, etc.), the meta row icon alignment\/spacing, and\nthe job title size\/weight were all tightened up.<\/li>\n<li>The auto-injected Job Listings \/ Application Form page content is now wrapped in a max-width, padded container,\nso it no longer renders edge-to-edge on full-width page templates and no longer butts up against the header\/footer.<\/li>\n<\/ul>\n\n<h4>2.1.0<\/h4>\n\n<ul>\n<li>Removed the hardcoded HR notification email default (now defaults to the site admin email).<\/li>\n<li>Security review: fixed missing wp_unslash() on several inputs, and restricted resume\/application access to\nAdministrators (was previously available to any Contributor-level role).<\/li>\n<li>Added Google for Jobs (schema.org JobPosting) structured data on single job pages.<\/li>\n<li>Added Job Listings and Job Application Form blocks for the block editor, alongside the existing shortcodes.<\/li>\n<li>Added a first-run admin notice pointing to Settings.<\/li>\n<li>Accessibility: the Apply modal now traps focus, closes on Escape, and returns focus to the triggering button.<\/li>\n<li>Full translation-readiness pass (all admin\/frontend\/JS strings wrapped for translation).<\/li>\n<\/ul>\n\n<h4>2.0.0<\/h4>\n\n<ul>\n<li>Rebuilt as a namespaced, multi-file OOP plugin (was a single procedural file).<\/li>\n<li>Added application status\/pipeline tracking.<\/li>\n<li>Added a Settings page (HR notify email is no longer a hardcoded constant).<\/li>\n<li>Added CSV export of applications.<\/li>\n<li>Added deadline-based Apply button hiding.<\/li>\n<li>Moved inline CSS\/JS into real enqueued asset files.<\/li>\n<li>Added custom application-form fields (HR picks a label + type; no shortcode\/name editing needed).<\/li>\n<li>Added page-select in Settings so the job listing \/ application form display automatically \u2014 no shortcodes required.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Job openings with an Apply modal, a persistent application form, an application pipeline, and CSV export.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/351931","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=351931"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/pritam02b"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=351931"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=351931"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=351931"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=351931"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=351931"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=351931"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}