Code Monkey home page Code Monkey logo

tw2.core's People

Stargazers

 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

tw2.core's Issues

Validators behave strange and differently from FormEncode

When converting an application from TW1+FormEncode to TW2+TW2-validators, I noticed substantial differences between the behavior of validators that I believed should actually do the same things.

For example, FormEncode 1.2.4 behaves like this:

import formencode.validators as fev

v = fev.String(min=2, not_empty=False)

print v.to_python(None) # ok, gives '' (?)
print v.to_python('') # ok
print v.to_python('x') # ValidationError: tooShort
print v.to_python('xy') # ok

v.validate_python(None) # ok
v.validate_python('') # ok
v.validate_python('x') # ok (??)
v.validate_python('xy') # ok

This works as expected, the only line that seems strange is the one marked with ?? - shouldn't this also give a ValidationError: tooShort?

On the other hand, ToscaWidgets 2 behaves like this:

import tw2.core as twc

v = twc.StringLengthValidator(min=2, required=False)

print v.to_python(None) # ok, gives None (?)
print v.to_python('') # ok
print v.to_python('x') # ok (??)
print v.to_python('xy') # ok

v.validate_python(None) # TypeError (??)
v.validate_python('') # ValidationError: tooshort (??)
v.validate_python('x') # ok
v.validate_python('xy') # ValidationError

Here I found three things that did not work as expected, marked with ??.

I feel like I don't understand how these methods are supposed to work, can somebody shed more light on this? Are to_python and validate_python supposed to work only in composition? But why then have these been made separate methods and why is this not documented? And even then, there are still differences in how empty values are treated.

I think the behavior should be made both more logical and more consistent with each other.

random crashes with widget display, seems related to concurrency issues

Sometimes in the logs it's found a crash on css_class collision, but no css_class is passed to the form at all. tw2.core-2.1.3 and tw2.forms-2.1.2

${form.display({'ticket':ticket._id})}
File 'tw2.core-2.1.3-py2.7.egg/tw2/core/widgets.py', line 418 in display
self.prepare()
File 'tw2.forms-2.1.2-py2.7.egg/tw2/forms/widgets.py', line 693 in prepare
b.prepare()
File 'tw2.core-2.1.3-py2.7.egg/tw2/core/widgets.py', line 352 in prepare
"Attr param clashes with user-supplied attr: '%s'" % a
ParameterError: Attr param clashes with user-supplied attr: 'css_class'

JSSource injected multiple times

Another problem I noticed when trying to adapt a TW1 app to TW2:

When a widgets uses a JSLink as a resource, then this JSLink will only be injected once on the same page, however, when it uses a JSSource as a resource, then this JSSource will be injected as many times as the widgets appears on the page.

Here is a typical use case that demonstrates the problem:

import tw2.core as twc, tw2.forms as twf
import tw2.devtools as twd

class MyField(twf.TextField):
    resources = [twc.JSLink(link='some_plugin'),
        twc.JSSource(src="$('.myfield').init_plugin()")]
    css_class = 'myfield'

class Index(twf.FormPage):
    title = "Test"
    class child(twf.TableForm):
        field1 = MyField()
        field2 = MyField()

twd.dev_server()

When you run this code, you will see that the plugin link is only injected once in the head of the page, but the initialization code is inserted twice at the bottom of the page, which is usually not what you want, and different from the behavior of TW1.

"Not a valid identifier error" needs to be more understandable

The error is too vague to be useful for corrective action. It should read "%s is not a valid HTML identifier" as it is a W3C spec code-style issue.

Changing this to a warning rather than exception is also a valid solution as it does not inhibit TW2 from working.

Random infrastructure problems

From IRC:

14:52:56 < moschlar> threebean, http://pypi.python.org/pypi/tw2.etc/2.0a3 that package seems to be a little strange on pypi
14:53:04 < moschlar> it has no meaningful source url
14:55:54 < moschlar> i went ahead and https://github.com/toscawidgets/tw2.etc/commit/010d95476d51c38f5519c5c8de9eb097b0a5b83b
14:56:02 < moschlar> maybe you can update, if you have some boring time :D
14:56:58 < moschlar> and for http://pypi.python.org/pypi/tw2.jqplugins.chosen/0.2dev-20121106, I wonder why you uploaded the -dev named release
14:57:16 < moschlar> I would upload it again, but you are the package owner! ;)
15:01:48 < moschlar> oh
15:01:58 < moschlar> www.toscawidgets.org is down :(
15:03:36 < moschlar> and, since I'm already criticizing all over the place: https://tw2core.readthedocs.org/en/latest/ points to Paj’s bitbucket account as the 
                     bugtracker, maybe that should be updated to point to github ! ;)

Howto chained select

Hi, I'm wondering if there's a way I can have a select field that when I select an option it would show a subselection for that option?

I got the following problem:
Main selection of a Vehicle Class of [Sedan, StationWagon] leads to a subselection list of different types to be stored under the same key (If you select Sedan it should show the options for the Sedan vehicle class) in a selection or list beneath the main selection of for example [5 seater, 7 seater].

Is there a way to achieve this?

tw2 .to_python should conform with formencode

Formencode takes a second argument, 'state' that we can just ignore, but we need to pass it on in super calls.

We'll need some serious unit-testery to make sure we catch every case.

require explicit engine_name when .html extension is used

@amol- reported this in #turbogears


16:49:33 < amol> threebean: a TG user found an interesting issue with tw2 that raised up only recently, probably after template management change in tw
16:49:45 < amol> it seems that instead of rendering the genshi template of a widget
16:49:53 < amol> it outputs the actual genshi code
16:50:19 < amol> is there anthing that comes to your mind that might cause this issue?
16:50:36 < amol> do I have to change something in the way TG initializes tw2 now?
17:01:27 < amol> Ok, I found the issue :/
17:08:26 < amol> The issue is that if my widget has a genshi template with .html extension and my application (as it uses jinja) has tw2 configured with ['jinja',
'genshi'] preferred templates then tw2 tries to render the template as a Jinja2 template as .html is one of the extensions accepted for Jinja2
17:09:24 < amol> As .html is an extension registed as valid for kajiki, genshi and Jinja2 in tw2.core.middleware.Config by default
17:09:55 < amol> I would suggest requiring to explicitly say the engine_name when .html extension is used, otherwise it would be impossible to render the widget with
the correct engine
17:37:09 < amol> the same issue happens with standard tw2 widgets as far as I see
17:38:00 < amol> as also input_field and so on provide a genshi template which ends with .html extension
17:52:52 < amol> the rendering_extension_lookup option is also totally ignored when looking up for templates, so even changing it doesn't have any effect

Improve resources injection management

Right now Tw2 suffers the same issues Tw1 had with resources injection.
Server side resolution of dependencies has limits related to:

  • Collision with resources injected manually by the user or by other frameworks (suppose your website uses jQuery and your widgets requires jQuery, you will end up with two jquery injected with different versions ad plugins enabled)
  • Ajax loading of widgets, suppose you load your widget through ajax your loaded partial will need to have a body and head section just to permit to tw2 to inject the resources there. You would end up with an head tag loaded inside your current body, relying on browser to resolve such issue
  • Resources injected multiple times if the widgets requires them between two different requests (again this happens when loading widgets inside an existing page) because tw doesn't know that the resources are already there due to a previous request.

The only way I can think of to resolve such issue is to move resources resolution to client side, using javascript. Using something like require.js would permit to solve modules and their dependencies at client side keeping track of what is already available and injecting them even at runtime.

If a solution like require.js that involves defining modules is considered too invasive there are other solutions like head.js that rely on the script path for collision resolution and don't require any change to the scripts. This second solution would not solve issues with collisions and dependencies, but would stil improve ajax management of widgets and resources injection between multiple requests.

Arguments to display() called as instance method are ignored

