- 0.1.30: When a theme colours the side menu column, the menu's own list now takes the column colour too, instead of the tab bar colour, so the column reads as one even block from top to bottom. Themes that colour only the tab bar see no change.
- 0.1.29: Themes can now colour the side menu on member and group pages from theme.json, with two more custom settings: settings.custom.buddypress.sideNavBackground, which fills the menu column for the full height of the page (as BuddyPress's Twenty Fifteen styles used to), and sideNavBorder, a divider between the menu and the page. They apply only when the menu sits beside the page, not when it shows as tabs above it. The gap between the side menu and the page is now padding inside the page area rather than a margin on the menu, so the divider and column colour meet cleanly; content moves by at most a pixel. A theme that sets neither looks as before.
- 0.1.28: Themes can now colour BuddyPress's navigation tabs, activity headers and comment threads from theme.json, through five custom settings: settings.custom.buddypress.navBackground (the tab bar), navCurrentBackground and navCurrentText (the current tab), headerBackground (the box behind an activity item's header line) and threadBackground (behind an activity item's comments). WordPress outputs them as –wp–custom–buddypress–nav-background and so on, and a site can override them in its global styles. A theme that sets none of them looks as before: the tab bar and boxes stay transparent and the current tab keeps the pack's faint tint.
- 0.1.27: BuddyPress screens lay themselves out by the space they are given, so themes no longer need a BuddyPress companion stylesheet. The #buddypress area is a size container: a member's or group's navigation sits beside the page as a side menu when the area is at least 760px wide, and as tabs above it otherwise; the messages inbox becomes a list of cards (sender and date, subject and excerpt, then Read and Delete) when the area is 640px wide or less, instead of a cramped table, and each card covers its row fully whatever background a site gives its tables. The Group Admins and Group Mods labels in a group's header are a normal text size instead of full-size headings. The #buddypress wrapper also gets the alignwide class (filterable through bp_localhero_theme_wrapper_classes), so on themes with a wide layout setting BuddyPress screens use the theme's wide width; on themes without one it has no effect. Breakpoints are in pixels and the side menu width in em, as some themes change the root font size.
- 0.1.26: Theme stylesheet updates now reach returning visitors. Stylesheets and scripts are cached by browsers for up to a year, and the pack versioned every asset by its own version number, including files a theme supplies itself, such as its BuddyPress companion stylesheet or its own copy of buddypress.css. A theme release that changed one of those kept the same address, so browsers went on using the old copy until the pack's next release. Each asset's version now also includes the file's modification time, so any edit to it, by the pack or by the theme, gives it a new address. This release also makes Princes Park Touch members' browsers fetch the updated LH 2015 companion stylesheet (2.13.7), which fixes faint text in unread message rows.
- 0.1.25: Fixes faint text from 0.1.24. The theme-following greys are mixed from the current text colour, so an element muted inside another muted element came out fainter still: the member and group menu count badges fell below readable contrast, and typed comment text, the profile field visibility options and alternate message rows were lighter than intended. These nested elements now take their parent's colour instead of muting it again, and every BuddyPress screen on Princes Park Touch passes the colour contrast check, apart from the theme's own highlighted unread message rows.
- 0.1.24: Neutral colours follow the theme. The greys BP Legacy hard-codes for meta text, borders, list and table rows, tabs, form fields and the cover image placeholder are now mixed from the text colour the theme sets (seven custom properties on :root, such as –bp-localhero-text-muted and –bp-localhero-border, each a color-mix of currentColor), so they suit light and dark themes alike and a theme can override any of them by name. Text fields and the fallback button style have transparent backgrounds instead of white. Colours with meaning keep their own values: notices, password strength, unread and highlight badges, the star, and the screen-reader focus style. On a theme with dark grey text, such as LH 2015, the result looks almost the same as before.
- 0.1.23: Buttons follow the theme. The pack's BP Legacy button styles (white with a grey border and grey text) are now only a fallback for themes that style no buttons: they sit in :where(), so they no longer outrank the theme's own button rules or its theme.json button element. On a theme that styles buttons, every BuddyPress button now looks the same, where before submit buttons such as Post Update, Search, Save Changes and the Manage Members actions kept the Legacy look while the action buttons used the theme's. Link buttons that act as buttons get the wp-element-button class so they pick up the theme.json button style too: View Conversation, View group and View Profile in the activity stream, and every button BuddyPress builds with BP_Button (through the bp_get_button filter). The top-level activity comment form's Post button is now a button element like the reply form's. The minified copies of buddypress.css and buddypress-rtl.css, left over from the BP Legacy fork, are deleted: they were served in place of the edited stylesheets.
- 0.1.22: Accessibility pass, part two (script). Screen readers now hear what changes in place: a polite status region announces when Load More adds older activity, when new activity is waiting and when Load Newest shows it, and repeats the outcome message of an action after the page reloads. Focus no longer gets lost: after Load More or Load Newest it moves to the first new activity item, after Show all comments to the first comment revealed, after Read More to the full text, and opening a Comment or Reply form puts the cursor in its text box. Load Newest and Show all comments are now buttons rather than links to a fragment. On profile edit and registration, opening a field's visibility options moves focus into them and Close returns it to the Change button. Bulk actions on messages, notifications and invitations: the Apply button is no longer silently disabled until an action is chosen; the action list is required instead, so the browser says what is missing. Delete group and delete account: the confirmation checkbox is now required rather than enabling a disabled button through an inline script, so it works without JavaScript and explains itself. The new strings come in through the bp_core_get_js_strings filter, and the two new buttons are styled to match the links they replace.
- 0.1.21: Accessibility pass, part one (markup). Navigation: the current tab in every BuddyPress navigation list (member and group menus, their sub-menus, group admin tabs, profile edit field-group tabs and the All tab in each directory) is now marked with aria-current="page", so screen readers announce which page you are on; the groups directory tabs are now a navigation landmark like the others, and the profile edit field-group tabs sit in a nav element. Pagination: the arrow-only previous and next links are now named "Previous page" and "Next page". Live regions: the activity streams and the member, group and manage-members lists no longer carry aria-live regions left over from the old AJAX refresh; on the activity stream, aria-atomic made screen readers re-read the whole stream whenever Load More added items. Profile fields: each visibility Change and Close button now names its field (for example "Change who can see Phone") and points at the panel it opens, on profile edit and on registration. Activity: the Comment button reads its count as "(3 comments)" rather than a bare number. Duplicate links: the cover image and avatar links in group and member headers and in created-group and new-avatar activity items repeat the name link next to them, so they are hidden from screen readers and skipped by the keyboard, and the View group and View Profile links no longer pretend to be buttons. Group members: the search box is a proper search landmark again (it was set on a list item, which broke the list), and member names are level-3 headings under the screen's level-2 heading instead of level 5. The navigation and pagination helpers live in a new file, bp-localhero-a11y.php, loaded when the template pack is registered. Found with axe-core on Princes Park Touch.
- 0.1.20: BP LocalHero phase B2b: the template pack's buddypress.js is rewritten without jQuery, so the pack no longer loads jQuery, bp-confirm or the jQuery scrollTo plugin. It keeps every enhancement: Load More, Load Newest and Read More on the activity stream (now with fetch, and falling back to the real link if a request fails), hiding all but the latest five comments with a Show all link (now also for activity added by Load More or Load Newest), the What's New form opening on focus, order selects submitting on change, profile field visibility toggles, the unsaved profile changes warning, select all and bulk action buttons on messages, notifications and invitations, the star and unstar bulk options, the blog details toggle on registration, and the no-js to js body class. Heartbeat is used through the wp.hooks heartbeat.send and heartbeat.tick actions, and the heartbeat script is loaded only where BuddyPress checks for new activity. Confirmations for links and action form buttons marked confirm, and for Leave Group, are handled by the pack itself, as BP Nouveau does, so they now also appear on subsites, where BuddyPress never loaded its confirm script. bp_get_query_var() and clear() remain available globally. The password strength script on registration and account settings still uses jQuery, as WordPress's password-strength-meter does.
- 0.1.19: BP LocalHero phase B2a: removed the template pack's cookie layer and dead JavaScript, with no change to what members see. Activity Load More now sends the activity filter from the page URL as a plain type parameter, and the activity heartbeat sends it as bp_activity_filter, instead of both packing it into the legacy cookie format; the AJAX query string reads those values and no longer falls back to the browser's bp- cookies. The blogs, forums, groups, members and requests filter AJAX handlers, which no pack JavaScript called any more, are no longer registered, and their template loaders are gone. Removed from buddypress.js: the directory preference and cookie functions (bp_get_directory_preference, bp_set_directory_preference, bp_init_objects, bp_filter_request, bp_get_cookies), the cookie clearing on logout, the unread/read message type select handler, the IE6 hover class, checkAll(), the .pending click blocker, and the dormant spam activity and spam comment handlers (the server side stays until the front-end spam decision). bp_get_querystring() is replaced by the pack's own bp_get_query_var(), so the script no longer depends on bp-jquery-cookie or bp-jquery-query. The unused store_filter_settings and my_favs_url script settings are gone, and the private message star settings are now always attached to the main script handle.
- 0.1.18: Notification and membership invitation actions are now plain POST forms that work without JavaScript, finishing the move away from state-changing links in the pack. On the notifications screens, Read, Unread and Delete on each notification are small forms; on the sent invitations screen, Resend and Cancel (Delete for an accepted invitation) are forms, and Resend is still not offered for an accepted invitation. Core BuddyPress screen actions handle every one of these as before; the notification forms keep the nonce in the form URL because core reads it from the query string only. The notifications and invitations bulk forms now wrap only the bulk action select, its button and nonce after the table, with each row's checkbox joined to its bulk form, so the row forms are not nested inside them. Select all, which needs JavaScript, is hidden without it on both screens, as on the messages inbox. Plugins filtering the core notification or invitation action link markup no longer change these screens.
- 0.1.17: The last state-changing AJAX actions and nonce links in the pack are now plain POST forms that work without JavaScript, and no action form is nested inside another form. Group invites: ticking friends and pressing Send Invites invites and sends them in one step (the Send Invites form now wraps only the friend checkboxes), and each pending invite's Remove Invite is a small form, on a group's Send Invites screen and on the group creation Invites step. Private messages: replying submits the reply form normally; Star and Unstar, Read and Unread, and Delete in the inbox, and Delete and Exit Conversation on a conversation, are forms; the inbox's bulk actions still work, with each row's checkbox joined to the bulk form; message search is a GET form whose terms stay in the URL. Sitewide notices: Activate, Deactivate and Delete Message on the notices screen are forms, and dismissing the notice shown across the site is a form that returns you to the page you were on. Profile photos: Delete My Profile Photo and Delete Group Profile Photo are forms placed after their upload forms. Core BuddyPress screen actions handle every one of these, as before. The pack's groups_invite_user, invite_filter, messages_filter, messages_send_reply, messages_star, messages_close_notice, messages_delete, messages_markread and messages_markunread AJAX handlers and their JavaScript are removed; only message autocomplete, Read More, Load More, the heartbeat and the dormant Akismet spam actions remain on AJAX. Pages now reload after each action instead of updating in place. The action form helper gains an option to keep the nonce in the form URL, for core handlers that read it from the query string only.
- 0.1.16: The Comment button on activity items now opens the comment form without JavaScript and without reloading the page. The button and the form are a native details disclosure at the foot of the item's comments, labelled with the comment count as before; it opens already expanded on a single activity page or when the old ?ac= link is followed, and closes from the same button, so the Cancel link is gone. This matches the Reply disclosure on each comment added in 0.1.15. The comment form is no longer revealed, moved and hidden by JavaScript, so that handler, the Cancel handler and the Escape-to-close handler are removed from buddypress.js. A small inline style lets the comment form show inside an open disclosure, because the pack stylesheet hides it for the old JavaScript reveal.
- 0.1.15: Activity actions are now plain form submissions, completing the move of state-changing actions off nonce links and AJAX. Favorite, Remove Favorite and Delete on activity items, and Delete on activity comments, each render as a small POST form with the nonce as a hidden field, so no nonce appears in any URL. Posting an update and posting a comment submit their forms normally instead of through AJAX. Each of these is handled by BuddyPress core's own screen action, which redirects back with its usual message, and everything works without JavaScript. Replying to a comment now works without JavaScript too: each comment has its own Reply form inside a native details disclosure, and a new pack handler on bp_actions, running just before core's, posts the reply under the right parent comment, respects the thread depth setting, and returns to the new reply. Deleting a comment goes through a pack handler that also removes the comment's replies, as the old AJAX path did, rather than core's single-row delete. Delete still asks for confirmation. The post_update, new_activity_comment, activity_mark_fav, activity_mark_unfav, delete_activity and delete_activity_comment AJAX handlers and their JavaScript are removed. The page now reloads after each action rather than updating in place; in-place updates will return with the Interactivity API. Read More, Load More and the spam actions (which need Akismet) are unchanged.
- 0.1.14: Friendship actions are now POST forms instead of links, continuing the conversion of state-changing actions started with group actions in 0.1.12 and 0.1.13. Add Friend, Cancel Friendship and Cancel Friendship Request (on member headers, the members directory and group member lists), and Accept and Reject on the member's Friendship Requests screen, each render as a small form that posts to the same URL with the nonce as a hidden field, so no nonce appears in any URL and nothing can be triggered by a prefetch, crawler or shared link. BuddyPress core's own screen actions handle them and redirect with their usual message, with or without JavaScript. The Friendship Requested link shown to a member who has received a request has no nonce and stays a link to the requests screen. The buttons carry the wp-element-button class like the other action forms. The addremove_friend, accept_friendship and reject_friendship AJAX handlers and their JavaScript are removed. A new bp_localhero_theme_friends_action_form_buttons filter lists which friends buttons become forms.
- 0.1.13: Group member management actions are now POST forms instead of links, completing the group actions converted in 0.1.12. On a group's Manage Members screen, Demote to Member, Promote to Mod, Promote to Admin, Kick and Ban, Remove Ban and Remove from group each render as a small form that posts to the same URL with the nonce as a hidden field, so no nonce appears in any URL and nothing can be triggered by a prefetch, crawler or shared link. BuddyPress core's own screen actions handle them and redirect as before, with or without JavaScript, and each still asks for confirmation. The buttons carry the wp-element-button class like the other action forms. The plugin header gains Requires at least, Requires PHP and Requires Plugins (BuddyPress), and its description is shortened to fit wordpress.org's 150-character limit.
- 0.1.12: Group actions that change state are now POST forms instead of links, so no nonce appears in any URL and nothing can be triggered by a prefetch, crawler or shared link. Join, Leave, Request Membership and Accept Invite (group header and groups directory), Accept and Reject on a group's membership requests, and Accept and Reject on the member Invites screen each render as a small form that posts to the same URL with the nonce as a hidden field; BuddyPress core's own screen actions handle them and redirect as before, with or without JavaScript. The pending Request Sent link is unchanged. The buttons carry the wp-element-button class, so themes with theme.json button styles style them like their own buttons; a minimal zero-specificity fallback style is added inline so they still look like buttons on themes without that support. The directory's joinleave_group AJAX handler and its JavaScript are removed; Leave Group still asks for confirmation, and buttons marked confirm (Reject an invite) now confirm too. New helpers: bp_localhero_theme_get_action_form(), bp_localhero_theme_action_form(), and the bp_localhero_theme_action_form_buttons filter listing which group buttons become forms. Group member management (promote, demote, ban, remove) is not yet converted.
- 0.1.11: The activity stream now keeps its state in the URL, like the directories. The Show filter on the activity directory, a member's activity and a group's activity is a GET form (?type=) that submits on change, with the current filter marked selected by the server, so reload, bookmark and back and forward work. The directory's scope tabs are now plain links: All Members stays on the directory and the other scopes open the member's own activity screens. Load More is a real ?acpage= link that works without JavaScript and carries offset_lower, now read on page loads too, so later pages do not shift as new activity arrives; with JavaScript it still appends the next page in place, taking the page number from the link. Page loads no longer read the bp-activity cookies: the activity, group invites and membership requests loops take their state from the URL, and Load More and the heartbeat send the filter from the URL instead of cookies. Focusing the post form no longer resets the scope and filter, and the My Favorites tab added after a first favourite links to the real favourites screen. The unused activity filter AJAX handler and its JavaScript are removed, and the phpcs:ignore annotations on the URL-state helpers are dropped. Posting updates, comments, favourites, delete, spam, Read More and heartbeat load-newest still use AJAX.
- 0.1.10: A member's Friends, Groups and Sites lists now keep their order and page in the URL, like the directories: the Order By select is a GET form that submits on change, and their pagination uses ordinary links, so reload, bookmark and back and forward work. With every directory and list screen now URL-driven, the legacy AJAX handlers for directory search, list tabs, filter selects and pagination have been removed from the pack's JavaScript; search forms, tabs and page links simply navigate. The members, groups and sites list templates now always render no-ajax pagination. Activity, private message search, group invite checkboxes and the friend, join and favourite buttons still use AJAX and are unchanged.
- 0.1.9: Group admin screens: the Send Invites list and the Membership Requests list now page with ordinary links, so the page number is in the URL and reload, bookmark and back and forward work, instead of the list being reloaded over AJAX. The Manage Members screen already paged this way. Inviting or uninviting a friend with the checkboxes, and accepting or rejecting a request, are unchanged for now.
- 0.1.8: The sites (blogs) directory now keeps its state in the URL, like the members and groups directories. Its page (?bpage=), search (?sites_search=) and order (?type=) are all visible in the address bar, so reloading, bookmarking and the back and forward buttons work, and no directory cookies are read or written for it on normal page loads. The order select is a GET form that submits on change and carries any other query arguments, the search form and pagination links navigate normally instead of reloading the list over AJAX, and a search or a change of order restarts the list at page one. The list of URL-driven screens is now filterable (bp_localhero_theme_url_state_objects). The pack's JavaScript no longer restores any directory's filter or scope from cookies. Activity and group admin screens are unchanged and still use AJAX.
- 0.1.7: Group members screen to URL state, PHP part. (1) bp_localhero_theme_url_state_objects() now includes group_members, so on normal page loads bp_ajax_querystring( 'group_members' ) is built from ?type= and the URL search terms instead of the bp-group_members-* cookies. (2) In bp_localhero_theme_ajax_querystring(), the group members screen's search terms are read from core's members search arg (members_search), which is what bp_group_has_members() and core's form use, not a group_members_search arg. (3) bp_localhero_theme_directory_hidden_query_args() also drops mlpage (group members pagination) alongside upage/grpage. Ships as 0.1.7 with the new groups/single/members-directory.php template part and the home.php/members.php changes. Apply order: lhcp_1d12c534 (new file), this, lhcp_d7c82c72 (templates), then the JS change. Group members screen conversion, follow-up to #148921.
- 0.1.6: Revert 0.1.5's profile changes so the pack stays upstream-faithful: members/single/member-header.php goes back to BuddyPress 14.5.2's version (@mentionname, shown when activity @-mentions are enabled), dropping the bp_localhero_member_header_name filter; the main file drops enqueue_inline_styles() and its hook (the profile h1 hiding). Both customisations now live in lh-buddypress-extender 1.1.2, which applies its legacy/ template override and inline styles to BP LocalHero as well as BP Legacy. Apply after lhcp_81258e1e. Override audit, task #148921 follow-up.
- 0.1.5: Port lh-buddypress-extender's profile tweaks into the pack (they are gated on the 'legacy' pack id, so they stopped applying on PPT when it switched to BP LocalHero). members/single/member-header.php: the header h2 shows the member's full name instead of @mentionname, filterable via bp_localhero_member_header_name ( $name, $user_id ); return '@' . bp_get_displayed_user_mentionname() for core's behaviour or '' to hide it. The h2 no longer depends on activity @-mentions being enabled, since it is now the name rather than the mention handle. Main file: enqueue_inline_styles() on bp_enqueue_community_scripts (BuddyPress pages only), when BP LocalHero is the active pack, hides the theme's page title (h1.entry-title / h1.post-title) on member profiles, where the header already shows the name; switchable with the lh_buddypress_template_pack_hide_profile_page_title filter. The extender's legacy-gated copies stay for sites still on Legacy. Task #148921 follow-up (override audit step 2).
- 0.1.4: Override audit fixes, part 1 of 2 (PHP). (1) bp_localhero_theme_ajax_querystring(): on the URL-state path, also put search_terms into the query string. Core already reads members_search/groups_search from the URL, but filters on bp_ajax_querystring look for search_terms there: lh-membership's modify_members_directory() skips its current-members restriction when searching, and since 0.1.3 that check never matched, so directory searches silently excluded non-current members. The search terms are also passed to the bp_legacy_theme_ajax_querystring filter as $object_search_terms. (2) New helper bp_localhero_theme_directory_hidden_query_args( $exclude ): prints hidden inputs for the current URL's other string query args (skipping the args the form sets itself and the upage/grpage pagination args), so URL filters from other plugins (e.g. lh-buddypress-group-taxonomies' $_GET params) survive a search or a change of order. Used by the templates in part 2. Task #148921 follow-up.
- 0.1.3: Phase 2 (members + groups directories), part 1 of 2. groups-loop.php: pagination wrappers get the no-ajax class on the groups directory, so legacy's delegated pagination handler lets the ?grpage= links navigate normally (other screens rendering this loop are unchanged). js/buddypress.js: (a) stop restoring members/groups filter and scope from cookies on page load (bp_init_objects now gets blogs and group_members only), so the URL-rendered state is not overwritten; (b) hide the order-form submit buttons when JS is present; (c) an order select inside a .bp-localhero-order-form submits that GET form on change instead of filtering over AJAX. Blogs, activity, group sub-screens, messages and the friendship/join buttons keep their legacy AJAX behaviour. Part 2 (PHP querystring, members/groups index, members loop, search form) adds the classes and forms these rely on; until it is applied these JS changes have no effect apart from not restoring members/groups cookie state. Task #148921 phase 2.
- 0.1.2: Phase 2 step 1: let the pack's own asset location fall back to the unminified file when the .min one is absent, so forked JS/CSS can be edited without maintaining hand-minified copies. Adds a second 'bp-legacy' location for the pack directory with '.min' stripped, after the existing one, so an existing .min file still wins and behaviour is unchanged until a .min file is deleted. Mirrors what the method already does for child and parent theme locations. Handles are unchanged (same 'bp-legacy' type). Task #148921 phase 2.
- 0.1.1: Register the forked pack with BuddyPress as 'bp-localhero' (BP LocalHero), and register the cover_image theme compat feature for it. Core only registers cover_image for id 'legacy' (bp_register_theme_compat_default_features), so without this member and group cover images would silently disappear when the pack is active. The feature is registered here rather than in the pack's buddypress-functions.php because core never loads that file in wp-admin. The package hook is added in the constructor because bp_register_theme_packages fires on bp_loaded (plugins_loaded), which may already have run by the time plugin_init executes. The package name is a plain string to avoid loading a text domain before init. Records the BuddyPress version forked from (14.5.2). Task #148921 phase 1.
- 0.1.0: Initial scaffold.