AppML Customization — Extending AppML with Custom Components and Integrations
In this tutorial, you will learn about AppML Customization. We cover key concepts, practical examples, and best practices to help you master this topic.
AppML provides extension points for custom field types, UI components, authentication backends, API integrations, and runtime hooks that let you tailor the framework to your specific needs.
What You'll Learn
You will create custom field types, build reusable UI components, integrate authentication, connect to external services, and extend the AppML runtime with plugins.
Why It Matters
Every application has unique requirements that the built-in features cannot cover. Customization lets you add exactly what you need without fighting the framework or writing a completely custom application.
Real-World Use
DodaTech built a custom color picker field type for the Durga Antivirus Pro theme configuration panel. The custom field integrates with a JavaScript color library and stores hex values in the database.
flowchart LR
A[AppML Core] --> B[Extension Points]
B --> C[Custom Field Types]
B --> D[Custom Components]
B --> E[Auth Backends]
B --> F[API Plugins]
B --> G[Runtime Hooks]
C --> H[Color Picker]
C --> I[Map Selector]
D --> J[Chart Widget]
D --> K[Timeline View]
style B fill:#1e293b,color:#fff
Custom Field Types
Create new field types beyond the built-in text, number, date, and dropdown.
// fields/color-picker.js
module.exports = {
type: 'color',
input: function(field, value) {
return `
<div class="color-picker-wrapper">
<input type="color"
name="${field.name}"
value="${value || '#000000'}"
class="appml-color-picker"/>
<input type="text"
name="${field.name}_hex"
value="${value || '#000000'}"
class="appml-hex-input"/>
</div>`;
},
validate: function(value) {
return /^#[0-9a-fA-F]{6}$/.test(value);
},
format: function(value) {
return `<span style="color:${value}">■</span> ${value}`;
}
};
Expected output: A color picker input with a hex text input. Values are validated as six-character hex codes. Display format shows a colored square with the hex value.
Use it in a form:
<field ref="primary_color" label="Brand Color" type="color"/>
Custom Authentication Backend
Replace the default authentication with a custom backend like LDAP or OAuth.
// auth/ldap.js
module.exports = {
authenticate: function(username, password) {
const ldap = require('ldapjs');
const client = ldap.createClient({ url: 'ldap://company-dc.example.com' });
return new Promise((resolve, reject) => {
client.bind(`cn=${username},dc=example,dc=com`, password, function(err) {
if (err) {
reject(new Error('Invalid credentials'));
} else {
resolve({
id: username,
name: username,
role: 'user'
});
}
});
});
},
authorize: function(user, resource, action) {
return user.role === 'admin' || resource.public === true;
}
};
Expected output: Users authenticate against the corporate LDAP server instead of the AppML internal user table.
Register the auth backend:
{
"auth": {
"backend": "auth/ldap.js",
"session_ttl": 3600
}
}
Custom API Endpoints
Add custom REST endpoints that run alongside AppML's built-in data controllers.
// api/reports.js
module.exports = {
route: '/api/reports/sales-summary',
method: 'GET',
handler: function(request, response) {
const db = request.context.database;
const results = db.query(`
SELECT DATE(order_date) as day,
COUNT(*) as orders,
SUM(total) as revenue
FROM orders
WHERE order_date >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY DATE(order_date)
ORDER BY day
`);
response.json(results);
}
};
Expected output: A custom JSON endpoint at /api/reports/sales-summary that returns daily sales data for the last 30 days.
Custom UI Components
Build reusable components for dashboards and views.
// components/chart-widget.js
module.exports = {
name: 'chart',
render: function(params) {
const data = params.context.database.query(params.query);
return `
<div class="chart-widget" data-type="${params.chart_type}"
data-labels='${JSON.stringify(data.map(r => r.label))}'
data-values='${JSON.stringify(data.map(r => r.value))}'>
<canvas></canvas>
</div>`;
},
scripts: ['/static/js/chart.js'],
styles: ['/static/css/chart.css']
};
Use the component in a template:
{{ component('chart', {
chart_type: 'bar',
query: 'SELECT category as label, COUNT(*) as value FROM products GROUP BY category'
}) }}
Expected output: A bar chart rendered in the dashboard showing product count by category.
Common Mistakes
Over-customizing instead of using built-in features: Before building a custom component, check if AppML already supports the feature. Custom code adds maintenance burden.
Not following the extension API conventions: Custom extensions must export the expected interface. Inconsistent return values cause runtime errors.
Skipping validation in custom field types: Custom field types should validate input server-side, not just client-side. Users can bypass browser validation.
Creating custom components without documentation: Other developers need to know how to use your extensions. Document the API surface.
Ignoring security in custom auth backends: Custom authentication handles sensitive credentials. Use established libraries and avoid storing passwords in plain text.
Practice Questions
- What is the purpose of custom field types?
They add new input types beyond the built-in options, like color pickers, map selectors, or tag inputs.
- How do you register a custom authentication backend?
Configure the auth backend path in appml.config.json under the auth section.
- What file would you create for a custom API endpoint?
Create a handler file in the api directory that exports route, method, and handler properties.
- How do you use a custom UI component in a template?
Use the
{{ component() }}function with the component name and parameters.
- What is the return value of a custom field type's input function?
An HTML string that renders the custom input element with the current value.
Challenge
Create a custom map-location field type that integrates with the Leaflet.js library. The field should let users click on a map to select coordinates and store latitude and longitude in two database columns.
Frequently Asked Questions
Mini Project
Build a dashboard plugin that displays three custom components: a bar chart showing monthly revenue, a donut chart showing order status distribution, and a custom metric card showing total orders, revenue, and average order value. Use custom API endpoints for the data.
What's Next
Continue to AppML Mini Project to apply everything you have learned by building a complete application.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro