<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
	xml:lang="en">
	<title>MonkeybreadSoftware Blog</title>
	<subtitle></subtitle>
        <link rel="alternate" type="text/html" href="https://www.mbsplugins.de/main.php"/>
        <link rel="self" type="application/atom+xml" href="https://www.mbsplugins.de/atom.xml"/>
	<updated>2026-06-11T09:26:42+02:00</updated>
	<author>
	<name>Christian</name>
	<uri>https://www.mbsplugins.de/main.php</uri>
	<email>Chef</email>
	</author>
	<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog</id>
	<generator uri="http://www.pivotlog.net" version="Pivot - 1.40.8: 'Dreadwind'">Pivot</generator>
	<rights>Copyright (c) 2026, Authors of MonkeybreadSoftware Blog</rights>
	
	
	
	<entry>
		<title>AtomicDictionaryMBS – Thread-Safe Dictionaries for Xojo</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-06-11/AtomicDictionaryMBS_–_Thread" />
		<updated>2026-06-11T09:26:00+02:00</updated>
		<published>2026-06-11T09:21:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6267</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">Modern applications increasingly rely on multi-threading: background tasks, network processing, rendering pipelines, and data caching often run in parallel. In such environments, shared mutable data structures become a critical source of bugs if not properly synchronized.



With AtomicDictionaryMBS introduced in MBS Xojo Plugins 26.3, we provide a dedicated thread-safe dictionary designed specifically for safe concurrent access in Xojo applications.




Why not just use a Xojo Dictionary?


The standard Dictionary in Xojo is not thread-safe. This means:



  Concurrent reads and writes can lead to crashes
  Race conditions can overwrite data unexpectedly
  Iteration while another thread modifies data can cause exceptions
  Complex locking must be implemented manually using Mutexes



In practice, this often leads to subtle bugs that are difficult to reproduce, especially in production environments where thread timing differs from debugging scenarios.



Developers typically solve this by wrapping a Dictionary in a Mutex, but this approach is error-prone:



  Locks may be forgotten for certain access paths
  Deadlocks can occur if multiple locks are used
  Fine-grained atomic operations are hard to implement correctly</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-06-11/AtomicDictionaryMBS_–_Thread"><![CDATA[
                <p>
Modern applications increasingly rely on multi-threading: background tasks, network processing, rendering pipelines, and data caching often run in parallel. In such environments, shared mutable data structures become a critical source of bugs if not properly synchronized.
</p>

<p>
With <strong><a rel="external" href="https://www.monkeybreadsoftware.net/class-atomicdictionarymbs.shtml">AtomicDictionaryMBS</a></strong> introduced in <a rel="external" href="https://www.monkeybreadsoftware.de/xojo/">MBS Xojo Plugins</a> 26.3, we provide a dedicated thread-safe dictionary designed specifically for safe concurrent access in Xojo applications.
</p>



<h2>Why not just use a Xojo Dictionary?</h2>

<p>
The standard <code>Dictionary</code> in Xojo is <strong>not thread-safe</strong>. This means:
</p>

<ul>
  <li>Concurrent reads and writes can lead to crashes</li>
  <li>Race conditions can overwrite data unexpectedly</li>
  <li>Iteration while another thread modifies data can cause exceptions</li>
  <li>Complex locking must be implemented manually using Mutexes</li>
</ul>

<div class="note">
In practice, this often leads to subtle bugs that are difficult to reproduce, especially in production environments where thread timing differs from debugging scenarios.
</div>

<p>
Developers typically solve this by wrapping a Dictionary in a <code>Mutex</code>, but this approach is error-prone:
</p>

<ul>
  <li>Locks may be forgotten for certain access paths</li>
  <li>Deadlocks can occur if multiple locks are used</li>
  <li>Fine-grained atomic operations are hard to implement correctly</li>
</ul><style>
    body {
      color: #222;
    }
    h1, h2, h3 {
      line-height: 1.3;
    }
    code {
      background: #f4f4f4;
      padding: 2px 5px;
      border-radius: 4px;
    }
    pre {
      background: #f4f4f4;
      padding: 12px;
      overflow-x: auto;
      border-radius: 6px;
    }
    .note {
      background: #fff8d6;
      padding: 10px 12px;
      border-left: 4px solid #f0c400;
      margin: 20px 0;
    }
  </style>

<h2>What AtomicDictionaryMBS improves</h2>

<p>
<a rel="external" href="https://www.monkeybreadsoftware.net/class-atomicdictionarymbs.shtml">AtomicDictionaryMBS</a> encapsulates synchronization internally and provides <strong>atomic operations</strong> that eliminate common race conditions entirely.
</p>

<p>
Instead of manually locking around read-modify-write sequences, you use purpose-built methods that guarantee correctness.
</p>



<h2>Core advantages</h2>

<h3>1. Built-in thread safety</h3>

<p>
All operations on <a rel="external" href="https://www.monkeybreadsoftware.net/class-atomicdictionarymbs.shtml">AtomicDictionaryMBS</a> are internally synchronized, meaning multiple threads can safely access the same instance without external locks.
</p>

<h3>2. Atomic operations instead of manual locking</h3>

<p>
Rather than doing this (unsafe in threaded code):
</p>

<pre>
Var v As Variant = dict.Value("counter")
dict.Value("counter") = v + 1
</pre>

<p>
You do:
</p>

<pre>
a.Increment("counter")
</pre>

<p>
This removes the race condition between read and write.
</p>



<h2>Key methods and why they matter</h2>

<h3>CompareAndSet – lock-free style synchronization</h3>

<pre>
Var ok As Boolean = a.CompareAndSet("state", "idle", "running")
</pre>

<p>
This ensures the value is only updated if it still matches the expected state. It prevents:
</p>

<ul>
  <li>lost updates</li>
  <li>double processing</li>
  <li>stale state overwrites</li>
</ul>

<p>
This pattern is widely used in concurrent programming and replaces fragile manual locking logic.
</p>



<h3>GetAndSet – atomic read-modify-write</h3>

<pre>
Var newValue As Variant = 100
Var oldValue As Variant = a.GetAndSet("queueSize", newValue)
</pre>

<p>
This ensures no other thread can modify the value between reading and updating it.
</p>



<h3>GetOrSet – safe lazy initialization</h3>

<pre>
Var v As Variant = a.GetOrSet("config", defaultConfig)
</pre>

<p>
This avoids duplicate initialization when multiple threads attempt to create the same entry.
</p>



<h3>Increment – safe counters without locks</h3>

<pre>
a.Increment("hits")
</pre>

<p>
A common problem in multithreaded apps is updating counters safely. This method guarantees correctness without requiring a mutex.
</p>



<h3>ExecuteLocked – grouped atomic operations</h3>

<pre>
a.ExecuteLocked(AddressOf UpdateDic)

Sub UpdateDic(dic As AtomicDictionaryMBS)
  dic.Value("Hello") = dic.Value("Hello") + 1
End Sub
</pre>

<p>
When multiple operations must be performed as a single atomic unit, this method ensures exclusive access for the duration of the delegate.
</p>



<h3>SetIfAbsent – safe initialization pattern</h3>

<pre>
a.SetIfAbsent("session", sessionObject)
</pre>

<p>
This ensures a value is only written if it does not already exist, preventing race conditions during initialization.
</p>



<h2>Iteration safety</h2>

<p>
The class provides an iterator for <code>For Each</code> loops:
</p>

<pre>
For Each v As Variant In a.Iterator
  // safe iteration snapshot behavior
Next
</pre>

<p>
This avoids common crashes that occur when a Dictionary is modified during enumeration.
</p>



<h2>How AtomicDictionaryMBS differs from manual Mutex usage</h2>

<table border="1" cellpadding="8" cellspacing="0">
  <tr>
    <th>Aspect</th>
    <th>Mutex + Dictionary</th>
    <th>AtomicDictionaryMBS</th>
  </tr>
  <tr>
    <td>Thread safety</td>
    <td>Manual, error-prone</td>
    <td>Built-in</td>
  </tr>
  <tr>
    <td>Atomic operations</td>
    <td>Must be implemented manually</td>
    <td>Built-in (CompareAndSet, Increment, etc.)</td>
  </tr>
  <tr>
    <td>Race conditions</td>
    <td>Easy to introduce</td>
    <td>Eliminated for API operations</td>
  </tr>
  <tr>
    <td>Code complexity</td>
    <td>High</td>
    <td>Low</td>
  </tr>
  <tr>
    <td>Deadlock risk</td>
    <td>Possible</td>
    <td>Greatly reduced</td>
  </tr>
</table>



<h2>Typical use cases</h2>

<p>We can use the dictionary for various use cases in our Xojo projects:</p>

<ul>
  <li>Shared caches across worker threads</li>
  <li>Game state synchronization (physics, AI, rendering)</li>
  <li>Network session and token management</li>
  <li>Producer/consumer pipelines</li>
  <li>Event subscription systems</li>
</ul>



<h2>When NOT to use it</h2>

<p>
A standard <code>Dictionary</code> is still appropriate when:
</p>

<ul>
  <li>Only one thread accesses the data</li>
  <li>All access is already protected externally</li>
  <li>Data is immutable after creation</li>
</ul>

<p>
Using <a rel="external" href="https://www.monkeybreadsoftware.net/class-atomicdictionarymbs.shtml">AtomicDictionaryMBS</a> in single-threaded scenarios is safe, but may introduce unnecessary overhead.
</p>



<h2>Availability</h2>

<p>
<a rel="external" href="https://www.monkeybreadsoftware.net/class-atomicdictionarymbs.shtml">AtomicDictionaryMBS</a> is available in <a rel="external" href="https://www.monkeybreadsoftware.de/xojo/">MBS Xojo Plugins</a> 26.3 and newer.
</p>



<h2>Summary</h2>

<p>
<a rel="external" href="https://www.monkeybreadsoftware.net/class-atomicdictionarymbs.shtml">AtomicDictionaryMBS</a> provides a modern, safe abstraction over shared key-value storage in multi-threaded Xojo applications. It removes the need for manual locking in most cases and replaces fragile concurrency patterns with clear, atomic operations.
</p>

