Commit graph

24 commits

Author SHA1 Message Date
Mitchell Hanberg
f942817994
Utilize the EEx Engine instead of creating an EEx string (#177) 2022-04-19 23:56:46 -04:00
Mitchell Hanberg
c965048f40
Better whitespace handling and control (#145)
* Fine tune whitespace

The EEx outut now emits more human-readable and predictable formatting.
This includes proper indenting, at least for each "root" template.

* Internal whitespace control

You can now use a bang version of any nonvoid tag to emit the markup
witout the internal whitespace. This means that there will not be a
newline emitted after the opening tag and before the closing tag.
2021-08-29 17:45:07 -04:00
Mitchell Hanberg
d9f00e5147
Class object syntax (#140)
* Class object syntax

Allows for conditionally setting classes on an element.

* Docs for class bindings
2021-06-27 12:04:19 -04:00
Mitchell Hanberg
9d05f74cdf
Properly emit boolean attributes (#139)
* Update some docs

* Properly emit boolean attributes.

* Account for quoted literals when compiling attributes

* Update changelog
2021-06-26 21:47:21 -04:00
Mitchell Hanberg
540692f7cd Void elements can be compiled with no attrs 2021-06-03 23:13:06 -04:00
Mitchell Hanberg
fe3aed5df7 Some cleanup 2021-04-09 00:16:30 -04:00
Mitchell Hanberg
41f9b94d0f Hook the AST generation in to the temple macros
- Removes the old way
- Removes the ability to compact an element
2021-04-09 00:16:30 -04:00
Mitchell Hanberg
ced2f6ab66 feat: New Component API 2021-01-02 13:22:03 -05:00
Mitchell Hanberg
396978b36c Update test 2020-11-04 20:21:32 -05:00
Mitchell Hanberg
5c5edfa67f case expressions 2020-11-04 19:58:35 -05:00
Mitchell Hanberg
459084285f Fix formatting 2020-08-09 10:10:53 -04:00
Mitchell Hanberg
265c413960 Allow element attrs to be evaluated at runtime
Before this change, only keyword list literals could be passed to
elements. If they had non-literals as values, then those would compile
to EEx expressions.

This allows a non-literal to be passed as attrs and have the entire thing
compile to an EEx expression, which will pass the non-literal to a
"runtime_attrs" function, which evaluates a keyword list into a safe
string.

That last part might need to be reworked if the user is not using
the Phoenix.HTML.Engine EEx Engine.
2020-08-09 10:07:27 -04:00
Mitchell Hanberg
7bf649c4b5 Correctly parse do blocks
Did not correctly parse expressions with do blocks
where the expression had two or more arguments before
the block.
2020-07-22 21:34:50 -04:00
Mitchell Hanberg
1f599f5f6d Handle expressions with do blocks that aren't if/unless/for 2020-07-15 23:23:12 -04:00
Mitchell Hanberg
1a5837d1b7 Components API
Components work very similarly to how they worked before, but with a few
differences.

To define a component, you can create a file in your configured temple
components directory, which defaults to `lib/components`. You would
probably want ot change that to be `lib/my_app_web/components` if you
are building a phoenix app.

This file should be of the `.exs` extension, and contain any temple
compatible code.

You can then use this component in any other temple template.

For example, if I were to define a `flex` component, I would create a
file called `lib/my_app_web/components/flex.exs`, with the following
contents.

```elixir
div class: "flex #{@temple[:class]}", id: @id do
  @children
end
```

And we could use the component like so

```elixir
flex class: "justify-between items-center", id: "arnold" do
  div do: "Hi"
  div do: "I'm"
  div do: "Arnold"
  div do: "Schwarzenegger"
end
```

We've demonstated several features to components in this example.

We can pass assigns to our component, and access them just like we would
in a normal phoenix template. If they don't match up with any assigns we
passed to our component, they will be rendered as-is, and will become a
normal Phoenix assign.

You can also access a special `@temple` assign. This allows you do
optionally pass an assign, and not have the `@my_assign` pass through.
If you didn't pass it to your component, it will evaluate to nil.

The block passed to your component can be accessed as `@children`. This
allows your components to wrap a body of markup from the call site.

In order for components to trigger a recompile when they are changed,
you can call `use Temple.Recompiler` in your `lib/my_app_web.ex` file,
in the `view`, `live_view`, and `live_component` functions

```elixir
def view do
  quote do
    # ...
    use Temple.Recompiler
    # ...
  end
end
```
2020-07-15 22:32:27 -04:00
Mitchell Hanberg
33c95186fb
Compile to EEx (#80)
Code is gross
2020-06-16 15:28:21 -04:00
Mitchell Hanberg
3993c798c0 Join markup with a new line
Text nodes separated by new lines still show whitespace when rendered,
so we should maintain user specified new lines.

Closes #59
Closes #60
2020-04-14 10:40:05 -04:00
Mitchell Hanberg
1093a4d602 Rename props to assigns
This helps stay consistent with the Phoenix nomenclature.
2020-04-14 10:40:01 -04:00
zimt28
fa41e73bb0 Add @props access to components (#66)
* Add @props access to components

* Document `@props` assign
2020-04-14 10:40:00 -04:00
Mitchell Hanberg
eb0fde6e83
Don't recursively call generated component macros (#12)
Recursively calling the macros works fine if you `import` the whole
module wherever you are using your components, but not if you `require`
the module.

This is because importing brings in the all the macros into the callers
namespace, which allows them to be called just by the macro name. When
you `require` the module, it will look for the generated 2-arity macro
in the callers namespace, which probably doesn't exist.

We get around this by not recursively calling them and avoiding the
problem all togther. A few utility functions solves the original issue
of wanting to DRY the file.
2019-08-10 01:09:24 -04:00
Mitchell Hanberg
7ad4b0e941 Rename Temple.htm to Temple.temple 2019-07-08 22:29:41 -04:00
Mitchell Hanberg
d210d3bff5 Extract safe result from hidden fields within inputs_for/4
Also switches to using `with` instead of `lexical_scoping` because it is
more idiomatic.
2019-07-07 22:26:32 -04:00
Mitchell Hanberg
8daf85fdb3 Allow defcomponent to work with runtime values for assigns
Also allows tags and defcomponents to accept maps in addition to keyword
lists
2019-07-04 00:16:29 -04:00
Mitchell Hanberg
9278f7fb4e Rename to Temple 2019-07-01 22:48:51 -04:00
Renamed from test/dsl_test.exs (Browse further)