The fastest and most convenient way to develop web applications

All features and benefits at a glance


Benefit from a revolutionary new technology for web application development.

Introduction

UCMS is a new revolutionary PHP framework / CMS for the development of internationalized enterprise web applications.

One of the key features is the awesome template engine which is based on the Twig syntax. This template engine is a completely new JavaScript-like programming language.

Due to the power of this new template language, things can be programmed that previously seemed completely impossible.

JavaScript-like Twig templates
  • {% set my_filter = function( number ) {
  • return number & 1
  • }
  • %}
  • <script>
  • var odd_numbers = {{
  • [1, 2, 3].\array_filter(
  • my_filter
  • )
  • }}
  • </script>

Be ahead of the times

The new template language includes many new programming paradigms such as a foreign function interface, anonymous functions, callbacks, dynamic tags, function expressions, method chaining, currying and scriptability.

Thanks to the hard work of a brilliant programmer, the new template language is an almighty programming language that offers many new solutions and makes impossible things possible.

You can only get this new technology here because it would take years to develop something similar.

Dynamic Tags
  • {% addtag leetspeak as function( words ) {
  • return words.\strtr(
  • 'leet', '1337'
  • )
  • }
  • %}
  • {% leetspeak %}
  • And God said, 'Let there be light'
  • and there was light.
  • {% endleetspeak %}
Leetspeak
  • And God said, 'L37 7h3r3 b3 1igh7'
  • and 7h3r3 was 1igh7.

Click here for more examples

Programming without limits

There are no limits anymore, you can call any function or method directly from your templates, no matter if static or object-oriented.

You can also make important variables, such as an API Object, available in any template so that you do not need to initialize them each time.

To do that, simply add the variable to the UCMS namespace object inside of the base class constructor of your application and that's it.

You can even access your class constants and PHP constants directly.

Access any class or function
  • {%- set api = new \Your\Api(
  • ucms.database
  • )
  • -%}
  • {{
  • api.doSomething('Hello World',
  • api::ANY_CONSTANT
  • )
  • }}
Also static
  • {{
  • \Your\Api::do_something('Hello World',
  • \Your\Api::ANY_CONSTANT
  • )
  • }}

Programming at a higher level

With the new Twig you can reference any function like in JavaScript, no matter if it is a PHP-internal function, an Object method, a static function in a class or a template function or template macro.

Additionally, any PHP internal function, any template function and any template macro can be chained like in JavaScript, so that you can write very readable code that is easy to understand.

You can of course also use the traditional recursive form of PHP.

Callbacks and functions expressions can be used and work same like in JavaScript.

Reference any function
  • {% set
  • message = "Hello World \u263a",
  • byteLength = \strlen,
  • charLength = \mb_strlen
  • %}
  • Byte length: {{ message.byteLength() }}
  • Char length: {{ message.charLength() }}
Chain any function
  • Hello {{ 'dlrow'.\strrev().\ucfirst() }}

Programming like a god

Even very advanced concepts such as function currying are now possible.

The new template engine is so powerful that you can program almost anything in your templates.

At the same time, it's so easy that even a kid could program websites, because the language syntax is based on the well-known JavaScript syntax, which is the most popular programming language.

Function currying
  • {% set add = function( x , y = null ) {
  • return @arguments.\count() > 1 ? x + y :
  • function( y ) use ( x ) {
  • return x + y
  • }
  • }
  • %}
  • {% set add_to_three = add( 3 ) %}
  • Default: {{ add( 3 , 5 ) }}
  • Curried: {{ add( 3 )( 5 ) }}
  • Curried: {{ add_to_three( 5 ) }}

Programming with magic

The template engine can handle references easily and even assign them with the reference assignment operator. Full UTF-8 and Unicode support is of course also available.

With all this features, it is now possible to perfectly separate backend specific logic and frontend specific logic from each other.

