Changelog

Every release of SocietyPress, what changed, and why. The [Unreleased] block at the top is what's landed in the development branch since the last tagged release.

All notable changes to SocietyPress are recorded here.

The format is based on Keep a Changelog.

SocietyPress uses a single running version shared by the plugin, the parent theme and every child theme — they are built, released and installed together, so they carry one number rather than drifting apart. The patch digit increments each release, without rolling over: 1.1.9, 1.1.10, 1.1.11, and so on. A change in the first or second digit marks a milestone release, not a technical distinction about the kind of change involved.

Entries describe user-visible changes only. For the underlying commits, see the Git log.

The 1.0 and 1.1 development line is archived in CHANGELOG-1.x.md; the pre-1.0 work in CHANGELOG-pre1.md.


[1.5.46] — 2026-09-28

Surveys have their own place in the menu, and running one takes no knowledge of pages or the page builder. Choose Add New Survey, type the questions, and press Publish. The survey makes its own page and gives you the link to copy into an email or newsletter. Close Survey stops new answers and leaves the page up to tell latecomers it has ended. Reopen brings it back at the same link. Results are on the survey's own Results tab: everyone's answers added up, how many members have answered out of how many could, a list of who has taken part, and a spreadsheet download.

Each member can answer once. A signed-in member who has answered is told so instead of being shown the questions again. Two quick presses of the button can't record two answers.

Surveys can be anonymous, and are unless you say otherwise. An anonymous survey records that a member took part, separately from what they said, and nothing connects the two. The answers keep no name, email, account or address, and are dated by day only. The list of who took part has no dates at all, so an answer can't be matched to a member by the day it arrived. The spreadsheet is shuffled for the same reason. Once anyone has answered, the Anonymous setting is locked, because members answered under that promise. Members see one line above the questions telling them which kind of survey it is. With Anonymous switched off, each member's name is shown with their answers.

Surveys are for members by default. A survey can be opened to anyone with the link. The survey screen then says in plain words what that costs: with no sign-in to check, a browser marker stops casual repeat answers, but someone determined could answer twice.

Members-only forms and surveys are now checked when answers arrive, not only when the page is shown. Before, a non-member who sent answers straight to the site, without using the page, had them accepted.

Members answering on the same network are no longer turned away. The limit of ten submissions an hour was counted per internet address, so at a meeting on the library's wifi the eleventh member to answer was refused. Signed-in members are now counted individually.

An agree/disagree scale's wording can now be changed on the Forms screen. The box for its choices was hidden for that one question type, so the default wording couldn't be replaced.

Spreadsheet downloads no longer log warnings on PHP 8.4.

[1.5.45] — 2026-09-23

Two new question types for asking how strongly people feel. A star rating from one to five, and an agree/disagree scale that arrives already worded — Strongly disagree through Strongly agree — which you can rewrite entirely. Star ratings report an average alongside the breakdown. Worded scales deliberately do not: they have an order but no arithmetic, and "3.4 Agree" would be precision the answers never contained.

Both are built from ordinary radio buttons, so they work with a keyboard, read correctly aloud, and still work if scripting is off. On a phone the points stack rather than shrink, with finger-sized targets, because five labels squeezed onto one line is how a rating scale becomes unanswerable.

Answers to a dropdown, multiple choice, scale or star question are now checked against the choices the form actually offered. Checkbox answers were already filtered this way; the others took whatever was sent. On a contact form that was untidy. On a survey it meant a single crafted submission could invent an answer nobody was ever shown and have it counted alongside the real ones.

[1.5.44] — 2026-09-23

Forms now show you what everybody said, not just what one person said. A form has always recorded every answer, but reading them meant opening submissions one at a time. That answers "what did this person say" when the question a society is actually asking is "what does the membership want more of". The submissions screen now opens with a tally: every question, every choice, counts and percentages, with written answers listed underneath. Options nobody picked are shown at zero, because nobody choosing the Saturday workshop is a finding rather than an absence. Questions from an earlier version of the form keep their answers and are marked as retired.

A form can now be restricted to members in good standing. Visitors are asked to sign in rather than shown an empty space, and the form itself is never sent to the page. Use it for surveys where only the membership should have a say.

[1.5.43] — 2026-09-22

A donation the giver abandoned no longer reads as money on its way in. When somebody opens the payment page and closes it without paying, the card company holds the attempt open for about a day and then expires it. Nothing in SocietyPress listened for that, and nothing ever asked, so the donation kept the "Pending" it was given the moment the page opened — permanently. A treasurer reading the donations list saw gifts arriving that were never coming, and no amount of waiting cleared them. Abandoned donations are now marked Expired when the card company says so.