<p>
The result is simpler code, fewer race conditions, and more reliable applications under real-world concurrent load.</p>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>FileMaker 2026 released</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-06-10/FileMaker_2026_released" />
		<updated>2026-06-10T13:22:00+02:00</updated>
		<published>2026-06-10T13:22:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6266</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">Claris released version 26 of the FileMaker product family. As you may have noticed, the version number is finally synchronized to the current year.</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-06-10/FileMaker_2026_released"><![CDATA[
                <img src="http://www.mbsplugins.de/image/FileMaker26icon.png" width="512" align="right" style="max-width: 50%;">
<p>
Claris released version 26 of the <a rel="external" href="https://www.claris.com/filemaker/">FileMaker product family</a>. As you may have noticed, the version number is finally synchronized to the current year. </p<

<p>There are a lot of new features in this release:</p>


<ul>
<li>This release brings a lot of new <b>AI integration</b>. You can install a standalone Claris AI Server to handle the workload of AI queries. It is highly recommended to buy a separate machine with lots of RAM and a good GPU to speed up the queries. Mac Studios with M5 Max/Ultra may come handy soon. <br  />
Related to this are new comments for fields to help the AI know what a field is about. In FileMaker Pro you can use the Insert Image Caption script step to use an image model on the AI server to get image captions.



<li>Claris offers a built-in <b>backup</b> feature. Great to keep the hassle low and it allows the Claris Partner to sell it to their clients. The data is uploaded to cloud storage, preferable in a different region. Of course you must still run your own scripts to upload the nightly backups and all the hourly increments to your own backup server.



<li>Related to the backup is the <b>standby server</b>. A feature we had in FileMaker 14, but now with a different implementation. It is built on top of the incremental backups Changes are regularly transferred in batches to the standby server via SSH. Your clients can opt-in to this, get a second server and have it wait for a switch over in case of a disaster. But please have the standby server in a different location and on a different Internet provider.

<li>The installer for FileMaker Server can install just the <b>tools</b>. Great if you like to have the tools on your machine. Once you have the FMUpgradeTool, you may notice that it has a new trick: it can create a new database from an XML representation. Related to this are upgrades to the Save as XML script step and enhancements in the options so you can choose what to export.

<li>The <b>OData interface</b> got upgrades to better handle metadata. Since OData is the preferred way for AI to talk to FileMaker Server, this helps a lot with various integrations. Please note that Claris like to see you move to OData in favor of ODBC and Data API on the long term.

<li>There is an updated inspector for layouts. The layout is in context related and only shows features available for the currently selected items. This makes relevant options easier to find and cleans up the old interface. But since not everyone likes changes, you may be able to turn it off in the preferences soon. And this is macOS only as the Windows side is still in development. 

</ul><p>Please read details in the release notes:</p>
 
<ul>
<li><a rel="external" href="https://www.claris.com/blog/2026/claris-filemaker-2026-is-now-available">Claris FileMaker 2026 is now available</a> on the Claris Blog
<li><a rel="external" href="https://community.claris.com/en/s/question/0D5Vy00002k6XAiKAM/claris-filemaker-2026-is-here-what-you-need-to-know">FileMaker 2026 Announcement</a>
<li><a rel="external" href="https://partner.claris.com/s/fm2026-resources">FileMaker 2026 Resources</a></li>
<li><a rel="external" href="https://community.claris.com/en/s/article/Claris-FileMaker-2026-Technical-Specifications">Claris FileMaker 2026 Technical Specifications</a></li>
<li><a rel="external" href="https://support.claris.com/s/article/Claris-FileMaker-Pro-2026-Technical-Limits">Claris FileMaker Pro 2026 Technical Limits</li>

<li><a rel="external" href="https://help.claris.com/en/pro-release-notes/content/index.html">FileMaker Pro release notes</a>
<li><a rel="external" href="https://help.claris.com/en/go-release-notes/content/index.html">FileMaker Go release notes</a>
<li><a rel="external" href="https://help.claris.com/en/server-release-notes/content/index.html">FileMaker Server release notes</a>
</ul>


<p>You can download it on the ESD website. The link is in the license email from Claris.</p>


<p>
In FileMaker 26 you can finally specify the position for a custom dialog. Before we had to use our <a rel="external" href="https://www.mbsplugins.eu/WindowPositionNextDialog.shtml">Window.PositionNextDialog</a> function. That one still works and can handle all kind of dialogs like various FileMaker dialogs. 
</p>

<p>
The SQL engine got an interesting upgrade. You can how create relationship with a SQL command. When you add a field, you can use e.g. AssetID int FOREIGN KEY REFERENCES Assets(AssetID) to link the AssetID field in that table to the AssetID field in the Assets table. The field names do not need to match and you can of course have text nodes. We can use the same with ALTER TABLE when adding a field to a table. See our <a rel="external" href="https://www.mbsplugins.eu/FMExecuteFileSQLOnIdle.shtml">FM.ExecuteFileSQLOnIdle</a> function and the examples there.
</p>

<p>
The GetTextFromPDF function in FileMaker can now better handle PDF images with images. Great to see what is on a page. This may need to render the PDF page and then get it through OCR on macOS. We do that with <a rel="external" href="https://www.mbsplugins.eu/VisionRecognizeText.shtml">Vision.RecognizeText</a> function in our plugin and there you can specify options like the language, how many pages to cover or provide custom words for the dictionary to help with spelling. And it works on macOS, iOS and Windows.
</p>

<p>
The Export Field Contents script step now works server-side. But it is still limited to temporary and documents folder. You may still use <a rel="external" href="https://www.mbsplugins.eu/ContainerWriteFile.shtml">Container.WriteFile</a> or similar plugin functions to write on different locations. For example you could have a data folder outside the FileMaker folder. Or you write to the html documents folder for the local web server to share files easily. Or you even write files to network attached storage.
</p>

<p>
The server has support for Webhooks. Great to catch callbacks from various services. We usually uses a PHP script to accept the hook, check the values and then use Data API to talk to the FileMaker Server and finally run a script. You can do this now a bit more direct, but still we may prefer the PHP script to filter out some requests in order to not overload the server. Check our <a rel="external" href="https://www.mbsplugins.eu/component_WebHook.shtml" translate="no">WebHook</a> functions if you need a WebHook in FileMaker Pro (e.g. for OAuth) or you like to turn one on for a short time in a server script and catch a callback.
</p>

<p>
In the scripts you have new PDF script steps. Instead of doing an export of records to PDF in one script step, you can split this into five steps. For example you can start a PDF, export records from one layout, then switch to another layout and export some more records into the same PDF file. If you need more options to merge PDFs, please check our <a rel="external" href="https://www.mbsplugins.eu/component_DynaPDF.shtml" translate="no">DynaPDF</a> functions. Also helpful to edit, split, encrypt, sign or render PDF files.
</p>

<p>
Finally Claris updated libraries. Tomcat, NodeJS, CURL, Vaadin, PDF-Writer, OmniORB, OpenSSL and others got upgraded. That's always great to fix various security holes. Although be aware that on Linux updating the system may cause FileMaker Server use newer system provided libraries. The ones included within the FileMaker products are always a bit behind the latest releases. CURL is currently at 8.20 and the older 8.18 is used by Claris. That is due to them needed to integrate a newer version and then doing the Q&amp;A for a few weeks to make sure there is no bug introduced with a newer library. Also wait to see if the release is quickly followed with a .2 bug fix. We do similar, but with a shorter cycle.
</p>

<p>
For <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/">MBS FileMaker Plugin</a> licensing on the server side, we count how many servers you have. Usually we start with a one server license. This covers the one machine with 3 copies of the plugin running in the script engine, Web Direct and Data API processes. This includes running multiple server scripting processes if you turn this on. If you add worker server for Web Direct and install the plugin there, that counts as separate servers. But the standby servers don't count since we expect you only use one of the two servers. When you switch over, the license server would detect that you stopped on the one machine and continued on the other machine. The license automatically transfers. And it automatically transfers back if you switch back. No worries.
</p>

<p>
Please try FileMaker 26. We recommend you use it with <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/">MBS FileMaker Plugin</a> 16.2 or newer. We had FileMaker 26 in testing for the last months and fixed a couple of issues. Version 15.x may load and work for most parts. But you can avoid trouble by using a newer version like 16.1 or 16.2.
</p>

<p>See also:</p>

<ul>
<li><a rel="external" href="https://www.1-more-thing.com/en/filemaker-2026-is-here/">FileMaker 2026 is here!</a> by Fabrice Nordman
<li><a rel="external" href="https://www.soliantconsulting.com/blog/filemaker-2026-executive-summary/">FileMaker 2026 Executive Summary</a> by Wim Decorte
<li><a href="https://fmtraining.tv/#LIVE">FMTraining Live streams</li>
</ul>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>MBS @ FMTraining.TV - FileMaker MonkeyBread Plug-in 16.2 Release</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-06-09/MBS_@_FMTrainingTV_-_FileMaker" />
		<updated>2026-06-09T17:20:00+02:00</updated>
		<published>2026-06-09T17:20:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6265</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">Check out the FMTraining.tv website. Richard Carlton and his team do a daily free live stream about FileMaker to watch. 

A few days ago Christian Schmitz from Monkeybread Software joined a live episode to talk a bit about the MBS FileMaker Plugin. Watch it on YouTube.



We talk about the new version 16.2 of MBS Plugin. Check out the announcement, the release notes and the new functions.</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-06-09/MBS_@_FMTrainingTV_-_FileMaker"><![CDATA[
                <p>Check out the <a rel="external" href="https://fmtraining.tv/">FMTraining.tv</a> website. Richard Carlton and his team do a <a rel="external" href="https://fmtraining.tv/#LIVE" title="">daily free live stream</a> about FileMaker to watch. </p>

<p>A few days ago Christian Schmitz from Monkeybread Software joined a live episode to talk a bit about the <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/">MBS FileMaker Plugin</a>. Watch it on <a rel="external" href="https://www.youtube.com/watch?v=2LdeIey0bK8" title="">YouTube</a>.</p>

<a rel="external" href="https://www.youtube.com/watch?v=2LdeIey0bK8"><img src="http://www.mbsplugins.de/image/mbsfmtraining87.jpg" width="640" height="360"></a>

<p>We talk about the new version 16.2 of MBS Plugin. Check out the <a rel="external" href="https://www.mbsplugins.de/archive/2026-05-05/MBS_Plugin_162_for_Claris_File/monkeybreadsoftware_blog_filemaker" title="">announcement</a>, the <a rel="external" href="https://monkeybreadsoftware.com/filemaker/releasenotes162" title="">release notes</a> and the <a rel="external" href="https://mbsplugins.eu/newinversion162" title="">new functions</a>.</p><p>More videos</p>
<ul>

<li><a rel="external" href="https://www.youtube.com/watch?v=2LdeIey0bK8">FileMaker MonkeyBread Plug-in 16.2 Update</a></li>
<li><a rel="external" href="https://www.youtube.com/watch?v=mK8mmHaRxW8">MonkeyBread Plug-in PDFs & Search Functionality in FileMaker Q&amp;A/a></li>
<li><a rel="external" href="https://www.youtube.com/watch?v=66IDZqfonYw">FileMaker MonkeyBread Plug-in 16.1 Update</a></li>
<li><a rel="external" href="https://www.youtube.com/watch?v=3zFhi2oNRTI">Installing the MBS Plug-in In FileMaker Via Script</a></li>
<li><a rel="external" href="https://www.youtube.com/watch?v=7iCFkkoodNs">FileMaker MonkeyBread Plug-in 16.0 Update</a></li>
<li><a rel="external" href="https://www.youtube.com/watch?v=e3EIDmbZFDA">FileMaker MonkeyBread Plug-in 15.5 Update</a></li>
<li><a rel="external" href="https://www.youtube.com/watch?v=4NJUfNedO60">FileMaker MBS Plug-in Q&A</a></li>
<li><a rel="external" href="https://www.youtube.com/watch?v=-EQ85M_q-Tw">FileMaker MonkeyBread Plug-in 15.4 Update</a></li>
<li><a rel="external" href="https://www.youtube.com/watch?v=BRunK_N1OR8">Make iOS Apps with the FileMaker App SDK & the MonkeyBread Plug-in</a></li>
<li><a rel="external" href="https://www.youtube.com/watch?v=sxS6fJnRGEQ">FileMaker MBS Plug-in Q&A</a></li>

<li>More in the <a rel="external" href="https://youtube.com/playlist?list=PLvH3LgGie0XOOeMweFff2blaukf47WJyi">YouTube playlist...</a></li>
</ul>
<p>Do you like this video? Please let us and RCC know!</p>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>MBS Xojo Conference 2026 - Protecting Sensitive Data in Xojo</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-06-09/MBS_Xojo_Conference_2026_-_Pro" />
		<updated>2026-06-09T09:24:00+02:00</updated>
		<published>2026-06-09T09:24:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6264</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">We recorded the presentations at the MBS Xojo Conference in April 2026 and here is the Protecting Sensitive Data in Xojo: Practical Encryption Techniques Using MBS Plugins by Bill OKeefe.




Encryption is essential for protecting sensitive user and business data—but implementing it correctly is often confusing. In this practical session,  building secure, efficient encryption workflows directly in Xojo using the MBS plugins will be shown.



Using the DICOM medical image format as a complex but relatable data model, we’ll explore how to handle mixed-type binary structures, manage endian differences, and work with Xojo’s MemoryBlock class to prepare data for encryption. From there, you’ll see real examples of AES-256 file encryption and decryption, key generation, chained encryption blocks, and performance optimization with the MBS Crypto classes.



Along the way we’ll cover common pitfalls (such as re-using IVs or ignoring data structure), when to use symmetric vs. asymmetric encryption, and how to keep your code aligned with regulatory standards such as FIPS 140 or HIPAA—even if you’re not working in medicine.



Attendees will receive a download code for working code fragments covering file, text, and database encryption techniques ready for adaptation in their own projects.
by Bill OKeefe



Watch on YouTube. All videos go into the playlist for the conference.</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-06-09/MBS_Xojo_Conference_2026_-_Pro"><![CDATA[
                <p>We recorded the presentations at the <a rel="external" href="https://www.monkeybreadsoftware.de/xojo/events/andernach-2026-event.shtml" title="">MBS Xojo Conference</a> in April 2026 and here is the Protecting Sensitive Data in Xojo: Practical Encryption Techniques Using MBS Plugins by Bill OKeefe.</p>

<a rel="external" href="https://youtu.be/yINbctQ4AWs"><img src="http://www.mbsplugins.de/image/MBS-Xojo-Conference-Bill-OKeefe.jpg" width="960"></a>

<p>
Encryption is essential for protecting sensitive user and business data—but implementing it correctly is often confusing. In this practical session,  building secure, efficient encryption workflows directly in Xojo using the MBS plugins will be shown.
</p>

<p>
Using the DICOM medical image format as a complex but relatable data model, we’ll explore how to handle mixed-type binary structures, manage endian differences, and work with Xojo’s MemoryBlock class to prepare data for encryption. From there, you’ll see real examples of AES-256 file encryption and decryption, key generation, chained encryption blocks, and performance optimization with the MBS Crypto classes.
</p>

<p>
Along the way we’ll cover common pitfalls (such as re-using IVs or ignoring data structure), when to use symmetric vs. asymmetric encryption, and how to keep your code aligned with regulatory standards such as FIPS 140 or HIPAA—even if you’re not working in medicine.
</p>

<p>
Attendees will receive a download code for working code fragments covering file, text, and database encryption techniques ready for adaptation in their own projects.<br  />
by Bill OKeefe
</p>


<p><a rel="external" href="https://youtu.be/yINbctQ4AWs">Watch on YouTube</a>. All videos go into the <a rel="external" href="https://www.youtube.com/playlist?list=PLvH3LgGie0XNbarXTLF5sKq34xLU6j4lG">playlist</a> for the conference.</p>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>The contacts for a license</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-06-03/The_contacts_for_a_license" />
		<updated>2026-06-03T15:55:00+02:00</updated>
		<published>2026-06-03T15:54:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6263</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">For our clients with plugin licenses for Monkeybread Software, we have a database with licenses and their email contacts.



Each license has multiple emails:



a primary email for renewal reminders and newsletters about new versions.
more emails as CC of licenses. e.g. the administrator or developer to install the license.
older alternative emails that are marked as old. 
sometimes an extra email just for invoices.



If you contact us with one of the emails and we search the database, we find your record.



When you buy a license for a client, we can put your email as developer in our database, so all communication goes through you. We would still like to know the name of the client and use it for the license keys.


Since you may disappear and clients still may need to renew, we appreciate having the client's email in the database as an alternative one. Then we can ask them directly if they like to renew. Since we do this for 20 years, we have seen multiple developers retire already.


When you order a license for a client in the web shop, you put in the billing address. That may be either the client itself if they pay themselves or your company if you buy it for the client and bill them later. When you use your address, consider adding somewhere a few letters for indicating which customer an order applies to. Or better email us the details for the client separately. If you order an update for one of your clients, we may apply it automatically to the one where we sent the last renewal reminder.


If you already have a couple of clients with MBS Plugin licenses, you can contact us if we should change the primary email for their licenses.</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-06-03/The_contacts_for_a_license"><![CDATA[
                <p>
For our clients with plugin licenses for Monkeybread Software, we have a database with licenses and their email contacts.
</p>

<p>
Each license has multiple emails:
</p>

<ul>
<li>a primary email for renewal reminders and newsletters about new versions.
<li>more emails as CC of licenses. <br  />e.g. the administrator or developer to install the license.
<li>older alternative emails that are marked as old. 
<li>sometimes an extra email just for invoices.
</ul>

<p>
If you contact us with one of the emails and we search the database, we find your record.
</p>

<p>
When you buy a license for a client, we can put your email as developer in our database, so all communication goes through you. We would still like to know the name of the client and use it for the license keys.
</p>

<p>Since you may disappear and clients still may need to renew, we appreciate having the client's email in the database as an alternative one. Then we can ask them directly if they like to renew. Since we do this for 20 years, we have seen multiple developers retire already.</p>

<p>
When you order a license for a client in the web shop, you put in the billing address. That may be either the client itself if they pay themselves or your company if you buy it for the client and bill them later. When you use your address, consider adding somewhere a few letters for indicating which customer an order applies to. Or better email us the details for the client separately. If you order an update for one of your clients, we may apply it automatically to the one where we sent the last renewal reminder.
</p>

<p>If you already have a couple of clients with MBS Plugin licenses, you can contact us if we should change the primary email for their licenses.</p>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>MBS Xojo Plugins, version 26.3pr1</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-06-01/MBS_Xojo_Plugins_version_263pr" />
		<updated>2026-06-01T10:52:00+02:00</updated>
		<published>2026-06-01T10:50:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6262</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">New in this prerelease of the 26.3 plugins:


Added AlternateHandle and DeviceNAttributesHandle properties to DynaPDFColorSpaceMBS to get the internal handles.
Added AtomicDictionaryIteratorMBS and AtomicDictionaryEntryMBS classes.
Added AtomicDictionaryMBS class.
Added AutoLock and TryAutoLock methods to MutexMBS class.
Added AutoMutexMBS class.
Added ConvColor to DynaPDFMBS class taking DynaPDFColorSpaceMBS object.
Added DataValidation and SheetDataValidationSize to XLSheetMBS class.
Added GetInfoSizeDelivered to CURLSMBS class.
Added GetSortEx and SortLevels to XLAutoFilterMBS class.
Added HeaderCMM property to LCMS2ProfileMBS class.
Added JBIG2Lossy property to DynaPDFImageMBS class.
Added LockCount property to MutexMBS class.
Added more class constants to LCMS2MBS module.
Added more constructors to AtomicFlagMBS class.
Added more constructors to AtomicIntegerMBS class.
Added more methods to AtomicQueueMBS class.
Added NetworkChanged method to CURLSMultiMBS class.
Added NLLanguageRecognizerMBS class.
Added NSScrollViewMBS method to DesktopScrollableArea control in Xojo 2026r2.
Added RemoveFilter and IsAutoFilter to XLTableMBS class.
Added ResolveThreadsMax and QuickExit properties to CURLSMultiMBS class.
Added TransformPipeline and TransformGamutCheckPipeline property to LCMS2TransformMBS class.
Added XLDataValidationValuesMBS class.
Changed Alternate and DeviceNAttributes properties in DynaPDFColorSpaceMBS class to create the object on first use.
Changed GetInfoSpeedUpload, GetInfoSpeedDownload, GetInfoSizeUpload, GetInfoSizeDownload, GetInfoContentLengthUpload and  GetInfoContentLengthDownload in CURLSMBS class to be Integer instead of Double.
Changed GetUsesTransparency in DynaPDFMBS class to return Integer instead of Boolean.
Deprecated ResourcesDirectory in SaxonProcessorMBS class.
Fixed an issue in FindTableName function not finding the table name in a SQL command.
Fixed Height in DynaPDFRectMBS class. The sign was incorrect. Broken in 26.1.
Improved LlamaMBS class to yield time after 1000 tokens.
Improved memory management for MongoDB functions.
Improved ReadAll and ReadAllMemory functions in MongoGridFSFileMBS to raise OutOfMemoryException in case of low memory situation.
Improved thread locking for SQL classes to better avoid two commands running on the same connection at the same time.
Removed LoadDLLfromMemory for SoftDeclareMBS class.
Updated CURL library to version 8.20.0.
Updated DynaPDF to version 5.0.2.11.
Updated expat to version 2.8.1.
Updated jsoncons to version 1.7.0.
Updated lcms to version 2.19.1.
Updated LibXL to version 5.2.0.
Updated mongo-c-driver to version 2.3.0.
Updated Xcode to version 26.5.



New functions in documentation

Download Links: Download Mac dmg or Download Windows/Linux zip

Download: monkeybreadsoftware.de/xojo/download/plugin/Prerelease/. 
Or ask us to be added to our shared DropBox folder.

You can subscribe to our Xojo mailing list to get notified for new pre-release and release versions.</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-06-01/MBS_Xojo_Plugins_version_263pr"><![CDATA[
                <img src="http://www.mbsplugins.de/images/xojoplugin.png" width="128" height="128" align="right">New in this prerelease of the 26.3 plugins:
<ul>

<li>Added AlternateHandle and DeviceNAttributesHandle properties to <a rel="external" href="https://www.monkeybreadsoftware.net/class-dynapdfcolorspacembs.shtml">DynaPDFColorSpaceMBS</a> to get the internal handles.</li>
<li>Added <a rel="external" href="https://www.monkeybreadsoftware.net/class-atomicdictionaryiteratormbs.shtml">AtomicDictionaryIteratorMBS</a> and <a rel="external" href="https://www.monkeybreadsoftware.net/class-atomicdictionaryentrymbs.shtml">AtomicDictionaryEntryMBS</a> classes.</li>
<li>Added <a rel="external" href="https://www.monkeybreadsoftware.net/class-atomicdictionarymbs.shtml">AtomicDictionaryMBS</a> class.</li>
<li>Added AutoLock and TryAutoLock methods to <a rel="external" href="https://www.monkeybreadsoftware.net/class-mutexmbs.shtml">MutexMBS</a> class.</li>
<li>Added <a rel="external" href="https://www.monkeybreadsoftware.net/class-automutexmbs.shtml">AutoMutexMBS</a> class.</li>
<li>Added ConvColor to <a rel="external" href="https://www.monkeybreadsoftware.net/class-dynapdfmbs.shtml">DynaPDFMBS</a> class taking <a rel="external" href="https://www.monkeybreadsoftware.net/class-dynapdfcolorspacembs.shtml">DynaPDFColorSpaceMBS</a> object.</li>
<li>Added DataValidation and SheetDataValidationSize to <a rel="external" href="https://www.monkeybreadsoftware.net/class-xlsheetmbs.shtml">XLSheetMBS</a> class.</li>
<li>Added GetInfoSizeDelivered to <a rel="external" href="https://www.monkeybreadsoftware.net/class-curlsmbs.shtml">CURLSMBS</a> class.</li>
<li>Added GetSortEx and SortLevels to <a rel="external" href="https://www.monkeybreadsoftware.net/class-xlautofiltermbs.shtml">XLAutoFilterMBS</a> class.</li>
<li>Added HeaderCMM property to <a rel="external" href="https://www.monkeybreadsoftware.net/class-lcms2profilembs.shtml">LCMS2ProfileMBS</a> class.</li>
<li>Added JBIG2Lossy property to <a rel="external" href="https://www.monkeybreadsoftware.net/class-dynapdfimagembs.shtml">DynaPDFImageMBS</a> class.</li>
<li>Added LockCount property to <a rel="external" href="https://www.monkeybreadsoftware.net/class-mutexmbs.shtml">MutexMBS</a> class.</li>
<li>Added more class constants to <a rel="external" href="https://www.monkeybreadsoftware.net/module-lcms2mbs.shtml">LCMS2MBS</a> module.</li>
<li>Added more constructors to <a rel="external" href="https://www.monkeybreadsoftware.net/class-atomicflagmbs.shtml">AtomicFlagMBS</a> class.</li>
<li>Added more constructors to <a rel="external" href="https://www.monkeybreadsoftware.net/class-atomicintegermbs.shtml">AtomicIntegerMBS</a> class.</li>
<li>Added more methods to <a rel="external" href="https://www.monkeybreadsoftware.net/class-atomicqueuembs.shtml">AtomicQueueMBS</a> class.</li>
<li>Added NetworkChanged method to <a rel="external" href="https://www.monkeybreadsoftware.net/class-curlsmultimbs.shtml">CURLSMultiMBS</a> class.</li>
<li>Added <a rel="external" href="https://www.monkeybreadsoftware.net/class-nllanguagerecognizermbs.shtml">NLLanguageRecognizerMBS</a> class.</li>
<li>Added <a rel="external" href="https://www.monkeybreadsoftware.net/class-nsscrollviewmbs.shtml">NSScrollViewMBS</a> method to DesktopScrollableArea control in Xojo 2026r2.</li>
<li>Added RemoveFilter and IsAutoFilter to <a rel="external" href="https://www.monkeybreadsoftware.net/class-xltablembs.shtml">XLTableMBS</a> class.</li>
<li>Added ResolveThreadsMax and QuickExit properties to <a rel="external" href="https://www.monkeybreadsoftware.net/class-curlsmultimbs.shtml">CURLSMultiMBS</a> class.</li>
<li>Added TransformPipeline and TransformGamutCheckPipeline property to <a rel="external" href="https://www.monkeybreadsoftware.net/class-lcms2transformmbs.shtml">LCMS2TransformMBS</a> class.</li>
<li>Added <a rel="external" href="https://www.monkeybreadsoftware.net/class-xldatavalidationvaluesmbs.shtml">XLDataValidationValuesMBS</a> class.</li>
<li>Changed Alternate and DeviceNAttributes properties in <a rel="external" href="https://www.monkeybreadsoftware.net/class-dynapdfcolorspacembs.shtml">DynaPDFColorSpaceMBS</a> class to create the object on first use.</li>
<li>Changed GetInfoSpeedUpload, GetInfoSpeedDownload, GetInfoSizeUpload, GetInfoSizeDownload, GetInfoContentLengthUpload and  GetInfoContentLengthDownload in <a rel="external" href="https://www.monkeybreadsoftware.net/class-curlsmbs.shtml">CURLSMBS</a> class to be Integer instead of Double.</li>
<li>Changed GetUsesTransparency in <a rel="external" href="https://www.monkeybreadsoftware.net/class-dynapdfmbs.shtml">DynaPDFMBS</a> class to return Integer instead of Boolean.</li>
<li>Deprecated ResourcesDirectory in <a rel="external" href="https://www.monkeybreadsoftware.net/class-saxonprocessormbs.shtml">SaxonProcessorMBS</a> class.</li>
<li>Fixed an issue in FindTableName function not finding the table name in a SQL command.</li>
<li>Fixed Height in <a rel="external" href="https://www.monkeybreadsoftware.net/class-dynapdfrectmbs.shtml">DynaPDFRectMBS</a> class. The sign was incorrect. Broken in 26.1.</li>
<li>Improved <a rel="external" href="https://www.monkeybreadsoftware.net/module-llamambs.shtml">LlamaMBS</a> class to yield time after 1000 tokens.</li>
<li>Improved memory management for MongoDB functions.</li>
<li>Improved ReadAll and ReadAllMemory functions in <a rel="external" href="https://www.monkeybreadsoftware.net/class-mongogridfsfilembs.shtml">MongoGridFSFileMBS</a> to raise OutOfMemoryException in case of low memory situation.</li>
<li>Improved thread locking for SQL classes to better avoid two commands running on the same connection at the same time.</li>
<li>Removed LoadDLLfromMemory for <a rel="external" href="https://www.monkeybreadsoftware.net/class-softdeclarembs.shtml">SoftDeclareMBS</a> class.</li>
<li>Updated CURL library to version 8.20.0.</li>
<li>Updated DynaPDF to version 5.0.2.11.</li>
<li>Updated expat to version 2.8.1.</li>
<li>Updated jsoncons to version 1.7.0.</li>
<li>Updated lcms to version 2.19.1.</li>
<li>Updated LibXL to version 5.2.0.</li>
<li>Updated mongo-c-driver to version 2.3.0.</li>
<li>Updated Xcode to version 26.5.</li>

</ul>

<p><a rel="external" href="https://www.monkeybreadsoftware.net/newinversion262.shtml">New functions in documentation</a></p>

<p>Download Links: <a rel="external" href="https://monkeybreadsoftware.com/cgi-bin/prerelease.php?type=xojo&format=dmg&cdn=1" download>Download Mac dmg</a> or <a rel="external" href="https://monkeybreadsoftware.com/cgi-bin/prerelease.php?type=xojo&format=zip&cdn=1" download>Download Windows/Linux zip</a></p>

<p>Download: <a rel="external" href="https://www.monkeybreadsoftware.de/xojo/download/plugin/Prerelease/">monkeybreadsoftware.de/xojo/download/plugin/Prerelease/</a>. <br />
Or ask us to be added to our shared DropBox folder.</p>

<p>You can subscribe to our <a rel="external" href="https://monkeybreadsoftware.de/mbsxojoplugin" title="">Xojo mailing list</a> to get notified for new pre-release and release versions.</p>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>MBS FileMaker Plugin, version 16.3pr1</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-06-01/MBS_FileMaker_Plugin_version_1" />
		<updated>2026-06-01T07:22:00+02:00</updated>
		<published>2026-06-01T07:22:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6261</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">New in this prerelease of version 16.3 of the MBS FileMaker Plugin:


Added CNContactPicker.CurrentProperties function.
Added CNContactPicker.GetDisplayedKeys and CNContactPicker.SetDisplayedKeys functions.
Added Command-Option-T shortcut for the calculation editor to insert the current selected table occurrence in the popup menu into the text.
Added CURL.GetSizeDelivered function.
Added flag 4 for WebView.CreateWindow function to make the window a floating palette.
Added flags to return JSON for SpeechRecognition.Recognize function.
Added GridFS functions for MongoDB functions: MongoDB.GridFS.Close, MongoDB.GridFS.Drop, MongoDB.GridFS.Find, MongoDB.GridFS.FindOne, MongoDB.GridFS.FindOneByFileName, MongoDB.GridFS.GetChunks, MongoDB.GridFS.GetFiles, MongoDB.GridFS.Open, MongoDB.GridFS.Read, MongoDB.GridFS.Remove, MongoDB.GridFS.RemoveByFileName and MongoDB.GridFS.Write.
Added JBIG2Lossy as option for DynaPDF.GetImage function.
Added Keychain.AddGenericPassword, Keychain.DeleteGenericPassword, Keychain.FindGenericPassword, Keychain.ListGenericPasswords and Keychain.UpdateGenericPassword functions.
Added PageRanges, PrinterName, PagesPerSide, Copies, Collation, ColorMode and Duplex parameters for WebView.SetPrintParameter function on Windows.
Added Printer.CancelJob and Printer.GetJobsAsJSON functions.
Added width and height for DynaPDF.GetField to ask for field size.
Added XL.Sheet.AutoFilter.GetSortEx and XL.Sheet.AutoFilter.SortLevels functions.
Added XL.Sheet.DataValidation, XL.Sheet.DataValidationSize and XL.Sheet.DataValidations functions.
Added XL.Table.IsAutoFilter and XL.Table.RemoveFilter functions.
Fixed a possible crash in GMImage.DrawPath function.
Fixed an issue on Linux where Barcode.Generate didn't create a picture due to a link issue using the wrong zint library version (broken in 16.2).
Fixed an issue with JSON.InsertRecord crashing when you have illegal type mismatches in the parameters.
Fixed DynaPDF.GetField to return the correct BBox.
Fixed memory leak in MongoDB.NowUTC, MongoDB.Time, MongoDB.ContainerToBinary and MongoDB.TextToBinary functions.
Fixed memory leaks in Llama.Tokenize and Llama.Detokenize functions.
Improved fmp: URL handling to work with newer version depending fmp URLs.
Improved Llama.Chat and Llama.Query to yield time after 1000 tokens.
Improved memory management for MongoDB functions.
Updated CURL library to version 8.20.0.
Updated DynaPDF to version 5.0.2.11.
Updated expat to version 2.8.1.
Updated jsoncons to version 1.7.0.
Updated lcms to version 2.19.1.
Updated LibXL to version 5.2.0.
Updated mongo-c-driver to version 2.3.0.
Updated Xcode to version 26.5.



New functions in documentation

Download Links: Download Mac dmg or Download Windows/Linux zip


Downloads at monkeybreadsoftware.com/filemaker/files/Prerelease/: 


You can subscribe to our FileMaker mailing list to get notified for new pre-release and release versions.</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-06-01/MBS_FileMaker_Plugin_version_1"><![CDATA[
                <img src="http://www.mbsplugins.de/image/fmplugin19.png" width="200" align="right">New in this prerelease of version 16.3 of the <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/">MBS FileMaker Plugin</a>:
<ul>

<li>Added <a rel="external" href="https://www.mbsplugins.eu/CNContactPickerCurrentProperties.shtml">CNContactPicker.CurrentProperties</a> function.</li>
<li>Added <a rel="external" href="https://www.mbsplugins.eu/CNContactPickerGetDisplayedKeys.shtml">CNContactPicker.GetDisplayedKeys</a> and <a rel="external" href="https://www.mbsplugins.eu/CNContactPickerSetDisplayedKeys.shtml">CNContactPicker.SetDisplayedKeys</a> functions.</li>
<li>Added Command-Option-T shortcut for the calculation editor to insert the current selected table occurrence in the popup menu into the text.</li>
<li>Added <a rel="external" href="https://www.mbsplugins.eu/CURLGetSizeDelivered.shtml">CURL.GetSizeDelivered</a> function.</li>
<li>Added flag 4 for <a rel="external" href="https://www.mbsplugins.eu/WebViewCreateWindow.shtml">WebView.CreateWindow</a> function to make the window a floating palette.</li>
<li>Added flags to return JSON for <a rel="external" href="https://www.mbsplugins.eu/SpeechRecognitionRecognize.shtml">SpeechRecognition.Recognize</a> function.</li>
<li>Added GridFS functions for <a rel="external" href="https://www.mbsplugins.eu/component_MongoDB.shtml" translate="no">MongoDB</a> functions: <a rel="external" href="https://www.mbsplugins.eu/MongoDBGridFSClose.shtml">MongoDB.GridFS.Close</a>, <a rel="external" href="https://www.mbsplugins.eu/MongoDBGridFSDrop.shtml">MongoDB.GridFS.Drop</a>, <a rel="external" href="https://www.mbsplugins.eu/MongoDBGridFSFind.shtml">MongoDB.GridFS.Find</a>, <a rel="external" href="https://www.mbsplugins.eu/MongoDBGridFSFindOne.shtml">MongoDB.GridFS.FindOne</a>, <a rel="external" href="https://www.mbsplugins.eu/MongoDBGridFSFindOneByFileName.shtml">MongoDB.GridFS.FindOneByFileName</a>, <a rel="external" href="https://www.mbsplugins.eu/MongoDBGridFSGetChunks.shtml">MongoDB.GridFS.GetChunks</a>, <a rel="external" href="https://www.mbsplugins.eu/MongoDBGridFSGetFiles.shtml">MongoDB.GridFS.GetFiles</a>, <a rel="external" href="https://www.mbsplugins.eu/MongoDBGridFSOpen.shtml">MongoDB.GridFS.Open</a>, <a rel="external" href="https://www.mbsplugins.eu/MongoDBGridFSRead.shtml">MongoDB.GridFS.Read</a>, <a rel="external" href="https://www.mbsplugins.eu/MongoDBGridFSRemove.shtml">MongoDB.GridFS.Remove</a>, <a rel="external" href="https://www.mbsplugins.eu/MongoDBGridFSRemoveByFileName.shtml">MongoDB.GridFS.RemoveByFileName</a> and <a rel="external" href="https://www.mbsplugins.eu/MongoDBGridFSWrite.shtml">MongoDB.GridFS.Write</a>.</li>
<li>Added JBIG2Lossy as option for <a rel="external" href="https://www.mbsplugins.eu/DynaPDFGetImage.shtml">DynaPDF.GetImage</a> function.</li>
<li>Added <a rel="external" href="https://www.mbsplugins.eu/KeychainAddGenericPassword.shtml">Keychain.AddGenericPassword</a>, <a rel="external" href="https://www.mbsplugins.eu/KeychainDeleteGenericPassword.shtml">Keychain.DeleteGenericPassword</a>, <a rel="external" href="https://www.mbsplugins.eu/KeychainFindGenericPassword.shtml">Keychain.FindGenericPassword</a>, <a rel="external" href="https://www.mbsplugins.eu/KeychainListGenericPasswords.shtml">Keychain.ListGenericPasswords</a> and <a rel="external" href="https://www.mbsplugins.eu/KeychainUpdateGenericPassword.shtml">Keychain.UpdateGenericPassword</a> functions.</li>
<li>Added PageRanges, PrinterName, PagesPerSide, Copies, Collation, ColorMode and Duplex parameters for <a rel="external" href="https://www.mbsplugins.eu/WebViewSetPrintParameter.shtml">WebView.SetPrintParameter</a> function on Windows.</li>
<li>Added <a rel="external" href="https://www.mbsplugins.eu/PrinterCancelJob.shtml">Printer.CancelJob</a> and <a rel="external" href="https://www.mbsplugins.eu/PrinterGetJobsAsJSON.shtml">Printer.GetJobsAsJSON</a> functions.</li>
<li>Added width and height for <a rel="external" href="https://www.mbsplugins.eu/DynaPDFGetField.shtml">DynaPDF.GetField</a> to ask for field size.</li>
<li>Added <a rel="external" href="https://www.mbsplugins.eu/XLSheetAutoFilter.shtml">XL.Sheet.AutoFilter</a>.GetSortEx and <a rel="external" href="https://www.mbsplugins.eu/XLSheetAutoFilter.shtml">XL.Sheet.AutoFilter</a>.SortLevels functions.</li>
<li>Added <a rel="external" href="https://www.mbsplugins.eu/XLSheetDataValidation.shtml">XL.Sheet.DataValidation</a>, <a rel="external" href="https://www.mbsplugins.eu/XLSheetDataValidationSize.shtml">XL.Sheet.DataValidationSize</a> and <a rel="external" href="https://www.mbsplugins.eu/XLSheetDataValidations.shtml">XL.Sheet.DataValidations</a> functions.</li>
<li>Added <a rel="external" href="https://www.mbsplugins.eu/XLTableIsAutoFilter.shtml">XL.Table.IsAutoFilter</a> and <a rel="external" href="https://www.mbsplugins.eu/XLTableRemoveFilter.shtml">XL.Table.RemoveFilter</a> functions.</li>
<li>Fixed a possible crash in <a rel="external" href="https://www.mbsplugins.eu/GMImageDrawPath.shtml">GMImage.DrawPath</a> function.</li>
<li>Fixed an issue on Linux where <a rel="external" href="https://www.mbsplugins.eu/BarcodeGenerate.shtml">Barcode.Generate</a> didn't create a picture due to a link issue using the wrong zint library version (broken in 16.2).</li>
<li>Fixed an issue with <a rel="external" href="https://www.mbsplugins.eu/JSONInsertRecord.shtml">JSON.InsertRecord</a> crashing when you have illegal type mismatches in the parameters.</li>
<li>Fixed <a rel="external" href="https://www.mbsplugins.eu/DynaPDFGetField.shtml">DynaPDF.GetField</a> to return the correct BBox.</li>
<li>Fixed memory leak in <a rel="external" href="https://www.mbsplugins.eu/MongoDBNowUTC.shtml">MongoDB.NowUTC</a>, <a rel="external" href="https://www.mbsplugins.eu/MongoDBTime.shtml">MongoDB.Time</a>, <a rel="external" href="https://www.mbsplugins.eu/MongoDBContainerToBinary.shtml">MongoDB.ContainerToBinary</a> and <a rel="external" href="https://www.mbsplugins.eu/MongoDBTextToBinary.shtml">MongoDB.TextToBinary</a> functions.</li>
<li>Fixed memory leaks in <a rel="external" href="https://www.mbsplugins.eu/LlamaTokenize.shtml">Llama.Tokenize</a> and <a rel="external" href="https://www.mbsplugins.eu/LlamaDetokenize.shtml">Llama.Detokenize</a> functions.</li>
<li>Improved fmp: URL handling to work with newer version depending fmp URLs.</li>
<li>Improved <a rel="external" href="https://www.mbsplugins.eu/LlamaChat.shtml">Llama.Chat</a> and <a rel="external" href="https://www.mbsplugins.eu/LlamaQuery.shtml">Llama.Query</a> to yield time after 1000 tokens.</li>
<li>Improved memory management for <a rel="external" href="https://www.mbsplugins.eu/component_MongoDB.shtml" translate="no">MongoDB</a> functions.</li>
<li>Updated CURL library to version 8.20.0.</li>
<li>Updated DynaPDF to version 5.0.2.11.</li>
<li>Updated expat to version 2.8.1.</li>
<li>Updated jsoncons to version 1.7.0.</li>
<li>Updated lcms to version 2.19.1.</li>
<li>Updated LibXL to version 5.2.0.</li>
<li>Updated mongo-c-driver to version 2.3.0.</li>
<li>Updated Xcode to version 26.5.</li>

</ul>

<p><a rel="external" href="https://www.mbsplugins.eu/newinversion162.shtml">New functions in documentation</a></p>

<p>Download Links: <a rel="external" href="https://monkeybreadsoftware.com/cgi-bin/prerelease.php?type=filemaker&format=dmg&cdn=1" download>Download Mac dmg</a> or <a rel="external" href="https://monkeybreadsoftware.com/cgi-bin/prerelease.php?type=filemaker&format=zip&cdn=1" download>Download Windows/Linux zip</a></p>

<br  clear="all" />
<p>Downloads at <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/files/Prerelease/">monkeybreadsoftware.com/filemaker/files/Prerelease/</a>: </p>
<br  clear="all" />

<p>You can subscribe to our <a rel="external" href="https://monkeybreadsoftware.com/mbsfmplugin" title="">FileMaker mailing list</a> to get notified for new pre-release and release versions.</p>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>Announcing Saxon 13.0</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-05-30/Announcing_Saxon_130" />
		<updated>2026-05-31T19:00:00+02:00</updated>
		<published>2026-05-30T10:17:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6260</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">We got notice that Saxonica released the version 13.0 of their Saxon Library:



The first release of Saxon 13 has just been published. This is a new release
for Java, C#, C/C++, PHP, and Python. The highlights in this release are:



A redesigned Schema API that allows multiple schemas to coexist. You can now validate
an input document with one schema and the result with another, even for the same namespace.
More than 175 features from the draft 4.0 specifications are now available
in Saxon-PE and Saxon-EE, including:
  
    JNodes, path navigation over trees of JSON maps and arrays,
    Lookahead and lookbehind in regular expressions,
    Functions for CSV parsing,
    Functions for parsing with Invisible XML, and
    More flexible XML-to-JSON conversions with fn:element-to-map.
  

On the topic of 4.0,
  
    Mike recently published
    a list of 101 new things you can do with Saxon using 4.0 features!
    (For more information about 4.0, see QT4CG.)
  

Support for SaxonC extension functions written in C++, Python, and PHP.
SaxonCS-HE, our first release of the free Saxon HE product built for .NET with C#.


For more details, please consult
the documentation.


If you encounter any issues with Saxon 13.0, please
report them
on our issue tracker.



Our MBS Plugins include Saxon 12.9 currently. We will soon review the new version and integrate it into MBS Plugins. 
If any issues prevent that, we may report them and wait for the 13.1 version.

Our Saxon integration for FileMaker and Xojo is a powerful add-on to use  XLST 3.0, XPath 3.1 and XQuery 3.1 in your solutions.</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-05-30/Announcing_Saxon_130"><![CDATA[
                <p>We got notice that <a rel="external" href="https://www.saxonica.com">Saxonica</a> released the version 13.0 of their Saxon Library:</p>

<blockquote>

<p>The first release of Saxon 13 has just been published. This is a new release
for Java, C#, C/C++, PHP, and Python. The highlights in this release are:
</p>

<ul>
<li>A redesigned Schema API that allows multiple schemas to coexist. You can now validate
an input document with one schema and the result with another, even for the same namespace.</li>
<li>More than 175 features from the draft 4.0 specifications are now available
in Saxon-PE and Saxon-EE, including:
  <ul>
    <li>JNodes, path navigation over trees of JSON maps and arrays,</li>
    <li>Lookahead and lookbehind in regular expressions,</li>
    <li>Functions for CSV parsing,</li>
    <li>Functions for parsing with <a rel="external" href="https://invisiblexml.org/">Invisible XML</a>, and</li>
    <li>More flexible XML-to-JSON conversions with <code>fn:element-to-map</code>.</li>
  </ul>
</li>
<li>On the topic of 4.0,
  <ul>
    <li>Mike <a rel="external" href="https://blog.saxonica.com/mike/2026/05/101-things-in-QT4.html">recently published</a>
    a list of <em>101 new things</em> you can do with Saxon using 4.0 features!</li>
    <li>(For more information about 4.0, see <a rel="external" href="https://qt4cg.org/">QT4CG</a>.)</li>
  </ul>
</li>
<li>Support for SaxonC extension functions written in C++, Python, and PHP.</li>
<li>SaxonCS-HE, our first release of the free Saxon HE product built for .NET with C#.</li>
</ul>

<p>For more details, please consult
<a rel="external" href="https://www.saxonica.com/documentation13">the documentation</a>.
</p>

<p>If you encounter any issues with Saxon 13.0, please
<a rel="external" href="https://saxonica.plan.io/projects/saxon/issues">report them</a>
on our issue tracker.</p>

</blockquote>

<p>Our MBS Plugins include Saxon 12.9 currently. We will soon review the new version and integrate it into MBS Plugins. 
If any issues prevent that, we may report them and wait for the 13.1 version.</p>

<p>Our Saxon integration for FileMaker and Xojo is a powerful add-on to use  XLST 3.0, XPath 3.1 and XQuery 3.1 in your solutions.</p>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>FM meets Mozart: FileMaker conference in Salzburg, Austria</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-05-28/FM_meets_Mozart_FileMaker_conf" />
		<updated>2026-05-28T09:06:00+02:00</updated>
		<published>2026-05-28T08:55:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6259</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">Following the cancellation of the FMK FileMaker Conference 2026, a low-cost alternative has been organized at short notice for the community: “FM meets Mozart.” The conference will take place from September 14 to 16, 2026, at the famous Mozarteum in Salzburg and is aimed at users and developers from the German-speaking FileMaker community.



The new event is designed as a community conference and will feature presentations and workshops on FileMaker, AI, interfaces, APIs, and cloud solutions. According to the event website, details of the program are currently being finalized. A three-day ticket costs €149.00 plus 20% Austrian VAT; participants are responsible for booking their own hotel accommodations and travel arrangements.

The event organizer, Bernhard Schulz, lives in Salzburg. He served on the board of the “FMK Association” until 2020 and, in addition to his work as a developer, regularly organizes successful business events. Jan Rüdiger had initially planned to organize the FMK event for Salzburg in 2026 with his own team. However, the event had to be canceled due to low registration numbers. To ensure that the community still has a top-notch gathering in Salzburg in September 2026, Bernhard Schulz stepped in at short notice with a streamlined concept, thanks to his extensive network in Salzburg. The “traditional” FMK remains unaffected by this and, as things stand, is scheduled to take place in Hamburg in September 2027.

The “FM meets Mozart” series kicks off on Monday, September 14, 2026, at 7:00 p.m. with the FMM Awards ceremony, hosted by Klemens Kegebein, at the Augustiner Bräu Kloster Mülln in Salzburg. A classic Bräustübl buffet will follow.

Visit the website: fm-meets-mozart.net

Auf Deutsch beim FileMaker Magazin</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-05-28/FM_meets_Mozart_FileMaker_conf"><![CDATA[
                <img src="https://fm-meets-mozart.net/assets/img/logo.svg" width="180" height="40" align="left">Following the cancellation of the FMK FileMaker Conference 2026, a low-cost alternative has been organized at short notice for the community: “<a rel="external" href="https://fm-meets-mozart.net/" title="">FM meets Mozart</a>.” The conference will take place from September 14 to 16, 2026, at the famous Mozarteum in Salzburg and is aimed at users and developers from the German-speaking FileMaker community.<br />
<br />
<img src="https://filemaker-magazin.de/assets/1/3220/Salzburg_mit_Mozarteum_700px.png?1779898788" width="700"><br />
<br />
The new event is designed as a community conference and will feature presentations and workshops on FileMaker, AI, interfaces, APIs, and cloud solutions. According to the event website, details of the program are currently being finalized. A three-day ticket costs €149.00 plus 20% Austrian VAT; participants are responsible for booking their own hotel accommodations and travel arrangements.<br />
<br />
The event organizer, Bernhard Schulz, lives in Salzburg. He served on the board of the “FMK Association” until 2020 and, in addition to his work as a developer, regularly organizes successful business events. Jan Rüdiger had initially planned to organize the FMK event for Salzburg in 2026 with his own team. However, the event had to be canceled due to low registration numbers. To ensure that the community still has a top-notch gathering in Salzburg in September 2026, Bernhard Schulz stepped in at short notice with a streamlined concept, thanks to his extensive network in Salzburg. The “traditional” FMK remains unaffected by this and, as things stand, is scheduled to take place in Hamburg in September 2027.<br />
<br />
The “FM meets Mozart” series kicks off on Monday, September 14, 2026, at 7:00 p.m. with the FMM Awards ceremony, hosted by Klemens Kegebein, at the Augustiner Bräu Kloster Mülln in Salzburg. A classic Bräustübl buffet will follow.<br />
<br />
Visit the website: <a rel="external" href="https://fm-meets-mozart.net/">fm-meets-mozart.net</a><br />
<br />
<a rel="external" href="https://filemaker-magazin.de/neuigkeit/4320-FM-meets-Mozart--FileMaker-Community-Konferenz-in-Salzburg" lang="de">Auf Deutsch beim FileMaker Magazin</a>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>Create PDF/UA with DynaPDF in FileMaker</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-05-27/Create_PDFUA_with_DynaPDF_in_F" />
		<updated>2026-05-27T07:57:00+02:00</updated>
		<published>2026-05-27T07:57:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6258</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">Accessible PDF documents are becoming increasingly important for government agencies, educational institutions, and companies that want to ensure their documents can be used by everyone, including people using assistive technologies like screen readers.
With the MBS FileMaker Plugin and the integrated DynaPDF library, you can create PDF/UA compliant documents directly from FileMaker.

What is PDF/UA?
PDF/UA stands for “PDF Universal Accessibility”. It is an ISO standard (ISO 14289) that defines how to create accessible PDF documents.
A normal PDF often contains only visual information. A human reader can see headings, paragraphs, tables, or image captions, but a screen reader cannot automatically understand the structure unless the PDF also contains semantic information.
PDF/UA solves this problem by adding structure information and accessibility metadata to the PDF document.</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-05-27/Create_PDFUA_with_DynaPDF_in_F"><![CDATA[
                <p>Accessible PDF documents are becoming increasingly important for government agencies, educational institutions, and companies that want to ensure their documents can be used by everyone, including people using assistive technologies like screen readers.</p>
<p>With the <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/">MBS FileMaker Plugin</a> and the integrated <a rel="external" href="https://www.mbsplugins.eu/component_DynaPDF.shtml" translate="no">DynaPDF</a> library, you can create PDF/UA compliant documents directly from FileMaker.</p>

<h3>What is PDF/UA?</h3>
<p>PDF/UA stands for “PDF Universal Accessibility”. It is an ISO standard (ISO 14289) that defines how to create accessible PDF documents.</p>
<p>A normal PDF often contains only visual information. A human reader can see headings, paragraphs, tables, or image captions, but a screen reader cannot automatically understand the structure unless the PDF also contains semantic information.</p>
<p>PDF/UA solves this problem by adding structure information and accessibility metadata to the PDF document.</p><p>A PDF/UA document typically includes:</p>
<ul>
<li>A document language</li>
<li>A structure tree</li>
<li>Tagged content</li>
<li>Accessible reading order</li>
<li>Alternative text for images</li>
<li>Proper heading hierarchy</li>
<li>Unicode text mapping</li>
<li>Metadata and viewer preferences</li>
</ul>
<p>In practice this means a screen reader can identify whether text is:</p>
<ul>
<li>A heading</li>
<li>A paragraph</li>
<li>A list</li>
<li>A table</li>
<li>A quotation</li>
<li>A figure</li>
<li>A label</li>
<li>Or other semantic content</li>
</ul>
<p>Instead of just placing text visually on a page, you describe the meaning of the content.</p>

<h3>Creating PDF/UA in FileMaker</h3>
<p>The <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/">MBS FileMaker Plugin</a> provides access to the <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/dynapdf.shtml">DynaPDF library</a>, which supports Tagged PDF and PDF/UA generation.</p>
<p>Compared to creating a normal PDF, only a few additional steps are required:</p>
<ul>
<li>Enable the document title display</li>
<li>Define the document language</li>
<li>Create the structure tree</li>
<li>Use the PDF/UA version</li>
<li>Add semantic tags around content</li>
</ul>
<p>The most important concept is tagging content with OpenTag and CloseTag.</p>
<p>For example:</p>
<ul>
<li>Headings use H1, H2, H3…</li>
<li>Paragraphs use P</li>
<li>Lists use L</li>
<li>Table structures use Table, TR, TH, and TD</li>
</ul>
<p>Without these tags, the PDF may still look correct visually, but it will not be accessible.</p>

<h3>Simple PDF/UA Example</h3>
<p>Here is a minimal example for generating a tagged PDF/UA document in FileMaker:</p>
<pre><code class="language-FileMaker">Set Variable [ $pdf ; Value: MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFNew.shtml">DynaPDF.New</a>&quot; ) ]

Set Variable [ $path ; Value: MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/PathAddPathComponent.shtml">Path.AddPathComponent</a>&quot;; MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/FoldersUserDesktop.shtml">Folders.UserDesktop</a>&quot; ); &quot;Create PDF.pdf&quot; ) ]

Set Variable [ $r ; Value: MBS( &quot;DynaPDF.CreateNewPDF&quot;; $pdf; $path ) ]

# We want to use top-down coordinates
Set Variable [ $r ; Value: MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFSetPageCoords.shtml">DynaPDF.SetPageCoords</a>&quot;; $pdf; &quot;TopDown&quot; ) ]

# Required: Display document title
Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFSetViewerPreferences.shtml">DynaPDF.SetViewerPreferences</a>&quot;;
        $pdf;
        &quot;DisplayDocTitle&quot;;
        &quot;None&quot;
    )
]

