Prisma PHP Reactivity
Prisma PHP Reactivity allows you to write dynamic templates using {{ expression }}
syntax. These expressions are evaluated to render state or computed values without side effects.
Expression Rules
Inside {{ ... }}
, only pure expressions are allowed. These include reading state, performing computations, and string formatting. Any mutation or imperative code is forbidden.
Allowed vs. Not Allowed
Allowed in | Not Allowed in |
---|---|
Read-only state access{{ title }} , {{ user.name }}
|
Assignments & mutations{{ title = 'hello' }}
|
Arithmetic expressions{{ count + 1 }}
{{ Number(count) * 2 }}
|
Variable declarations{{ const x = 1 }}
|
Logical & ternary expressions{{ isActive ? 'Yes' : 'No' }}
|
Function definitions or classes |
String methods{{ name.length }}
{{ name.trim() }}
|
Multiple expressions or semicolons{{ a = 1; b = 2 }}
|
Optional chaining{{ user?.email }}
|
Impure functions{{ alert('Hi') }}
|
Nullish coalescing{{ title ?? 'default' }}
{{ title && 'default' }}
{{ title || 'default' }}
|
Modifying global/built-in objects |
Pure function calls{{ formatDate(date) }}
|
|
Inline template literals with backticks{{ `Username: ${user.name}` }}
{{ `Username length: ${user.name.length}` }}
{{ `Username UPPERCASE: ${user.name.toUpperCase()}` }}
|
Multiline template literals{{ `Line 1\nLine 2` }}
|
Attribute bindingclass="{{ className }}"
value="{{ user.name }}"
class="bg-green-500 {{ className }}"
|
Attribute bindings that cause side effects or mutate DOM<p {{ myText }}>Hello</p>
<img {{ ...myAttributes }}/>
|
β οΈ Reserved Variable Names
When using reactivity with {{ jsVariable }}
syntax, avoid naming your variables with commonly used HTML attributes or global DOM properties. These may cause unexpected behavior due to browser-native conflicts or overwritten properties during binding.
β Do Not Use These Reserved Names
Reserved Name | Why It's Problematic |
---|---|
class |
Conflicts with HTML class attribute; use className or customClass instead. |
name |
Clashes with form controls and global window.name . |
id |
Conflicts with window.id and DOM element identifiers. |
value |
Conflicts with input/textarea value bindings. |
type |
Can interfere with buttons, inputs, and script tags. |
length |
Often misused when working with strings or arrays. |
constructor |
Reserved by JavaScript objects; accessing it may expose prototype. |
toString |
Overwrites built-in object behavior and string conversion. |
children |
Reserved in many UI frameworks and DOM traversal. |
If you use any of these by accident, Prisma PHP will attempt to handle them safely using proxies and fallback defaults. However, for clarity and stability, itβs best to rename your variables when possible. Use prefixes like userClass
, formName
, or textValue
.
Using Mustache Variables
When you declare a variable using {{ jsVariable }}
, it becomes globally accessible and is available in pphp.props.jsVariable
. This mechanism allows Prisma PHP to enable shorthand usage of variable names within your script tags. Behind the scenes, the PPHP class manages reactivity and ensures seamless template rendering.
Examples
{{ user.name }}
<h1>Welcome, {{ user.name }}!</h1>
<p>Length: {{ textCount.length }}!</p>
<p>Balance: {{ Number(account.balance) + Number(bonus) }}</p>
<p>Status: {{ isActive ? 'Active' : 'Inactive' }}</p>
<p class="bg-red-500 {{ textColor }}"></p>
π§ͺ Example: Using Backticks with Expressions
You can use JavaScript template literals inside expressions as long as they remain on a single line. This is especially helpful when combining strings and variables.
{{ `Username: ${user.name}` }}
{{ `Balance: ${Number(balance).toFixed(2)}` }}
Avoid using line breaks inside the backticks. If you need multiline output, use multiple elements instead of a multiline template string.
When you use , the variable becomes globally accessible via window.jsVariable
and pphp.props.jsVariable
. Inside a function, you can retrieve its value using pphp.props.jsVariable
. To update the variable and trigger a re-render of the template, simply assign a new value to pphp.props.jsVariable
, like pphp.props.jsVariable = 'new value'
.
Initialize Variable
{{ user.name }}
<h1>Welcome, {{ user.name }}!</h1>
<p>Length: {{ textCount.length }}!</p>
<p>Balance: {{ Number(account.balance) + Number(bonus) }}</p>
<p>Status: {{ isActive ? 'Active' : 'Inactive' }}</p>
<p class="bg-red-500 {{ textColor }}"></p>
<script>
// Initialize variables using pphp.state
const [user, setUser] = pphp.state({ name: 'John Doe' });
const [textColor, setTextColor] = pphp.state('bg-red-500');
const [textCount] = pphp.state('Hello World');
const account = pphp.state({ balance: 100, bonus: 20 });
pphp.state('isActive', true); // Note: Direct effect methods (like pphp.effect) do not support this pattern
// Initialize variables using pphp.share
const [user, setUser] = pphp.share({ name: 'John Doe' });
const [textColor, setTextColor] = pphp.share('bg-red-500');
const [textCount] = pphp.share('Hello World');
const account = pphp.share({ balance: 100, bonus: 20 });
pphp.share('isActive', true); // Note: Direct effect methods (like pphp.effect) do not support this pattern
</script>
π₯ Example: Getting Input Value
<input type="text" onchange="inputValue = this.value" value="{{ inputValue }}" class="input input-bordered" />
<p>You entered: {{ inputValue }}</p>
<button onclick="getInputValue">Click Me!</button>
<script>
const [inputValue, setInputValue] = pphp.state(''); // Initialize input value state
const [user, setUser] = pphp.state({ name: 'John Doe' }); // Initialize user state
export function getInputValue() {
// This function can be called on button click
console.log(inputValue); // Access the current input value
setUser({ name: inputValue.value }); // Update user state with input value
}
</script>
Special Attributes: pp-bind
and pp-bind-*
Prisma PHP Reactivity introduces special attributes for dynamic DOM bindings:
pp-bind
and
pp-bind-*
.
These enable you to bind JavaScript variables to specific DOM properties and attributes in a declarative way, by default this will replace the content of the element with the value of the variable.
NOTE: When using pp-bind-class
, the existing class
attribute will be replaced entirely by the value of the JavaScript variable. If you want to preserve existing classes and append the variable's value, consider using a template like <p class="bg-amber-200 {{ jsVariable }}"></p>
instead.
π¬ pp-bind="jsVariable"
This binds the content of the element directly to the specified JavaScript variable. It sets the textContent of the element.
<span pp-bind="username"></span>
// sets: span.textContent = username
π§ pp-bind-*
(Dynamic Attribute Bindings)
The wildcard asterisk (*
) in pp-bind-*
allows you to bind any specific attribute or property of a DOM element.
pp-bind-value="age"
β setselement.value = age
pp-bind-checked="isChecked"
β setselement.checked = isChecked
pp-bind-class="dynamicClass"
β updateselement.className
pp-bind-disabled="isDisabled"
β setselement.disabled = isDisabled
π Key Differences
Feature | pp-bind |
pp-bind-* |
---|---|---|
Target | Element's textContent |
Specific attribute or property |
Use Case | Display text | Input, checkbox, class, disabled, etc. |
Example | <span pp-bind="username"></span> |
<input pp-bind-value="username" /> |
Note: Using pp-bind-*
attributes such as pp-bind-class
will replace the entire attribute with the value of your bound variable. For example, pp-bind-class="isActive ? 'bg-blue-500' : 'bg-red-500'"
will overwrite all existing classes on the element.
To combine static and dynamic classes, use string interpolation in the class
attribute, such as <p class="bg-amber-200 {{ jsVariable }}"></p>
. You can also use JavaScript template literals for more flexibility: class="{{ `bg-amber-200 ${jsVariable}` }}"
.
This approach preserves your static classes while appending or combining dynamic ones.
π§ͺ Live Example
<input type="text" pp-bind-value="userInput" />
<p pp-bind="userInput"></p>
<input type="checkbox" pp-bind-checked="acceptTerms" />
<div pp-bind-class="cardClass">Card</div>
These bindings ensure your DOM elements always stay in sync with your reactive state.
Setting Variables Using Events
In Prisma PHP Reactivity, you can directly update your reactive variables using standard DOM events such as onclick
, onchange
, oninput
, and more. Once a variable is updated, any element that uses it via {{ }}
or pp-bind
will automatically reflect the change.
π₯ Input Binding
Use an onchange
or oninput
event to assign the value to your variable.
<input type="text" onchange="name = this.value" class="input input-bordered" />
<p>Your name is: {{ name }}</p>
βοΈ Checkbox Binding
Combine pp-bind-checked
with an event to toggle booleans.
<input type="checkbox" pp-bind-checked="active" onchange="active = this.checked" />
<p>Account is: {{ active ? 'Active' : 'Inactive' }}</p>
π±οΈ Toggle on Button Click
A button click can toggle values or modify them in any way using pure expressions.
<button onclick="active = !active" class="btn btn-primary">
Toggle Active
</button>
<p>Status: {{ active ? 'Enabled' : 'Disabled' }}</p>
π§ͺ More Examples
<!-- Updating a number -->
<input type="number" onchange="age = this.value" class="input input-bordered" />
<p>Age: {{ age }}</p>
<!-- Dropdown selector -->
<select onchange="role = this.value" class="select select-bordered">
<option value="admin">Admin</option>
<option value="editor">Editor</option>
<option value="viewer">Viewer</option>
</select>
<p>Selected Role: {{ role }}</p>
<!-- Toggle visibility using a boolean -->
<button onclick="showInfo = !showInfo" class="btn btn-info">
Toggle Info
</button>
<div class="mt-2 {{ showInfo ? 'block' : 'hidden' }}">
Extra info is now visible!
</div>
Any JavaScript expression that updates a variable will automatically re-render all related reactive bindings. Keep expressions pure and declarative for best results.
NOTE: If you need to apply multiple behaviors, it is recommended to use a JavaScript function. For example, you can set attributes like pp-bind="setText"
and pp-bind-class="replaceClass"
. Within the function triggered by an event (e.g., onclick
), you can update the variable values and class names.
Conclusion
By restricting {{ ... }}
to pure expressions only, Prisma PHP Reactivity ensures your templates stay safe, fast, and easy to reason about. Avoid side effects, and your UI will stay in sync with the state like magic β¨.