A nightly check also settles anything still pending after two days by asking the card company directly rather than waiting to be told. That catches the more expensive version of the same fault: a real gift that arrived while the notification link was misconfigured, which until now would have gone unrecorded and unreceipted. Nothing is ever marked paid without the card company confirming it against that specific donation.

[1.5.42] — 2026-09-08

A stray note in the Store's table definition stopped filling the error log. An explanatory comment sat inside the statement that builds the store products table. WordPress reads that statement a line at a time and has no notion of an SQL comment, so it took the note for a column and tried to add it to the table on every single admin page load — failing each time and writing the failure to the log. The columns themselves were always created correctly and no data was affected; the note now sits above the statement instead of inside it.

[1.5.41] — 2026-09-08

Media Type, Subject and Location now take as many values as an item needs. A book about Texas cemeteries during the Civil War is all three subjects, and a volume can be both a periodical and a rare book, but these fields held one value each. Catalogers did the only thing available and typed several into the single box, which the catalog then read as one long value: the public filters offered "Book, Rare Books" and "Rare Books, Book" as though they were two different collections, and the subject facets split "Alamo, The" into "Alamo" and "The" — a subject nobody had chosen.

Each of the three is now a list of tick boxes drawn from the society's own vocabulary, with a box to narrow a long list by typing and the same "add one that is not listed" it always had. Filters, the Browse by Collection cards, the Popular Subjects tags and the admin breakdowns all count individual values, so a facet means what it says. Existing catalogs are converted on upgrade, and the conversion consults the society's vocabulary before treating any comma as a separator, so terms that contain one survive whole.

[1.5.40] — 2026-09-08

A reference-only library is no longer asked about lending. Society libraries are overwhelmingly reference-only — local history, rare material and one-of-a-kind manuscripts are consulted on the premises and never leave the building. SocietyPress assumed the opposite: it labelled every item "Available", asked a cataloger on each item whether it could be checked out, and — worst of all — flipped that label to "Checked Out" in red the moment an item was marked non-lendable, telling a researcher a book was away on loan when in truth it never leaves the shelf.

Library → Catalog Options now asks the society once whether it lends anything at all. Left unticked, the per-item checkout box disappears, the Status column is withdrawn from the public catalog, the item detail panel stops reporting a loan status, and the admin "Available" tile goes with them. A lending library ticks the box and the whole set returns, with each item's stored setting exactly as it was left.

[1.5.39] — 2026-09-08

Recording what an item is worth no longer puts it up for sale. The Store decided what to offer by looking for a price: any catalog item with a Value above 0 appeared in the shop. But a library records what an item is worth for insurance and accession long before anyone considers selling it, and most societies never sell from the collection at all — so a catalog imported with its values intact would quietly put thousands of reference books in the shop window the moment the Store was switched on. Selling is now something a librarian says explicitly: each item has a "List this item for sale in the Store" tick box, off unless chosen, and a price is still needed for the listing to make sense. Societies already running a Store keep every priced item on sale, so nothing disappears from an existing shop on upgrade.

[1.5.38] — 2026-09-08

The library's Category field is gone; Media Type does the job. A catalog item carried both a Media Type and a Category, and the two shipped with near-identical lists — Books, Periodicals, Maps, Microfilm — so a cataloger had to guess which one to use and often filled in both. Only one of them earned its place: Media Type can be filtered on in the public catalog and the admin catalog, drives the Browse by Collection cards, and arrives filled in from an import. Category could only ever be set by hand, one item at a time, and nothing anywhere let a researcher or a librarian search by it. Removing it takes away the guesswork and leaves the field that actually works. The Library Categories admin screen goes with it, and the catalog page builder block loses its unusable "Filter by category" setting. Nothing stored is deleted, so a society that had filled the field in keeps that data.

[1.5.37] — 2026-09-08

A new library item no longer assumes it can be checked out. The "Item can be checked out" box started ticked, so every book a cataloger added quietly declared itself lendable. Most genealogical and historical society libraries are reference-only — local history and rare material does not leave the building — which made the default wrong for the majority of collections, and wrong in a way nobody had reason to notice. New items now start unticked; a lending library ticks the box, and existing items are untouched.

[1.5.36] — 2026-09-08

Members-only pages no longer appear in the menu for people who aren't members. The menu hid "Members" and "Member Directory" from logged-out visitors, but it decided by asking whether anyone was signed in — not whether the person signed in actually belongs to the society. Anyone with a site account but no membership, a volunteer or a lapsed member among them, saw those links, followed them, and hit a wall. The menu now asks the same question the page itself asks, so a link that appears is a link that opens. This covers the member directory and every page a society has marked members-only.