# Required: Set document language
Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFSetLanguage.shtml">DynaPDF.SetLanguage</a>&quot;;
        $pdf;
        &quot;en-EN&quot;
    )
]

# Required for Tagged PDF
Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFCreateStructureTree.shtml">DynaPDF.CreateStructureTree</a>&quot;;
        $pdf
    )
]

# Enable PDF/UA mode
Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFSetPDFVersion.shtml">DynaPDF.SetPDFVersion</a>&quot;;
        $pdf;
        &quot;PDF/UA-1&quot;
    )
]

Set Variable [ $r ; Value:MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFAppendPage.shtml">DynaPDF.AppendPage</a>&quot;; $pdf ) ]

Set Variable [ $pageWidth ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFGetPageWidth.shtml">DynaPDF.GetPageWidth</a>&quot;; $pdf )
]

Set Variable [ $pageHeight ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFGetPageHeight.shtml">DynaPDF.GetPageHeight</a>&quot;; $pdf )
]

Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFSetTextRect.shtml">DynaPDF.SetTextRect</a>&quot;;
        $pdf;
        50;
        50;
        $pageWidth - 100;
        $pageHeight - 100
    )
]

# Set font
Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFSetFont.shtml">DynaPDF.SetFont</a>&quot;;
        $pdf;
        &quot;Arial&quot;;
        0;
        12;
        True
    )
]

