fusion4j - declarative rendering language for the JVM based on Neos.Fusion

Overview

fusion4j - declarative rendering language for the JVM based on Neos.Fusion

Supports the Neos Fusion syntax/semantic as described in the official Neos Fusion documentation.

  • full Fusion language parser with out-of-the-box AFX support
  • Fusion runtime for the JVM usable as standalone, server-side template engine
  • default Fusion objects from Neos.Fusion
  • written in Kotlin
  • functional, library styled API - modules are usable standalone
  • antlr parser grammar for Fusion / AFX
  • runtime and parser fully stateless, immutable and thread-safe
  • runtime evaluation happens lazy everywhere
  • works great with the IntelliJ Neos-Support Plugin (except jump-to-class)
  • coming soon: Spring boot integration
  • coming soon: a Monocle-like Fusion styleguide for presentational components (also serves as Spring boot example / how to use)

Check out the BDD feature tests for:

Spring integration

Currently, I develop the Spring Boot integration inside the styleguide sub-package before generalizing it.

Features:

  • FusionView for Fusion runtime delegation of Spring view rendering
  • Immutable runtime container for PROD mode (loaded once at startup)
  • Reloadable runtime container for local dev mode (with hot-Fusion-code-reloading on file changes)
  • runtime configuration integration via externalized properties
  • CDI integration: custom EEL Helpers and Fusion Object Implementation as Spring beans
  • Fusion object for HTTP Response

This is currently WIP, so there is no doc for now :/ but check out:

TODO how to use doc

fusion4j styleguide

The styleguide has three purposes:

  • living styleguide for your Fusion components, as known from Monocle
  • analyzing / browsing of your parsed and semantically normalized Fusion code
  • real-world example of the Spring integration and fusion4j in action

The styleguide UI itself is written in fusion4j plus a bit of kotlin models and controllers.

TODO doc

Info on development state

I consider the current development state early alpha. Expect some missing edge-case features, bugs and performance issues. Pls report, I need input ;)

The basic functionality of the Fusion runtime is mainly done. The parser already supports all Fusion syntax features. The lang module contains most logic to implement the Fusion semantics. Only a small part is actually implemented in the runtime itself.

Missing features that I'm aware of:

  • Bugfix: PositionalArraySorter -> keep track of declared key order instead of alphanumeric key sorting!
  • @position sorting in some places: (inside @context, @if) - WIP
  • Neos.Fusion:Augmenter basic Fusion Object
  • include ant paths, for now just * (same folder) and ** (include all sub-folders) works
  • caching
  • configurable processing of AFX HTML comments / style tags / script tags -> parsing already done

I actively develop this package, feel free to contact me and/or contribute ;)

Things to validate/finish:

  • multiline EEL expression tests / error message with offending symbol

Use-Cases

  • use the Neos Fusion declarative rendering approach as standalone template engine in your JVM application!
    • structured & testable rendering components
    • no more messy template includes ;)
  • write awesome code analysis based tools for the Fusion language, e.g.
    • linters and validators
    • performance/complexity analysis tools
    • pre-compilers
    • documentation tools
  • re-using rendering logic / template integration in a two-stack CMS approach
    • with Neos as CMS content editing stack (providing both data and template), and
    • JVM based applications as delivery stack
    • "single source of template"

two stack CMS with Neos

There are several reasons for architectures, where the PHP / Neos CMS is not front-facing but used as an internal content editing tool. Content is instead delivered by more "enterprisy" technology like JVM web server frameworks (f.e. Spring Boot). An architecture approach to separate those concerns is sometimes called "two-stack CMS". One stack provides an editing platform (Neos CMS) and the other stack delivers a somehow statically released content snapshot. Those two stacks may run in separate networks, where the delivery stack focuses on security, reliability, performance and scalability. The editing stack may not have such high availability requirements but focuses more on the editing experience. That's probably why you chose Neos in the first place ;) <3

TODO write concept on how to share templates between two-stacks

Usage

include via Maven / Gradle

Internal module dependencies:

  • lang (independent)
  • runtime (lang)
  • default-fusion (lang, runtime)
  • test-utils (lang, runtime)

For now, there are just SNAPSHOT releases I made local for testing: First 0.9.0 release is coming soon...