A catalog import now shows what it actually brought in. The import reported the number of items and nothing more, so a catalog could arrive cleanly with only titles and authors — every other column left on "Skip", or blank in the export — and read as a complete success. Months later the searching and filtering had nothing to work with and nobody knew why. The results screen now lists every field alongside the column it came from and how many items received a value, and says plainly when a field arrived empty so the mapping can be corrected and the import run again.

[1.5.35] — 2026-09-08

The library catalog no longer shows filters that have nothing in them. A catalog only carries the details a society actually recorded, and plenty of collections have never used media types, shelf locations or acquisition codes at all. Until now the filter dropdowns appeared regardless, offering "All Types" and nothing else, and the browse panels — Browse by Collection, Popular Subjects, By Media Type, By Acquisition — stood as headings over empty white space. Both read as a broken page rather than an empty shelf: researchers opened a dropdown expecting choices and found none, and librarians assumed the screen had failed to load. Every one of these controls now appears only once there is something behind it, on the public catalog and in the admin catalog alike, so a filter on screen is always a filter that works.

[1.5.34] — 2026-09-04

Searching a list no longer throws you back to the top of the page. These search boxes sit partway down a page the society wrote themselves, under a heading and a few paragraphs of explanation. Pressing Search reloaded the page and the browser landed at the very top, so the results the reader had just asked for were a long scroll away and looked, for a moment, like nothing had happened. Every list block now lands on its own results instead: vertical files, surnames, the library catalog, records, events, resources and documents. Turning to the next page of results does the same.

Reported against the vertical files, but it was never about vertical files.


[1.5.33] — 2026-09-04

The cart is back at the right end of the menu bar, and the menu centres in the space beside it. Yesterday's fix moved the cart in among the menu items to stop it dragging a centred menu off-centre. It now holds the right end again without taking the row's spare width with it, and a menu set to centre does so inside the space the cart is not using. A theme that left-aligns its menu is unaffected. Behind the hamburger, where the menu is a stacked list, the cart is one more row like every other.


[1.5.32] — 2026-09-04

Album photos are filed under the album they belong to. The Files screen grew a folder called Albums the day it was built, but the only thing that ever landed in it was each album's cover picture — the photos inside the albums were in Unfiled with everything else, which on a society with a few galleries is hundreds of pictures in one heap. Every album now has its own folder inside Albums, holding its photos and its cover, and the folder follows the album when it is renamed. Adding photos, importing a gallery and approving a Picture Wall submission all file as they go, and a society that already has albums has them sorted a few at a time as the admin is used.

Deleting an album no longer leaves a folder named after it: the photos go back to Unfiled, because deleting an album deletes the grouping, not the pictures.

Phone numbers read the same everywhere. A number imported as 2103425242 now shows as 210-342-5242 in the directory, the member list, the printed roster, the contact card, the account page and the footer. Only the display changes — the number is stored exactly as it was typed or imported, so exports still match the file they came from, and anything that is not a ten-digit number is left alone.

The shopping cart only appears once there is something in it. Most people who visit a society's website are not there to buy anything, and a cart icon on every page made the site look like a shop first. It shows up the moment something is added, without a page reload.

A centred menu stays centred with the store switched on. The cart was pinned to the right end of the menu bar, which used up the space a centred menu needs and pushed it back to the left. The cart now rides at the end of the menu and sits wherever the society put their menu.


[1.5.31] — 2026-09-03

Volunteers, officers, committees and openings can be imported from a spreadsheet. Three new screens take a .csv, .tsv or .xlsx file, show you what is in it, let you say what each column holds, and then fill the lists — the same upload-and-check flow the members, events and library imports already use.

  • Import Volunteers takes one row per position held. Volunteers, officers
  • and committee members are all the same list underneath, so a Role Type column is what tells them apart, and it reads Officer, Board, Director, Committee and Chair as the right thing without being taught.

  • Import Committees takes the committee list itself, chair included.
  • Import Openings takes the positions you are recruiting for.

Everyone named in a file has to be a member already: a name that matches nobody is reported with its row number rather than quietly turned into a new person, because that is a typo far more often than it is a stranger. Names are matched on email first and only then on name, and a name shared by two members is reported rather than guessed at. Running the same file again updates what is already there instead of duplicating it, so a spreadsheet can stay the master copy and be re-imported after edits.


[1.5.30] — 2026-09-03