# Open paragraph tag
Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFOpenTag.shtml">DynaPDF.OpenTag</a>&quot;;
        $pdf;
        &quot;P&quot;;
        &quot;&quot;;
        &quot;&quot;;
        &quot;&quot;
    )
]

# Write tagged text
Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFWriteFText.shtml">DynaPDF.WriteFText</a>&quot;;
        $pdf;
        &quot;Left&quot;;
        &quot;Hello World&quot; &amp; ¶ &amp; &quot;Second line&quot;
    )
]

# Close paragraph tag
Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFCloseTag.shtml">DynaPDF.CloseTag</a>&quot;;
        $pdf
    )
]

# Close page, then file and free memory
Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFEndPage.shtml">DynaPDF.EndPage</a>&quot;;
        $pdf
    )
]

Set Variable [ $r ; Value:
    MBS( &quot;DynaPDF.CloseFile&quot;;
        $pdf
    )
]

Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFRelease.shtml">DynaPDF.Release</a>&quot;;
        $pdf
    )
]
</code></pre>
<h3>Understanding the Structure Tree</h3>
<p>A Tagged PDF internally contains a structure tree. This tree defines the logical structure of the document.</p>
<p>For example:</p>
<ul>
<li>Document
<ul>
<li>H1</li>
<li>P</li>
<li>P</li>
<li>H2</li>
<li>P</li>
<li>Table</li>
</ul>
</li>
</ul>
<p>Each visible element on the page is connected to a semantic tag.</p>
<p>The call to:</p>
<pre><code class="language-FileMaker">MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFCreateStructureTree.shtml">DynaPDF.CreateStructureTree</a>&quot;; $pdf )
</code></pre>
<p>creates the root structure node for the document.</p>
<p>After that, every OpenTag/CloseTag pair adds content into this structure hierarchy.</p>
<h3>Adding Headings</h3>
<p>For accessibility, headings are very important because screen readers use them for navigation.</p>
<p>Example:</p>
<pre><code class="language-FileMaker"># Heading level 1
Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFOpenTag.shtml">DynaPDF.OpenTag</a>&quot;;
        $pdf;
        &quot;H1&quot;;
        &quot;&quot;;
        &quot;&quot;;
        &quot;&quot;
    )
]

Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFWriteText.shtml">DynaPDF.WriteText</a>&quot;;
        $pdf;
        50;
        50;
        &quot;Invoice&quot;
    )
]

