Giter Club home page Giter Club logo

liquid's Introduction

Build status Inline docs

Liquid template engine

Introduction

Liquid is a template engine which was written with very specific requirements:

  • It has to have beautiful and simple markup. Template engines which don't produce good looking markup are no fun to use.
  • It needs to be non evaling and secure. Liquid templates are made so that users can edit them. You don't want to run code on your server which your users wrote.
  • It has to be stateless. Compile and render steps have to be separate so that the expensive parsing and compiling can be done once and later on you can just render it passing in a hash with local variables and objects.

Why you should use Liquid

  • You want to allow your users to edit the appearance of your application but don't want them to run insecure code on your server.
  • You want to render templates directly from the database.
  • You like smarty (PHP) style template engines.
  • You need a template engine which does HTML just as well as emails.
  • You don't like the markup of your current templating engine.

What does it look like?

<ul id="products">
  {% for product in products %}
    <li>
      <h2>{{ product.name }}</h2>
      Only {{ product.price | price }}

      {{ product.description | prettyprint | paragraph }}
    </li>
  {% endfor %}
</ul>

How to use Liquid

Install Liquid by adding gem 'liquid' to your gemfile.

Liquid supports a very simple API based around the Liquid::Template class. For standard use you can just pass it the content of a file and call render with a parameters hash.

@template = Liquid::Template.parse("hi {{name}}") # Parses and compiles the template
@template.render('name' => 'tobi')                # => "hi tobi"

Error Modes

Setting the error mode of Liquid lets you specify how strictly you want your templates to be interpreted. Normally the parser is very lax and will accept almost anything without error. Unfortunately this can make it very hard to debug and can lead to unexpected behaviour.

Liquid also comes with a stricter parser that can be used when editing templates to give better error messages when templates are invalid. You can enable this new parser like this:

Liquid::Template.error_mode = :strict # Raises a SyntaxError when invalid syntax is used
Liquid::Template.error_mode = :warn # Adds strict errors to template.errors but continues as normal
Liquid::Template.error_mode = :lax # The default mode, accepts almost anything.

If you want to set the error mode only on specific templates you can pass :error_mode as an option to parse:

Liquid::Template.parse(source, error_mode: :strict)

This is useful for doing things like enabling strict mode only in the theme editor.

It is recommended that you enable :strict or :warn mode on new apps to stop invalid templates from being created. It is also recommended that you use it in the template editors of existing apps to give editors better error messages.

Undefined variables and filters

By default, the renderer doesn't raise or in any other way notify you if some variables or filters are missing, i.e. not passed to the render method. You can improve this situation by passing strict_variables: true and/or strict_filters: true options to the render method. When one of these options is set to true, all errors about undefined variables and undefined filters will be stored in errors array of a Liquid::Template instance. Here are some examples:

template = Liquid::Template.parse("{{x}} {{y}} {{z.a}} {{z.b}}")
template.render({ 'x' => 1, 'z' => { 'a' => 2 } }, { strict_variables: true })
#=> '1  2 ' # when a variable is undefined, it's rendered as nil
template.errors
#=> [#<Liquid::UndefinedVariable: Liquid error: undefined variable y>, #<Liquid::UndefinedVariable: Liquid error: undefined variable b>]
template = Liquid::Template.parse("{{x | filter1 | upcase}}")
template.render({ 'x' => 'foo' }, { strict_filters: true })
#=> '' # when at least one filter in the filter chain is undefined, a whole expression is rendered as nil
template.errors
#=> [#<Liquid::UndefinedFilter: Liquid error: undefined filter filter1>]

If you want to raise on a first exception instead of pushing all of them in errors, you can use render! method:

template = Liquid::Template.parse("{{x}} {{y}}")
template.render!({ 'x' => 1}, { strict_variables: true })
#=> Liquid::UndefinedVariable: Liquid error: undefined variable y

Usage tracking