The dashboard's columns are even, and the empty strip down the middle is gone. The cards were only ever placed in two columns however many you asked for in Screen Options, and WordPress's own dashboard stylesheet then sized the first column for the count you picked — so at three columns the left side was squeezed to make room for a third column that had nothing in it, leaving two hundred pixels of blank page between the two that did. The cards now spread across as many columns as you choose, every column is the same width, and the space between them is one even gutter.


[1.5.29] — 2026-09-03

The cart count is smaller again. Down to 14px digits in an 18px pill, still sitting on the same line against the cart's top edge.


[1.5.28] — 2026-09-03

A smaller count on the cart. The number rode high enough on the glyph to compete with it. It is smaller now, and sits where it did against the cart's top edge.


[1.5.27] — 2026-09-03

The cart is the size it should have been, and it sits with your name. The glyph and its count were drawn a quarter too large, and the cart sat in the middle of the menu among the pages. It now sits at the right end of the bar beside the signed-in member's name, which is where a shopper looks for it.

The page you are on is no longer inside a box. The current menu item, and any item under the pointer, were filled with translucent white — invisible on a dark header and a pale smudge on a light one, with no setting to turn it off. Hovering underlines the item instead, which reads the same on any header colour, and the current page keeps the colour it already had.

A left-aligned menu now lines up with the logo. Menu links carry padding so they stay easy to click, which left the first word sitting eighteen pixels inside the row while the logo above it sat on the edge. The row is pulled over by exactly that padding, so the two line up and every click target is the size it was.


[1.5.27] — 2026-09-03

The cart sits with your name now, at the size it should be. The glyph and its count were drawn about a quarter too large, and the cart sat in the middle of the menu among the pages because nothing pushed it anywhere else. It moves to the right end of the bar beside the signed-in member's name, which is where a shopper looks for it, and the count is sized to sit on the cart rather than cover it.

The page you are on is no longer inside a box. The current menu item, and any item under the pointer, were filled with translucent white — invisible on a dark header and a pale smudge on a light one, with no setting to turn it off. Hovering underlines the item instead, which reads the same on any header colour, and the current page keeps the colour it already had.

A left-aligned menu now lines up with the logo. Menu links carry padding so they stay easy to click, which left the first word sitting eighteen pixels inside the row while the logo above it sat on the edge. The row is pulled over by exactly that padding, so the two line up and every click target keeps its size.

The menu no longer crowds the logo. Society logos often finish with a descending flourish, and the menu row sat close enough to touch it. There are three more pixels between them.


[1.5.26] — 2026-09-03

An update now shows up the first time you load the page. The offline support kept a copy of the site's stylesheets and scripts and used the saved copy before checking for a newer one, so the first visit after an update was drawn with the previous release's design. Somebody told a volunteer a fix was live, the volunteer opened the site, and the old thing was still there. Styles and scripts are fetched fresh now, with the saved copy kept only for when the network is unreachable. Photos and fonts are still served from the saved copy, because those don't change within a release.


[1.5.25] — 2026-09-03

The cart is a symbol now, and the member's name lost its ghost box. The word "Cart" is gone from the menu — a shopping-cart glyph is one of the few symbols a visitor reads without a label, and the word made the item twice as wide as anything else in the navigation. The name still reaches screen readers. The cart is centred on the menu line rather than sitting on the text baseline, and the count rides above it on a pale gold pill outlined in navy, which reads clearly on a light menu and a dark one alike.

The signed-in member's name no longer sits in a floating box. The name and photo were drawn with a translucent white fill and border, which is only invisible on a dark header. Every society running a cream, white or otherwise light header saw a pale rectangle around the member's name that no setting could switch off. The name is a menu item now, drawn like the rest of them, and the profile photo is larger.


[1.5.24] — 2026-09-03

The cart count is bigger and sits on the corner. The number now rides on a large gold disc at the top right of the cart, outlined in your menu's own text colour so it reads clearly whether your menu is light or dark — and the cart underneath still looks like a cart.


[1.5.23] — 2026-09-03

The cart icon looks like a cart again. The number's disc was wider than the basket it sat in, so the whole thing read as a gold coin with wheels. The count now sits on the top corner of the cart, where it does not cover it, and carries a thin outline in your menu's own text colour so it stands out whether your menu is light or dark. The cart is a little smaller and sits closer to the word.


[1.5.22] — 2026-09-03

Four fixes to the cart in your menu. The word "Cart" was heavier than every other item beside it, and sat a few pixels below them; both now match the rest of your menu exactly. The cart's wheels rest on the same line the menu text sits on. And the number of items now has its own gold disc behind it instead of floating over the cart's white outline, so it can actually be read — on a light menu or a dark one, in any of the themes. It stretches to a pill if the count reaches double figures.


[1.5.21] — 2026-09-03