Set Variable [ $r ; Value:
    MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFCloseTag.shtml">DynaPDF.CloseTag</a>&quot;;
        $pdf
    )
]
</code></pre>
<p>You should use heading levels in the correct order:</p>
<ul>
<li>H1 for the main title</li>
<li>H2 for sections</li>
<li>H3 for subsections</li>
</ul>
<p>Avoid skipping heading levels.</p>
<h3>Alternative Text for Images</h3>
<p>Images should include alternative descriptions so screen readers can explain their meaning.</p>
<p>For decorative images, you may mark them as artifacts instead.</p>
<p>Example image tag structure:</p>
<pre><code class="language-FileMaker">MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFOpenTag.shtml">DynaPDF.OpenTag</a>&quot;; $pdf; &quot;Figure&quot;; &quot;&quot;; &quot;&quot;; &quot;&quot; )
</code></pre>
<p>Then attach alternative text to the structure element.</p>
<p>This becomes especially important for charts, logos, diagrams, and icons.</p>
<h3>Debugging PDF/UA Files</h3>
<p>While developing accessible PDFs, debugging can help a lot.</p>
<p>For example, disabling compression makes it easier to inspect the PDF source code in a text editor:</p>
<pre><code class="language-FileMaker">MBS( &quot;<a rel="external" href="https://www.mbsplugins.eu/DynaPDFSetCompressionLevel.shtml">DynaPDF.SetCompressionLevel</a>&quot;; $pdf; 0 )
</code></pre>
<p>You can then search for:</p>
<ul>
<li>Structure tags</li>
<li>Marked content</li>
<li>Metadata</li>
<li>Language definitions</li>
</ul>
<h3>Validation Tools</h3>
<p>Creating a Tagged PDF does not automatically guarantee PDF/UA compliance.</p>
<p>You should validate your generated files with accessibility checking tools such as:</p>
<ul>
<li>PAC (PDF Accessibility Checker)</li>
<li>Adobe Acrobat accessibility tools</li>
<li>veraPDF</li>
</ul>
<p>These tools can identify:</p>
<ul>
<li>Missing tags</li>
<li>Invalid reading order</li>
<li>Missing alternative text</li>
<li>Incorrect metadata</li>
<li>Font encoding problems</li>
</ul>
<p>Things to Watch Out For
Some common PDF/UA issues include:</p>
<ul>
<li>Missing document language</li>
<li>Untagged content</li>
<li>Missing Unicode mappings</li>
<li>Incorrect reading order</li>
<li>Tables without TH cells</li>
<li>Images without alt text</li>
<li>Decorative elements not marked as artifacts</li>
</ul>
<p>Accessibility is often less about visual appearance and more about semantic structure.</p>
<h3>Conclusion</h3>
<p>With only a few additional function calls, DynaPDF allows you to generate accessible PDF/UA documents directly from FileMaker.</p>
<p>The key steps are:</p>
<ul>
<li>Create the structure tree</li>
<li>Set PDF/UA mode</li>
<li>Define language and viewer preferences</li>
<li>Add semantic tags around content</li>
</ul>
<p>Once you start thinking in terms of document structure instead of only page layout, generating accessible PDFs becomes quite straightforward.</p>

<p>See an <a rel="external" href="https://www.mbsplugins.eu/MBS-FileMaker-Plugin-Examples/DynaPDF/Create%20Text%20as%20PDFA.shtml#2ScriptAnchor_">example script</a> in <a rel="external" href="https://www.mbsplugins.eu/MBS-FileMaker-Plugin-Examples/DynaPDF/Create%20Text%20as%20PDFA.shtml">Create Text as PDF/A</a> example database.</p>

<p>Please try it and let us know if you have questions.</p>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>MBS Xojo Conference 2026 - Auto Reports — run Reports in your Sleep</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-05-26/MBS_Xojo_Conference_2026_-_Aut" />
		<updated>2026-05-26T08:07:00+02:00</updated>
		<published>2026-05-26T08:07:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6257</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">We recorded the presentations at the MBS Xojo Conference in April 2026 and here is the MBS Plugin presentation with David Cox:  

Auto Reports — run Reports in your Sleep

Xojo is very useful for creating databases and reporting your data to the screen, a PDF, an email or a printer. Users often need to run these reports daily, weekly or monthly. But this can be a problem when staff are sick, on holidays, just too busy, we forget or when the number of reports gets too large.
Auto Reports are normal Xojo reports where your Xojo application runs the reports themselves automatically based on a time or database trigger, then send the results to email or SMS with no human intervention.
If you charge for your reports, you can have them delivered even when you are away from your computer, support more clients than you could manually manage and even have your invoices sent automatically.





Watch on YouTube. All videos go into the playlist for the conference.</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-05-26/MBS_Xojo_Conference_2026_-_Aut"><![CDATA[
                <p>We recorded the presentations at the <a rel="external" href="https://www.monkeybreadsoftware.de/xojo/events/andernach-2026-event.shtml" title="">MBS Xojo Conference</a> in April 2026 and here is the MBS Plugin presentation with David Cox:  </p>

<p><b>Auto Reports — run Reports in your Sleep</b>
<p>
Xojo is very useful for creating databases and reporting your data to the screen, a PDF, an email or a printer. Users often need to run these reports daily, weekly or monthly. But this can be a problem when staff are sick, on holidays, just too busy, we forget or when the number of reports gets too large.
Auto Reports are normal Xojo reports where your Xojo application runs the reports themselves automatically based on a time or database trigger, then send the results to email or SMS with no human intervention.
If you charge for your reports, you can have them delivered even when you are away from your computer, support more clients than you could manually manage and even have your invoices sent automatically.</p>


<a rel="external" href="https://youtu.be/16HPRFHzRyA"><img src="http://www.mbsplugins.de/image/MBS-Xojo-Conference-David-Cox3.jpg" width="960"></a>


<p><a rel="external" href="https://youtu.be/16HPRFHzRyA">Watch on YouTube</a>. All videos go into the <a rel="external" href="https://www.youtube.com/playlist?list=PLvH3LgGie0XNbarXTLF5sKq34xLU6j4lG">playlist</a> for the conference.</p>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>Using DynaPDF with Data API for PDF generation</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-05-25/Using_DynaPDF_with_Data_API_fo" />
		<updated>2026-05-25T10:32:00+02:00</updated>
		<published>2026-05-25T10:21:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6256</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">Did you know that you can use MBS FileMaker Plugin in the Data API and provide an API to the outside world to produce PDFs?



You can have an external request come in to start a script, have the script create a PDF based on the given script parameters and then store it in a contaner field. Then another call can download that specific PDF from the container field. We use a global field here for the temporary storage. On a server script, global fields act like global variables and each session has their own one. So unless you prefer to store the PDF in a new record, you could simply use a global field to keep it until the session is finished.



Let's start with installation. The MBS FileMaker Plugin and the dynapdf library files go into the /FileMaker Server/Web Publishing/publishing-engine/wip/Plugins/ folder. After you copied the plugin there, you need to restart the wip process for Data API to have it load it. Once loaded you see a new log file in the Logs folder. When the dynapdf library is in the same folder as the plugin, we can load it with "" as path. If you registered the MBS server license before on the scripting engine, the MBS FileMaker Plugin for Data API should pick that up. But it is always good to have an MBS register script to apply the license if IsRegistered functions returns a zero.</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-05-25/Using_DynaPDF_with_Data_API_fo"><![CDATA[
                <p>
Did you know that you can use <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/">MBS FileMaker Plugin</a> in the Data API and provide an API to the outside world to produce PDFs?
</p>

<p>
You can have an external request come in to start a script, have the script create a PDF based on the given script parameters and then store it in a contaner field. Then another call can download that specific PDF from the container field. We use a global field here for the temporary storage. On a server script, global fields act like global variables and each session has their own one. So unless you prefer to store the PDF in a new record, you could simply use a global field to keep it until the session is finished.
</p>

<p>
Let's start with installation. The <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/">MBS FileMaker Plugin</a> and the dynapdf library files go into the <code>/FileMaker Server/Web Publishing/publishing-engine/wip/Plugins/</code> folder. After you copied the plugin there, you need to restart the wip process for Data API to have it load it. Once loaded you see a new log file in the Logs folder. When the dynapdf library is in the same folder as the plugin, we can load it with "" as path. If you registered the MBS server license before on the scripting engine, the <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/">MBS FileMaker Plugin</a> for Data API should pick that up. But it is always good to have an MBS register script to apply the license if IsRegistered functions returns a zero.</p><p>Here is a sample script to make a PDF with text from the script parameter:</p>
<style>
pre
{
	overflow: scroll;
}
</style>
<div style="white-space:pre; color: #660066; "><span style="color: #004d00"># Initialize DynaPDF if needed</span>
<span style="color: #0066ff">If [ MBS("<a rel="external" href="https://www.mbsplugins.eu/DynaPDFIsInitialized.shtml">DynaPDF.IsInitialized</a>")  ≠  1 ]</span>
<span style="color: #0099ff">	Perform Script [ “InitDynaPDF” ; Specified: From list ; Parameter:    ]</span>
<span style="color: #0066ff">End If</span>
<span style="color: #004d00"># </span>
<span style="color: #008e00">Go to Layout [ “Asset Details” (Assets) ; Animation: None ]</span>
<span style="color: #004d00"># 
# Start with a new PDF document</span>
Set Variable [ $pdf ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/DynaPDFNew.shtml">DynaPDF.New</a>") ]
<span style="color: #004d00"># Add page</span>
Set Variable [ $r ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/DynaPDFAppendPage.shtml">DynaPDF.AppendPage</a>"; $pdf) ]
Set Variable [ $r ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/DynaPDFSetPageCoords.shtml">DynaPDF.SetPageCoords</a>"; $pdf; "topdown") ]
Set Variable [ $r ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/DynaPDFSetFont.shtml">DynaPDF.SetFont</a>"; $pdf; "Helvetica"; 0; 12) ]
<span style="color: #004d00"># Write some text</span>
Set Variable [ $text ; Value: "Parameter: " & Get(ScriptParameter) ]
Set Variable [ $r ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/DynaPDFSetFillColor.shtml">DynaPDF.SetFillColor</a>"; $pdf; 0; 0; 0) ]
Set Variable [ $r ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/DynaPDFWriteStyledTextEx.shtml">DynaPDF.WriteStyledTextEx</a>"; $pdf; 10; 10; 300; -1; "justify"; $Text) ]
<span style="color: #004d00"># now figure out how much space we needed to make the page the right size</span>
Set Variable [ $height ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/DynaPDFGetLastTextPosY.shtml">DynaPDF.GetLastTextPosY</a>"; $pdf) ]
Set Variable [ $ph ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/DynaPDFGetPageHeight.shtml">DynaPDF.GetPageHeight</a>"; $pdf) ]
Set Variable [ $r ; Value: MBS( "<a rel="external" href="https://www.mbsplugins.eu/DynaPDFSetBBox.shtml">DynaPDF.SetBBox</a>"; $PDF; "Media"; 0; $ph; 320; $height - 10 ) ]
<span style="color: #004d00"># close page, document and save PDF</span>
Set Variable [ $r ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/DynaPDFEndPage.shtml">DynaPDF.EndPage</a>"; $pdf) ]
Set Variable [ $Result ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/DynaPDFSave.shtml">DynaPDF.Save</a>"; $pdf; "hello.pdf") ]
Set Variable [ $r ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/DynaPDFRelease.shtml">DynaPDF.Release</a>"; $pdf) ]
<span style="color: #004d00"># Put in Container</span>
Set Field [ Assets::PDF ; $Result ]
<span style="color: #0099ff">Exit Script [ Text Result: "PDF Created" ]</span></div>

<p>Let's call this script from the outside. This could be in FileMaker again, but we could use the curl command line tool. We have to make the following API calls:</p>

<ol>
<li><p>We start by asking for a new session token. The query goes to the URL of our server, e.g. "https://10.211.55.16" for the local server here. Then we need to specify which database we use and what credentials we have. Also we need to pass some JSON with further options, but since we have none, this is just "{}".</p>

<pre>curl -s -k -X POST \
  "${BASE_URL}/fmi/data/v2/databases/${DATABASE}/sessions" \
  -H "Content-Type: application/json" \
  -u "${USERNAME}:${PASSWORD}" \
  -d "{}"</pre>
<p>From the result, we extract the session token.</p>
</li>
<li><p>We continue with triggering the script. This time we need to specify a layout and for this we made a specific PDFLayout, which only has the fields needed for the script. Here we can pass a parameter, which needs to be URL encoded. But you can pass JSON here if you need structured data.</p>

