hasgeek / baseframe Goto Github PK
View Code? Open in Web Editor NEWBaseframe for Hasgeek projects
License: BSD 3-Clause "New" or "Revised" License
Baseframe for Hasgeek projects
License: BSD 3-Clause "New" or "Revised" License
At least some of our validation can be moved client-side with ParsleyJS, particularly with this extension: https://github.com/johannes-gehrs/wtforms-parsleyjs
Setting up a HasGeek project on a new developer's computer is painfully unintuitive. Baseframe should have a /config handler that walks a user through this setup procedure and writes out settings/production.py files to the instance folder.
Hgapp's default handler for / should check for an incompletely configured app (possibly available only when Flask is in debug mode) and call Baseframe's config handler to take it forward.
RadioField and SelectField (with Checkbox widget) currently do not support an "Other" option. This is often required and should be fairly easy to implement:
name
value (with '-other'
suffixed) so that the contents of the field are submitted.name-other
field's value should be read. Perhaps just a blank string as anything else could potentially conflict with existing choices.choices
list and look in name-other
for values.It works fine on Chrome Android, however. On iOS there's no keyboard.
Baseframe's Form class should override the validate
method and log all validation errors. Since a validation error indicates the user did not understand what was expected of them, this is a useful way for us to understand how UI could be better.
We do not have a logging framework in place at the moment, so that is also to be discussed.
The dropdown menu for Events in the networkbar springs to life at inopportune moments. It needs to have a small delay in both opening and closing.
In Baseframe's 404 error handler, if the URL has a trailing slash and there is a matching rule for without a trailing slash, redirect to that.
Baseframe needs versioning for assets and templates. The lack of versioning makes it really hard to try new ideas that may break archived sites. Even changing the default font size and line height can propagate badly.
Assets are easy to version, but templates will need some thinking as blueprints have just one templates folder. The version should be picked at the time of adding the blueprint, not when referring to each template from the app's templates. That is, no {% from "baseframe/1/components.html" import networkbar %}
. Versions should not appear here.
The new version of the networkbar will probably look like this:
baseframe.forms.Form
should provide two additional helper methods: validate_partial
(and validate_on_submit_partial
) and populate_obj_partial
that validate and populate only the fields present in request.form
(or submitted form).
This will allow building views with inline edit, submitting only whatever has changed while reusing existing forms.
Since this does mess with forms that override validate
to do full form validation, or have custom cross-field validation (like the WTForms EqualTo
validator for password fields), there should be a mechanism to protect them:
CRUD views are a recurring pattern in HasGeek apps:
/new
handler exists that presents a blank form using render_form
and creates a new instance if the form validates, following which the user is redirected to the new instance./edit
handler exists that loads the object into the form and otherwise behaves exactly like /new
./delete
handler exists that asks for confirmation, then deletes the object and redirects to the parent object.This pattern can be abstracted away so that (a) we can get past the pain of making views and (b) add new features in a centralised place instead of updating every view in every app. Sample usage:
from flask import g
from coaster.views import load_models
from baseframe.views import CrudView
from .. import app, lastuser
from ..models import MyModel
from ..forms import MyForm
my_model_view = CrudView(model=MyModel, form=MyForm, lastuser=lastuser, template='mymodel.html')
@app.route('/new', methods=['GET', 'POST'])
@my_model_view.new(login=True)
def my_model_new():
return {
'model_args': {'user': g.user},
}
@app.route('<my_model>/edit', methods=['GET', 'POST'])
@my_model_view.edit(login=True)
@load_models(
(MyModel, {'name': 'my_model'}, 'mymodel'),
permission='edit')
def my_model_edit(mymodel):
return {'instance': mymodel}
currently render_form
supports single form rendering. It would be helpful to list similar objects in single page.
WTForms has a RadioField and a SelectField which are identical except for the widget used. Sometimes the UI will call for showing a RadioWidget for lists of four or fewer items and a drop-down SelectWidget for more items.
The RadioSelect field will automatically switch widgets based on how many choices are available.
Increase Flask-WTF CSRF timeout to 6+ hours.
Creating a User instance has many gotchas. The autocomplete widget should defer the task to flask-lastuser's getuser API call.
3.3 is out. Time to upgrade. This time we should apply our customisations as a theme instead of tweaking the core CSS.
Executing python setup.py install
is failing for few packages. And every time it is showing error: None
. First it failed for Flask-assets. I assumed you are using easy_install for installing the packages. So I tried installing Flask-assets with pip and it got installed and I reran the installation. It went past the Flask-assets and got stuck at Coaster. This is what it says -
Searching for coaster
Reading http://pypi.python.org/simple/coaster/
error: None`
Which is same as before. So I tried pip, but this time it said Could not find any downloads that satisfy the requirement coast
. Now when I visited http://pypi.python.org/simple/coaster/
, it simply says that Coaster has no release. And I also couldn't find coaster
searching at Pypi.
What is going wrong here?
Ubuntu 11.10, Python 2.7.2+
Bootstrap 3.1 has been out for a while. We are on 3.0. We should upgrade. Bootstrap 3.1 also includes Sass support, so we no longer need to work with static files, but that is a later update.
There is a header margin that shows up on some sites in some situations, such as mobile view and print view. This needs to be normalized. Spotted in:
Bootstrap and Baseframe's default 14px/20px font-size/line-height is too small for the information density of HasGeek's websites. This should be bumped up to 16px/24px.
In addition to requires
, baseframe.init_app
should take additional parameters with fully configured asset bundles that are added to js_all
and css_all
without manipulation (no minification or rewrite). This is for assets that are sensitive to such manipulation (leaflet.js and path dependency or presentz.js and minification, etc).
Bootstrap's typeahead plugin doesn't support dynamic data sources. This patch adds that: https://gist.github.com/1866577
The first link in the networkbar is misaligned when HasGeek is the current site. See hasgeek.com for example. It's left aligned with the orange bar, not the letter H.
A few small issues have come up with the migration to Bootstrap 3:
LAB.js can be used to move script loading into the head, but we have additional requirements:
This means LAB.js won't be a simple drop-in replacement. We need to think about how an app can define its resource requirements outside of the webasset mechanisms.
Fields.js provides a declarative way of attaching validators to form fields.
We should use it in baseframe.forms
, linking common WTForms validators to Fields.js validators and applying them to the form client side. If there is a validation error, it should be displayed immediately.
Any validator that is missing on the client side will be handled by the server side and the form will reload showing those errors (as at present).
Its useful to know what validation errors users are making.
bleach
is added in requirements.py
but missing in setup.py
, The best way to tackle this
requires = open('requirements.py', 'r').readlines()
in setup.py
,
Similar to Modernizr's classes to allow JS-driven login.
The setup.py already has the make tinymce
, so you might want to remove that. :)
Missing files or erroneous URLs that should result in a 404 response simply end up crashing the server. Unsure if this a BaseFrame issue, but reporting it here in any case.
Collaborative editing of forms is becoming increasingly necessary. While a large text field can be setup with something like Etherpad Lite, there's no obvious solution for forms with many fields. I propose we do this as a standard solution with Baseframe's render_form.
/edit
endpoints. /new
is not shared.This solution doesn't work for client-side forms such as dynamically added fields without additional work, but it's a useful start. It's also inefficient for textareas and may interfere with the user's own editing, so we may have to disable it there.
Usage described in the README here: https://github.com/typekit/webfontloader
Baseframe by default requires the meta-asset 'extra.js', which includes 'jquery.tinymce.js', among others.
TinyMCE has a new 4.0 release series that has a new API. The RichText widget and all sites will have to be reconfigured for the new version.
As a first step, we should remove jquery.tinymce.js
from extra.js
and all sites should explicitly ask for jquery.tinymce.js>=3.5.0,<4.0.0
in their requirements. We can think include the 4.0 release series and start porting sites and widgets.
Current sites using TinyMCE include Hasjob, Hacknight, HGTV and Kharcha.
Baseframe includes Bootstrap 2.0.1. The newer 2.0.3 release has new features and bugfixes. It also has a new Makefile.
Since we've patched Bootstrap wherever it needed direct patching (as opposed to redeclaring styles later), we need to make a diff of these changes (git blame or diff against the 2.0.1 release), then upgrade Bootstrap and (a) reapply the changes or (b) move them to somewhere more maintainable.
This issue concerns the ValidUrl class in the validators module.
http://www.bitcot.com/ is an example URL that is currently accessible, but for which Hasjob reports as inaccessible. The error is reproducible on development, and the request call (when run in the console) returns 200.
requests.get('http://www.bitcot.com/', timeout=30, allow_redirects=True, verify=False, headers={'User-Agent': 'HasGeek/linkchecker'})
JSON requests shouldn't get HTML error pages. Baseframe's default error handlers should use coaster.views.render_with
and include templates for JSON (and XML?) responses.
Baseframe.Forms needs an OrGroup field which, like a RadioSelect, allows the user to select from a list of options and selectively enables the sub-form attached to each.
Fields in a non-selected form are disabled and their data is not validated or processed for populate_obj.
Baseframe should use Cookiefree assets where available, using the ASSET_SERVER
config key to identify the server.
The networkbar's shadow is rather dark, obscuring its bottom border. The shadow needs to be lighter.
CodeMirror doesn't work reliably on Chrome Android. We should disable it on mobile browsers.
How to resolve/ run the redis.
Traceback (most recent call last):
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/flask/app.py", line 1836, in call
return self.wsgi_app(environ, start_response)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functionsrule.endpoint
File "/www/sites/hasjob/hasjob/views/listing.py", line 782, in newjob
return editjob(post.hashid, post.edit_key, form, post, validated=True)
File "/www/sites/hasjob/hasjob/views/listing.py", line 698, in editjob
db.session.commit()
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/sqlalchemy/orm/scoping.py", line 150, in do
return getattr(self.registry(), name)(_args, *_kwargs)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 776, in commit
self.transaction.commit()
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 384, in commit
self.session.dispatch.after_commit(self.session)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/sqlalchemy/event/attr.py", line 221, in call
fn(_args, *_kw)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/flask_sqlalchemy/init.py", line 194, in session_signal_after_commit
models_committed.send(session.app, changes=list(d.values()))
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/blinker/base.py", line 267, in send
for receiver in self.receivers_for(sender)]
File "/www/sites/hasjob/hasjob/search.py", line 90, in on_models_committed
update_index.delay(data)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/flask_rq.py", line 87, in delay
return q.enqueue(fn, _args, *_kwargs)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/rq/queue.py", line 223, in enqueue
description=description, depends_on=depends_on)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/rq/queue.py", line 189, in enqueue_call
return self.enqueue_job(job)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/rq/queue.py", line 234, in enqueue_job
self.connection.sadd(self.redis_queues_keys, self.key)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/redis/client.py", line 1477, in sadd
return self.execute_command('SADD', name, _values)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/redis/client.py", line 570, in execute_command
connection.send_command(_args)
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/redis/connection.py", line 556, in send_command
self.send_packed_command(self.pack_command(*args))
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/redis/connection.py", line 532, in send_packed_command
self.connect()
File "/www/sites/hasjob/flask/lib/python2.7/site-packages/redis/connection.py", line 436, in connect
raise ConnectionError(self._error_message(e))
ConnectionError: Error 111 connecting to localhost:6379. Connection refused.
Baseframe needs to support FieldList widgets when rendering forms. This involves four things:
#46 needs to be tested and verified for support.
HasGeek apps currently depend on Flask-Lastuser, but in the hgapp structure of all apps, Baseframe (which handles UI) and Flask-Lastuser (which handles auth) have no explicit awareness of each other. Baseframe however does refer to the g.user
object which is expected to be a Lastuser User object.
All code related to Flask-Lastuser integration in the app is in the hgapp skeleton, which makes it difficult to make upgrades as patches have to be applied manually to all hgapp-based apps. Baseframe has started adding functionality to apps since it acquired an init_app
method -- most recently cache and assets and some awareness of the Lastuser extension -- but still no explicit handling for Flask-Lastuser.
This should change. Flask-Lastuser should be provided by Baseframe, including the boilerplate methods in login.py.
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.