The cart in your menu is easier to see. It is now a proper cart symbol with the number of items sitting inside the basket, the way a shopper expects, and both are drawn large enough to read without leaning in. The count was previously sized relative to whatever your theme used for menu text, which on some themes worked out to about ten pixels.


[1.5.20] — 2026-09-03

A cart symbol in the menu. The Cart link now carries a drawn cart icon alongside the word, and the item count is larger and easier to read.


[1.5.19] — 2026-09-03

Clearer wording on the sales tax setting. The checkbox now says "digital downloads" rather than just "downloads", and the help text spells out that it means any product you attached a file to. The worked example is a neutral 6.5% instead of a real city's rate, so nobody reads it as an assumption about where their society is.


[1.5.18] — 2026-09-03

Sales tax, if your state asks for it. Store orders have always had a place to record tax and have always recorded zero. Settings → Store now takes a rate, the name your state calls it, and a tick box for leaving downloads alone. Set a rate and it appears in the cart before anyone commits, on the order, and on the receipt; leave it at zero — which is right for most societies — and nothing about your store changes.

Tax is worked out on the items, not on postage, because whether postage is taxable is one of the things that differs from state to state and guessing on your behalf would be worse than not guessing. What applies to your society is a question for your treasurer or your state comptroller; SocietyPress holds the number they give you and does the arithmetic.


[1.5.17] — 2026-09-03

Sell a file and the buyer gets it the moment they pay. Attach a PDF, an EPUB, a ZIP, a spreadsheet or an image to any store product and it becomes a download: as soon as the payment clears, the buyer's receipt carries a private link, good for thirty days and five downloads. No account needed, so a researcher who bought your surname index at midnight has it at midnight instead of waiting for a volunteer to email it out.

The file itself never sits on a public address. It is kept in a folder that refuses web requests outright and is only ever handed over after the link is checked — so the thing you sell is not quietly downloadable by anyone who guesses at it.

And when someone writes in saying their link stopped working, you can see exactly what they were given. Every order now lists its downloads, how many times each has been used and when it runs out, with the link there to copy back into a reply.


[1.5.16] — 2026-09-03

Anyone can buy from your store now — no account required. Until this release the shop only worked for signed-in members: a visitor who clicked Add to Cart got no response at all, and the cart page told them to log in first. That is backwards for a society, because the people buying your cemetery transcriptions and surname indexes are usually researchers who found you through a search engine and have no reason to want an account.

A visitor's basket now follows them for thirty days, and they check out with just a name and an email for the receipt. If they do have a membership, the cart offers them a chance to sign in for member pricing rather than quietly charging them full price — and anything already in their basket comes with them through the login instead of vanishing.

Orders now record where to send things. SocietyPress has always had places to store a shipping address on an order and has never once filled them in, so no society was ever told where to post what somebody bought. Checkout now asks, for members and visitors alike, and the answer is saved with the order.


[1.5.15] — 2026-09-03

The store now has a front door. SocietyPress has had a working shop for some time — products, member pricing, card and PayPal checkout, orders, refunds — and almost nobody could find it. The Store and Cart pages were never among the pages a new site is given, and the routine that creates those pages stops the moment a site has any page at all, so no society running SocietyPress has ever been handed either one. Both are now created for you, and a Cart appears in your main menu with a count of what is in it, on every page of the site.

If you already had a page using the Store or Cart layout, yours is left exactly as it is.


[1.5.14] — 2026-09-03

Website > Files works again. The screen carried a "What is using this file" panel that was meant to stay out of sight until you asked for it. Its styling overruled that, so the panel and its full-page dimming layer were sitting over the Files screen from the moment it loaded — an empty box you had not asked for, and an invisible sheet over everything behind it that quietly ate every click. Adding files, opening a folder and ticking a box all did nothing, and the panel's close button did nothing either, so the only way out was the browser's back button. The panel now stays down until you open it, closes when you close it, and Files takes clicks normally.

Marking anything hidden now holds across the whole of SocietyPress, so no other screen can grow the same fault.


[1.5.13] — 2026-09-02

Record review learned to tell a list from a mistake. The first pass of the new Review check treated every column as free text, so a Book column holding twelve titles across forty thousand rows had its longest title — "Sexton Burial Records City Cemetery #7" — reported as an oddity five hundred times over. A column whose values are drawn from a short list is now recognised as a list, and judged on whether it is filled in rather than on how long its entries are.

