inveniosoftware / flask-breadcrumbs

Flask-Breadcrumbs is a Flask extension that adds support for generating site breadcrumb navigation.
https://flask-breadcrumbs.readthedocs.io
Other
30 stars 23 forks source link

Can we get a better example of a dynamic list constructor? #39

Open cswarth opened 8 years ago

cswarth commented 8 years ago

I just cannot figure out how to use the dynamic list constructor for variable rules from the example in the documentation.
Could we get another example?

My question that I don't see addressed in the examples are,

I have looked at the test routines in the flask-breadcrumbs repo for a hint but the single test program does not demonstrate breadcrumbs on variable content. Any help would be appreciated.

from flask import request, render_template

def view_user_dlc(*args, **kwargs):
    user_id = request.view_args['user_id']
    user = User.query.get(user_id)
    return [{'text': user.name, 'url': user.url}]

@app.route('/users/<int:user_id>')
@breadcrumbs.register_breadcrumb(app, '.user.id', '',
                                 dynamic_list_constructor=view_user_dlc)
def view_user(user_id):
    user = User.query.get(user_id)
    return render_template('user.html', user=user)
jirikuncar commented 8 years ago

@cswarth I agree that the dynamic_list_constructor parameter is not well documented. If it helps I can tell you that User is an arbitrary SQLAlchemy model with columns id, name, and url. Do you have an example with your use-case? We can also discuss how we can improve the API.

cswarth commented 8 years ago

Thanks for the very fast reply. My use case looks pretty similar to the example, except the content is stored in the app config rather than a sql db. I followed the implementation of register_breadcrumb into flask-menu enough to get my breadcrumbs working,

def view_gene_dlc():
    id = request.view_args['id']
    genes = app.config['GENES']
    gene = genes[id]    
    return [{'text': id, 'url': id}]

@app.route("/gene/<id>.html")
@register_breadcrumb(app, '.gene', '',
                     dynamic_list_constructor=view_gene_dlc)
def gene_page(id=None):
    genes = app.config['GENES']
    gene = genes[id]    
    return render_template('gene.html', gene=gene)

My observations: The path parameter of @register_breadcrumb expresses levels in the breadcrumb hierarchy. The actual text between the '.' doesn't matter but it should reflect a consistent hierarchy across multiple calls to register_breadcrumb. For my usage it can be either breadcrumb.gene or .gene, but should not have extraneous levels like .foo.bar.gene unless the .foo and .bar levels are also registered.

The third parameter to register_breadcrumb, text, is ignored if the dynamic_list_constructor keyword is supplied. Maybe register_breadcrumb and/or register_menu should take either a string or a function for text. That way they would be mutually exclusive without redundancy.

jirikuncar commented 8 years ago

Maybe register_breadcrumb and/or register_menu should take either a string or a function for text. That way they would be mutually exclusive without redundancy.

Would you be willing to prepare a PR with test-cases for it?

cswarth commented 8 years ago

Can't promise anything, but I'll try some experiments with the API change I was thinking of and report results here. I wouldn't expect to change flask-menu, just make small mod to the breadcrumb interface for users supplying their own dynamic_list_constructor.