<pre>curl -s -k \
  "${BASE_URL}/fmi/data/v2/databases/${DATABASE}/layouts/${LAYOUT}/script/CreatePDF?script.param=${ENCODED_PARAM}" \
  -H "Authorization: Bearer ${TOKEN}</pre>

<p>The result should indicate the script run through and provide the script result. That allows the script to return the record ID for a new record or a JSON for more detailed structured response. In our case we return the PDF via a global field, so we don't need a record ID.</p>
</li>
</li>
<li><p>Time to query the first record to get the URL to download the PDF. We query the records and limit the output to one record. Since FileMaker likes to set a session cookie for the download of the PDF, we need to tell CURL to keep cookies.</p>

<pre>curl -s -k \
  "${BASE_URL}/fmi/data/v2/databases/${DATABASE}/layouts/${LAYOUT}/records?_limit=1" \
  -H "Authorization: Bearer ${TOKEN}" \
  -c "${COOKIE_FILE}</pre>

<p>The result is a JSON which contains the PDF download URL.</p>
  
</li>
<li><p>Once we have the URL, we do the download:</p>
<pre>curl -s -k \
  -H "Authorization: Bearer ${TOKEN}" \
  -b "${COOKIE_FILE}" \
  -o "${OUTPUT_FILE}" \
  "${PDF_URL}"</pre>

<p>This writes the PDF directly to the output file.</p>

</li>
<li><p>On the end of the script, we need to close the session, which also releases the global field:</p>

<pre>curl -s -k -X DELETE \
  "${BASE_URL}/fmi/data/v2/databases/${DATABASE}/sessions/${TOKEN}"</pre>

</ol>

<p>Here is a shell script doing all the steps in Terminal:</p>

<pre style="background-color: rgb(247, 247, 247); padding: 1em;"><code>
<span style="color: rgb(150, 122, 178);">#!/usr/bin/env bash
</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(0, 118, 129);">set</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">euo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(20, 20, 20);">pipefail</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(150, 122, 178);"># Configuration
</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(20, 20, 20);">BASE_URL</span><span style="color: rgb(20, 20, 20);">=</span><span style="color: rgb(189, 22, 107);">"https://10.211.55.16"</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(20, 20, 20);">DATABASE</span><span style="color: rgb(20, 20, 20);">=</span><span style="color: rgb(189, 22, 107);">"Assets"</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(20, 20, 20);">LAYOUT</span><span style="color: rgb(20, 20, 20);">=</span><span style="color: rgb(189, 22, 107);">"PDFLayout"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(20, 20, 20);">USERNAME</span><span style="color: rgb(20, 20, 20);">=</span><span style="color: rgb(189, 22, 107);">"user"</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(20, 20, 20);">PASSWORD</span><span style="color: rgb(20, 20, 20);">=</span><span style="color: rgb(189, 22, 107);">"user"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(20, 20, 20);">SCRIPT_PARAM</span><span style="color: rgb(20, 20, 20);">=</span><span style="color: rgb(189, 22, 107);">"Hello World"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(20, 20, 20);">COOKIE_FILE</span><span style="color: rgb(20, 20, 20);">=</span><span style="color: rgb(189, 22, 107);">"cookies.txt"</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(20, 20, 20);">OUTPUT_FILE</span><span style="color: rgb(20, 20, 20);">=</span><span style="color: rgb(189, 22, 107);">"test.pdf"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(150, 122, 178);"># Step 1: Create session and get token
</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Creating session..."</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(20, 20, 20);">SESSION_RESPONSE</span><span style="color: rgb(20, 20, 20);">=$(</span><span style="color: rgb(0, 118, 129);">curl</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">s</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">k</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">X</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(20, 20, 20);">POST</span><span style="color: rgb(20, 20, 20);"> \
  </span><span style="color: rgb(189, 22, 107);">"${BASE_URL}/fmi/data/v2/databases/${DATABASE}/sessions"</span><span style="color: rgb(20, 20, 20);"> \
  -</span><span style="color: rgb(20, 20, 20);">H</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Content-Type: application/json"</span><span style="color: rgb(20, 20, 20);"> \
  -</span><span style="color: rgb(20, 20, 20);">u</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${USERNAME}:${PASSWORD}"</span><span style="color: rgb(20, 20, 20);"> \
  -</span><span style="color: rgb(20, 20, 20);">d</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"{}"</span><span style="color: rgb(20, 20, 20);">)

</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Session response:"</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${SESSION_RESPONSE}"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(20, 20, 20);">TOKEN</span><span style="color: rgb(20, 20, 20);">=$(</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${SESSION_RESPONSE}"</span><span style="color: rgb(20, 20, 20);"> | </span><span style="color: rgb(0, 118, 129);">sed</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">n</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">'s/.*"token":"\([^"]*\)".*/\1/p'</span><span style="color: rgb(20, 20, 20);">)

</span><span style="color: rgb(56, 79, 244);">if</span><span style="color: rgb(20, 20, 20);"> <!-- snippet = _<slashspan><span style="color= is not defined because file doesn't exist -->; </span><span style="color: rgb(56, 79, 244);">then</span><span style="color: rgb(20, 20, 20);">
  </span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"ERROR: Could not extract token"</span><span style="color: rgb(20, 20, 20);">
  </span><span style="color: rgb(0, 118, 129);">exit</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(20, 20, 20);">1</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(56, 79, 244);">fi</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Token: ${TOKEN}"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(150, 122, 178);"># Step 2: Run FileMaker script
</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(20, 20, 20);">ENCODED_PARAM</span><span style="color: rgb(20, 20, 20);">=$(</span><span style="color: rgb(0, 118, 129);">printf</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">'%s'</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${SCRIPT_PARAM}"</span><span style="color: rgb(20, 20, 20);"> | </span><span style="color: rgb(0, 118, 129);">sed</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">'s/ /%20/g'</span><span style="color: rgb(20, 20, 20);">)

</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Running CreatePDF script..."</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(20, 20, 20);">SCRIPT_RESPONSE</span><span style="color: rgb(20, 20, 20);">=$(</span><span style="color: rgb(0, 118, 129);">curl</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">s</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">k</span><span style="color: rgb(20, 20, 20);"> \
  </span><span style="color: rgb(189, 22, 107);">"${BASE_URL}/fmi/data/v2/databases/${DATABASE}/layouts/${LAYOUT}/script/CreatePDF?script.param=${ENCODED_PARAM}"</span><span style="color: rgb(20, 20, 20);"> \
  -</span><span style="color: rgb(20, 20, 20);">H</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Authorization: Bearer ${TOKEN}"</span><span style="color: rgb(20, 20, 20);"> \
  -</span><span style="color: rgb(20, 20, 20);">c</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${COOKIE_FILE}"</span><span style="color: rgb(20, 20, 20);">)

</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Script response:"</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${SCRIPT_RESPONSE}"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(150, 122, 178);"># Step 3: Get one record and extract PDF URL
</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Fetching record..."</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(20, 20, 20);">RECORD_RESPONSE</span><span style="color: rgb(20, 20, 20);">=$(</span><span style="color: rgb(0, 118, 129);">curl</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">s</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">k</span><span style="color: rgb(20, 20, 20);"> \
  </span><span style="color: rgb(189, 22, 107);">"${BASE_URL}/fmi/data/v2/databases/${DATABASE}/layouts/${LAYOUT}/records?_limit=1"</span><span style="color: rgb(20, 20, 20);"> \
  -</span><span style="color: rgb(20, 20, 20);">H</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Authorization: Bearer ${TOKEN}"</span><span style="color: rgb(20, 20, 20);"> \
  -</span><span style="color: rgb(20, 20, 20);">c</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${COOKIE_FILE}"</span><span style="color: rgb(20, 20, 20);">)

</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Record response:"</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${RECORD_RESPONSE}"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(20, 20, 20);">PDF_URL</span><span style="color: rgb(20, 20, 20);">=$(</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${RECORD_RESPONSE}"</span><span style="color: rgb(20, 20, 20);"> | </span><span style="color: rgb(0, 118, 129);">sed</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">n</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">'s/.*"PDF":"\([^"]*\)".*/\1/p'</span><span style="color: rgb(20, 20, 20);">)

</span><span style="color: rgb(150, 122, 178);"># Unescape JSON escaped slashes
</span><span style="color: rgb(20, 20, 20);">PDF_URL</span><span style="color: rgb(20, 20, 20);">=$(</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${PDF_URL}"</span><span style="color: rgb(20, 20, 20);"> | </span><span style="color: rgb(0, 118, 129);">sed</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">'s#\\/#/#g'</span><span style="color: rgb(20, 20, 20);">)

</span><span style="color: rgb(56, 79, 244);">if</span><span style="color: rgb(20, 20, 20);"> <!-- snippet = _<slashspan><span style="color= is not defined because file doesn't exist -->; </span><span style="color: rgb(56, 79, 244);">then</span><span style="color: rgb(20, 20, 20);">
  </span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"ERROR: Could not extract PDF URL"</span><span style="color: rgb(20, 20, 20);">
  </span><span style="color: rgb(0, 118, 129);">exit</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(20, 20, 20);">1</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(56, 79, 244);">fi</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"PDF URL:"</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${PDF_URL}"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(150, 122, 178);"># Step 4: Download PDF
</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Downloading PDF..."</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(0, 118, 129);">curl</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">s</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">k</span><span style="color: rgb(20, 20, 20);"> \
  -</span><span style="color: rgb(20, 20, 20);">H</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Authorization: Bearer ${TOKEN}"</span><span style="color: rgb(20, 20, 20);"> \
  -</span><span style="color: rgb(20, 20, 20);">b</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${COOKIE_FILE}"</span><span style="color: rgb(20, 20, 20);"> \
  -</span><span style="color: rgb(20, 20, 20);">o</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${OUTPUT_FILE}"</span><span style="color: rgb(20, 20, 20);"> \
  </span><span style="color: rgb(189, 22, 107);">"${PDF_URL}"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"PDF downloaded to ${OUTPUT_FILE}"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(150, 122, 178);"># Step 5: Delete session
</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Deleting session..."</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(0, 118, 129);">curl</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">s</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">k</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">X</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(20, 20, 20);">DELETE</span><span style="color: rgb(20, 20, 20);"> \
  </span><span style="color: rgb(189, 22, 107);">"${BASE_URL}/fmi/data/v2/databases/${DATABASE}/sessions/${TOKEN}"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Session deleted"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(150, 122, 178);"># Step 6: Cleanup
</span><span style="color: rgb(150, 122, 178);"># -----------------------------------------------------------------------------
</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(0, 118, 129);">rm</span><span style="color: rgb(20, 20, 20);"> -</span><span style="color: rgb(20, 20, 20);">f</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"${COOKIE_FILE}"</span><span style="color: rgb(20, 20, 20);">

</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Cookies removed"</span><span style="color: rgb(20, 20, 20);">
</span><span style="color: rgb(0, 118, 129);">echo</span><span style="color: rgb(20, 20, 20);"> </span><span style="color: rgb(189, 22, 107);">"Done"</span><span style="color: rgb(20, 20, 20);">
</span></code></pre>

<p>When you run such a script, you see the following output:</p>

<pre>
Creating session...
Session response:
{"response":{"token":"5d203f8e9fa48ae10dda519ac3a79513b44ec1a7cc486d9f8a25"},"messages":[{"code":"0","message":"OK"}]}
Token: 5d203f8e9fa48ae10dda519ac3a79513b44ec1a7cc486d9f8a25
Running CreatePDF script...
Script response:
{"response":{"scriptResult":"PDF Created","scriptError":"0"},"messages":[{"code":"0","message":"OK"}]}
Fetching record...
Record response:
{
  "response": {
    "dataInfo": {
      "database": "Assets",
      "layout": "PDFLayout",
      "table": "Assets",
      "totalRecordCount": 25,
      "foundCount": 25,
      "returnedCount": 1
    },
    "data": [
      {
        "fieldData": {
          "PDF": "https://10.211.55.16:443/Streaming/MainDB/77C8957F305297674C98AF4F9DCF
           5847722CC4D1F525316A33B3412DAC81D9B7.pdf?RCType=EmbeddedRCFileProcessor"
        },
        "portalData": {},
        "recordId": "1",
        "modId": "25"
      }
    ]
  },
  "messages": [
    {
      "code": "0",
      "message": "OK"
    }
  ]
}
PDF URL:
https://10.211.55.16:443/Streaming/MainDB/77C8957F305297674C98AF4F9DCF
  5847722CC4D1F525316A33B3412DAC81D9B7.pdf?RCType=EmbeddedRCFileProcessor
Downloading PDF...
PDF downloaded to test.pdf
Deleting session...
{"response":{},"messages":[{"code":"0","message":"OK"}]}
Session deleted
Cookies removed
Done
</pre>

<p>Please try this. Generating PDF documents on the fly using Data API calls may be very useful. Especially if you use data in the database to fill the records. FileMaker may create a temporary PDF from some records and then you post process them with DynaPDF. e.g. adding page numbers, watermarks or signatures. And this could be called from a custom facing website to download receipts or confirmations on demand.</p>

<p>On the security note, please keep such an API to a separate file with specific logins and only the scripts, records and fields people should see from the outside. Don't let anyone access the whole solution and cause damage.</p>

<p>See also</p>

<table cellspacing="3" cellpadding="3">

<tbody><tr valign="top">
<td align="center" height="190" valign="top"><a rel="external" href="https://www.youtube.com/watch?v=q-hHh1GmOK0"><img src="https://www.monkeybreadsoftware.com/filemaker/video/q-hHh1GmOK0.jpg" width="256" height="144" alt="Thumbnail"></a><br  /><a rel="external" href="https://www.youtube.com/watch?v=q-hHh1GmOK0">DynaPDF Interview</a></td>

<td align="center" height="190" valign="top"><a rel="external" href="https://www.youtube.com/watch?v=mK8mmHaRxW8"><img src="https://www.monkeybreadsoftware.com/filemaker/video/mK8mmHaRxW8.jpg" width="256" height="144" alt="Thumbnail"></a><br  /><a rel="external" href="https://www.youtube.com/watch?v=mK8mmHaRxW8">Q&amp;A DynaPDF &amp; Search</a></td>

<td align="center" height="190" valign="top"><a rel="external" href="https://www.youtube.com/watch?v=2DiFv4rnp8U"><img src="https://www.monkeybreadsoftware.com/filemaker/video/2DiFv4rnp8U.jpg" width="256" height="144" alt="Thumbnail"></a><br  /><a rel="external" href="https://www.youtube.com/watch?v=2DiFv4rnp8U">DynaPDF in FileMaker</a></td>
</tr>
</tr>

</tbody></table>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>News from the MBS Xojo Plugins in version 26.2</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-05-22/News_from_the_MBS_Xojo_Plugins" />
		<updated>2026-05-22T09:02:00+02:00</updated>
		<published>2026-05-22T09:02:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6255</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">In this article I want to introduce you the new functionalities from the MBS Xojo Plugins in version 26.2.

DynaPDF
In this release, DynaPDF is all about the DynaPDF Content Parser.
As PDF documents contain pages with content streams, you may be interested to inspect the content with our DynaPDFParserMBS class. You open a PDF document, you import pages into memory and then parse the page. Once you parse them page, you can access the content objects. How this works and what posibilityies you have you learn in the new Article DynaPDF Content Parser. 


In DynaPDF, you can also embed tables. In this release, the SetColOrRowSpan methode from the DynaPDFTableMBS class allows you to specify the row height or column width of a cell in your table. In the parameters you first define the cell using its row and column numbers. Next, you specify the height or width of the cell. In the last parameter, you specify whether to use col span (true) or row span (false). 


DynaPDF has also recently updated its licensing system. In detail the DynaPDF Starter license now includes encryption, form fields, and digital signatures. Previously, these features were part of the Lite license. If you are interested in these and other updates, we recommend reading the article DynaPDF Starter License Extended and taking a look at the product feature matrix: DynaPDF Starter vs. Lite vs. Pro vs. Enterprise</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-05-22/News_from_the_MBS_Xojo_Plugins"><![CDATA[
                In this article I want to introduce you the new functionalities from the <a rel="external" href="https://www.monkeybreadsoftware.de/xojo/">MBS Xojo Plugins</a> in version 26.2.</p>