Two more things it was wrong about: a transcriber's aside counted towards the length of a name, so "Frank [inf of]" looked like a three-word given name and thousands of good rows were set aside; and a middle initial "E." was read as the Spanish name particle e, which flagged everyone in the index recorded by their initials. Notes in brackets no longer count towards a name's length, and a single letter is treated as an initial. On a real 40,548-row cemetery index this took the queue from 2,279 rows to 872, and what is left are genuine faults — surnames split mid-word, maiden names stranded in the wrong column.


[1.5.12] — 2026-09-02

Records → Review finds the rows an import split wrongly. An index typed up from a book arrives as one line per entry, and splitting that line into columns is guesswork — "Abbot Martha Louisa Woodhull" is a surname and three given names, or a surname and a maiden name, and no importer can tell which. Most guesses are right. A few hundred in forty thousand are not, and once they are rows in a table they look exactly like the ones that are.

Every collection now has a Review button. It reads through the collection and sets aside the rows that look wrong: a column that is filled in on nearly every other record and empty on this one, a column that normally holds two words holding five, an entry beginning with De or Van where that is normally part of the name beside it, a quotation mark opened and never closed, a whole entry that is a note in brackets rather than a name. Each one is listed with its columns laid out for editing and two buttons — save the fix, or say it is right as it is. The count of what is waiting rides on the Review button in the collections list, because a queue nobody is told about is a queue nobody works.

Nothing here is configured. The checks work out what normal looks like from the collection itself rather than from any knowledge of what a column is called, so they apply to a cemetery index, a marriage register or a set of obituaries without being told which is which. The check runs in slices so a collection of any size finishes rather than timing out, and it can be run again after a batch of corrections — rows already accepted stay accepted.


[1.5.11] — 2026-09-02

The help desk takes screenshots now. Ask for Help had nowhere to put a picture, so a volunteer describing a fault had to put the screen into words — and tickets have arrived saying "got the attached screen" with nothing attached, leaving the person answering to guess at what the picture would have shown. Both the form and every reply in the conversation now take files, so a screenshot can travel in either direction: yours when you file, and yours again when somebody answering asks to see the screen. Up to five files a message, 5 MB each, pictures and PDFs. Attaching a screenshot with nothing typed is a perfectly good reply.

Screenshots of an admin screen are screenshots of members, so these are not put in the media library, where everything is readable by anyone who knows the address. They are stored outside it and handed back only to the person who filed the ticket and whoever answers tickets. The notification email says a file is waiting rather than carrying it, so nothing leaves the login the rest of the ticket sits behind.


[1.5.10] — 2026-09-02

A menu item you add now appears, however deep you put it. Every theme decided for itself how many levels of drop down menu it would draw, and the six of them disagreed — three levels in the SocietyPress theme, two in Ledger and Parlor, one in Coastline. WordPress does not warn about a menu item nested deeper than the theme allows. It simply renders nothing for it. So a society that built Resources → Research → Bexar County Records → the five record pages watched the record pages vanish from the menu with no error and nothing to click, and a society that switched to Coastline lost every drop down on the site at once.

Depth is now unlimited, and no theme sets it any more: all six ask the same shared function for their navigation, so the six of them cannot drift apart again. Build the menu your society's material actually needs and it renders.

Deep menus stay on the screen and stay navigable. Flyouts open to the right of their parent, so a menu four or five levels deep used to walk off the edge of the window — with the level you were reaching for as the part that disappeared. A flyout with no room on the right now opens to the left instead. In the phone panel each level is indented one step further than its parent, so level five reads as level five rather than as more of level two. Every item that opens a menu announces itself to a screen reader whether or not JavaScript has loaded, and Escape now closes one level and returns you to the item that opened it, rather than collapsing the whole menu and making you start over.


[1.5.9] — 2026-09-03

Records results sort by clicking a column heading, and open A–Z. A transcribed collection is imported in the order it was typed — for a cemetery roster or a surname index, alphabetical — and the search then ordered the results by the row number the import handed out, newest first. That ran the whole index backwards: every visitor who arrived before typing anything into the search box got Z to A.

Results now arrive sorted A–Z on the first column, and every heading that names a single value is a link — click it to sort by that column, click it again to reverse, with an arrow marking the column in use. The sort runs across the whole collection rather than the page on screen, so the first page of a sort by Death Date holds the earliest dates in the collection and not merely the earliest of the twenty-five rows already visible. Records with that column empty go last in both directions, and a column of numbers sorts as numbers — Lot 9 before Lot 10 rather than after Lot 1. On a phone, where the table drops its heading row entirely, the sort appears as two dropdowns beside the search box.

A society with one collection now sees that collection's own columns. The results table showed a Collection column beside a run-together Summary column until a collection was chosen from the filter — and a society with a single collection has no filter to choose from. They were left with a column repeating the same name next to a column of mashed-together values, neither of which can be ordered by anything a reader recognizes. Their only collection is now treated as the chosen one, so the table shows its own field names as columns.

