Giter Club home page Giter Club logo

levee's People

Contributors

vlthr avatar

Watchers

 avatar  avatar

levee's Issues

Implement filters

  • append
  • capitalize
  • date
  • divided_by
  • downcase
  • escape
  • escape_once
  • first
  • join
  • last
  • map
  • minus
  • modulo
  • newline_to_br
  • plus
  • prepend
  • remove_first
  • remove
  • replace_first
  • replace
  • size
  • sort
  • split
  • strip_html
  • strip_newlines
  • times
  • truncate
  • truncatewords
  • upcase
  • json
  • reverse

Generate Filter argument parser using a macro

Liquid custom tags allow each tag to define the structure of its arguments entirely freely, so a filter must handle the parsing of its own arguments. It would be nice if this complexity was not exposed to the user of the library, since the vast majority of filters would not it.

Filters could possibly be represented as a partial function, defined something like follows:

@Filter
case class MyFilter() {
    def apply() {
        case (input: Value, a: Int, b: Int) => ...
        case (input: Value, args: String) => ...
    }
}

In the Filter macro, matching String -> (Int, Int) and String -> String parsers could be generated automatically, such that the filter above would work when called with:

{{ "Hello world" | myfilter: "xxx" }}
or 
{{ "Hello World" | myfilter: 1, 2 }}

Cover all error types

Parsing:

  • Unrecognized tokens (needs special case for improved error messages)
  • Unbalanced tags/objects (needs special case for improved error messages)
  • Unmatched tag pair (needs special case for improved error messages)
  • No input to filter
  • Nonexistent tag

Evaluation/Rendering:

  • Undefined identifier use
  • Invalid iterable in for loop
  • Incomparable values (needs test)
  • Invalid index type
  • Invalid indexable in IndexExpr
  • Index out of range
  • Undefined fields in map
  • Invalid map type in DotExpr
  • Invalid filter input type
  • Invalid filter argument type
  • Invalid number of filter arguments
  • Unknown filter

Implement tags

  • assign
  • capture
  • case
  • comment
  • cycle
  • for
  • if
  • include
  • raw
  • tablerow
  • unless
  • increment

Handle errors in render() in a better way

Rendering a template should not error out on the first exception but rather collect as many errors as is meaningful and then report them to the user.

Possible solutions:

  • Refactor render methods signature to Try[String]
  • Implement an error listener system similar to ANTLRs

Add end-to-end template rendering tests

Something like sbt testExamples to render all the template files in a given folder, then comparing the result with another file containing the expected output. Then sbt genExamples to regenerate the expected outputs.

Gestalt dependency error

 dottydoc-templating (de-submodule) โœ— sbt compile                 
[warn] Executing in batch mode.
[warn]   For better performance, hit [ENTER] to switch to interactive mode, or
[warn]   consider launching sbt without any commands, or explicitly passing 'shell'
[info] Loading global plugins from /home/von/.sbt/0.13/plugins
[info] Loading project definition from /home/von/bb/dottydoc-templating/project
[info] Set current project to dottydoc-templating (in build file:/home/von/bb/dottydoc-templating/)
[warn] Binary version (0.1.2-RC1) for dependency ch.epfl.lamp#scala-library;0.1.2-RC1
[warn]  in macros#macros_0.1;0.1-SNAPSHOT differs from Scala binary version in project (0.1).
[info] Updating {file:/home/von/bb/dottydoc-templating/}macros...
[info] Resolving ch.epfl.lamp#dotty-library_0.1;0.1.2-RC1 ...
[warn] circular dependency found: ch.epfl.lamp#scala-library;0.1.2-RC1->ch.epfl.lamp#dotty-library_0.1;0.1.2-RC1->...
[warn] circular dependency found: ch.epfl.lamp#dotty-library_0.1;0.1.2-RC1->ch.epfl.lamp#scala-library;0.1.2-RC1->...
[info] Resolving my.fengy#gestalt_2.11;0.1.1 ...
[warn]  module not found: my.fengy#gestalt_2.11;0.1.1
[warn] ==== local: tried
[warn]   /home/von/.ivy2/local/my.fengy/gestalt_2.11/0.1.1/ivys/ivy.xml
[warn] ==== public: tried
[warn]   https://repo1.maven.org/maven2/my/fengy/gestalt_2.11/0.1.1/gestalt_2.11-0.1.1.pom
[warn] ==== sonatype-snapshots: tried
[warn]   https://oss.sonatype.org/content/repositories/snapshots/my/fengy/gestalt_2.11/0.1.1/gestalt_2.11-0.1.1.pom
[warn] ==== sonatype-releases: tried
[warn]   https://oss.sonatype.org/content/repositories/releases/my/fengy/gestalt_2.11/0.1.1/gestalt_2.11-0.1.1.pom
[warn] ==== typesafe-ivy-releases: tried
[warn]   https://repo.typesafe.com/typesafe/ivy-releases/my.fengy/gestalt_2.11/0.1.1/ivys/ivy.xml
[info] Resolving org.scala-lang.modules#scala-xml_2.11;1.0.1 ...
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: my.fengy#gestalt_2.11;0.1.1: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn] 
[warn]  Note: Unresolved dependencies path:
[warn]          my.fengy:gestalt_2.11:0.1.1 (/home/von/bb/dottydoc-templating/build.sbt#L26)
[warn]            +- macros:macros_0.1:0.1-SNAPSHOT
sbt.ResolveException: unresolved dependency: my.fengy#gestalt_2.11;0.1.1: not found
[trace] Stack trace suppressed: run last macros/*:update for the full output.
[error] (macros/*:update) sbt.ResolveException: unresolved dependency: my.fengy#gestalt_2.11;0.1.1: not found
[error] Total time: 3 s, completed Jun 9, 2017 4:31:16 PM

The error seems to be related to a mismatch in dotty versions. Doing an sbt publishLocal in gestalt publishes to:

[info]  published ivy to /home/von/.ivy2/local/me.fengy/gestalt_0.4/0.1.1/ivys/ivy.xml

Redesign filter and (custom) tag API

Implementing both filters and custom tags with arguments turns out to be fairly cumbersome due to all the type checking required to make the filter robust - especially if trying to catch all detectable errors before returning.

Having a somewhat cumbersome API for defining these in a well-behaved way is not necessarily a problem for code that is internal to the project, but the current API is not easily approachable by users and is also fairly verbose and boilerplate heavy. Fixing this now would both allow for user-extensibility and would also make implementing the remaining standard set of filters and tags easier.

Filter API Requirements

A filter application has the following form:

{{ input | filterName: arg0, arg1 }}

Error types

The filter must be able to (where possible) simultaneously detect all instances of the following:

Invalid input type

Filters always take a single value as input, so type checking should amount simply to checking which subclass of value was given as input. Error message should at least specify what the invalid type is, but preferably also what the expected type/types are.

Invalid count argument count

A given filter may be defined for a variable number of arguments, and if an invalid number of arguments is given, the error message should preferably be able to give some indication of how to fix it.

Invalid filter argument type

If a filter is given the correct number of arguments but of the wrong value types, the error message should specify the invalid type and if possible also an expected type.

Other

  • Filters should be easy to implement for users
  • There should not be any gotchas that could cause type unsafe behavior
  • Implementations of standard filters should be as DRY as possible
  • A filter should be easy to define for multiple input types

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.