edge-js / edge Goto Github PK
View Code? Open in Web Editor NEWNode.js template with a breath of fresh air
Home Page: https://edgejs.dev
License: MIT License
Node.js template with a breath of fresh air
Home Page: https://edgejs.dev
License: MIT License
When extended a layout some of the sections dont appear later in the final template.
In the following example the content section doesn't get rendered, as I would expect.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
</head>
<body>
@!section('content')
@!section('footer')
</body>
</html>
Then an extended layout:
@layout('layouts/master')
@section('footer')
<h2>footer content</h2>
@endsection
Then I have the actual page / template:
@layout('layouts/extended-layout')
@section('content')
CONTENT HERE DOESNT APPEAR
@endsection
Hey friend,
I've this code
@each(item in flags) @!components('components/bullet',els=item) @endeach
and in my components i've
@each(el in els) {{el.token}} @endeach
When i run this code, the information is that i'm using nothing is happen. Could you explain me why is that?
In my controller, I pass variables to my view like this:
return view.render('search', {
total: 0
})
From my view, if I do {{ total }}
it will be empty, but it works if I pass the variable like a string:
return view.render('search', {
total: '0'
})
Reproduce:
resources/views/layouts/base.edge
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
@!section('content')
</body>
</html>
resources/views/dashboard.edge
@layout('layouts/base')
@section('content')
<a href="#" class="btn btn-link btn-notification">
<div class="icon-badge">
<i class="fa fa-bell fa-lg" />
<span class="badge"> </span>
</div>
</a>
@endsection
Edge will render more than one icon. It has problem with self-closing tag at line <i class="fa fa-bell fa-lg" />
Hi Virk,
If this platform is wrong then I appologise in advance. Right now i am confused about how to declare a variable in edge.js. like say i want to declare a variable named "i" and then want to increment in a loop. how to do it?
I have an edge file with the following line:
<form action="{{ route('MyController.action') }}?_method=PUT">
The router using adonisjs is:
Route.put("/action/:id", "MyController.action");
How do I pass the id to the route function?
Where can I find the route documentation(The source I already found)?
Thanks
Example:
@each(day in range(7))
@each(hour in range(9,17))
{{ day }}:{{ hour }}
@endeach
@endeach
Gives the following result
:9 :10 :11 :12 :13 :14 :15 :16 :9 :10 :11 :12 :13 :14 :15 :16 :9 :10 :11 :12 :13 :14 :15 :16 :9 :10 :11 :12 :13 :14 :15 :16 :9 :10 :11 :12 :13 :14 :15 :16 :9 :10 :11 :12 :13 :14 :15 :16 :9 :10 :11 :12 :13 :14 :15 :16
When I was really expecting:
0:9 0:10 0:12 0:13... 1:9 1:10 ... 6:15, 6:16
I couldn't find anything in the documents to suggest how the engine is supposed to manage nested loops, but I would expect the outer iterator value to remain accessible in inner loops.
it is possible to parse a edge object to normal javascript object?
I am trying to pass a object to "data" attribute from datatables plugin
My .edge template
var myTable = $('#dataTable').DataTable({
dom: 'tpi',
data: {{data}},
columns: [
@each(item in colunas)
{ data: '{{item}}'},
@endeach
]
})
The result:
var myTable = $('#dataTable').DataTable({
dom: 'tpi',
data: [object Object], //HERE IS THE PROBLEM
columns: [
{ data: 'id'},
{ data: 'name'},
{ data: 'description'}
]
})
I encountered a weird error, that was initially puzzling: I got an output which should have been impossible when looking at the expression I wrote in a mustache block. Only when I looked at it in the debugger, I noticed that edge.js was transforming my expression to something it was never intended to be, messing up its logic.
Code in template:
{{line.lineName + ((user.line.id === line.id) ? ' (current)' : (' (' + (line.user.username || 'unselected') + ')'))}}
Compiled code:
out += ` ${this.context.escape(this.context.accessChild(this.context.resolve('line'), ['lineName']) + this.context.accessChild(this.context.resolve('user'), ['line','id']) === this.context.accessChild(this.context.resolve('line'), ['id']) ? ' (current)' : (' (' + this.context.accessChild(this.context.resolve('line'), ['user','username']) || 'unselected') + ')')}\n`
Values:
line.id === 1
line.lineName === 'aaa'
line.user === null
user.line === null
Expected result: aaa (unselected)
Actual result: (undefined)
<< that is a space and then "(undefined)"
I used edge.js 1.1.3 from @adonisjs/framework
4.0.28
it would be nice to be able to work with the data at the component level instead on a separate presenter file
such feature will allow for writing a much easier/cleaner component based applications where the component holds all of the html and the logic that drives it in one place.
@presenter
// presenter block will have the same scope to the file it lives in
// so in the case of components it will only have access to props and to the global variables
// where on a normal edge file it will have access to everything that gets passed to it
@endpresenter
// html/edge syntax goes here...
by making it inside a presenter block we avoid confusing it with the script tag for new-comers and they will be able to tell which is which.
appending content to a master layout using @!section('content')
works fine, however using @!section('content')
(notice the whitespace AFTER closing parenthesis?) throws an error:
InvalidExpressionException
E_INVALID_EXPRESSION: Invalid expression <'content') > passed to (section)
block
I was looking for hours as of why it didn't work, while following edge docs closely.
Version 1.1.1
Found Bug
After reading the docs from both AdonisJS 4 and Edge (awesome projects btw) and write an example ...
@if(username)
<h1> Hello {{ username }} </h1>
@else
<h1> Hello anonymous </h1>
@endif
this happened
{ InvalidExpressionException: E_INVALID_EXPRESSION: Invalid expression <username) > passed to (if) block
at (C:\Users\prvjefolar0\Desktop\personal_workspace\test\views\whitespace.edge:1:0)
at Function.invalidTagExpression (C:\Users\prvjefolar0\Desktop\personal_workspace\test\node_modules\edge.js\src\Exceptions\index.js:87:19)
at IfTag._compileStatement (C:\Users\prvjefolar0\Desktop\personal_workspace\test\node_modules\edge.js\src\Tags\BaseTag.js:43:43)
at IfTag.compile (C:\Users\prvjefolar0\Desktop\personal_workspace\test\node_modules\edge.js\src\Tags\IfTag.js:82:36)
at TemplateCompiler.parseTag (C:\Users\prvjefolar0\Desktop\personal_workspace\test\node_modules\edge.js\src\Template\Compiler.js:152:21)
at TemplateCompiler.parseLine (C:\Users\prvjefolar0\Desktop\personal_workspace\test\node_modules\edge.js\src\Template\Compiler.js:186:12)
at ast.forEach (C:\Users\prvjefolar0\Desktop\personal_workspace\test\node_modules\edge.js\src\Template\Compiler.js:116:32)
at Array.forEach (native)
at TemplateCompiler._compileAst (C:\Users\prvjefolar0\Desktop\personal_workspace\test\node_modules\edge.js\src\Template\Compiler.js:116:9)
at TemplateCompiler.compile (C:\Users\prvjefolar0\Desktop\personal_workspace\test\node_modules\edge.js\src\Template\Compiler.js:225:80)
at Template._compileView (C:\Users\prvjefolar0\Desktop\personal_workspace\test\node_modules\edge.js\src\Template\index.js:221:37) lineno: 1, charno: '0' }
At first I wasn't sure about the problem. Then I copy/paste from docs and tried it again and everything was ok.
It turns out that I wrote the first line with a space
@if(username)//space or
But only the first line, following tags (@else or @END_TAG ) take this without a problem.
Previous versions handle this except for 1.1.0.
Is not a big problem, if one write each line correctly this can be avoided but I thought I should report this.
PS. If this was already fixed in a future release please ignore this.
Thanks for your time and effort on this projects.
Is there an option to minify the generated HTML.
Thank you.
Hi,
I would like to know if it's planned to have the Syntax Highlighting plugin also for Visual Studio Code, as AdonisJS development seems to be great also with that IDE.
Hi
example code:
@each( item in items )
<td> {{ item.name }} </td>
@each( plan in plans )
{{ renderPlan( item.plans, plan.id ) }}
@endeach
@endeach
Where renderPlan
is registered View.global via service provider in Adonis like
renderPlan( plans, idToFind){
// here plans is always empty string
...
}
I've set debugger like
@each( item in items )
<td> {{ item.name }} </td>
@debugger
@each( plan in plans )
@debugger
{{ renderPlan( item.plans, plan.id ) }}
@endeach
@endeach
on the first debugger at runtime
this this.context.resolve('item.plans')
returns correct value from object
the second debugger stop, however, returns ""
( right after the newFrame() call )
If you put a space between @if
and the condition parens, you get E_INVALID_EXPRESSION
, which seems like a strange restriction. I looked through this repo but didn't see a place where I could suggest patching to allow for the space (assuming you think it's even a good change to make)...
Hello,
Where am I supposed to add global ?
I'm rendering the view in my controller with
return view.render('menu/main')
e.g.
{{ elIf('<span class="helper-text" data-error="$self"></span>', getErrorFor('email'), hasErrorFor('email')) }}
will edge support Express?
How can I include a file using relative paths using Edge?
Example:
@include('./includes.user-card')
Does not work. Then I have to do:
@include('pages.user.includes.user-card')
Thanks a lot if you can help.
At this time, I'm unable to do this: @include('my-folder.' + someVariable)
because it will throw: InvalidExpressionException: E_INVALID_EXPRESSION: Invalid expression <'my-folder.' + someVariable> passed to (include) block
and the only way to achieve this is doing a long if/elseif which is really ugly.
I suppose the problem is also for other tags, but I haven't tested it with them.
Is anyone working on IDE/TextEditor integrations (or has it already been done) ?
Hey 👋
Edge Components doesn't have access to globals registered with View.globals
.
A simple test would be to use the globals url
provided by Adonis.
How to Used in Koa2?
Is there anyway to reload a @component with jquery? sorry if its a noob question.
Hi
When I use {{ console.log( variable ) }}
inside .edge
file, I get the following error:
this.context.resolve(...).log is not a function
How to use console.log or any raw javascript statement inside .edge file?
In many cases when you are looping through an object, you will need to write a conditional, the logic throws an error if I add a if within an each. Is this normal?
From @clayderson on September 19, 2018 2:9
If I try to use the backticks, an error message appears when I try to access the page
Example
player.attr('src', `https://example.com/renders/body/${data.uuid}?scale=4`)
Copied from original issue: adonisjs/core#951
Hi, is it possible to use a custom file extension such as .html
or .edge.html
?
Hi. I have a question. It is possible to format an floating point value into 2 decimal places? example output is 45.6785 and it should be display as 45.68.
Stuck with impossibility of access to parent variables in Edge, like this:
@each(fabric in fabrics)
<h2>{{ fabric.name }} </h2>
@each(product in products)
@if(product.parent == fabric.id)
<a href="/settings/product/{{product.id}}">{{ product.name }}</a>
@endif
@endeach
@endeach
Later on forum I got explanation that I should use $parent.fabric.id
.
I came from Laravel world, where all variable accesible in all @foreach while it open.
I more like Edge way with '$parent', it's more clear, but nowhere in documentation I can't find it. Can you add reference to '$parent' on 'Conditionals' page? Something called 'nested loops' maybe.
Hi there,
Is it possible to create globals that support coroutines?
for example:
edge.global('test', async function () {
return await asyncFunc()
})
Thank you
Hi,
First of all thanks for this project and the entire AdonisJS ecosystem.
I read the docs but couldn't find how to declare a variable inside an edge file.
I would like to define an items constant and use it inside a loop.
then I would like to display the value and manipulate the value.
Here is an example:
file.edge
<script>
const items = ["A","B","C"];
<script>
<select>
@each(item in items)
<option value="{{item.toLowerCase()}}">{{item}}</option>
@endeach
</select>
Thanks in advance
Hi.
Is there a way for modulo operation?
Thanks.
I’ve noticed that when you use a @section
tag inside a @component
the component throws an error!
I would like to decouple things and probably re-use the sections defined in the @layout('layouts.master')
inside a @component
.
For instance, I have a @!section('extra_js')
which is right at the bottom of the @layout('layouts.master')
and within the @component
, I would like to add JS dependencies that are only related to the component itself and to be loaded only when that component is in use.
e.g.
- master.edge
<html>
...
<body>
@!section('header')
<main>
@!section('content')
</main>
<footer>
@!section('footer')
</footer>
{{-- extra js --}}
@!section('extra_js')
</body>
</html>
- home.edge
@section('header')
@!component('components.header', type = 'header', title = title, description = description)
@endsection
- components/header.edge
<header id="{{ type }}">
...
</header>
@section('extra_js')
<script type="text/javascript" src="{{ appUrl('js/vendor/file.min.js') }}"></script>
@endsection
Another thing that I’ve noticed is that when you try to re-use a @section within a @section itself it doesn’t include the code where is supposed to be.
e.g.
- master.edge
@!section('content')
@!section('bottom')
- home.edge
@section('content')
<h1>Welcome</h1>
@section('bottom')
<p>some other text</p>
@endsection
@endsection
the code from the nested section is included within the @section('content')
rather than @section('bottom')
So in Nunjucks I was able to do something like this....
layout
<div class="main-content {% block classes %}{% endblock %}"></div>
This allowed me to do this in a child template
{% block classes %}container is-about{% endblock %}
It's a tiny example but it was definitely helpful for keeping view specific settings outside of the controller. This doesn't work with @section blocks. Would this be something that you want to look to add?
Instead of using a custom "global" or writing:
{{ my_data !== undefined || my_data !== '' ? my_data : 'nothing' }}
It will be really handy/cleaner to have a shortcut like:
{{ my_data or 'nothing' }}
From @watzon on November 8, 2017 21:15
Laravel gives us the ability to have blade templates that take blade/markdown and turn it into an HTML email template. This saves some major headache when it comes to making emails beautiful and responsive. It would be awesome if Adonis had the same functionality.
Add a markdown method to the Mailer and some built in components that get added to edge templates. Developers should ideally be able to use the markdown method to render an edge template, or send plain markdown which will be parsed into valid email HTML before being sent.
<!-- resources/views/emails/shipped.edge -->
@component('mail.message')
# Order Shipped
Your order has been shipped!
@component('mail.button', url = {{ order.viewUrl }})
View Order
@endcomponent
Thanks,<br>
{{ Config('appName') }}
@endcomponent
// app/Controllers/Http/OrdersController.js
await Mail.markdown('emails.shipped', Order.toJSON(), (message) => {
message.subject('Hello ...')
message.from('[email protected]')
message.to('[email protected]')
})
https://laravel.com/docs/5.5/mail#markdown-mailables
https://www.npmjs.com/package/markdown
https://www.npmjs.com/package/markdown-it
Copied from original issue: adonisjs/mail#15
Hello i'm trying to do something like this :
<input value="{{object1[object2.id]}}">
But I can't find a solution. Is this even possible ?
Hi!
I have a code in edge template:
@if(field.type == 'checkbox')
<fieldset id="{{ field.name }}">
@each(checkBoxItem in field.data)
<span class="checkbox-item">
<input type="checkbox" id="{{ checkBoxItem.name }}" name="{{ field.name }}" value="{{ checkBoxItem.value }}" {{ checkBoxItem.checked ? "checked" : "" }}>
<label for="{{ checkBoxItem.name }}">{{ checkBoxItem.title }}</label>
</span>
@endeach
</fieldset>
@endif
When I use 'field.name' outside of @each loop, it works fine, but when I use it inside a loop, it renders as 'undefined'.
P.S. Wanna say thanks to all people who are working with Adonis, Edge and all ecosystem, it's really cool.
Hi,
Is there a way to have nested layouts with sections ?
partials/popups.edge
@!component('components/modalLogin')
components/modalLogin
<form>
{{ csrfField() }}
</form>
Error
[1] { Error: Cannot call function csrfField from components/modalLogin.edge view
[1] at Context.callFn (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Context/index.js:286:13)
[1] at Template.templateFn (eval at run (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/Runner.js:51:20), <anonymous>:9:52)
[1] at Template.eval (eval at run (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/Runner.js:51:20), <anonymous>:29:14)
[1] at TemplateRunner.run (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/Runner.js:54:39)
[1] at Template.renderWithContext (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/index.js:445:55)
[1] at Template.isolate.bind.newContext.$slot.main (eval at run (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/Runner.js:51:20), <anonymous>:51:20)
[1] at Template.isolate (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/index.js:398:5)
[1] at Template.templateFn (eval at run (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/Runner.js:51:20), <anonymous>:50:8)
[1] at Template.eval (eval at run (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/Runner.js:51:20), <anonymous>:81:14)
[1] at TemplateRunner.run (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/Runner.js:54:39)
[1] at Template.runTimeRender (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/index.js:374:65)
[1] at Template.templateFn (eval at run (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/Runner.js:51:20), <anonymous>:4:18)
[1] at Template.eval (eval at run (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/Runner.js:51:20), <anonymous>:12:14)
[1] at TemplateRunner.run (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/Runner.js:54:39)
[1] at Template.runTimeRender (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/index.js:374:65)
[1] at Template.templateFn (eval at run (/home/dimensi/projects/paraspace/node_modules/edge.js/src/Template/Runner.js:51:20), <anonymous>:24:18) status: 500 }
Hello!
I have two codes for each. In the second each, I want to access the values of the first each. But it doesn't. Returns undefined.
Thanks!
Is there a way to set the value of a variable if it is not set already? I think I could use something like:
@unless(optionalVar)
@set('optionalVar', 'default value')
@endunless
But that's pretty much code. Something like this would be better:
@setDefault('optionalVar', 'default value')
This would be very useful in components. The documentation mentions that one could write their own tags. But it just points to a video that does not exist.
Upcast v2.1.1 has been published and this package is still using v1.x.x
Hello,
How do I turn off xss protection?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.