An import can no longer point two spreadsheet columns at the same field. The mapping screen allowed it, and the result was two stored values for one field: the record editor showed one of them and deleted the other on the next save, and the detail panel printed whichever came back last. The first column mapped to a field now keeps it.


[1.5.8] — 2026-09-01

A record collection can now be searched from any page. The genealogical records search was only available as a page-builder widget or on the dedicated records template. That left out the page most societies actually want it on — the research page they have already written, with their own table of local cemeteries and their own notes about which courthouse burned in which year. Rebuilding that page in the builder to gain a search box is not a trade anyone makes, so in practice the search stayed where visitors weren't, and the page went on linking out to a file download instead.

Paste [societypress_records] into any page or post and the search appears there. Add collection="cemeteries-index" to search one collection — the slug or the ID both work — or leave it off to search all of them. Access rules are unchanged: a members-only collection still asks for a login, wherever the shortcode sits.


[1.5.7] — 2026-09-01

Importing a record collection no longer throws away repeated lines. When a transcribed index lists the same entry more than once, it usually means what it says. A sexton's book records "Grant Ira [triplets of]" three times because three infants were buried; a cemetery volume lists two Groenkes on the same page with the same name. The record importer treated any row identical to one it had already seen as a duplicate and skipped it, so those extra burials never arrived — and the only trace was a "duplicates skipped" number that looked reassuring. It now counts copies instead of merely noticing them: a collection takes as many copies as the file offers, while importing the same file a second time still adds nothing. On a 40,000-row county index this was the difference between 311 lost records and none.

The import summary now also reports how many identical rows it kept, so a genuine copy-paste slip is still visible rather than silently doubled.


[1.5.6] — 2026-09-01

More on the formatting bar, and the same bar everywhere. Underline, justify, a Highlight button, a divider line and a special-characters button (©, ½, é, —) have joined the toolbar above the Content box. The divider and the special characters were already in SocietyPress, but they sat on a second row behind the "Toolbar Toggle" button, which there was no reason to know existed — so in practice they may as well not have been there.

The Rich Text block on a page now has the full toolbar. Building a page out of blocks, the Rich Text block gave you five buttons — bold, italic, two kinds of list, and a link — while the Content box on the same screen had the Table menu, the Picture menu, fonts, sizes and colours. Same kind of box, two different sets of buttons, and no way to tell why. They are now one toolbar.

Highlight follows your theme. Highlighted text takes its colour from your society's accent colour rather than having a colour written into the page, so a page highlighted under one theme still looks right after you switch to another one.


[1.5.5] — 2026-08-29

Importing no longer leaves you with the same tier twice. SocietyPress starts with five membership tiers, and an import used to add one for every plan name in your file without checking whether it already had that tier under a slightly different word. A society whose export said "Joint" and "Life" finished the migration with eight tiers — "Joint" sitting beside "Joint/Family", "Life" beside "Lifetime" — and a tidying job nobody asked for. Those names are now recognised as the tiers you already have.

The import tells you what it did to your tier list. Which tiers it created, and which names it matched onto tiers you already had, both now appear on the results screen when the import finishes. Folding one name onto another is a judgement made on your behalf, so it is said out loud rather than left for you to find in Settings — and if two of them should have stayed separate, you know straight away which members to move.

Genuinely different tiers are left alone. Only the five SocietyPress ships with have alternative names recognised; a society's own "Sustaining", "Patron" or "Senior" tier is never folded into anything, because putting members on a plan and a price that isn't theirs would be worse than a duplicate in a list.


[1.5.4] — 2026-08-29

Imported institutions keep their names. A library or museum in an ENS export usually appears as a contact person's name with the institution in the File Name column, and SocietyPress would only file it as an organization when the Membership Type column said the exact word "Organization." Societies write "Institutional," or "Corporate," or "Non-Profit" — and when they did, the institution's name was thrown away during the import with no error and nothing in the log to notice. The import now recognises the ordinary ways of saying the same thing.

And when it still doesn't recognise the word, it says so. Any row that carried an organization name the import decided not to use is now counted on the results screen, along with the Membership Type values it saw, so a society using its own vocabulary is told which rows to look at rather than finding out months later that the library is filed under its librarian. Correcting those rows and importing the file again is safe — a second import updates the same members instead of duplicating them.


[1.5.3] — 2026-08-29

