Skip to content

v0.2.7

Choose a tag to compare

@NOOBBase NOOBBase released this 30 Sep 12:42
d50ddf6

[0.2.7]

Added

  • Polish, Ukrainian, and Russian. Added public-site and admin interface translations, including navigation, comments, search, app installation prompts, and error and maintenance pages. All three languages are available in the admin language selector and server-rendered admin pages. Ukrainian and Russian are also offered in the installation language picker.

  • Demo mode. The Demo mode plugin adds a Demo role and a demo sign-in for trying the site. That account can edit content. It is not an administrator, so settings, users, plugins, and themes stay closed to it, and the plugin never edits the administrator account. On a schedule it deletes the content, media, and comments that demo user created, then asks the plugins an administrator selected to restore their own data through the justflows.demo.targets, justflows.demo.snapshot, and justflows.demo.restore hooks.

  • SDK: ctx.content.deleteCreatedBy(userId). Permanently deletes content that user authored, media they uploaded, and comments they wrote, and drops their unpublished working revisions on other entries. It does not delete the user, and it refuses an administrator. Requires content:delete.

  • Placeholder images. Justflows ships neutral placeholder images for a generic image, a featured image, a thumbnail, an avatar, and the social share image. Featured Image and Post List show the placeholder when a post has no image, an Image block without an image shows the generic one, and a page with no share image falls back to the site logo and then the share placeholder. Settings → Placeholders replaces any placeholder with your own image or turns them all off, and Featured Image and Post List can each turn them off. og:image is now an absolute URL.

  • SDK: ctx.media placeholders. ctx.media.placeholder(kind) and placeholderHtml(kind) return the site's placeholder from a block's render(). ctx.media.registerPlaceholder() ships a default for a plugin's own kind, and the media.placeholder filter replaces or clears one. See docs/PLUGINS.md.

  • Shop page. /shop lists published catalog products. A sidebar can hold search and category and tag filters. Products show in a grid by default, or as a list. Commerce → Shop page turns the sidebar, search, each filter, the default layout, and the visitor layout switch on or off.

  • Shop blocks choose from the catalog. Product list and Related products show all products, products related to a product, products you pick, or products from chosen categories or tags, with a sort order and a product count. Gallery, Buy box, Breadcrumbs, and the details accordion can show a picked product on any page. Breadcrumbs follow the product's category, and every shop block field has a label and help text.

  • SDK: richer plugin block fields. A block schema field can set label, help, optionLabels, optionsUrl (choices loaded from a same-origin route), multiple (a checklist saved as a string array), and showWhen (hide the field unless another prop matches). See PluginBlockField and docs/PLUGINS.md.

  • Product pages sell the catalog item. A product detail page shows that product's price, stock, and variations. Choosing an option such as size updates the price, SKU, and stock, and Add to cart stores the selected variation. Related products come from the catalog. The product template no longer repeats the blog title and date.

  • Shop cart page. /shop/cart lists each product with its photo, options, unit price, and line total. Quantities can be changed or removed, the subtotal follows the catalog tax display, and checkout stays closed until every line can be sold. Shipping is left for checkout. The cart template no longer shows the blog date and excerpt.

  • Shop checkout page. /shop/checkout collects contact, shipping, and billing, then prices delivery, tax, and discounts from the shop settings. Country lists follow the selling and shipping countries. Guest checkout closes when the shop requires an account. Enabled payment methods are offered without collecting card details, and a placed order is stored as awaiting payment.

  • Shop registers a Customer role. Activating the Shop plugin adds a customer user role with no administration access. It appears in New User Default Role, user invites, and the user editor, and can be the role new registrations receive. Deactivating Shop removes it from those lists.

  • Shop → Customers can add a customer. The form collects the sign-in account, phone, company, tax ID, invoice address, and shipping address. The new account is also created under Admin → Users with the customer role. Plugins that declare users:manage can create users only in a role they registered.

  • Shop → Customers can edit a customer. Open a customer to change their name, phone, company, tax ID, invoice address, and shipping address. The sign-in address stays on the user account.

  • Shop → Customers can import customers. CSV, JSON, and XML files create or update customers, including invoice and shipping addresses. A new email also creates a user with the customer role. A matching email updates the shop record and leaves the existing sign-in alone.

  • Shop → Payments connects the provider accounts. Turn on Stripe, PayPal, Mollie, Adyen, Square, bank transfer, cash on delivery, or check. Sandbox and live secrets stay in plugin secrets and are not returned to the browser. The page lists payment attempts, captures, cancellations, refunds, and disputes. Another plugin can add a gateway, including Justflows Payments, through the justflows.shop.payments.gateways filter.

  • Shop → Payments has a page per provider. Open Mollie and choose Mollie checkout or the methods active on that profile. Checkout offers one of those, not both. Each method is its own choice and sends the customer straight to that method. Payment method logos at checkout can be turned on or off.

  • Mollie payments include the shop order. Starting a Mollie payment sends the Justflows user id, the shop customer and order ids, billing and shipping addresses, the visitor's language, a cancel link, and the order lines with tax. The ids are stored in the payment's metadata.

  • Shop → Shipping calls DHL, PostNL, and DPD. Test connection asks DHL Express for live rates, PostNL for delivery options, and DPD to sign in and list pickup points. Sandbox mode uses each carrier's test host. PostNL and DPD do not return a contract price, so the rate on the zone is still what the customer pays for those two.

  • Shop → Shipping covers zones and carriers. Add shipping zones by country, postcode, or the rest of the world, then offer flat rate, free shipping, local pickup, or a carrier service. DHL, DPD, and PostNL are included. Another plugin can add a carrier through the justflows.shop.shipping.carriers filter. Carrier API keys stay in plugin secrets and are never sent back to the browser.

  • Plugins can keep pages out of the static export. The new staticExport.exclude filter lists paths the exporter leaves to the live app, such as a cart, checkout, or account page. Those paths are never crawled, even when linked. Copies from earlier runs are removed, and the generated .htaccess and _nginx.conf route them to the app. With STATIC_EXPORT_ORIGIN_URL set, links and form actions that point at them go to that origin. Shop uses it for its cart, checkout, order confirmation, customer account, and order tracking pages. See docs/STATIC-EXPORT.md. (#24)

  • Admin → Users opens a user page. Click a user's name or row to open /admin/users/<id>. The page shows the account ID, role, created and last-updated dates, whether two-factor sign-in is on, the user's effective capabilities, and their authored content with counts by status and links to the 10 most recently updated items. Editors with users:read can now open this page too, read-only. Administrators also see the user's 20 most recent audit entries, IP addresses included, and can download the user's personal data. GET /api/users/:id returns these fields.

  • Users can have additional roles. A user keeps one main role and can also hold other built-in or plugin roles, such as a subscriber who is also a shop Customer. Tick them under Additional roles on the user page, or send additionalRoles to PATCH /api/users/:id. Additional roles only add capabilities. Admin-only checks and the last-administrator guard still read the main role, and Administrator can only be a main role. An author or contributor can still edit only their own content when the role is an additional one. Admin → Users shows the extra roles next to the main one. Adds migration 0035_user_additional_roles.

  • Existing users can become shop customers. Adding a customer in Shop → Customers, or importing one, with an email that already signs in now links that user and gives them the Customer role. Before, this failed with "already exists". Their password and main role stay unchanged. A signed-in user who places their first order also gets the Customer role. The other way round works too: anyone who gets the Customer role, as main or additional role, from Admin → Users, an invite, or sign-up, now appears in Shop → Customers.

  • SDK: ctx.users.addRole(), ctx.users.get(), and session.roles. ctx.users.addRole({ userId } | { email }, role, actor) gives an existing user one of the plugin's own roles as an additional role. ctx.users.get(userId) reads a user with all their roles. Both need users:manage, like ctx.users.create. Plugin HTTP sessions now include roles, with the main role first. All three are optional on older hosts. See docs/PERMISSIONS.md.

  • Plugin errors show up in Diagnostics. Every plugin's ctx.logger.error() call, every exception from a plugin hook handler, and every uncaught plugin route failure now lands in Admin → System → Diagnostics → Recent errors, tagged plugin:<id>. Plugins do not opt in and cannot opt out. A failing plugin route now also returns a requestId.

  • Beta installs from the Marketplace. A plugin or theme can set registry.beta: true in justflows.json. Admin → Marketplace and Themes show a Beta badge on it. Install stays off until an administrator turns on Settings → Marketplace → Allow installing beta plugins and themes, and each beta install then asks for confirmation with a warning first. POST /api/marketplace/install enforces the same setting and returns 403 while it is off. SDK: isRegistryListingBeta().

  • Shop publishes health checks. Diagnostics shows whether Shop setup is complete and whether each enabled payment gateway has its credentials for the current mode.

Changed

  • Core updates are verified by default. Every release now ships justflows.zip.sig, an Ed25519 signature over the archive and its version, next to justflows.zip. Update, force reinstall, automatic updates, and uploads all refuse an archive without a valid signature. To upload a release by hand, select justflows.zip and justflows.zip.sig together. A pinned JUSTFLOWS_UPDATE_DIGEST or an HMAC made with JUSTFLOWS_UPDATE_SIGNING_KEY still lets an operator apply their own build. JUSTFLOWS_ALLOW_UNSIGNED_CORE_UPDATES=1 turns the check off. An operator's JUSTFLOWS_UPDATE_SIGNING_KEY no longer blocks the Update button, because official releases carry their own signature.

  • Shop sandbox mode uses the PostNL shipping sandbox. With Sandbox / test mode on, Test connection still asks PostNL for delivery options, and it also creates a confirmed shipment on the PostNL shipping sandbox and reads that shipment's status. Live mode does not create a shipment.

  • SDK: A plugin declares CSRF exemption, a host rate limit, and raw-body capture on the ctx.http route itself (PluginHttpRouteOptions). The host applies that policy and no longer matches Shop cart, checkout, catalog, or payment-webhook URLs.

  • Theme layout targets come from the active plugin. theme.layoutScopes adds a customizer layout section (content width and wide width) for a public prefix and the pages under it. permalinks.typeBases contributes that type's default permalink base. Core ships neither; deactivating the plugin removes both. Shop registers Product (/product) and Shop (/shop) while it is active.

  • Plugin content lists show one row per item. A menu page such as Shop → Products lists the site's default language only. Other translations stay on the content editor, where the language switcher already lives.

Fixed

  • Shop orders reserve stock, and a paid order commits it. Placing an order holds tracked stock for the inventory hold time: available goes down and reserved goes up. When the payment is captured, that quantity moves to committed. An unpaid hold returns to available when the hold time ends. Opening Commerce → Inventory commits stock for payments that were already captured and releases holds that have expired.
  • Shop sends order, payment, and refund emails. Placing an order emails the customer (Order confirmed) and the store contact address (New order). Capturing a payment emails Payment received, and recording a refund emails Refund issued. Commerce → Emails lists each message that went out. A template that is switched off is not sent.
  • Mollie checkout opens Mollie's payment page. Choosing Mollie at checkout starts a payment and sends the customer to Mollie. A test API key opens Mollie's test payment page. The order stays awaiting payment until Mollie reports it paid. Bank transfer, cash, and check still confirm on this page.
  • Shop product pages calculate tax. When tax is on, the product price, {{price}}, and related products follow Prices in the catalog. A price entered excluding tax is shown with tax added when the catalog displays prices including tax. The price suffix is filled in. When the catalog shows prices excluding tax, the product page shows that net price large and the including-tax price in small text beside it.
  • A rejected Mollie key shows on Diagnostics. Shop tested a standard API key against Mollie's organization endpoint, which only accepts an organization token, so a sandbox key from Developers → API keys was refused. The connection test now uses the current profile. Admin → System → Diagnostics lists that failure on the overview and under Plugin health checks. (#57)
  • Product options show in the content editor menu. Editing a product listed one Product data item for the whole catalog. Images, pricing, inventory, shipping, attributes, variations, categories, and tags are now separate menu entries, and the editor shows the one you pick.