<h3>DynaPDF</h3>
<p>In this release, DynaPDF is all about the DynaPDF Content Parser.
As PDF documents contain pages with content streams, you may be interested to inspect the content with our <a rel="external" href="https://www.monkeybreadsoftware.net/class-dynapdfparsermbs.shtml">DynaPDFParserMBS</a> class. You open a PDF document, you import pages into memory and then parse the page. Once you parse them page, you can access the content objects. How this works and what posibilityies you have you learn in the new Article <a rel="external" href="https://www.mbsplugins.de/archive/2026-05-07/DynaPDF_Content_Parser/monkeybreadsoftware_blog_xojo">DynaPDF Content Parser</a>. 
</p>
<p>
In DynaPDF, you can also embed tables. In this release, the SetColOrRowSpan methode from the <a rel="external" href="https://www.monkeybreadsoftware.net/class-dynapdftablembs.shtml">DynaPDFTableMBS</a> class allows you to specify the row height or column width of a cell in your table. In the parameters you first define the cell using its row and column numbers. Next, you specify the height or width of the cell. In the last parameter, you specify whether to use col span (true) or row span (false). </p>

<p>
DynaPDF has also recently updated its licensing system. In detail the DynaPDF Starter license now includes encryption, form fields, and digital signatures. Previously, these features were part of the Lite license. If you are interested in these and other updates, we recommend reading the article <a rel="external" href="https://www.mbsplugins.de/archive/2026-05-02/DynaPDF_Starter_license_extend/monkeybreadsoftware_blog_xojo">DynaPDF Starter License Extended</a> and taking a look at the product feature matrix: <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/dynapdf-editions.shtml">DynaPDF Starter vs. Lite vs. Pro vs. Enterprise </a></p><h3> JSON </h3>
<p>In the last release, we introduced the ToToon method from the <a rel="external" href="https://www.monkeybreadsoftware.net/class-jsonmbs.shtml">JSONMBS</a> class, which converts JSON to TOON. TOON is an information format that is particularly well-suited for use with AI communication. It minimizes the number of tokens required for communication. Now, with the new version 26.2, we have added methods that convert TOON to JSON. We hope that the FromToon method, which allows you to pass Toon as text or as a memory block, will further simplify your work with AI.</p>

<h3>Barcodes</h3>
<p>We have added support for new barcode types in the ZXing library. If you want to specify which barcodes and barcode groups should be read you need the suitable integer that belongs to the typ. You can use the new shared methods, which return the appropriate integer constant for a given barcode format. You now have the option to choose between: All GS1, All Industrial, All Linear, All Matrix, All Readable, All Retail, Aztec, Aztec Code, Aztec Rune, Codabar, Code 128, Code 32, Code 39, Code 39 Extended, Code 39 Standard, Code 93, PDF417, DataBar, DataBar Expanded, DataBar Expanded Stacked, DataBar Limited, DataBar Omni, DataBar Stacked, DataBar Stacked Omni, Data Matrix, DX Film Edge, EAN-13, EAN-2, EAN-5, EAN-8, EAN/UPC, ISBN, ITF, ITF-14, MaxiCode, MicroPDF417, Micro QR Code, None of the barcodes, Other barcodes, Pharmazentralnummer, QR Code, QR Code Model 1 and Model 2, rMQR Code, UPC-A and UPC-E. </p><p>In addition to these shared methods, which return the individual integers corresponding to the types specified in the function, we also have a shared method called BarcodeFormatFromString, which returns the corresponding integer when provided with the barcode name.</p>

<pre>
Var f As Integer = <a rel="external" href="https://www.monkeybreadsoftware.net/module-zxingbarcodembs.shtml">ZxingBarcodeMBS</a>.BarcodeFormatFromString("EAN-13")
</pre>

<p>If you want to obtain an integer array containing multiple barcode types, use the BarcodeFormatsFromString method and separate the individual barcode types with a pipe. </p>

<pre>
Var formats() As Integer = <a rel="external" href="https://www.monkeybreadsoftware.net/module-zxingbarcodembs.shtml">ZxingBarcodeMBS</a>.BarcodeFormatsFromString("EAN-8|EAN-13")
</pre>

<p>You can then use this array again with the setFormats method. </p>

<p>You can also query the supported formats using the shared method supportedFormats. This returns an integer array containing the constants. You can then use BarcodeFormatsToString to convert these back into a list of barcode types. </p>

<p>MBS Plugins supports generating over 80 barcode types, so we made a new graphics to show a few common barcodes:</p>

<img src="http://www.mbsplugins.de/image/Barcodes.jpg" width="780" height="551">

<h3>Zip </h3>
<p>You can now use raw mode with the InitZip method from the <a rel="external" href="https://www.monkeybreadsoftware.net/class-zlibcompressmbs.shtml">ZLibCompressMBS</a> class. A Boolean parameter is now available for this purpose, allowing you to specify whether raw mode should be used. 
</p>

<h3> Phidget</h3>
<p>
There are also minor changes in the Phidget section. You can now read the maximum and minimum data rates in hertz from the MinDataRate and MaxDataRate properties of the <a rel="external" href="https://www.monkeybreadsoftware.net/class-phidgetgyroscopembs.shtml">PhidgetGyroscopeMBS</a> class. This class can be used in combination with a Phidget device that has a gyroscope chip integrated. 
</p>
<p>
With the new PortSupportsSetSpeed method from the <a rel="external" href="https://www.monkeybreadsoftware.net/class-phidgethubmbs.shtml">PhidgetHubMBS</a> class, you can also check whether the communication speed of the VINT port can be set. The same class also includes the new PortSupportsAutoSetSpeed method. It indicates whether this VINT port supports Auto Set Speed and returns the supported state.  
</p>

<h2>New functionalities for Mac</h2>
<p>The <a rel="external" href="https://www.monkeybreadsoftware.de/xojo/">MBS Xojo Plugins</a> in version 26.2 offers some more new features for Mac users.</p>

<h3> Natural Language </h3>
<p>
We've added a new section: Natural Languages. The classes in this section allow us to identify a string that is contextually similar to a given string, for example, to correct spelling errors. This is achieved through vector embeddings using built-in models on macOS/iOS. Feel free to take a look at the new classes: <a rel="external" href="https://www.monkeybreadsoftware.net/class-nlcontextualembeddingmbs.shtml">NLContextualEmbeddingMBS</a>, <a rel="external" href="https://www.monkeybreadsoftware.net/class-nlcontextualembeddingresultmbs.shtml">NLContextualEmbeddingResultMBS</a>, <a rel="external" href="https://www.monkeybreadsoftware.net/class-nlcontextualembeddingresultvectormbs.shtml">NLContextualEmbeddingResultVectorMBS</a>, <a rel="external" href="https://www.monkeybreadsoftware.net/class-nlembeddingmbs.shtml">NLEmbeddingMBS</a> and <a rel="external" href="https://www.monkeybreadsoftware.net/class-nlembeddingneighbormbs.shtml">NLEmbeddingNeighborMBS</a> 
</p>

<h3>Token Count </h3>
<p>Already last year, we introduced the Foundation Models section and have continued to expand it. The classes available in this section use Apple's own functionality to run a local large language model. Sometimes it can be important to determine how many tokens a query to an LLM contains. With the new tokenCount method, you can now do this. You can find the method in the <a rel="external" href="https://www.monkeybreadsoftware.net/class-systemlanguagemodelsmbs.shtml">SystemLanguageModelsMBS</a> and <a rel="external" href="https://www.monkeybreadsoftware.net/class-languagemodelsessionsmbs.shtml">LanguageModelSessionsMBS</a> classes. The method can process the prompt as text or as an object of the <a rel="external" href="https://www.monkeybreadsoftware.net/class-promptmbs.shtml">PromptMBS</a> class. 
</p>
<p>
The <a rel="external" href="https://www.monkeybreadsoftware.net/class-systemlanguagemodelsmbs.shtml">SystemLanguageModelsMBS</a> class also includes the new ContextSize property. From this, we can determine the maximum number of tokens our LLM supports in a session, including both input prompts and generated responses. 
</p>
<p>
If you're not done with AI yet, check out our article <a rel="external" href="https://www.mbsplugins.de/archive/2026-04-27/AI_Development_with_the_MBS_Xo/monkeybreadsoftware_blog_xojo">AI Development with the MBS Xojo Plugins</a> and discover everything the MBS plugin has to offer in terms of AI</a>. </p>

<img src="http://www.mbsplugins.de/image/FoundationModelsXojo.png" width="780">

<h3>QuickLook</h3>
<p> 
The <a rel="external" href="https://www.monkeybreadsoftware.net/class-qlpreviewpanelmbs.shtml">QLPreviewPanelMBS</a> class now includes two new events. The beginPreviewPanel event is triggered when the QuickLook preview panel starts, and the endPreviewPanel event is triggered when the preview panel ends.
</p>

<img src="http://www.mbsplugins.de/image/quicklook-screenshot.png" width="672">

<h3>Search Field</h3>
<p>We also have new features in the <a rel="external" href="https://www.monkeybreadsoftware.net/control-desktopnssearchfieldcontrolmbs.shtml">DesktopNSSearchFieldControlMBS</a> and <a rel="external" href="https://www.monkeybreadsoftware.net/control-nssearchfieldcontrolmbs.shtml">NSSearchFieldControlMBS</a> classes. First, we have the new events searchFieldDidEndSearching and searchFieldDidStartSearching. These fire when the search with the search field begins or is completed. Also new are the events cancelButtonRectForBounds, searchButtonRectForBounds, and searchTextRectForBounds. These events fire when the respective area to which they belong is modified. So, for example, if the bounding rectangle for the search button cell is changed, the searchButtonRectForBounds event fires. It provides us with the updated bounding rectangle to use for the search button. In addition, the <a rel="external" href="https://www.monkeybreadsoftware.net/class-nssearchfieldcellmbs.shtml">NSSearchFieldCellMBS</a> class contains methods that can trigger these events, as we can use cancelButtonRectForBounds, searchButtonRectForBounds, and searchTextRectForBounds to query the positioning of the individual areas. </p>

<h3>Text Attachments </h3>
<p>
We have also added a few new properties to the <a rel="external" href="https://www.monkeybreadsoftware.net/class-nstextattachmentmbs.shtml">NSTextAttachmentMBS</a> class. The contents property allows us to read the contents of a text attachment or set it as a memory block. With the new fileType property, we can specify the data type of the contents. You can define the bounds of the attachment in the bounds property as an object of the <a rel="external" href="https://www.monkeybreadsoftware.net/class-nsrectmbs.shtml">NSRectMBS</a> class. The image property returns an instance of the relevant image class that represents the contents of the text attachment object. 
</p>

<h2>New functionalities for Windows </h2>
<p>Last but not least we offer new features for Windows users</p>
<h3>UI Automation</h3>
<p>We're excited to announce a new set of UIAutomation classes for Xojo in the <a rel="external" href="https://www.monkeybreadsoftware.de/xojo/">MBS Xojo Plugins</a>—making it possible to automate and inspect user interfaces on Windows directly from your Xojo applications!
With these new classes, you can use Microsoft's UI Automation API to interact with elements of other Windows applications. We explain what this means for you in the article:<a rel="external" href="https://www.mbsplugins.de/archive/2026-04-15/Introducing_UIAutomation_Suppo/monkeybreadsoftware_blog_xojo"> Introducing UIAutomation Support in MBS Xojo Plugins</a> </p>

<h3> WebView </h3>


<p>We have added a new method called MoveFocus to the <a rel="external" href="https://www.monkeybreadsoftware.net/control-webview2controlmbs.shtml">WebView2ControlMBS</a> and <a rel="external" href="https://www.monkeybreadsoftware.net/control-desktopwebview2controlmbs.shtml">DesktopWebView2ControlMBS</a> classes , which allows us to direct focus to our WebView and its elements. WebView changes focus through user interaction, including selecting within a WebView or tabbing into it. For tabbing, the app runs MoveFocus with Next or Previous to align with Tab and Shift+Tab, respectively, when it determines that the WebView is the next tabsable element.</p>

<img src="http://www.mbsplugins.de/image/WebView2control.jpg" width="760">

<p>We hope you will also find some interesting new features. We wish you a lot of fun with <a rel="external" href="https://www.monkeybreadsoftware.de/xojo/">MBS Xojo Plugins</a> version 26.2. If you have any ideas for new cool features, need a license or have any questions, please contact us.</p>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>LibXL 5.2 released</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-05-21/LibXL_52_released" />
		<updated>2026-05-21T12:31:00+02:00</updated>
		<published>2026-05-21T11:42:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6254</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">Recently LibXL 5.2 was released and we include this update in our upcoming MBS Plugins for FileMaker and Xojo.

Version 5.2.0 (2026-05-15)
       
fixed the vulnerability CVE-2026-22184, updated zlib to the version 1.3.2
added possibility to read data validations from xlsx files
added possibility to remove filters from tables (xlsx)
added the support for xlsx files in the Book::loadWithoutEmptyCells()
fixed a bug with reading strings with incorrect character encoding in the Sheet::readStr() on Linux/MacOSX (xls)
fixed an issue with loading some xls files with message "read error: record id can't be 0"
fixed an issue with corrupting output files in the AutoFilter::setSort() method (xlsx)
fixed the unhandled exception in the Format::borderLeftColor() method (xlsx)                  

New methods:

Sheet::dataValidation()
Sheet::dataValidationSize()
Table::isAutoFilter()
Table::removeFilter()</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-05-21/LibXL_52_released"><![CDATA[
                <img src="http://www.mbsplugins.de/images/libxl.png" style="float:right;margin-left:10px;margin-bottom:5px;border:0px solid" title="" alt="" class="pivot-image">

<p>Recently LibXL 5.2 was released and we include this update in our upcoming MBS Plugins for FileMaker and Xojo.</p>

<h4>Version 5.2.0 (2026-05-15)</h4>
<ul class="changelog">       
<li>fixed the vulnerability CVE-2026-22184, updated zlib to the version 1.3.2
</li><li>added possibility to read data validations from xlsx files
</li><li>added possibility to remove filters from tables (xlsx)
</li><li>added the support for xlsx files in the <a rel="external" href="https://libxl.com/workbook.html#load7">Book::loadWithoutEmptyCells()</a>
</li><li>fixed a bug with reading strings with incorrect character encoding in the <a rel="external" href="https://libxl.com/spreadsheet.html#readStr">Sheet::readStr()</a> on Linux/MacOSX (xls)
</li><li>fixed an issue with loading some xls files with message "read error: record id can't be 0"
</li><li>fixed an issue with corrupting output files in the <a rel="external" href="https://libxl.com/autoFilter.html#setSort">AutoFilter::setSort()</a> method (xlsx)
</li><li>fixed the unhandled exception in the <a rel="external" href="https://libxl.com/format.html#borderLeftColor">Format::borderLeftColor()</a> method (xlsx)                  
</li></ul>
<div class="changelogsec2">New methods:</div>
<ul class="changelog">
<li><a rel="external" href="https://libxl.com/spreadsheet.html#dataValidation">Sheet::dataValidation()</a>
</li><li><a rel="external" href="https://libxl.com/spreadsheet.html#dataValidationSize">Sheet::dataValidationSize()</a>
</li><li><a rel="external" href="https://libxl.com/table.html#isAutoFilter">Table::isAutoFilter()</a>
</li><li><a rel="external" href="https://libxl.com/table.html#removeFilter">Table::removeFilter()</a>
</li></ul><h4>Version 5.1.0 (2026-01-20)</h4>
<ul class="changelog">                         
<li>added the <a rel="external" href="https://libxl.com/workbook.html#errorCode">Book::errorCode()</a> for getting error codes
</li><li>added possibility to read conditional formats with the <a rel="external" href="https://libxl.com/workbook.html#conditionalFormat">Book::conditionalFormat()</a>
</li><li>added possibility to remove conditional formattings with the <a rel="external" href="https://libxl.com/spreadsheet.html#removeConditionalFormatting">Sheet::removeConditionalFormatting()</a>
</li><li>added possibility to clear all data from a workbook with the <a rel="external" href="https://libxl.com/workbook.html#clear">Book::clear()</a>
</li><li>fixed a bug with decrypting password-protected workbooks for the 32-bit version of the library
</li><li>fixed an issue that caused a crash when using an empty password
</li></ul>
<div class="changelogsec2">New methods:</div>
<ul class="changelog">
<li><a rel="external" href="https://libxl.com/workbook.html#errorCode">Book::errorCode()</a>
</li><li><a rel="external" href="https://libxl.com/workbook.html#conditionalFormat">Book::conditionalFormat()</a>
</li><li><a rel="external" href="https://libxl.com/workbook.html#conditionalFormatSize">Book::conditionalFormatSize()</a>
</li><li><a rel="external" href="https://libxl.com/workbook.html#clear">Book::clear()</a>
</li><li><a rel="external" href="https://libxl.com/spreadsheet.html#conditionalFormatting">Sheet::conditionalFormatting()</a>
</li><li><a rel="external" href="https://libxl.com/spreadsheet.html#removeConditionalFormatting">Sheet::removeConditionalFormatting()</a>
</li><li><a rel="external" href="https://libxl.com/spreadsheet.html#conditionalFormattingSize">Sheet::conditionalFormattingSize()</a>
</li></ul>