Passing and assigning references
  • {% set currencies = ["\u20ac","\u0e3f",'$'],
  • myShift = \array_shift
  • %}
  • {% do copy =& currencies %}{# assign byref #}
  • Default: {{ currencies.\array_shift() }}
  • Aliased: {{ currencies.myShift() }}
  • Aliased: {{ myShift( currencies ) }}
  • Emptied: {{ copy.toJson() }}

Real scripting language


Now you can use Twig like a real scripting language, because it is a real scripting language.

Turing completeness

The new template language is a programming language with Turing completeness.

You can use all control structures and paradigms as in any other modern programming language.

The templates and expressions are compiled into an abstract syntax tree. The compiler can detect and optimize static expressions so that, for example, 1 + 1 is stored as 2 in the abstract syntax tree.

This new revolutionary template language combines the advantages of PHP, JavaScript and the Twig syntax, in a new incredible and almighty programming language.

Full script-ability
  • {% script %}
  • function calcPi(accuracy = 1000)
  • {
  • pi = 4
  • hi = 4
  • lo = 3
  • ng = true
  • for(i = 0; i < accuracy; i++)
  • {
  • pi += ng ? -(hi / lo) : hi / lo
  • lo += 2
  • ng = !ng
  • }
  • return pi
  • }
  • {% endscript %}

Universal script-ability

The template parser, the script parser, and the expression parser of the template language can also be used as an independent component.

Scriptability can be added to any existing PHP application because our technology can instantiate any class and call any function.

Therefore, this technology could be of interest to you, even if you do not need a content management system.

Fibonacci sequence
  • {% script %}
  • function fibonacci( n ) {
  • return n <= 2 ? 1 :
  • fibonacci( n - 1 ) +
  • fibonacci( n - 2 )
  • }
  • {% endscript %}
  • The first 10 fibonacci numbers: {{
  • 1..10.map( fibonacci ).join(', ')
  • }}

Click here for more examples

Development made easy


Save time with powerful built-in components and with a simple MVC workflow

More possibilities less effort

Controllers need only one function with one line of code in most cases where no POST data needs to be processed.

The AbstractController class can add variables to the namespace, and that's it. You do not have to provide countless variables for each of your template.

That way, you can access your entire back-end API in your templates and get all the functionality right in your templates. (See below)

InvoicingController.php
  • <?php
  • namespace Ucms\Controller\YourApp;
  • class InvoicingController
  • extends AbstractController {
  • public function getContent() {
  • return $this->renderFile(
  • $this->site->template
  • // or 'YourApp/Invoicing.twig'
  • );
  • }
  • };
  • // No Joke, simple controllers only
  • // need such a code snippet!

Rapid application development

Call your backend API directly from a template, this will speed up your development process significantly.

This type of programming is a key element of rapid application development and a real innovation.

You can do almost anything within a template, as in PHP, but with a flexible JavaScript-like syntax.

Invoicing.twig
  • {% set invoices = api.getInvoices(
  • {customer_id: customer.id},
  • {due_date: 'asc'},
  • 10
  • )
  • %}
  • {% for invoice in invoices %}
  • {{
  • invoice.renderInvoice()
  • }}
  • {% endfor %}
  • {# NO joke, you can access anything! #}

Dead easy API functions

The database adapter allows you to create API functions with object-relational mappings (ORMs) super easy.

The database interface design was chosen so that it is easy to pass arguments from a template to an API function.

In this way, your data models can access these API functions and query additional model-specific data.

This means that an Invoice object can have a getCustomer method to provide a Customer object that relates to the invoice.

Many more examples can be found in the documentation.

Api.php
  • public function getInvoices(
  • $where = null,
  • $order = null,
  • int $limit = null,
  • int $start = null
  • ) {
  • return $this->database()->selectRows([
  • 'table' => self::TABLE_INVOICES,
  • 'where' => $where,
  • 'order' => $order,
  • 'limit' => $limit,
  • 'start' => $start,
  • 'key' => function(&$row, &$key)
  • {
  • $row = new Invoice($this, $row);
  • return true;
  • }
  • ]);
  • }
  • // The database adapter can do much more
  • // than that. For example, assign a key
  • // to a particular MySQL token.

Adaptable and flexible


UCMSSwiss army knife of web application development

Adapter technology

The adapter technology makes it possible that any important core component can be provided through an adapter, defined by an interface.

Adapters are available for user management, configuration, caching, captcha, database access, logging, markdown, namespace, sessions, sites, translations and views.

For example, users can be managed through a database or .htpasswd and .htgroups files, both have the same adapter interface.

The same applies to any other core component. If you, for example, want to use .json files instead of .ini files as the configuration source, just create a JsonFileBiosAdapter.

bios.ini
  • [ucms]
  • title = 'Example App'
  • [auth]
  • adapter = 'HtaccessAuthAdapter'
  • tables.users = '.../example/.htpasswd'
  • tables.groups = '.../example/.htgroups'
  • [cache]
  • adapter = 'ApcuCacheAdapter'
  • [database]
  • adapter = 'GenericDatabaseAdapter'
  • # NOTE:
  • # IniFileBiosAdapter is passed to the
  • # kernel in index.php
  • #
  • # Any config format is possible in
  • # that way - if you dont like .ini

Modular system

You can use these adapters in your own classes to access specific functions, for example, database functions or translation functions.

If you just pass the ucms object to the constructor of your PHP class you will have access to all adapters.

Controllers and templates have access to the ucms object by default. In this way, you get a modular system that you can tailor to your needs.

If you change an adapter, for example FileCache instead of ApcuCache, this is completely transparent to the underlying application because the cache adapter interface is still the same.

Adapter Example
  • Current database adapter:
  • {{ ucms.getCurrentAdapter(
  • 'database'
  • ) }}
  • Available database adapter:
  • {{ ucms.listAdapters(
  • 'database'
  • ).join("\n") }}
  • Example database query:
  • {{
  • ucms.database.selectRows({
  • table: 'example',
  • where: {
  • column: 'value'
  • }
  • })
  • .print()
  • }}

Flexible applications

The different adapters allow very flexible configurations. It's easy to create an application that works completely without database query.

You can also switch off adapters completely. For example, if your application is in English only, simply select the NullTranslationAdapter to turn off translations.

Example Output
  • Current database adapter:
  • GenericDatabaseAdapter
  • Available database adapter:
  • GenericDatabaseAdapter
  • MysqliDatabaseAdapter
  • ...

It could not be easier


Manage your business logic as easily as files and folders and set access permissions.

Simple configuration

You can easily manage your business logic and use a database or even a file (.ini, .json, .xml, ...) as data storage location.

This can be done both with a text editor and graphically in the admin panel. Experienced programmers will love it to add new sites within seconds with a text editor.

sites.ini
  • [invoice-pdf]
  • parent = 'invoices'
  • title = 'Generate PDF'
  • controller = 'Example\PdfController'
  • template = 'Example/Pdf.twig'
  • url = 'invoices/{invoice_id:digit}.pdf'
  • methods = 3 # decimal value of: HEAD | GET
  • mode = 40 # decimal value of: ---r-x---
  • gid = 'customers' # allow group customers

Simple management

You can manage your business logic as a tree structure which contains all relevant properties, including the access rights that work in the same way as in a file system.

The tree object has a number of useful methods that make it easy to generate site navigations such as menus, sidebars, navigation paths, and many more.

Business Logic

Simple logic

You do not have to pre-set a list of variables like in other template engines, instead you can access anything within your templates.

This is a true rapid application development (also called RAD) that saves you a lot of time and money.

Invoices.twig
  • {% set child = site.child('*-pdf') %}
  • {% for invoice in customer.getInvoices() %}
  • <a href="{{ child.getUrl( invoice.id ) }}">
  • {%- trans 'Download PDF' -%}
  • </a>
  • {% endfor %}

It could not be smarter


Create pretty URLs even with a variety of filter conditions

Visualize your routes as tree

The ucms has the most powerful URL routing technology on the market.

The routes can be visualized as a tree structure that is automatically generated from the URLs of your websites.

Any number of domains can be managed, even wildcard domains.

Router

Trace your routes

You can trace your routes (URLs) in the context of a user or group, so that you can see which site a URL references and with what arguments.

This facilitates your work considerably.

Trace a route

Conditional routing

Conditional routing allows you to define complex filter conditions, similar to GET parameters but in the path component of the URL.

The conditional elements can be defined as a single part or key-value pair that depends on each other.

Conditional elements can be auto-fillable, skippable or mandatory and they can have a specific format like digit or word.

For example, it is possible to define a condition which is first initiated by a keyword like "search" and then has to be continued with a term that match defined format.

If there is no match, and that part is defined as skippable, then the next condition is tried to match.

Complex database queries with many conditions and pretty URLs are easily possible in this way.

You can also define an alternate route for each site so that you can rename URLs without confusing GoogleBot and without generating 404 errors in Google webmaster tools.

Any other technology is very far away from what UCMS can do in this field!

Shortened result view
  • HTTP Code: 200 OK
  • Endpoints: invoice-pdf
  • Arguments:
  • Array
  • (
  • [invoice_id] => 12345
  • )
Shortened verbose output
  • +---+-----------+------------+-------------+
  • | L | Filename | Keys | Endpoints |
  • +---+-----------+------------+-------------+
  • | 0 | dashboard | - | - |
  • | 1 | invoices | - | - |
  • | 2 | 12345.pdf | invoice_id | invoice-pdf |
  • +---+-----------+------------+-------------+
  • Lookup took 0.027 ms

Faster than pure PHP code


Awesome processing speed even if you depend on slow third-party middleware.

Super fast template engine

Our technology is able to parse the entire syntax with a single regular expression.

This makes the new templates language extremely fast in code processing because the underlying Perl Compatible Regular Expressions (PCRE) are programmed in C.

Caching mechanisms for expressions, scripts and templates can speed up this additionally. Even your code can be speed up, see below.

Tokenizer
  • (?(DEFINE)
  • (?P<T_SIMPLE_PROPERTY>
  • \.\s*+(?P>T_WORD)
  • )
  • (?P<T_PROPERTY>
  • (?P>T_SIMPLE_PROPERTY)|
  • (?P>T_NESTED_PROPERTY)
  • )
  • )

Identify problems

UCMS makes it easy to measure the efficiency of your source code and to find bottlenecks.

Benchmark
  • {% benchmark %}
  • {{
  • yourApi.yourMiddleware().renderRows()
  • }}
  • {% endbenchmark %}

Effective solutions

UCMS makes it easy to speed up your application and to increasing your productivity.

Caching
  • {% cache 3 hours %}
  • {{
  • yourApi.yourMiddleware().renderRows()
  • }}
  • {% endcache %}

Happy customers

It's pretty simple: the faster the speed of your web application, the happier your visitors will be.

Optimizing page load time leads to noticable improvements in customer experience, conversion rates, and ultimately, your sales revenue.

Fast server response
  • ...
  • <p>Website was generated in 1 ms</p>
  • </body>
  • </html>

Additional database capabilities


Apply database logic to any files, arbitrary arrays or iterators, and query or aggregate records.

Query records from any source

Our technology allows you to apply database logic to any local or remote database-like file.

Redundant reading operations on one and the same table can be prevented by a caching mechanism.

All conventional database operations are available, including update, insert and delete.

  • {{
  • ucms.database.selectRows({
  • 'table': 'http://api.com/sales.json',
  • 'columns': {
  • 'date': '@{ DATE(`time`) }',
  • 'item': 'item'
  • },
  • 'limit': 25
  • })
  • .renderRows()
  • }}

Aggregate records from any source

Any file or iterator can be queried and aggregated, even data from a remote API, your log files or things like /proc/net/tcp.

We have implemented all the database functions available in MySQL, including all aggregation functions.

This will give you again a revolutionary technology from the future!

  • {{
  • ucms.database.selectRows({
  • 'table': 'http://api.com/sales.json',
  • 'columns': {
  • 'date': '@{ DATE(`time`) }',
  • 'sum': '@{ SUM(`revenue`) }'
  • },
  • 'group': {
  • 'date': 'asc'
  • }
  • })
  • .renderRows()
  • }}

Convert any format to another

As a business professional you know that not every business associate has the same business logic as you, and may use other file formats than you.

Thanks to the generic database emulator API, you can also work with such file formats. This gives you the right solution in every situation because you can convert any format to another.

All database emulator API functions can also be used at a low level so that you, for example, can apply a query directly to an array, if maximum performance and speed is desired.

Convert any format
  • {% set converter = new
  • \Ucms\Lib\Database\Emulator\Model\Table()
  • %}
  • {% do converter.import(
  • 'test.csv'
  • ) %}
  • {{
  • converter.export(
  • null, 'json'
  • )
  • .print().pre()
  • }}

Create .po files automatically


Extract translations from your source code and from your templates.

Translation generator available

The initial translation file can be generated automatically from the PHP source code and the templates.

Simply select the files of your application in a tree view and generate a .po file from them.

That will save you a lot of time, work and money!

Translation generator

Context and plural available

The translation context allows you to distinguish between two identical English strings and disambiguate the translation. See the msgstr line below.

The plural forms of any language can also be translated, and even expressions and comments can be included in the translations (see documentation).

This is again technology from the future! Because there is no other system with context translations and such a generator...

Startpage.twig
  • {% set apple_count = 3 %}
  • {% context 'Views.YourApp.Startpage' %}
  • <h1>{% trans 'Hello world!' %}</h1>
  • <br />
  • <p>
  • {%- translate -%}
  • I have one apple.
  • {%- plural apple_count -%}
  • I have {{ apple_count }} apples.
  • {%- notes -%}
  • Hey translator, eat an apple!
  • {%- endtranslate -%}
  • </p>
  • {% endcontext %}

Translation editor available

Thanks to the generic database emulator API, it is easily possible to read and write .po and .mo files. Even database logic can be applied to it.

Together with the intelligent routing functions and the powerful template language, it was a breeze to program an language editor in the admin panel.

You can simply switch to the translator in the admin panel, select a file in the tree view, choose a context and edit translations in it.

In update mode, the translation generator can mark outdated translations as obsolete and newly added translations as fuzzy. So you always keep track of changes. That will save you again a lot of time, work and money...

Without an automation like this, internationalized applications would be almost impossible. Because it would take an incredibly long time for a human to manually reconcile thousands of translations. In addition, this would cause very high costs.

French Translation.po
  • #: Views/YourApp/Startpage.twig:2
  • msgctxt "Views.YourApp.Startpage"
  • msgid "Hello world!"
  • msgstr "Bonjour monde!"
  • # Hey translator, eat an apple!
  • # {1} = {{ apple_count }}
  • #: Views/YourApp/Startpage.twig:5
  • msgctxt "Views.YourApp.Startpage"
  • msgid "I have one apple."
  • msgid_plural "I have {1} apples."
  • msgstr[0] "J'ai une pomme."
  • msgstr[1] "J'ai {1} pommes."
  • ...
  • #: Views/YourApp/ApiDocu.twig:5
  • msgctxt "Views.YourApp.ApiDocu"
  • msgid "Hello world!"
  • msgstr "Bonjour le monde!"
  • # {1} = {{ chr( 0x263A ) }}
  • #: Views/YourApp/ApiDocu.twig:7
  • msgctxt "Views.YourApp.ApiDocu"
  • msgid "That's **quite** easy! {1}"
  • msgstr "C'est **assez** facile! {1}"
  • ...

Styling options available

Translations with formatting and links can be created in combination with the markdown tag. Even internationalized PDF documents can be created this way.

You can write translatable API documentations or FAQs in just a few hours instead of a few days.

‪C'est assez facile! ☺‬

ApiDocu.twig
  • {% markdown %}{% context
  • 'Views.Application.ApiDocu'
  • %}
  • # {% trans 'Hello world!' +%}
  • {% translate %}
  • That's **quite** easy! {{ chr( 0x263A ) }}
  • {%- endtranslate +%}
  • {% endcontext %}{% endmarkdown %}

Machine translation available

With the translation tools in the Administration section, you can translate your application into any other language within seconds.

Just select the file and the language, click the button and you're done!

Automatic translator

As if by magic

This will save you thousands of euros again, and that for each individual language. Simply calculate the translation cost of an app with 50 different languages...

Markdown formatting is preserved during automatic translation and the translation has a very good quality. If you want it to be perfect, have the automatic translation checked by a human translator.

Without this tool you will need at least one week per translated language.

Nobody but us owns the technology that makes it possible to fully automatically translate internationalized applications in more than one hundred languages with a few clicks!

UCMS saves you a lot more money than it costs!

German Translation.po
  • ...
  • #: Views/YourApp/ApiDocu.twig:5
  • msgctxt "Views.YourApp.ApiDocu"
  • msgid "Hello world!"
  • msgstr "Hallo Welt!"
  • # {1} = {{ chr( 0x263A ) }}
  • #: Views/YourApp/ApiDocu.twig:7
  • msgctxt "Views.YourApp.ApiDocu"
  • msgid "That's **quite** easy! {1}"
  • msgstr "Das ist **ganz** einfach! {1}"
  • ...

Awesome PDF Generator


Create business documents like a pro with our awesome PDF generator.

PDF creation made easy

With our PDF generator it is very easy to create business documents because the documents can be generated in XML format.

This greatly simplifies the creation process and allows you to use all the template engine features in your PDF templates.

If you, for example, have a very complex invoicing the template inheritance capability of the template engine allows you to build a base layout.

A child template can extend the base layout and override any of its defined blocks.

Again, technology from the future!

Business PDF.twig
  • <?xml version="1.0" encoding="UTF-8" ?>
  • <pdf size="A4">
  • <header>
  • {%- block head -%}
  • <p font-size="2em" text-color="red">
  • {%- trans 'Invoice' -%}
  • </p>
  • {%- endblock -%}
  • </header>
  • <body>
  • {%- block body -%}
  • <skew angle-x="30">
  • <text x="50%" y="50%">
  • {%- trans 'Order number:' -%}
  • </text>
  • </skew>
  • {%- endblock -%}
  • </body>
  • </pdf>

Very many features

We have implemented a lot of features in this generator, for example, UTF-8 and Unicode support, TTF-Fonts, many filters, and the use of arbitrary units such as em, px, pt, mm, cm, in and %.

It is possible to use relative and absolute units of measure. This makes it even possible to create responsive PDFs that look the same in different sizes, such as A4 or A3.

You can create PDF documents more than pixel-accurate in a very short time with this generator.

It's just awesome...

Open the graph paper

Graph paper.twig
  • {%- macro renderLine( x1, y1, x2, y2, n ) -%}
  • <line line-width="{{ n.renderLW() }}"
  • x1="{{ x1 }}" y1="{{ y1 }}"
  • x2="{{ x2 }}" y2="{{ y2 }}" />
  • {%- endmacro -%}
  • {%- macro renderLW( n ) -%}{{
  • !(n % 10) ? '0.20' :
  • !(n % 5) ? '0.15' : '0.10'
  • }}mm{%- endmacro -%}
  • <?xml version="1.0" encoding="UTF-8" ?>
  • <pdf size="A4" draw-color="#FF6D2A"><body>
  • {%- for x in 0..170 %}{{ renderLine(
  • x ~ 'mm', '0%', x ~ 'mm', '100%', x
  • ) }}{% endfor -%}
  • {%- for y in 0..257 %}{{ renderLine(
  • '0%', y ~ 'mm', '100%', y ~ 'mm', y
  • ) }}{% endfor -%}
  • </body></pdf>

Click here for more examples

Render any markup language


Create SVG images or render any other markup language like a pro

Unlimited possibilities

Our revolutionary Template Engine is not limited to HTML code. It can be used with any markup language.

Creating SVG graphics, such as bar charts or pie charts, is extremely easy with our Template Engine.

For example, you can simply create a macro and customize it according to your database structure.

Then just apply the records to the macro and that's it:

SVG Bar Chart.twig
  • {% macro renderBarChart( bars ) %}
  • <svg xmlns="http://www.w3.org/2000/svg"
  • version="1.1" viewBox="0 0 192 78"
  • >
  • {% for x, bar in bars %}
  • <rect x="{{ x * 50 }}" y="-78"
  • rx="5" ry="5" fill="{{ bar.color }}"
  • width="40" height="{{ bar.value }}%"
  • transform="scale(1 -1)"
  • /><text x="{{ x * 50 + 20 }}" y="72"
  • fill="#ffffff" text-anchor="middle"
  • font-family="Montserrat, sans-serif"
  • font-size="7" font-weight="500">{{
  • ucms.getCountryName( bar.cc )
  • }}</text>
  • {% endfor %}
  • </svg>
  • {% endmacro %}
  • {{ renderBarChart([
  • {cc: 'FR', color: '#3c9ee5', value: 65},
  • {cc: 'DE', color: '#32bc00', value: 85},
  • {cc: 'IT', color: '#ffa100', value: 45},
  • {cc: 'ES', color: '#df0627', value: 25}
  • ]) }}

Much more is possible

You see, rendering SVG graphics is so trivial that the required code fits in the little yellow box.

These trivial examples are already extremely cool. But imagine what else you could program with more sophisticated code.

Whatever you program, with the UCMS you will succeed!

Touch me!
75% 95%

Super easy HTML Emails


Create HTML Emails with internationalization and template-based super easy

RFC compliant

With UCMS, you can send emails to your customers in a variety of ways. It is possible to send text e-mails, HTML e-mails, or both.

The text and the HTML part of the e-mail can optionally be processed by the Template Engine so that you have a standard layout and only have to pass the e-mail text.

With the help of the translation features, you can also generate internationalized emails.

Of course files can also be attached. Even HTML inline elements such as images can be easily passed as Data-URL.

Simple Example.twig
  • {% do
  • customer.sendEmail('Subject', 'Message', {
  • 'Invoice.pdf' : invoice.renderPdf()
  • })
  • %}
Full Customization.php
  • // dump raw content in mime format
  • print_r((string)(new \Ucms\Model\Email(
  • 'Support', 'support@' . $ucms->fqdn,
  • 'Customer', 'customer@example.provider',
  • 'Subject', 'Text', 'HTML', [
  • 'Invoice.pdf' => $invoice->renderPdf()
  • ])));

Click here for more examples

Useful tools


UCMS is exactly how web application development should be

CSS and Javascript minification

You can split your .css and .js files into modules and then select and minimize them as needed.

The corresponding minification controllers combine the modules into a single file.

In this way, you always keep track of your scripts and style sheets.

Do not be one of this crazy people who load 50 scripts to display a line of text in the browser.

CSS minification

Create pretty error pages

You can configure an error controller that can output template-based error messages, completely integrated into your layout. A debug backtrace can also be issued.

This error controller can even handle fatal errors such as parse errors.

This can also be triggered by the raise tag in a template. For example, if a user wants to access a product that is sold out, then simply use: {% raise 404 "Product sold out" %}

Pretty error page

Oops!

Something went wrong
404 Not Found

Product sold out.

Reusable controllers

The UCMS has many more reusable default controllers such as create account, login, logout, change email address, change password, forgot password, reset password, contact, sitemap, captcha and admin panel controllers.

If you need such features just extend the controller, overwrite methods if necessary and you're done with half of your web application.

A blog and an example company are also included.

SignupController
  • <?php
  • namespace Ucms\Controller\YourApp;
  • class YourSignupController extends
  • \Ucms\Controller\Ucms\AbstractSignupController
  • {
  • protected function onSignup(User $user) {
  • // do something application specific
  • return parent::onSignup($user);
  • }
  • };

Automatic source code documentation


Source code documentation in real time, just click a file and see a php.net-like info page.

Doc comments can be used

Let's say you have a simple model, for example an invoice, and this invoice has a getCustomer method.

Then you can insert doc comments into your source code (see example model).

This information can be extracted and used to create a documentation similar to that of php.net.

For example, if you look at a class on php.net, it will always be similarly documented as in the example below.

This can be realized with the reflection features of PHP.

Invoice.php (Example model)
  • /**
  • * Returns the customer object associated
  • * with the invoice.
  • *
  • * Returns the customer object using the
  • * **customerId** property of the invoice.
  • *
  • * @return The customer object.
  • *
  • * @example
  • * Example #1
  • * ```twig
  • * {% set invoice = api.getInvoice( 123 ),
  • * customer = invoice.getCustomer( )
  • * %}
  • * ```
  • * @notes
  • * That's just a simple example.
  • */
  • public function getCustomer() {
  • return $this->api->getCustomer(
  • $this->customerId
  • );
  • }

Explore your source code

A tree view will hierarchically display all source code and template files. You can click on any file in the treeview and then you will get a similar view as the one on php.net.

That works because our template engine can do almost anything, including instantiating php classes, so that it is possible to use PHP's reflection capabilities within a template and in real time.

Source code explorer

Visualize your PHP classes

We have programmed a controller that visualizes any class same like on php.net.

Thanks to the power of the new template language, it took only a few hours.

Every method, every property and every constant is linked to a subpage.

You can click on any method and you will see an information page as well as on php.net.

Documentation of a PHP class
  • namespace Ucms\Lib\YourApp;
  • class Invoice extends AbstractModel
  • {
  •     /* Private Properties */
  •     private $api = null
  •     /* Protected Properties */
  •     protected $id = null
  •     protected $customerId = null
  •     ...
  •     /* Methods */
  •     public __construct ( Api $api, array $row )
  •     public getCustomer (  )
  •     ...
  •     /* Inherited from AbstractModel */
  •     public __debugInfo (  )
  •     ...
  • }

Documented business logic

Here comes the doc comments from the beginning into play.

As you can see, the doc comment information has been extracted and added to a view that looks like the one on php.net but is related to your own code.

With decades of experience, we know how extremely important features like this are for a business.

It can happen at any time that an important employee leaves a company, and then his successor must be able to continue where the predecessor left off. That requires documentation.

Another example is the creation of a documentation in the form of a PDF file.

Instead of HTML code the controller could generate XML code for a PDF template.

And that's how easy it is to have professional documentation that is automatically generated without much effort, just from the source code.

Documentation of a method
Invoice::getCustomer

Returns the customer object associated with the invoice.


Description
public getCustomer ( )

Returns the customer object using the customerId property of the invoice.


Parameters

This function has no parameters.


Return Values

The customer object.


Example

Example #1

  • {% set invoice = api.getInvoice( 123 ),
  • customer = invoice.getCustomer( )
  • %}

Notes

That's just a simple example.


Look deeper than ever before


Never seen features are possible — with the UCMS and its super innovative components

Templates can be explored

Since our template engine can generate abstract syntax trees, it is possible to display this tree as a treeview, which you can click and explore.

This visual analysis gives you deeper insights into your business processes and business logic.

All your templates can be easily viewed using the source code documentation tool mentioned above. Just click on a file and explore the tree.

Abstract syntax tree — Click me!

    Scripts can be explored

    Even your scripts can be visualized so that you can see semicolons and curly braces in gray color if they are missing.

    Each function and control structure can be displayed as you see it here.

    So you can always check exactly if your code really corresponds to your desired logic.

    Such things are easy to programm even for you, after you have some experience with our template engine.

    Script AST — Click me!
          • :

    Expressions can be explored

    The operator precedence of any operation can be visualized using gray parentheses and nestings.

    This can help you to better understand when it is necessary to use parentheses and when they are unnecessary.

    1 + 2 * 3 % 4

    Made for developers, entrepreneurs and visionaries


    A system designed for maximum customizability, flexibility, performance and simplicity

    UCMS — made for business use

    The UCMS was designed for business use, but it can also be used for any other purpose.

    It is not a visual composer like Wordpress and requires PHP knowledge.

    The UCMS is intended for advanced use cases that cannot be solved with a visual composer.

    Conclusion
    • {% script %}
    • if( you_have_ucms )
    • {
    • your_development_costs--
    • your_development_time--
    • your_flexibility++
    • your_fun_at_programming++
    • }
    • {% endscript %}

    Become a Master of the universe and write code like a god — with UCMS

    Frequently Asked Questions

    Can I download the UCMS for free?

    Developing this software has taken a lot of time, money, and experience. These costs need to be covered. For this reason, a license to use the UCMS is required.

    Will the UCMS ever be open source?

    After the development costs have been amortized, we may publish the source code and allow free non-commercial use for individuals (but not companies). You should not expect that to happen in the near future, rather in 2021 or later.

    What payment methods can I use?

    You can pay by bank transfer or PayPal. Credit card payments are also possible via PayPal, all major credit cards from Visa, Mastercard, American Express and Discover are accepted.

    When do I get the license key?

    You will receive the license key and source code as soon as the payment has been credited to our bank account. If you pay with PayPal, we will send the license key and the source code with a delay of 3-5 days after receipt of the payment to protect us from payment fraud.

    What are the licensing terms?

    We grant license holders a non-exclusive, non-transferable, non-resellable, perpetual licence to use this software for one internet domain. This software license can not be transferred to third parties or resold.

    Can I get a custom license/support?

    Call us and let us talk about it. We offer many additional services, such as: Advice, support or creation of a skeleton of your application if you pay us for this. However, we do not manage or maintain any projects, and you will need your own developer to run your digital business for the long term.

    Can I publish my project on Github?

    It is not allowed to pass on or publish the UCMS source code in whole or in part. This means that you can only publish your own code that you wrote yourself, but you can not publish any parts of the UCMS code as open source on github or similar.

    Will I get an invoice if I purchase?

    Of course, after sending the order form you will receive an order confirmation / pro forma invoice (which is without tax relevance). The final (and tax law significant) invoice is sent together with your licence key and the source code after receipt of payment.

    Do I have to pay VAT?

    If you live in a member state of the European Union, you must also pay the VAT applicable to your country. The VAT rate depends on the EU member state in which you live. If you live somewhere else, there is no VAT.

    Are the UCMS costs tax deductible?

    Be sure to ask your accountant! If you are a company, the chances are very good that you can deduct the costs completely or at least partially from the tax. In the ideal case, it does not cost you anything to buy a UCMS license.