flask-navigation icon indicating copy to clipboard operation
flask-navigation copied to clipboard

Be "active" for included resources

Open tonyseek opened this issue 10 years ago • 6 comments

The related topic is here #4

The situation is like this:

top_bar = nav.Bar('top', [
    nav.Item(u'Home', 'home'),
    nav.Item(u'Posts', 'post_list'),
])

@bp.route('/post/<int:post_id>')
def post(post_id):
    post = Post.query.get_or_404(post_id)
    return render_template('post.html', post=post)

The problem is how to let the item.is_active be True while accessing /post/123. I have three solutions for it:

  • Using URL prefix
top_bar['post_list'].mount_views(url_prefix='/post', blueprint=bp)
  • Marking for each URL rules
top_bar['post_list'].mount_url_rule(endpoint='post')
  • Using whole blueprint as view bundle
top_bar['post_list'].mount_blueprint(bp)

@shonenada @tonicbupt What do you think about these?

tonyseek avatar Apr 27 '14 07:04 tonyseek

@tonyseek I prefer to using URL prefix. Consider the situation like:

@bp.route('/post/<int:post_id>/edit')
def edit_post(post_id):
    post = Post.query.get_or_404(post_id)
    return render_template('edit_post.html', post=post)

Codes looks not simple if using the 2nd way. As for the 3rd way, there may be some one who doesn't like using blueprint...

shonenada avatar Apr 27 '14 07:04 shonenada

@shonenada How about the second way with a declarative usage?

@nav.on(bar='top', item=nav.ItemReference('post_list'))
@bp.route('/post/<int:post_id>/edit')
def edit_post(post_id):
    post = Post.query.get_or_404(post_id)
    return render_template('edit_post.html', post=post)

The URL prefix way will restrict users to use layer-clear URL rules. They may have to make mass changes in a exists app or give up Flask Navigation, that worried me.

tonyseek avatar Apr 27 '14 07:04 tonyseek

@tonyseek How about:

@nav.on(bar='top', item='post_list')
# balabala

Make it more simple?

shonenada avatar Apr 27 '14 07:04 shonenada

@shonenada I did a bad design in previous version. =。=

The navigation items don't have own names. We can find a item by nav.ItemReference only, which has another optional argument named args.

It may be like this: @nav.on(bar='top', item=nav.ItemReference('post_list', {'kind': 'latest'}))

tonyseek avatar Apr 27 '14 07:04 tonyseek

@tonyseek =,= More worse...Why not get item reference in on function? maybe like this:

def on(bar, item, **args):
    item_ref = nav.ItemReference(item, **args)
    # balabala

shonenada avatar Apr 27 '14 07:04 shonenada

@shonenada Just like this @nav.on(bar='top', endpoint='post_list', args={'kind': 'latest'})?

I don't have better idea. :(

Identifying item with the tuple of endpoint and args is really a bad idea. TAT

tonyseek avatar Apr 27 '14 08:04 tonyseek