<p>LibXL is a powerful library to create, read, edit and write Excel documents in older and newer Excel file formats and without the need to install Microsoft Excel. It allows the developer to automate a lot of tasks related to Excel spreadsheets within your solution or application.</p>

<p>Learn more on our <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/libxl.shtml">LibXL for FileMaker</a> and <a rel="external" href="https://www.monkeybreadsoftware.de/xojo/plugin-xls.shtml">LibXL for Xojo</a> pages.</p>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
	<entry>
		<title>MBS FileMaker Plugin 16.2 News</title>
		<link rel="alternate" type="text/html" href="https://www.mbsplugins.de/archive/2026-05-20/MBS_FileMaker_Plugin_162_News" />
		<updated>2026-05-20T07:00:00+02:00</updated>
		<published>2026-05-20T07:00:00+02:00</published>
		<id>tag:pivotpowered,2026:MonkeybreadSoftwareBlog.6253</id>
		<link rel="related" type="text/html" href=""  />
		<summary type="text">In this article we want to introduce you the new functions from the MBS FileMaker Plugin in version 16.2.

DynaPDF
This release includes new features for DynaPDF. 
With DynaPDF.Parser.Content, you can now retrieve the page content as JSON. In the parameters, you can limit the information in the JSON by specifying a filter. For example, the code snippet below retrieves only the DrawPath operators.</summary>
        <content type="html" xml:lang="en" xml:base="https://www.mbsplugins.de/archive/2026-05-20/MBS_FileMaker_Plugin_162_News"><![CDATA[
                <p>In this article we want to introduce you the new functions from the <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/">MBS FileMaker Plugin</a> in version 16.2.</p>

<h3>DynaPDF</h3>
<p>This release includes new features for DynaPDF. 
With <a rel="external" href="https://www.mbsplugins.eu/DynaPDFParserContent.shtml">DynaPDF.Parser.Content</a>, you can now retrieve the page content as JSON. In the parameters, you can limit the information in the JSON by specifying a filter. For example, the code snippet below retrieves only the DrawPath operators.</p><pre>
Set Field [ DynaPDF Replace Text::Content ; MBS( "<a rel="external" href="https://www.mbsplugins.eu/DynaPDFParserContent.shtml">DynaPDF.Parser.Content</a>"; $pdf; "DrawPath") ]

[
	{
		"OperatorIndex": 5,
		"OperatorCode": 8,
		"Operator": "DrawPath",
		"IsOpener": false,
		"IsCloser": false,
		"IsGSProperty": false,
		"IsDrawingCommand": true,
		"BBox": {
			"x1": 0,
			"y1": 0,
			"x2": 0,
			"y2": 0
		},
		"Mode": 0,
		"OP": [5, 4, 4, 4, 3],
		"OPNames": ["MoveTo", "LineTo", "LineTo", "LineTo", "ClosePath"],
		"OPCount": 5,
		"Vertices": [
			{
				"x": 0,
				"y": 595.275574
			}, 
			{
				"x": 842,
				"y": 595.275574
			}, 
			{
				"x": 842,
				"y": -0.724426
			}, 
			{
				"x": 0,
				"y": -0.724426
			}
		],
		"VerticesCount": 4
	}, 
	{
		"OperatorIndex": 23,
		"OperatorCode": 8,
		"Operator": "DrawPath",
		"IsOpener": false,
		"IsCloser": false,
		"IsGSProperty": false,
		"IsDrawingCommand": true,
		"BBox": {
			"x1": 0,
			"y1": 0,
			"x2": 0,
			"y2": 0
		},
		"Mode": 1,
		"OP": [
			6
		],
		"OPNames": [
			"Rectangle"
		],
		"OPCount": 1,
		"Vertices": [
			{
				"x": 0,
				"y": 0
			}, 
			{
				"x": 645,
				"y": 400
			}
		],
		"VerticesCount": 2
	}, 
	{
		"OperatorIndex": 285,
		"OperatorCode": 8,
		"Operator": "DrawPath",
		"IsOpener": false,
		"IsCloser": false,
		"IsGSProperty": false,
		"IsDrawingCommand": true,
		"BBox": {
			"x1": 0,
			"y1": 0,
			"x2": 0,
			"y2": 0
		},
		"Mode": 1,
		"OP": [5, 4],
		"OPNames": [
			"MoveTo", 
			"LineTo"
		],
		"OPCount": 2,
		"Vertices": [
			{
				"x": 0,
				"y": 0.5
			}, 
			{
				"x": 165,
				"y": 0.5
			}
		],
		"VerticesCount": 2
	}, 
	{
		"OperatorIndex": 321,
		"OperatorCode": 8,
		"Operator": "DrawPath",
		"IsOpener": false,
		"IsCloser": false,
		"IsGSProperty": false,
		"IsDrawingCommand": true,
		"BBox": {
			"x1": 0,
			"y1": 0,
			"x2": 0,
			"y2": 0
		},
		"Mode": 1,
		"OP": [5, 4],
		"OPNames": [
			"MoveTo", 
			"LineTo"
		],
		"OPCount": 2,
		"Vertices": [
			{
				"x": 0,
				"y": 0.5
			}, 
			{
				"x": 165,
				"y": 0.5
			}
		],
		"VerticesCount": 2
	}
]

</pre>

<p>
With the <a rel="external" href="https://www.mbsplugins.eu/DynaPDFParserDelete.shtml">DynaPDF.Parser.Delete</a> function, you can now also delete operators on the current page. In the parameters, you can specify the index of the corresponding operator. As mentioned above, the <a rel="external" href="https://www.mbsplugins.eu/DynaPDFParserContent.shtml">DynaPDF.Parser.Content</a> function is available to help you find this index. 
</p>
<p>
If you'd like to learn more about PDF structures and content streams, we recommend our new blog article <a rel="external" href="https://www.mbsplugins.de/archive/2026-05-13/Understanding_PDF_Structure_an/monkeybreadsoftware_blog_filemaker">Understanding PDF Structure and Content Streams</a> </p>

<p>In DynaPDF, you can also embed tables. In this release, the <a rel="external" href="https://www.mbsplugins.eu/DynaPDFTableSetColOrRowSpan.shtml">DynaPDF.Table.SetColOrRowSpan</a> function allows you to specify the row height or column width of a cell in your table. In the parameters of this function, you first specify the table in which the cell is located. Then you define the cell using its row and column numbers. Next, you specify the height or width of the cell. In the last parameter, you specify whether to use col span (true) or row span (false). </p>


<h3>CURL</h3>
<p>
Since years, our plugin has included the <a rel="external" href="https://www.mbsplugins.eu/CURLSetOptionHTTPHeader.shtml">CURL.SetOptionHTTPHeader</a> function. While <a rel="external" href="https://www.mbsplugins.eu/CURLSetOptionHTTPHeader.shtml">CURL.SetOptionHTTPHeader</a> sets all HTTP headers, you can call the new <a rel="external" href="https://www.mbsplugins.eu/CURLAddOptionHTTPHeader.shtml">CURL.AddOptionHTTPHeader</a> function as often as needed to add additional HTTP headers.
This function accepts a variable number of parameters. Pass as many parameters as needed, separated by semicolons in FileMaker.
</p>

<pre>Set Variable [ $curl ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/CURLNew.shtml">CURL.New</a>") ]
Set Variable [ $result ; Value: MBS("<a rel="external" href="https://www.mbsplugins.eu/CURLSetOptionURL.shtml">CURL.SetOptionURL</a>"; $curl; CURL Test::URL) ]
Set Variable [ $result ; Value: MBS( "<a rel="external" href="https://www.mbsplugins.eu/CURLAddOptionHTTPHeader.shtml">CURL.AddOptionHTTPHeader</a>"; $curl; "Content-Type: application/json" ) ]
Set Variable [ $result ; Value: MBS( "<a rel="external" href="https://www.mbsplugins.eu/CURLAddOptionHTTPHeader.shtml">CURL.AddOptionHTTPHeader</a>"; $curl; "Expect:"; "Cache-Control: no-cache" ) ]
Set Field [ CURL Test::Result ; MBS("<a rel="external" href="https://www.mbsplugins.eu/CURLPerform.shtml">CURL.Perform</a>"; $curl) ]
</pre>

<h3>SQL</h3>
<p>
You also get a new function from the FM module for debugging SQL. With <a rel="external" href="https://www.mbsplugins.eu/FMExecuteSQLLastParameters.shtml">FM.ExecuteSQL.LastParameters</a>, you can retrieve the query parameters from the last failed SQL command.
This allows you to debug issues with MBS functions that execute multiple commands; for example, you can see which values were used in the failed insert record. For more information on this and other SQL debugging features, check out our new article <a rel="external" href="https://www.mbsplugins.de/archive/2026-04-30/SQL_error_checking_improved/monkeybreadsoftware_blog_filemaker">SQL error checking improved</a> on our blog. </p>

<h3>FileState</h3>
<p>With the new <a rel="external" href="https://www.mbsplugins.eu/FilesStat.shtml">Files.Stat</a> function, you can check the file status of a file or directory. The result is a JSON object containing the relevant information. It might look like this, for example: </p>

<img src="http://www.mbsplugins.de/image/16.2_FileState.png" width="550">

<h3>Graphics Magick</h3>
<p>With the new <a rel="external" href="https://www.mbsplugins.eu/GMImageAffineTransform.shtml">GMImage.AffineTransform</a> function, we have added a feature that applies a specified affine or free transform matrix to an image. </p>



<h3>JSON and TOON</h3>
<p> 
In the last release, we introduced the <a rel="external" href="https://www.mbsplugins.eu/JSONToToon.shtml">JSON.ToToon</a> function, which converts JSON to TOON. TOON is an information format particularly well-suited for use with AI communication. It minimizes the number of tokens required for communication. Now, with the new version 16.2, we've also added a function that converts TOON to JSON. We hope the JSON. FromToon will make your work with AI even easier. </p>


<h3>Llama</h3>
<p>
We also introduced the new <a rel="external" href="https://www.mbsplugins.eu/component_Llama.shtml" translate="no">Llama</a> section in the last version. A new addition is the <a rel="external" href="https://www.mbsplugins.eu/LlamaLoadBackend.shtml">Llama.LoadBackend</a> function. It loads a backend for Llama from a location specified by a path. By default, we load all backends. But if you have a separate library located elsewhere, you can explicitly load it using <a rel="external" href="https://www.mbsplugins.eu/LlamaLoadBackend.shtml">Llama.LoadBackend</a>.</p>

<img src="http://www.mbsplugins.de/image/LlamaFileMaker.png" width="700" alt="Llama chat example showing what the LLM knows about FileMaker.">
<h3>Matrix</h3>
<p>We have also added new features to the <a rel="external" href="https://www.mbsplugins.eu/component_Matrix.shtml" translate="no">Matrix</a> section. One feature that can be helpful in many areas is the <a rel="external" href="https://www.mbsplugins.eu/MatrixMBS.shtml">Matrix.MBS</a> function. It allows you to run a function with a variable parameter list. The values for the desired parameters are entered into a matrix, which is then processed by our <a rel="external" href="https://www.mbsplugins.eu/MatrixMBS.shtml">Matrix.MBS</a> function to collect the values. This might look as follows: </p>

<pre>
let([ 
    m = MBS("<a rel="external" href="https://www.mbsplugins.eu/MatrixNew.shtml">Matrix.New</a>"; 3; 1);
    s = MBS("<a rel="external" href="https://www.mbsplugins.eu/MatrixSetValue.shtml">Matrix.SetValue</a>"; m; 0; 0; "Hello");
    s = MBS("<a rel="external" href="https://www.mbsplugins.eu/MatrixSetValue.shtml">Matrix.SetValue</a>"; m; 1; 0; " ");
    s = MBS("<a rel="external" href="https://www.mbsplugins.eu/MatrixSetValue.shtml">Matrix.SetValue</a>"; m; 2; 0; "World");
    r = MBS("<a rel="external" href="https://www.mbsplugins.eu/MatrixMBS.shtml">Matrix.MBS</a>"; m; "<a rel="external" href="https://www.mbsplugins.eu/TextConcat.shtml">Text.Concat</a>");
    m = MBS("<a rel="external" href="https://www.mbsplugins.eu/MatrixRelease.shtml">Matrix.Release</a>"; m)
]; r)
</pre>

<img src="http://www.mbsplugins.de/image/16.2_Matrix.png" width="550">

<p>
If you'd like to learn more about this feature, feel free to check out our article <a rel="external" href="www.mbsplugins.de/archive/2026-05-08/Introducing_MatrixMBS_Dynamic_/monkeybreadsoftware_blog_filemaker"> Introducing <a rel="external" href="https://www.mbsplugins.eu/MatrixMBS.shtml">Matrix.MBS</a>: Dynamic Function Calls with Matrix Parameters </a>
</p>
<p>Three functions that can be particularly useful in connection with this feature also been added: You can use the <a rel="external" href="https://www.mbsplugins.eu/MatrixSearchAndReplace.shtml">Matrix.SearchAndReplace</a> function to search for text in a matrix and then replace it with different text. With the <a rel="external" href="https://www.mbsplugins.eu/MatrixSwapColumns.shtml">Matrix.SwapColumns</a> and <a rel="external" href="https://www.mbsplugins.eu/MatrixSwapRows.shtml">Matrix.SwapRows</a> functions, you can swap columns or rows within a matrix. </p>



<h3>Web View</h3>
<img src="https://www.mbsplugins.de/image/WebViewCreateWindow.png" width="306" align="right">
<p>The new <a rel="external" href="https://www.mbsplugins.eu/WebViewCreateWindow.shtml">WebView.CreateWindow</a> function is a powerful tool. With this function, you can create a standalone WebViewer window that is hidden by default and can be used to perform tasks in the background, for example. The window can be displayed as needed and can be controlled using both WebViewer functions and standard <a rel="external" href="https://www.mbsplugins.eu/component_Window.shtml" translate="no">window</a> functions. If you'd like to learn more about this great feature and what you can do with it, feel free to check out our blog post <a rel="external" href="https://www.mbsplugins.de/archive/2026-05-11/Creating_Custom_Web_Viewer_Win/monkeybreadsoftware_blog_filemaker">Creating Custom Web Viewer Windows in FileMaker with <a rel="external" href="https://www.monkeybreadsoftware.com/filemaker/">MBS FileMaker Plugin</a></a></p>

<p>For Windows users, we've introduced a new feature called <a rel="external" href="https://www.mbsplugins.eu/WebViewMoveFocus.shtml">WebView.MoveFocus</a>, which allows us to control the focus on our WebViewer and its elements. WebView changes focus through user interaction including selecting into a WebView or Tab into it. For tabbing, the app runs MoveFocus with Next or Previous to align with Tab and Shift+Tab respectively when it decides the WebView is the next tabable element.
</p>


<h3> FoundationModels </h3> 
<p>Last but not least, we also have news for Mac users.
The <a rel="external" href="https://www.mbsplugins.eu/component_FoundationModels.shtml" translate="no">FoundationModels</a> section has also gained two new functions. First, you can determine the maximum size of the context supported by a model. The <a rel="external" href="https://www.mbsplugins.eu/FoundationModelsContextSize.shtml">FoundationModels.ContextSize</a> function returns the allowed number of tokens that can be used in a single session, including both input prompts and generated responses. If you want to determine how many tokens a specific request has, you can use <a rel="external" href="https://www.mbsplugins.eu/FoundationModelsTokenCount.shtml">FoundationModels.TokenCount</a>. In the parameters of this function, you first specify the LLM to which you want to send the request and, in another parameter, the instructions text. You will then receive a number that describes the token count for the specified instructions.  </p>

<p>We hope you will also find some interesting new features. We wish you a lot of fun with MBS FileMaker Plugin version 16.2. If you have any Ideas for new cool features, need a license or have any questions, please contact us.</p>
		]]></content>
		<author>
			<name>Chef</name>
		</author>
	</entry>
	
	
	
</feed>