To help track usages of a feature or code path in production, we have released opt-in usage tracking. To enable this, we provide an empty Liquid:: Usage.increment method which you can customize to your needs. The feature is well suited to https://github.com/Shopify/statsd-instrument. However, the choice of implementation is up to you.

Once you have enabled usage tracking, we recommend reporting any events through Github Issues that your system may be logging. It is highly likely this event has been added to consider deprecating or improving code specific to this event, so please raise any concerns.

liquid's People

Contributors

arthurnn avatar ashmaroli avatar byroot avatar charlespwd avatar davidcornu avatar dylanahsmith avatar fw42 avatar gauravmc avatar ggmichaelgo avatar ianks avatar jake-olney avatar jamesmacaulay avatar jasonhl avatar maaarcocr avatar macournoyer avatar mhw avatar peterzhu2118 avatar pushrax avatar richardmonette avatar shainaraskas avatar shopmike avatar singpolyma-shopify avatar sirupsen avatar soleone avatar ssoroka avatar titanous avatar tjoyal avatar tobi avatar trishume avatar watson1978 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

liquid's Issues

Request: allow LiquidDrops to accept arguments

First, I'm not a security guru, so I'm not too sure about the dangers of this. Second, this isn't my actual use case, but it is an analogy. I just want to simplify things and give an example others would understand. Here goes:

I want users to have access to a scope of products. The scope is based on the category it is in. I can get this with a named_scope (Product.of_category "Shoes/Slippers"). The problem is 1) they get to define their own categories, and 2) how do I give them access to these products via liquid?

When making their own categories, ideally, they could name these whatever they wanted. This poses a problem though. Based on the email thread in the Google group (http://groups.google.com/group/liquid-templates/browse_thread/thread/f2192f66adf68ef) there are ways to access named scopes dynamically via Liquid. It feels hackish and dirty though, and telling users how to name their categories (see the thread for samples) makes me feel icky.

My proposal:

  • Allow arguments to be passed into Liquid Drops BUT escape the strings to avoid SQL injection. If it's an array or a hash, it will escape the strings in them.
  • Only named_scopes that are explicitly put in the drop can be used, just like other methods/attributes. Ex:

def in_category(args)
Product.in_category(args).all
end

Example:

  1. Passing one arg

{% for product in products.in_category("Shoes/Slippers") %}

  1. Passing multiple arguments

{% for product in products.in_any_category("Shoes/Slippers", "Shorts", "Toys") %}

{% for product in products.in_all_categories("Kids", "Shorts") %}

  1. To make things simple, don't allow chaining:

{% for product in products.in_category("Toys").in_category("Kids") %}

How can I use an array for the capture tag

Hi.
I try to use array for capture tag:

{% capture alphabets_ari %}{{ 'alphabets' | translate | split_str: ',' }}{% endcapture %}

the filter method:

def split_str(str, separator)

str => A,B,C,D and etc.

str.split(separator) #=> will be return array

end

but alphabets_ari is String instead Array
Why?

Thanks

Filters not parsed on Liquid::Template.parse

When parsing filters inside a if/else the the filter inside the if condition is not parsed.

require 'liquid'
vars = Liquid::Template.parse('{% if true %} {{"I am never showed" | capitalize }} {% else %} {{"but I am" | capitalize }} {% endif %}')
p vars.root.nodelist

returns only:

[#<Liquid::If:0xa1eec78 @blocks=[#, #], @Nodelist=[" ", #<Liquid::Variable:0xa1ec160 @markup=""but I am" | capitalize ", @name=""but I am"", @filters=[[:capitalize, []]]>, " "], @tag_name="if", @markup="true ">]

2 For Loops in Ruby 1.9.2

Currently experiencing some very strange behavior in liquid templates on ruby 1.9.2 when including 2 for loops in the same layout. For example:

{% for agent_answer in qna_thread.answers_agent %} do something {% endfor %}
{% for custo_answer in qna_thread.answers_custo %} do something {% endfor %}

Which ever loop occurs first, is carried over into the second loop as if its caching the object. If there are supposed to be 2 results for the first loop and 10 for the second. It will loop through the 2 results from the first loop in the second. If I am to switch the order of the loops, so the one with 10 results is hit first. The second loop will display 10 results as well regardless of the collection I've passed it.

rubyforge gem outdated

Hey

The liquid gem on rubyforge is outdated,
and it doesn't work propperly with jekyll...

just thought I'd mention it.

Thanks
Stefan

Trying to understand before_method and creating dynamic drops

I'm trying to setup a drop, that can be called like so:

{% for item in collections.mycollection %}
  {{ item.name }}
{% endfor %}

This requires that the context of the drop be dynamic, based on the user input (mycollection in this case). I've tried setting up a before_method ( doesn't seem to get called at all ), and I've tried an initialize method. Is this even possible? Code included below.

I've been able to do this, if I include all of the records in the parse/render call like so:

Liquid::Template.parse("{% for item in collection.mycollection %} {{ item.name }} {% endfor %}").render('collections' => Collection.all)

However, this isn't very efficient, since the database will pull an unlimited number of collections. This could be hundreds, or even thousands.

class CollectionsDrop < ::Liquid::Drop

  def initialize(name)
    @source = Collection.find_by_name(name)
  end

  # def before_method(name)
  #   @source = Collection.find_by_name(name)
  # end

  def name
    @source.name
  end

end
class Collection < ActiveRecord::Base
  def to_liquid
    Inkblot::Liquid::Drops::CollectionDrop.new(self)
  end
end

Consider removal of Rails support

Liquid isn't a very good template engine for rails projects. It's optimized to work in a hostile environment where you cannot trust the people who write the templates. This is different from a development environment in which you should trust your designers and developers who create the templates.

I feel that by including a init.rb we encurage a usage of Liquid that is different from it's actual intend.

Liquid Forms

Dears,

how to use Liquid Template for Forms and User Inputs.
and for user customization and editing of the default forms.

Best Regards,
Shenouda Bertel

Create a new release

Some of the new features added since the last release are really really useful (as are some of the outstanding pull requests). To make them actually be usable for a broader range of people (and esp. for us ChiliProject guys), it would be awesome if you could create a new release soonish, i.e. sometime this year.

Thanks for your consideration :)

