Mastering custom buttons
Mastering Custom Buttons: A Developer's Recap
Congratulations on completing our custom button tutorial series! We've journeyed from a simple "Show on Map" button to a sophisticated PDF letter generator. You now have the foundational knowledge to create a wide range of custom actions that can dramatically enhance your application's functionality.
This final article will summarize the core concepts we've learned, provide some useful tips and tricks, and point you to further resources within the application's help system to continue your learning journey.
The Core Concepts of Custom Buttons
Across all our examples, a few fundamental patterns emerged. Understanding these will allow you to build almost any custom action you can imagine.
Concept 1: The Anatomy of a Button Script
Every custom button script we've built has two distinct parts, each with a critical role:
- The PHP "Security Guard" (Server-Side): The PHP code at the top of every script runs first on the server. Its primary job is to ensure the request is secure and legitimate. It always performs the same essential checks: loading the application core (
init.php), verifying the user is logged in, and—most importantly—validating the cryptographic signature (sig) to prevent URL tampering. This part is non-negotiable for security. - The JavaScript "Action Hero" (Client-Side): If the security checks pass, the rest of the file (HTML and JavaScript) is sent to the browser. The JavaScript part is where the actual work happens, and we've seen three main patterns for this.
Concept 2: The Three Main Action Patterns
The "Action Hero" part of your script can follow one of three main strategies, depending on what you want to achieve.
Pattern A: Client-Side DOM Reading
The script reads data directly from the form fields on the current page. This is the simplest and fastest pattern.
Example: Our Google Maps button, which reads the address from the input fields.
Use When: You need a quick action that only operates from the "Edit Record" form and doesn't require data that isn't already on the page.
Pattern B: Server-Side Processing
The script runs entirely on the server, performs a complex action (like sending an email), and returns a simple JSON success or error message.
Example: Our Send via SMTP button, which sends an email in the background.
Use When: The action is complex, requires secure credentials, or shouldn't be interrupted by the user closing their browser tab.
Pattern C: Client-Side File Generation
The script fetches raw data from the server via an API call, then processes and formats this data in JavaScript to create a downloadable file.
Example: Our vCard, iCalendar, and PDF Letter export buttons.
Use When: You need to generate custom files (like reports, documents, or calendar entries) without creating temporary files on the server. This is a modern and highly efficient approach.
Tips, Tricks, and Best Practices
- Always Start with a Template: Don't write a new button from scratch. Copy an existing one (like `template_record_googlemaps.php`) that matches the pattern you need. This ensures you always have the correct security checks in place.
- Use the `lang()` Function: Hardcoding text in your scripts makes them difficult to maintain and translate. Use language keys (e.g., `lang('my_button_title')`) for all user-facing text.
- Embrace `console.log()`: When developing, especially with client-side generation, `console.log()` is your best friend. Use it to inspect the data you receive from the API and the content you are generating before creating the file.
- Server-Side vs. Client-Side: Decide early which pattern fits your needs. If the task involves sensitive data or must be completed reliably, do it on the server (Pattern B). If it's about displaying or formatting data for the user, do it on the client (Pattern A or C).
- Keep It Simple: As we learned with the Google Maps button, sometimes the simplest solution is the best. If a direct DOM read works for your primary use case, it might be better than a complex API-based solution.
Where to Find More Information
Our tutorials have only scratched the surface. The application's built-in help system provides deep dives into the tools and functions you'll need to build even more advanced features.
REST API Documentation
Learn how to use the `api/v1.php` endpoint to securely fetch records, fields, and other data. This is the foundation for all advanced client-side buttons.
Technical File Documentation
This guide explains the purpose of key files like `dbfunctions.php`. Understanding functions like `DBGet()`, `DBInsert()`, and `DBUpdate()` is essential for writing server-side button logic.
Custom Events
Discover how to create scripts that run automatically after an action (e.g., `after_create`, `after_update`). This is perfect for logging, sending notifications, or triggering follow-up actions that complement your buttons.
Frequently Asked Questions (FAQ)
document.querySelector('[name="street"]')) that only exist on the edit page. To make the button work everywhere, you must refactor it to use Pattern C (Client-Side File Generation), where it fetches the record data via the API instead of reading it from the form.
{table_id} and {id} correctly, as the application replaces these before generating the signature.
- Simple (Pattern A): Your JavaScript reads the value from the form field using
document.querySelector(). - Robust (Pattern C): Your JavaScript makes an API call to get the entire record, and then you can access the value from the returned JSON object.
DBUpdate() or DBInsert() functions from dbfunctions.php to modify the database. Finally, it would return a JSON response like {'success': true, 'message': 'Record updated!'}, which the application will automatically display to the user.
Thank you for following along with our series. Happy coding!