repositories {
    maven("https://s01.oss.sonatype.org/content/repositories/snapshots")
    // ...
}

dependencies {
    // ...
    implementation(module("io.neos.fusion4j:default-fusion:0.9.0-SNAPSHOT"))
    // ...
    testImplementation(module("io.neos.fusion4j:test-utils:0.9.0-SNAPSHOT"))
    // ...
}

code examples

TODO - I will complete this when the API is more stable. For now, checkout the BDD Steps

or the Spring integration

Modules

All parts of fusion4j are designed to give you the experience of using a library instead of being caged in a framework. There is some code to be written to get started with fusion4j (see usage), but you can use the single aspects of this library pretty easily in a standalone way. F.e. you can only parse Fusion code and perform custom logic like analysing it.

Note, that if you want to reuse the BDD step definitions, they are found

Language module

This is implemented in the lang sub-package.

  • grammar definition of Fusion in antlr4
  • validated, consistent and immutable domain model
    • raw language meta model
      • parsing of Fusion code into a usable raw AST-like, but Fusion-domain-specific model
      • AST code references
      • code comments are part of the raw meta-model!
      • code comments to fusion element correlation (e.g. for code analysis or a "Fusion-Doc")
    • semantic meta-model / normalization of loaded Fusion files
      • merging of prototype declarations
      • merging of path configurations
      • nested path normalization
      • application of path erasures
      • file includes / load order
      • loading of Fusion object instances
  • DSL support
    • domain specific language parser API
    • default DSLs:
      • AFX
  • Fusion file abstraction
    • filesystem
    • classpath
    • in-memory (String)
  • Reloading Fusion code at runtime is possible by creating a new instance of the Runtime (it's immutable)

Runtime module (WIP)

This is implemented in the runtime sub-package.

  • FusionRuntime implemented for usage in Java
  • immutable, thread-safe Runtime
  • almost everything is evaluated lazy
  • TODO/DISCUSS: reactive implementation for reactor / kotlin coroutines
  • IMPORTANT: for now, the runtime is blocking code. If you use Spring Webflux or any other reactive / non-blocking technology, you should load your model first, then use the Fusion Runtime as blocking mapper. -> for now there is no way to use non-blocking code in Fusion Object implementations or EEL Helpers!

Important classes (also entry points for class documentation):

  • FusionRuntimeImplementationAccess
  • FusionRuntime

Default Fusion module (WIP)

Basic Fusion library - prototypes + implementations of Neos.Fusion

Implemented Fusion prototypes:

  • Neos.Fusion:Join
  • Neos.Fusion:DataStructure
  • Neos.Fusion:Case
  • Neos.Fusion:Matcher
  • Neos.Fusion:Renderer
  • Neos.Fusion:Value
  • Neos.Fusion:Component
  • Neos.Fusion:CanRender
  • Neos.Fusion:Tag
  • Neos.Fusion:Map
  • Neos.Fusion:Loop
  • Neos.Fusion:Reduce
  • Neos.Fusion:Augmenter

Deprecated Fusion objects (will throw an exception on usage with alternative message):

  • Neos.Fusion:Array
  • Neos.Fusion:RawArray
  • Neos.Fusion:Template
  • Neos.Fusion:Collection
  • Neos.Fusion:RawCollection
  • Neos.Fusion:Attributes

Unsupported Fusion objects (will throw an exception on usage with explanation message):

  • Neos.Fusion:Http.ResponseHead
  • Neos.Fusion:Http.Message
  • Neos.Fusion:UriBuilder
  • Neos.Fusion:ResourceUri
  • Neos.Fusion:Link.Resource

development

generate antlr code with: gradlew clean generateGrammarSource

run all tests gradlew clean test

run styleguide css resources sass compiler

cd styleguide
npm run sass-dev

further ideas

  • (TODO) code analysis API
    • possible use cases: validators / linters, performance analysis, documentation
    • API for analysing fusion code on both:
      • raw lang model
      • normalized meta model
    • (TODO / Discuss / Ideas welcome) default analysis for:
      • unused/unreachable code
      • raw to normalized "declaration application path" debugging (a.k.a. "which code overrides my root path"?)
      • recognition of possible runtime errors / pre-compile-like validations on normalized model, e.g.
        • type checks, e.g.
          • warnings on type morphing
          • render evaluation result type check ()
        • no implementation class set for prototypes
      • side effect detection (a.k.a. "is my component side effect free"?), looks for:
        • context mutations via @context meta property
        • global state access via expression analysis

discuss: will there be a reactive/non-blocking IO implementation? do we need one? For now, if you want to use fusion4j with reactor/Spring Boot Webflux or another non-blocking IO library, the rendering logic (more specific: the Fusion object implementations or EEL helper calls) should not perform any blocking IO code. To work around this, perform all IO operations before hands (in the controller) and put the emitted object in the Fusion context before rendering.

You might also like...
An under development minecraft plugin (1.8.8) to learning Kotlin language

CorePlus CorePlus is a minecraft plugin coded with Kotlin language. Still under development CorePlus will be an essential for each minecraft servers !

Metremenqeemi - Android/iOS app to teach the Coptic Language

ⲙⲉⲧⲣⲉⲙⲛ̀ⲭⲏⲙⲓ The Open Source Android/iOS app to learn how to read and understand the Coptic Language Join our Discord Channel About the Curriculum The

Lambda-snake.kt - Snake Game Implementation for Web using Kotlin programming language compiled for Javascript
Lambda-snake.kt - Snake Game Implementation for Web using Kotlin programming language compiled for Javascript

Projeto da disciplina de Linguagem de Programação Funcional 2021.1 (jan/2022) 📄

FaceTimeClone app that implements Coroutines , mvvm architecture , clean architecture , navigation component , hilt , etc.... using kotlin language
FaceTimeClone app that implements Coroutines , mvvm architecture , clean architecture , navigation component , hilt , etc.... using kotlin language

This repository contains a FaceTimeClone app that implements Coroutines , mvvm architecture , clean architecture , navigation component , hilt , etc.... using kotlin language

Kotlin DALL·E 2 is a new AI system that can create realistic images and art from a description in natural language.
Kotlin DALL·E 2 is a new AI system that can create realistic images and art from a description in natural language.

OpenAI Dall•E AI Kotlin Mobile App OpenAI Dall•E Application Build With Kotlin MVVM (Model - View - ViewModel) Clean Architecture, Beautiful Design UI

🔴 A non-deterministic finite-state machine for Android & JVM that won't let you down
🔴 A non-deterministic finite-state machine for Android & JVM that won't let you down

HAL is a non-deterministic finite-state machine for Android & JVM built with Coroutines StateFlow and LiveData. Why non-deterministic? Because in a no

:blowfish: An Android & JVM key-value storage powered by Protobuf and Coroutines

PufferDB PufferDB is a ⚡ key-value storage powered by Protocol Buffers (aka Protobuf) and Coroutines. The purpose of this library is to provide an eff

🚟 Lightweight, and simple scheduling library made for Kotlin (JVM)
🚟 Lightweight, and simple scheduling library made for Kotlin (JVM)

Haru 🚟 Lightweight, and simple scheduling library made for Kotlin (JVM) Why did you build this? I built this library as a personal usage library to h

A injection minecraft cheat using jvm attach api

Luminous A injection minecraft cheat using jvm attach api Website: https://lumi.getfdp.today Build We used a thing called Wrapper to make development

Comments
  • Task: performance improvement runtime attempt 1

    Task: performance improvement runtime attempt 1

    Adresses: #4

    • optimized RuntimeFusionObjectInstance
    • removed big toStrings
    • fixed some static (Kotlin) initializers
    • commented out log.debug messages / may be removed or something^^

    For now, there is a 150% performance improvement on the styleguide page: http://localhost:8080/fusion/path-index

    Also, the performance.feature tests reflect the improvement.

    More profiling/debugging to come.

    opened by erickloss 2
  • profile / improve performance of runtime evaluation

    profile / improve performance of runtime evaluation

    currently, there seems to be an overhead, that slows down the evaluation method. Big loops / context objects / deep AFX components cause the overall rendering to be pretty slow.

    Tasks:

    • [ ] profile performance issues
    • [ ] improve performance, independently from the Fusion rendering cache #2

    any help is appreciated <3

    also see performance.feature in the default-fusion package

    help wanted performance-issue fusion4j-runtime 
    opened by erickloss 1
  • PositionalArraySorter does not keep track of originally declared key positions

    PositionalArraySorter does not keep track of originally declared key positions

    Currently, all nested keys that have no explicit specified position are sorted alpha-numerical by name instead of keeping track of their declaration position.

    That needs to be fixed in the PositionalArraySorter class.

    bug 
    opened by erickloss 0
  • Implement Fusion rendering cache

    Implement Fusion rendering cache

    • [ ] read/index/store @cache configuration in path index / prototype store / fusion object instances (at startup time)
    • [ ] evaluate @cache directives at runtime
      • [ ] cache identifier creation
      • [ ] cache modes
      • [ ] cache tags
    • [ ] implement cache backend abstraction
      • [ ] implement default filesystem cache backend
    • [ ] implement cache flush API
    enhancement good first issue help wanted missing-core-feature 
    opened by erickloss 0
Releases(0.9.2)
  • 0.9.2(May 6, 2022)

  • 0.9.1(May 3, 2022)

  • 0.9.0(Apr 1, 2022)

    This is the first pre release of fusion4j.

    missing features:

    • Fusion Cache
    • position sorting in some places (if, process)
    • profiler WIP
    • Spring integration module WIP (currently developed in the styleguide application)

    bugs:

    • rendering performance for complex components is still not good enough
    • positional array sorter default sorting (alpha-numeric instead of keeping original declaration order)
    Source code(tar.gz)
    Source code(zip)
Owner
sandstorm
sandstorm - building great web applications
sandstorm
{ } Declarative Kotlin DSL for choreographing Android transitions

Transition X Kotlin DSL for choreographing Android Transitions TransitionManager makes it easy to animate simple changes to layout without needing to

Arunkumar 520 Dec 16, 2022
A declarative, Kotlin-idiomatic API for writing dynamic command line applications.

A declarative, Kotlin-idiomatic API for writing dynamic command line applications.

Varabyte 349 Jan 9, 2023
Kotlin Multiplatform Mobile + Mobile Declarative UI Framework (Jetpack Compose and SwiftUI)

Kotlin Multiplatform Mobile + Mobile Declarative UI Framework (Jetpack Compose and SwiftUI)

Kotchaphan Muangsan 3 Nov 15, 2022
Ivy FRP is a Functional Reactive Programming framework for declarative-style programming for Android

FRP (Functional Reactive Programming) framework for declarative-style programming for Andorid. :rocket: (compatible with Jetpack Compose)

null 8 Nov 24, 2022
Solves the audit needs for any JVM based application

Auditor-v1 Solves the audit needs for any JVM based application.

Lowe's 12 Dec 15, 2022
An example for who are all going to start learning Kotlin programming language to develop Android application.

Kotlin Example Here is an example for who are all going to start learning Kotlin programming language to develop Android application. First check this

Prabhakar Thota 56 Sep 16, 2022
LifecycleMvp 1.2 0.0 Kotlin is MVP architecture implementation with Android Architecture Components and Kotlin language features

MinSDK 14+ Download Gradle Add to project level build.gradle allprojects { repositories { ... maven { url 'https://jitpack.io' }

Robert 20 Nov 9, 2021
🍼Debug Bottle is an Android runtime debug / develop tools written using kotlin language.

???? 中文 / ???? 日本語 / ???? English ?? Debug Bottle An Android debug / develop tools written using Kotlin language. All the features in Debug bottle are

Yuriel Arlencloyn 846 Nov 14, 2022
ATH Sample is a sample Authentication and Authorization Application with Kotlin Language and MVVM architecture.

ATH Sample ATH Sample is a sample Authentication and Authorization Application with Kotlin Language and MVVM architecture. Overview ATH Sample is a sa

AbolfaZl RezaEi 4 Jun 8, 2021
A furry-themed assembly language and interpreter written in Kotlin.

A furry-themed assembly language and interpreter written in Kotlin. Inspired by Furcode, the Synacor challenge, and JVM bytecode. I spent multiple hou

Maow 9 Nov 22, 2021