Support for unicode characters in variable names and templates

Hi,

I just wanted to let you guys know about an issue I found with Liquid templates, and a possible (at least temporary) fix in case somebody else encounters the same issue.

Basically, I have some templates that I render with objects having properties that can include special characters, for example french characters such as à, ç, æ, ê and others.

So for example, say you have a template containing among other things something like this:

{{aaaçbbb}}

What happens is that if the code is executed in irb/console (I am using Sinatra right at the moment), the template is rendered correctly and the placeholder replaced with the value of the property "aaaçbbb" of the object that I pass as argument to the render method of the parsed template.

However, for some weird reason, if the same code is executed in a server instance (I am using Unicorn at the moment, but the issue I am about to describe is also present with Thin), that part of the template is replaced with an empty value.
After some investigation, I found that the issue is in the "variable" method of the Context class, in this code:


      def variable(markup)
        parts = markup.scan(VariableParser)
        square_bracketed = /^\[(.*)\]$/

        first_part = parts.shift

        if first_part =~ square_bracketed
          first_part = resolve($1)
        end

        if object = find_variable(first_part)

    …..

The scan basically splits the string aaaçbbb into an array like ["aaa", "bbb"] - the special character disappeared - causing the call find_variable("aaa") not finding the actual value with which the placeholder {{aaaçbbb}} should be replaced in the template, as the object/context does not have a property named "aaa".

I still couldn't find why the issue only shows up when the code is running under a server instance but not in the console,
however I have found an easy, temporary fix that does not require patching liquid. The fix is as follow:


require 'liquid'

…

# Patch for unicode support in variable names in Liquid templates
Liquid.instance_eval do
  remove_const :VariableSegment
  remove_const :VariableParser
  
  VariableSegment = /[\w\-]/u
  VariableParser  = /\[[^\]]+\]|#{VariableSegment}+\??/u