The store's page-size control is three buttons instead of a box to type in. Choosing how many items to see at once no longer means typing a number and pressing Go, and no longer means knowing that zero is the way to ask for everything. The store now offers 20, 50 and All as buttons, with the current one highlighted. The buttons appear only when the catalog runs past two pages at the default size — a store with forty items or fewer shows just the page links, since a page-length choice on a list that short is one more thing to read for no gain.


[1.5.2] — 2026-08-29

Removes a private domain reference from the shipped plugin and repairs the build-time scanner that was supposed to have caught it.

A code comment named a private development site. A comment explaining the affiliation-logo safety net cited the maintainer's own test site by name to illustrate the case it guards against. The illustration was never necessary — the sentence makes its point better in general terms, since any society that has customized its footer is in exactly that position — and the name had shipped inside every release since 1.1.11. The comment now describes the case without naming anyone.

The leak scanner had never run. build-softaculous.sh announced "Scanning for data leaks..." on every build and checked nothing, in three independent ways: it read its pattern list from a local configuration file that had never been created, so the list was empty and a guard skipped the scan entirely; it looked only at the plugin file, never at the parent theme or the five child themes that ship in the same bundle; and it recorded a hit in a variable that nothing ever read, so even a detected leak printed a warning and let the build succeed. The scanner now refuses to build when it has no patterns configured, scans everything that ships, and exits non-zero on a hit. A scanner that cannot fail the build is decoration.

The Softaculous package was missing its wordmark. info.xml opens its catalog description with an inline logo.png that did not exist, so the listing would have rendered a broken image against its own text. It is a separate file from the square catalog icon and keeps its literal name rather than taking the assigned script ID, which is why it went unnoticed.


[1.5.1] — 2026-08-28

Repairs the Softaculous package, which had drifted far enough from both the product and Softaculous's actual file format that a one-click install would have produced a half-working site.

The install bundle was missing the plugin's assets. The builder copied societypress.php and the translations but not assets/, so every Softaculous install would have shipped without the PWA icons and favicons and without the CSS and JS behind the gallery viewer, the events pages, the editor table, the searchable select and the leadership search. The builder now copies them, and refuses to build at all if they are absent rather than quietly producing a broken bundle.

The package files were written against a schema that does not exist. Softaculous ignores tags it does not recognise without reporting anything, so the catalog entry would have appeared with no description, no version and no PHP requirement, and the installation form would have been empty. The metadata, install form and upgrade form have been rewritten against the shipped WordPress package, and the file index rewritten in the plain-text format Softaculous actually reads.

Installs no longer hide themselves from search engines. The installer forced the "discourage search engines" setting on for every new site, and the switch that undoes it is buried three menus deep where a volunteer will never find it. A society exists to be found, so the install form now asks, and defaults to visible.

The database table prefix is honoured. It was hardcoded to wp_, which meant two SocietyPress sites could never share one database. The install form now offers the prefix and the installer uses it.

Smaller things. The install form gained a site tagline field, so a new site no longer launches carrying WordPress's "Just another WordPress site" placeholder. Child themes are no longer excluded from upgrades — they ship as part of one versioned set, and holding them back was what made the Theme Gallery offer an update that installed and then reappeared forever. The declared install footprint is now measured from a real build rather than guessed, and the builder warns when it falls behind.


[1.5.0] — 2026-08-28

The first release SocietyPress considers finished.

Everything a genealogical or historical society needs to run online, in one free, GPL-licensed WordPress product: members and dues, events and registrations, a library catalog, record collections, newsletters, blast email, donations, a store, committees and meetings, ballots, volunteers, documents, photo galleries, lineage programs, research help, and a help desk of its own. Eighteen optional modules on top of Members and Finances, which are always available, so a society runs the parts it actually uses.

For the volunteer who has to operate it. A page builder rather than a theme editor. A setup wizard on first run. Every module screen tells you when the public cannot see it yet and offers to make the page — and then to put it in your menu. Nothing that renders is hardcoded: every visible string is editable from the admin by somebody with no technical background.

For the society that is moving. A migration path from EasyNetSites that reads their export column by column, a handbook that names every field and what it becomes, and three ways to back out if it goes wrong.

For the society that outgrows the look. Five child themes ship with the product. The Theme Exchange adds saved looks and bundles from other societies, and full child themes that have been read line by line before they carry a badge.

Under it. 77 custom tables, ~107 AJAX endpoints, XChaCha20-Poly1305 encryption for sensitive member data, GDPR exporters and erasers, a PWA, and ~7,900 translatable strings with templates for the plugin and parent theme.

What it tells us. Once a week an install sends its society name, website address and version, and nothing else. Settings → Privacy shows exactly what went and says plainly that there is no switch.

The development history that led here is archived in CHANGELOG-1.x.md.