I found another small issue with the display() method of the Widget class. Basically, the current code looks like this:

class Widget(pm.Parametered):

    @util.class_or_instance
    def display(self, cls, value=None, displays_on=None, **kw):

        if value is not None and 'value' not in kw:
            kw['value'] = value

        if not self:
            self = cls.req(**kw)

The problem here is that the cls and kw arguments are completely ignored when display() is called on a Widget instance. Is this really intended? I had expected you could pass arguments to an instance as well. But for that to work, the code must be changed like this:

class Widget(pm.Parametered):

    @util.class_or_instance
    def display(self, cls, value=None, displays_on=None, **kw):

        if value is not None and 'value' not in kw:
            kw['value'] = value

        if self:
            for key, value in kw.items():
                setattr(self, key, value)
        else:
            self = cls.req(**kw)

Or, if the value und kw arguments really shall be used only when called as a class method, then this should be documented and the code should be changed to this:

class Widget(pm.Parametered):

    @util.class_or_instance
    def display(self, cls, value=None, displays_on=None, **kw):

        if not self:
            if value is not None and 'value' not in kw:
                kw['value'] = value
            self = cls.req(**kw)

Widget.add_call should call safe_modify if the first argument is an instance

When add_call is called from an instance (like from prepare method) it is safe to assume that the call should be added to the instance and not to the class resources.

Also it is not really obvious that one has to call safe_modify('resources') before calling add_call from prepare as people won't probably look at add_call implementation and so won't know that add_call modifies resources.

Another solution is probably to always call safe_modify('resources') in Widget.prepare, both are fine

tw2.core>=2.1.2 breaks tw2.dynforms.GrowingGridLayout validation

Since updating to tw2.core>=2.1.2, GrowingGridLayout's fields don't get validated correctly anmore...

An example is at https://github.com/moschlar/SAUCE/blob/feature/simpleusers/sauce/widgets/judgement.py#L17

request.POST:

MultiDict([('judgement:assignment_id', u''), ('judgement:submission_id', u''), ('line', u''), ('comment', u''), ('line', u''), ('comment', u''), ('judgement:comment', u''), ('judgement:corrected_source', u''), ('judgement:grade', u'')])

After validation:

 {'comment': u"[u'', u'2', u'']", 'submission_id': 1, 'assignment_id': 1, 'grade': None, 'corrected_source': u'', 'annotations': []}

The problem seems to be that id and name are not the same anymore.
@ralphbean confirmed the diversion between those in the rendered html.

Cannot import Genshi templates by filename

@Cito wrote to the mailing list here: https://groups.google.com/forum/?fromgroups#!topic/toscawidgets-discuss/KZtFsfgJ6DE


