I want to create a “last visited pages” list with Symfony and Twig.
For that purpose I wrote a history service which saves the last visited routes in the session.
But I just have the route name no alias for the user experience.
So the route country_info should hold a string like “Country Information”.
Is it possible to define a alias in the routing.yml?
No, it's not possible to define route aliases in routing.yml. The routing system is not meant to do that.
If you have a fixed number of pages you could just read the session values in your Controller and translate each route name in order to print it with Twig later.
Supposing you are storing last visited pages routes in an array, you can try the following:
In your Controller action:
// Read session
$page_routes = $session->get('last_visited_routes_array');
$output_array=array();
foreach ($page_routes as $route){
// Translate route to name
switch($route){
case "country_info":
$output_array['country_info'] = "Country Information";
break;
// ... Add more Cases here ...
}
}
// Return generated array so it can be used by Twig
return array('output_array' => $output_array);
In your Twig template:
{% for page_route, page_name in output_array %}
{{page_name}}
{% endfor %}
Hope it helps.
Related
In my django project I have a lot of tables which return models. The last column is mostly an Action-Column where users may edit or delete an instance. How do I proceed if I want to pass additional arguments to TemplateColumn if in some tables I want an edit and delete button and in other tables I only need an edit and info button? I want to use the same template.html but with conditions in it. Here what I have in Table:
import django_tables2 as tables
from select_tool.models import DefactoCapability
class DefactoCapabilityTable(tables.Table):
my_column = tables.TemplateColumn(verbose_name='Actions', template_name='core/actionColumnTable.html')
class Meta:
model = DefactoCapability
template_name = 'django_tables2/bootstrap-responsive.html'
attrs = {'class': 'table table-xss table-hover'}
exclude = ( 'body', )
orderable = False
And how do I check perms on the actions in order to display the button or not?
Quoting the TemplateColumn docs
A Template object is created [...] and rendered with a context containing:
record – data record for the current row
value – value from record that corresponds to the current column
default – appropriate default value to use as fallback
row_counter – The number of the row this cell is being rendered in.
any context variables passed using the extra_context argument to TemplateColumn.
So you could do something like this:
my_column = tables.TemplateColumn(
template_name='core/actionColumnTable.html',
extra_context={
'edit_button': True,
}
)
The context also contains the complete context of the template from where {% render_table %} is called. So if you have 'django.template.context_processors.request' in your context_processors, you can access the current user using {{ request.user }}.
I'm writing a simple web app in web2py that stores and retrieves some data from a database. To keep the entries in chronological order, my table has an attribute which stores a date time. Like so:
db.define_table('tablename',
Field( ....
....
....
Field('created_on','datetime', default=request.now, writable=False),
Field('last_modified','datetime', default=request.now, update=request.now),
)
Then when I request the data, I set the orderby attribute to last_modified:
rows = db().select(db.tablename.ALL, orderby=db.tablename.last_modified)
Then, I pass the results onto a Json dictionary object. Like so:
I'm passing them into a JSON dictionary object.Like so:
d = { r.index_id : {'index_id':r.index_id,
....
....
'comments':r.comments,
'created_on':r.created_on,
'last_modified':r.last_modified}
for r in rows}
return response.json(dict(entry_dict=d))
When I get the response from the server, I return the dict to my ractive object.
MAIN.set('data_entries', data['entry_dict']);
Then, I render the results in ractive:
{% #data_entries:index_id%}
<tr class = "datarow" onclick="window.document.location='{% url+ '/'+ index_id %}';">
<td>{% index_id %}</td>
....
<td>{% last_modified %}</td>
</tr>
{% /data_entries %}
However, when the data is returned to the webapp, I get to following:
Am I doing this right?
In Python, dictionaries do not preserve order, so when you convert the d dictionary to JSON, you will not necessarily get the keys in the order of the original Rows object. You could instead use an OrderedDict, but it doesn't appear you really need a dictionary anyway -- just create a list (using the as_list method):
return response.json(dict(entry_dict=rows.as_list()))
Then in Ractive, change:
{% #data_entries:index_id %}
to:
{% #data_entries %}
It doesn't appear you need the index value within each loop. Instead, you will be able to access the index_id field of each record as part of the data context of the section.
I have an app where you can choose (or add if they don't exist!) a superhero/villain character from a certain universe on the first page; then outfit him with weapons, clothes, and gadgets on the second page (build).
I have this route defined:
Router.route('/build/:character', {
name: 'build'
waitOn: Meteor.subscribe('characters', {name: this.params.character})
//and a few other subscriptions and sessions as well for the items
//and stuff, but those don't matter here.
}
The link from the specific character, though, passes along a query as well:
<a href="{{pathFor 'build' query=this.universe}}">
So the final link could look something like this:
/build/Aquaman?DCComics
Now the page you are on will display a list of weapons and gadgets where you could also add other stuff if you so wish. Then you are supposed to drag the items you want to include onto your version of this hero.
Problem is, at this point the app doesn't know you even want to create your own hero. Maybe the user is just looking through them for fun. There's a button that the user has to click first to initialize the creating process, and that's when the actual _id is created, something like this:
Meteor.methods({
buildHero: function(heroCharacterName, heroUniverse) {
var heroToAdd = {}
heroToAdd['characterName'] = heroCharacterName
heroToAdd['universe'] = heroUniverse
heroToAdd['_createdAt'] = new Date()
CreatedHeroes.insert(heroToAdd, function() {
if (! error)
//Update the subscription somehow...
})
}
})
So, the _id that is created here in the new Collection must be passed along to a subscription somehow, because I don't want the user to see other personal heroes that have been created, only his own newly created one.
The solution I have in mind is adding the _id onto the URL in form of a hastag, and use this.params.hash in the subscription like so:
Router.route('/build/:character', {
name: 'build'
waitOn: [Meteor.subscribe('characters', {name: this.params.character}),
Meteor.subscribe('createdheroes', this.params.hash)]
}
First of all, is this a valid approach? If so, how do I accomplish it; how do I actually update the URL to include this hash?
If not, what would be a better approach?
I think you have to handle this logic in the data context or in a template helper and not in the way of subscribing/publishing.
If I was you I would besure that the newly created item is being published and subscribed by the client and modify your search query just that it only adds the newly created item.
I am not sure if I understand your question well but what I got, you will know the last _id which was used on your insert.
Instead of letting done this automatically by meteor, just use the meteor method to create / get that _id value >> see Meteor Documentation
var new_id = new Mongo.ObjectID()
col1.insert({ _id: new_id, ... });
col2.insert({ ..., ref_col1_id: new_id, ... });
I have an app where users can take notes.
In the html page I iterate over each note like so:
<div id="notes-container" class="notes">
{{each notes}}
{{> note}}
{{/each}}
</div>
and in my router file I return the data like so:
#route: 'notes'.
path: '/notes/:_id',
data: ->
notes = Notes.find
threadId: #params._id
trash:
$exists: false
,
sort:
date: -1
All is typical meteor stuff so far. But I am confused now about how to adjust the data that is iterated on in the html page.
Each notes has a array field for tags like tags: ['apple' ,'red', 'green']
What if the user wants to return all notes with the tag 'red'. So there is a input box on the site the user enters a tag and presses enter.
How can I adjust the data that is sent to the page so queries mongodb to return all notes with tag red? I know how to write the query I am not sure how to set this up though in meteor.
One way I tried to do it is called the same route with query paramters like: '/notes/326363235474?tags=apple'
And in iron router I can look for query parameters and return the right set of documents but then when I call the original route again to clear the search, it does not load all of the original documents again.
Any suggestion on how I can set this up? Thanks
the data function simply needs to return the data you want available within the template context, if I'll define this function to a certain route:
data: ->
return Drawing.findOne
_id: window._drawing_id
I will have that data in my "this" object when proccessing that template.
To get understandable links to share, I don't want to put only the ._id in the url but the .name as well.
Router.map(function () {
this.route('here', {
path: 'here/:_id/:name/',
template: 'here'
})
})
The Problem is that the .name entry can have special characters like /.
www.example.com/here/1234/name_with special-characters like / (<-this slash) /
Is there a way to replace the slash (and other special characters) in iron-router?
(if there is a good way to handle this, maybe in some cases I don't even need the id anymore.)
If I want to use <a href="{{pathFor 'showCourse'}}">
I can not use a wildecardpath: 'here/:_id/*
Thanks
It's not specific to Iron Router, but JavaScript's native global functions encodeURIComponent and decodeURIComponent exist for just this purpose:
encodeURIComponent("foo/bar"); // returns "foo%2Fbar"
decodeURIComponent("foo%2Fbar"); // returns "foo/bar"
What I do in my projects is add a field called slug and write a function that generates an URL-friendly slug from the document's title and checks the collection to make sure the slug is unique (otherwise it appends "-2" or "-3" etc. as appropriate). With a slug or similar field that is unique per document, you can use it as the only query parameter and forgo the _id.
Expanding on Geoffrey Booth's answer, you can do this with a template helper.
Define a template helper to encode your name value (I made it global so it can be reused by all templates):
Template.registerHelper('encodeName', function() {
this.name = encodeURIComponent(this.name);
return this;
});
Then, in your templates, you can pass this function to iron-router's pathFor helper:
<a href="{{pathFor 'showCourse' encodeName}}">
This works for me on Meteor 1.1.0.2.