end

By adding this code and so overriding the regex used by markup.scan (I've just appended /u for the unicode support), the unicode characters don't break anything and the template is correctly rendered.
As said I haven't figured out yet why this issue disappears when I test in the console, but I was wondering whether it would be a good idea to add unicode support directly in Liquid by simply appending /u to those regexes.
Is there any reason why this could cause other issues elsewhere?

Many thanks in advance

Encoding problem with ruby 1.9

Hi, I have an encoding problem when using liquid with ruby1.9... Unfortunately I don't know if it comes from liquid, from the yaml library, or from my input data... It works fine on ruby 1.8

incompatible character encodings: UTF-8 and ASCII-8BIT

/opt/local/lib/ruby1.9/gems/1.9.1/gems/liquid-2.0.0/lib/liquid/template.rb:122:in `join'

/opt/local/lib/ruby1.9/gems/1.9.1/gems/liquid-2.0.0/lib/liquid/template.rb:122:in `render'

/Users/hugo/nwndoc/Rakefile:101:in `block in generate'
...

the template was loaded with
Liquid::Template.parse(File.read(File.join(TEMPLATE_DIR, 'functions.liquid')))
and the "data" it uses to render is parsed from a YAML file (using the yaml library)
I still have this problem even when I'm using the -U option (forces default internal to unicode)

Please tag releases

I would appreciate it if you could tag the releases in the github repository. The reason for this is that the gem no longer contains the full source code (specifically, the tests). It's possible to clone the github repository and run tests, but in that case it is nice to know exactly which commit is what is released in the gem.

Context is lost when moving into a Liquid FileSystem

When implementing my own FileSystem for include tags, I got stuck when the context was lost on the call to file_system.read_template_file(). I ended up changing Liquid::Include so that it passes the context.

file_system.read_template_file(context[@template_name])
file_system.read_template_file(context, @template_name)

I have more than one virtual filesystem in a database and they must remain isolated from each other. For future sanity, I am not putting context in globals.

{{with thanks for sharing liquid}}

times filter not working with text

Like the wiki describes you can use the times filter:
times - multiplication e.g {{ 'foo' | times:4 }} #=> 'foofoofoofoo', {{ 5 | times:4 }} #=> 20

This works for numbers and did work for text in an earlier version (I think 2.0.0). After a update (to version 2.2.2) this no longer works for text.
e.g {{ 'foo' | times:4 }} #=> 0

Now I had to use a for loop instead...

Failure to build gem from github.

I have done:
gem sources -a http://gems.github.com
gem install tobi-liquid

ERROR: could not find gem tobi-liquid locally or in a repository

The documentation on http://gems.github.com/ says:
If your gem isn't showing up, double-check that your 'RubyGem' checkbox is checked on your repo, it's really easy to forget this step.

Possible you've forgot this step? Or is this isolated?

More concise comment syntax

The {% comment %} and {% endcomment %} work very well, but I'd really like to see a comment syntax that's easier to type, preferably Django's {# like this #} or Smarty's {* these *}. Is there a chance something like that makes it into liquid?

rendering

i changed yesterday from rails3 beta4, where liquid runs smoothly with my app, to rails3 RC. Now if i want to render my LiquidTemplate i receive an error for my Liquid Filter

my rendering code:

<%= raw(Liquid::Template.parse(theme.theme_content).render({'pages' => @pages, 'current_page' => @page}, :filters => [LiquidFilters])) %>

the error i receive is:

ActionView::Template::Error (uninitialized constant ActionView::CompiledTemplates::LiquidFilters):

should i manually include the lib path or do anyone have an idea whats going on here

thanks

thomas

Filters not handling parameters '' correctly

My filter looks like this:

def text_field(input, value=nil, css_class=nil)
end

My liquid looks like this:

{{ form.search | text_field: '', "text-field-class" }}

What I'm seeing is that "css_class" is being assigned to the value attribute, and css_class is showing up nil.

Noticing a similar issue with the cycle tag:
{% cycle '', '', '', '', ' class="end"' %}

I get a liquid syntax error. So I put a name in like so...
{% cycle random_name: '', '', '', '', ' class="end"' %}

And the page doesn't error out, but it puts class="end" on every iteration when it should only be every fifth. If I put anything within the blank iterations it that is output properly.

So 2 issues with cycle:

  • It should work without a name.
  • A blank iteration should output nothing and move on.

For compatability with ruby 1.9 lookup_and_evaluate should check the arity of Procs before calling them

In 1.8.x doing: (lambda {}).call(1) works fine, but in 1.9.1 it raises an error. The arity of Procs called in Context#lookup_and_evaluate should therefore be checked before calling them. Doing this fixes a pair of failing tests.

I've written a very simple patch to fix this in my fork, the commit for which is here:

http://github.com/tomafro/liquid/commit/2713973803ceb0e6803688597062ebd8beca3b75

Liquid and Rails3

Dears,

kindly, an updated wiki page for Liquid with Rails3 is highly recommended.
and how to use Liquid in Rails3.

Best Regards,
Shenouda Bertel

named_scope is not working

When I was integrating liquid template in my application, I found that I was unable to render all records fetched using named_scope. Here is the scenario what I did:

In my User model, I have named_scope called active:
named_scope :active, :conditions => {:active => true}

And in controller, I am fetching all records using,
@users = User.active

Such a way, I should be able to access @users object in my liquid template. But when I tried it, it's giving me an error like
Liquid error: undefined method `to_liquid' for #

Don't know why it happens? Instead, if I remove named_scope and creates a class method in User model like

def self.active
find(:all, :conditions =>{:active => true})
end

It's working fine. Can anybody help me?

Add truncate html filter

Would love to see a filter that allows truncating words or characters by not clipping HTML tags.

rspec 2

Should we consider migrating the tests from Test::Unit to rspec ~> 2.0.0.beta? I personally enjoy the clarity of the context / describe tags, along with the ease of mocking. However, I'm easy.

Your thoughts?

Best regards,
DBA

Create a shorthand parser

Currently liquid supports the following shorthand syntax for literals:

{{{ my literal }}}

instead of

{% literal %}my literal{% endliteral %}

However, such enhancement could be applicable to other tags, namely comments:

{* my comment *}

instead of

{% comment %}my comment{% endcomment %}

In order to prevent such shorthand parsers to pop like mushrooms, we should control their flow. Much like tags, they should register themselves as shorthand parsers, which will must run before the parser itself.

Effectively, the shorthands currently only need to work as a pre-parser replacing the shorthand version with their longer counter parts.

Your thoughts?

Escaping Liquid Tags

Is there a way to escape a liquid tag so it can be printed rather than parsed?

Liquid class inheritance

Currently:

  • Document is a Tag
  • Block is a Tag
  • If is a blog, so it is a tag

I find this to make less sense than

  • Document is a Document and implements Block behaviors
  • Block is not a Tag
  • If is a Tag and implements Block behaviors

The current inheritance chain makes it hard to change document, and to some extent block, without affecting tag directly.

If this makes sense it's something that could be changed for liquid 3, effectively making it more modular and cleaner.

Best regards,
DBA

System.Web reference not really needed in .NET 4

Hi,
In StandardFilers.cs a reference to System.Web is used and the method HttpUtility.HtmlEncode() is called in Escape(). In .NET 4 that method (when a string is passed in) just ends up calling System.Net.WebUtility.HtmlEncode(). Using the System.Net method instead of the System.Web one means you can remove the System.Web reference for .NET 4 builds.

Can’t use symbols as hash keys for local variables in Liquid::Template#render

Here’s a minimal test case:

Liquid::Template.parse('Hi, {{name}}!').render(:name => 'Cody')  #=> 'Hi, !'
Liquid::Template.parse('Hi, {{name}}!').render('name' => 'Cody') #=> 'Hi, Cody!'

This is especially annoying because as a result you can't use Ruby 1.9's new hash syntax:

Liquid::Template.parse('Hi, {{name}}!').render(name: 'Cody')  #=> 'Hi, !'

This problem occurs for me using both 2.3.0 and 2.2.2.

grouping loop results

Hi, supposing I have 8 items on an array and I want to filter the for loop to show me the results in groups of 3 like:

//array = [1,2,3,4,5,6,7,8];

and I want to emit this

[1,2,3]
[4,5,6]
[7,8]

I would usually inside the array loop do something like if array.size % 3 == 1 then do my combinations but since we don't have that type of method it is a bit complicated.

Any ideas?

Conditional Includes

I'm playing around with Octopress (and therefore Jekyll and Liquid) and I'm trying to conditionally include something like so:

{% if post.layout == "article" %}
    {% include article.html %}
{% endif %}

When I do that, the include doesn't work. I'd have to remove the conditional to have it 'work'. I also tried a simpler conditional like so:

{% if true %}
    {% include article.html %}
{% endif %}

And that also didn't work. Any ideas what's going on? Here's the full liquid template for context.

Using filters in tags

I want to be able to use a filter inside a {% if expression %}. I've tried all sorts of things but cannot figure out if it's possible. Here is what I've tried:

{% if page.content | number_of_words > 200 %}
   ...
{% endif %}

Have I got the syntax wrong? or is this supported? or is there a bug?

'and' in string causing error in if/elsif/else statements

When trying to do something like this:

{% if foo contains 'word' %}
do this
{% elsif foo contains 'word-and-another-word' %}
do that
{% endif %}

I get this error: Liquid error: can't convert nil into String

When I take the substring 'and' out of 'word-and-another-word' so it becomes 'word-another-word' it works. Looks like the word 'and' is causing the issue here.

.swp files

Hello,

Can we delete the .swp files from the project's repository (eg gemspec)?

Best regards,
DBA

Some issues

e.g.

{% for p in ViewBag.BestsellerInCategory %}
{% assign fidx = forloop.index | Plus:1 %} -> this isn't working
{{fidx}}
{% endfor %}

I think it should write 2, 3, 4, 5. The result is 1, 2, 3, 4

BestsellerInCategory is an ENumerable variable.

{{ViewBag.BestsellerInCategory | Size}}

it gives me 12 and there are 12 items in it. Right.

{% assign tbic = ViewBag.BestsellerInCategory | Size %}
{{tbic}} -> this is not working

this code causes to be written ....Drops .... Drops. It writes class names

another code:

{% assign a = 1 %} -> this works
{{a}}
{% assign b = a %} -> this works
{{b}}
{% assign c = a | Plus:1 %} -> not working
{{c}}

I expect it 1, 1, 2
but the result is 1, 1, 1

Raw Template Tag

It would be great to see a template tag for handling raw code:

{% raw %}
{% this shouldnt get evaluated %}
{% endraw %}

Why you use different brackets style?

Dear Liquid developers!

We are looking at your great templating engine with a goal to embed it in our LineAct Website Builder.

The first question after reading docs is the only one: why you use 2 different style of curles, e.g. {{ }} and {% %} ?

Why we cannot just use 1 style? (say {{ }} ) I think it is much more easier for user to remember this.
And actually, we can automatically distinguish between output formatting and tags. E.g. if the first word after {{ is from tag's dictionary, that's tag, else it is output formatting.

Waiting for your opinion!

Thank you very much!

Running side by side with HAML

Currently I am getting quite a bit of HAML errors, that weren't existent when I was using ERB. Specifically is_haml? which is HAML's doing, but I am trying to figure out how to default back to ERB somehow.

So question being, is there a way to have Liquid exclude the default rendering engine, and fall back to ERB explicitly?

Thanks!

Requiring RubyGems >= 1.3.7

Why are you suddenly requiring RubyGems 1.3.7 or greater? Seems unnecessary and currently breaks compatibility with Heroku.

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.