I noticed that since the template-sys branch has been merged in (see 8324359), loading Genshi templates does not work anymore via filenames (template = 'genshi:./index.html') as it is done in the tutorial here (http://tw2core.readthedocs.org/en/latest/standalone/). I get an Error - <type 'exceptions.ImportError'>: Import by filename is not supported.

Is this this functionality been removed deliberately? If yes, the tutorial should be adapted accordingly.

-- Christoph

Mirror github and bitbucket

We need a permanent solution for this; some of the older-schoolers want to use bitbucket. It's the least we could do to keep their repo in sync with ours.

There's the bitbucket2github script(s) out there.

Update TG2 tutorial

It uses w.fetch_data(...)(tw2) instead of @validate(tg2). When I wrote it, the TG2-integration wasn't really nailed down yet.

It should probably be modernized.

/cc @moschlar who reported it in IRC.

Translation of validator messages

Currently, tw2.core does not provide any translations for the messages of the built-in validators. It only provides a way of passing a translator function per middleware configuration, but this means that the application that is using tw2.core needs to provide these translations even though these do not belong to its translation domain. This does not make much sense to me.

It would be much better if tw2.core provided its own translations, like FormEncode does. The only problem here is that tw2.core then needs to know which language to use for the translation. For FormEncode this has been done by having the framework determine the right translator for FormEncode and sending that to FormEncode via the state object that is passed with validators. This seems like a complicated, roundabout way to me with that also involves too much coupling. Instead, it would be much easier if the validator is only passed a function that get the current user language and then figures out the correct translator on its own.

I have made a proof of concept implementation by adding translations for 3 languages and support for a new middleware configuration setting get_lang that can be used instead of translator (see Cito/tw2.core@a10a14e). Frameworks like TurboGears could pass their get_lang function here. I've tried it with TurboGears 2.2 and it works great when I make this little addition to its add_tosca2_middleware method.

If people think this is a good idea, we can get this into the next TurboGears release, and add some more translations.

id of the root form gets added to form parameters

class MovieForm(TableForm):
   #id = 'movieform'
   title = TextField()
   year = TextField()

Reported by @Cito

Submitting this form results in title and year values, but if we decomment the #id line the submitted values will be movieform:title and movieform:year. While this behavior makes sense for nested forms or fieldsets and was already there for those on TW1, in case of the root form probably the id shouldn't be added to field names.

Labels cause validation to add None key to data

I have form with Label like:

class MyForm(TableForm):
  class child(TableLayout):
    field1 = TextField()
    infoLabel = Label(text="IMPORTANT: Please read..etc...")
    field2 = TextField()

The validation in tw2.core.widgets, line 661 (in version 2.1.2), includes the Label and results in adding None key to data:

{None: '', 'field1': 'value', 'field2': 'value'}

which bombs out later (in Turbogears causes "keywords must be strings:" exception).

Improve docs on class/instance pattern

@Cito reports in Issue #41:


The point that widgets are meant to be used as classes should be better explained in the docs, I did not get it at first reading. There is a passage in the docs that says:

"ToscaWidgets 2 creates a new instance of a widget every time it is used in a request. This allows widget and application code to update widget attributes in the natural, pythonic manner, ..."

In the beginning, when trying out TW2, I had been mislead by the words "and application code" to believe that widgets are intended to be used as instances by the application. Because otherwise, if the application works only with classes, and instances are created only internally, then application code cannot benefit from the pythonic way of updating widget attributes, only widget code (overwritten methods) can.

Also, if the application is supposed to work with classes only, we need something like the child_args argument of TW1 for making it easier to do standard things like setting options of SelectionFields dynamically. We discussed that earlier, maybe I can work something out this week.

The add_call() method should be documented

The add_call() method of tw2.core Widgets is nowhere documented. Same with js_symbol, js_callback and js_function in tw2.core.js. Please add some explanations and usage examples in the documentation.

Testing resources in tw2.core.testbase

12:17:43 < Mahi> we also need to think about adding resource testing into tw2.core.testbase

12:18:18 < Mahi> right now its nearly impossible to test resource classes outside of tw2.core..

Make adding resources and css classes easier

TW 1 supported a css_classes parameter to add css classes in addition to css_class. TW 2 only has the css_class parameter which makes it difficult to add CSS classes to an existing parent class. You need to write something like css_class = ParentWidget.css_class + " another_class"in order to not overwrite an existing parent class.

A similar problem exists concerning the resources parameter. Usually you want to just add resources to a parent widget, not replace the parent resources completely.

Maybe we could add parameters like add_css_class and add_resources for this purpose? When using these parameters, the classes/resources would be just added to existing base classes/resources.

jqplotwidget is broken

Something recently changed so that the options for jqplotwidget no longer works and returns a javascript error. Even the tw2facemelt code gives this same problem. It seems it is escaping the quote for some reason.

firebug reports "invalid property id" and complains around this line:

<script type="text/javascript"> $(document).ready( function(){ doJQPlotWidget( 'awesome-logplot', [[1, 2, 3, 4, 5]], {"seriesDefaults": {"renderer": $.jqplot.BarRenderer, "rendererOptions": {"barPadding": 4, "barMargin": 10}}, "axes": {"xaxis": {"renderer": $.jqplot.CategoryAxisRenderer}, "yaxis": {"min": 0}}} ); } ); </script>

Distinguishable multiple SubmitButtons in the buttons attribute of a form

I need to have multiple SubmitButtons that I need to distinguish on the server side! If they have a name attribute, their values get send in the POST request. But validation strips their values from the resulting dictionary.
Since I would like to use TurboGears @validate decorator, I would like to have some kind of trick to include the buttons in the validated data!

To reproduce the behaviour, consider the following form definition:

import tw2.core as twc
import tw2.forms as twf
import tw2.dynforms as twdf

class JudgementForm(twdf.CustomisedTableForm):

    title = 'Judgement'

    assignment_id = twf.HiddenField()
    submission_id = twf.HiddenField()

    class annotations(twdf.GrowingGridLayout):
        line = twf.TextField(size=3, validator=twc.IntValidator, css_class='span1')
        comment = twf.TextField(size=65, css_class='span4')
    comment = twf.TextArea(placeholder=u'Comment on the above source code', css_class='span5', rows=8)
    corrected_source = twf.TextArea(placeholder=u'Correct the above source code', css_class='span5', rows=8)

    buttons = [
        twf.SubmitButton('submit', name='submit', value='Submit', css_class='btn btn-primary'),
        twf.SubmitButton('reset', name='reset', value='Delete', css_class='btn btn-danger')]

If I just try it in a IPython shell, I just get:

In [4]: JudgementForm().validate({})
Out[4]: 
{'annotations': [],
 'assignment_id': '',
 'comment': '',
 'corrected_source': '',
 'submission_id': ''}

In [5]: JudgementForm().validate({'submit':'Submit'})
Out[5]: 
{'annotations': [],
 'assignment_id': '',
 'comment': '',
 'corrected_source': '',
 'submission_id': ''}

where I would like to have at least the name of the pressed button included.

Is there any way to achieve that?

Tw2.core 2.1.5 and TurboGears 2.2.2 webob version conflicts leads to multiselect widget bugs

Hello, there appears to be a version synchronization issue with TurboGears 2.2.2, the most current version as of writing this, and tw2.core 2.1.5, also the current version of tw2.core.

TurboGears 2.2.2 requires WebOb version 1.1.1 which uses the UnicodeMultiDict to store request params. It appears that WebOb >= 1.2 has since replaced the UnicodeMultiDict with the MultiDict object and tw2 has correctly accommodated for this change but tg2 hasn't.

Because current version of tg2 and tw2 are dependent on different versions of webob, this causes a nasty bug where multiselect widgets in tg2 are only able to save one value.

I think the simplest fix would be to modify the "Hack" for webob versions at the top of tw2.core.validation from (line 13) from:

if not hasattr(webob, 'MultiDict'):
webob.MultiDict = webob.multidict.MultiDict

to:

if not hasattr(webob, 'MultiDict'):

Check for webob versions with UnicodeMultiDict

if hasattr(webob.multidict,'UnicodeMultiDict'):
    webob.MultiDict = webob.multidict.UnicodeMultiDict
else:
    webob.MultiDict = webob.multidict.MultiDict

I tested this and it works. It would be awesome if we can keep tg2 and tw2 compatible!

Thanks
Gregg

tzinfo in DateTimeValidator

Now that we can deal with tz aware datetimes in TG2/Ming, it would be great if tw2 DateTimeValidator accepts a tzinfo parameter

Something like

def to_python(self, value, state=None):
    if not value:
        return None
    try:
        return datetime.datetime.strptime(value, self.format).replace(tzinfo=getattr(self, 'tzinfo', None))
    except ValueError:
        raise ValidationError('baddate', self)

Port paster create to gearbox

In the feature/2.2 branch of tw2.devtools, I ported the paster tw2.browser command to gearbox tw2.browser.

However, I neglected to do the template stuff as described in doc/devtools.rst in the tw2.core repo. Gotta do that and update that doc.

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.