TS is confusing :)
I'm trying to create a typolink with a conditional parameter depending on the language.
10 = TEXT
10 {
typolink {
parameter = http://myLink.com
returnLast = url
if.isTrue.data = GP:L = 1
}
wrap (
<li class="mod-metanav--item">
<a class="mod-metanav--link" target="_blank" href="|">
The Link
</a>
</li>
)
}
As you can see, I tried to add an IF-statement to the typolink, asking for a language (at least, that's what I think I did).
The thing is, that, depending on the current language I want a different link (but the rest needs to remain the same).
I could use [globalVar = GP:L = 1] but that would create a HUGE overhead, since this typolink is just a fraction of a bigger script-part.
I tried to google for variables or constants that I could add to the parameter, but nothing gave me a useful result...
HELP! :)
To override the link value depending on the current language you may use the »lang« parameter.
To change the link url depending on the current language you may want to use a CASE object…
10 = TEXT
10 {
value = English
lang.de = German
lang.fr = French
typolink.parameter.cObject = CASE
typolink.parameter.cObject {
key.data = GP:L
1 = TEXT
1.value = http://example.com/german/bar/
2 = TEXT
2.value = http://example.com/french/baz/
default = TEXT
default.value = http://example.com/englisch/foo/
}
typolink.ATagParams = class="mod-metanav--link"
typolink.extTarget = _blank
wrap = <li class="mod-metanav--item">|</li>
}
…or you use a constant:
constants:
languagedependentlink = http://example.com/englisch/foo/
[globalVar = GP:L = 1]
languagedependentlink = http://example.com/german/bar/
[global]
[globalVar = GP:L = 2]
languagedependentlink = http://example.com/french/baz/
[global]
setup:
10 = TEXT
10 {
value = English
lang.de = German
lang.fr = French
typolink.parameter = {$languagedependentlink}
typolink.ATagParams = class="mod-metanav--link"
typolink.extTarget = _blank
wrap = <li class="mod-metanav--item">|</li>
}
And again, I'm answering my own question - may it help somebody else.
10 = TEXT
10 {
typolink {
parameter = myLinkInEnglish
returnLast = url
}
wrap (
<li class="mod-metanav--item">
<a class="mod-metanav--link" target="_blank" href="|">
Click here
</a>
</li>
)
if.value = 1
if.equals.data = GP:L
}
Again, I'm not satisfied with this since I have to repeat the same block for every language. I'd rather have a variable I could set for the link and the link-text (using translations for the latter).
If someone has a better solution, I'd be happy to know about it...
Hm, maybe I'm wrong but it doesn't look like huge overhead:
10 = TEXT
10 {
typolink {
parameter = http://worldwide.com
returnLast = url
}
wrap (
<li class="mod-metanav--item">
<a class="mod-metanav--link" target="_blank" href="|">
The Link
</a>
</li>
)
}
[globalVar = GP:L = 1]
10.10.typolink.parameter = http://english.co.uk
[end]
[globalVar = GP:L = 2]
10.10.typolink.parameter = http://german.de
[end]
[globalVar = GP:L = 3]
10.10.typolink.parameter = http://french.fr
[end]
Related
text = "hellovision hey creator yoyo b creator great publisher"
I want to extract creator's name and publisher's name from text.
The result will be,
creator = hellovision hey, yoyo
publisher = great
How can I get text using regular expression?
Do I need to use span()..?
This is my code.
def preprocess2(text):
text_list = test.split(' ')
lyricist = []
composer = []
music_arranger = []
temp = []
lyricist.clear()
composer.clear()
music_arranger.clear()
for i in range(0, len(text_list)):
if text_list[i] == 'creator':
print(len(text_list))
for a in range(0, i-1):
temp.append(text_list[a])
lyricist.append(''.join(temp))
temp.clear()
for b in range(0, i+1):
print(b)
text_list.pop(b)
print(len(text_list))
break
elif text_list[i] == 'pulisher':
for a in range(0, i-1):
temp.append(text_list[a])
composer.append(''.join(temp))
temp.clear()
for b in range(0, i+1):
text_list.pop(b)
break
i = i +1
return text_list
If you split your array using regex with a capture group, the value that you split on will also be passed into the output array.
You can then loop through looking for 'creator' or 'publisher' and in each case, pass the previous entry into the proper collection.
const text = "hellovision hey creator yoyo b creator great publisher"
const splitArr = text.split(/(creator|publisher)/)
const creators = [], publishers = []
let i = -1, len = splitArr.length
while(++i < len){
if(splitArr[i] == "creator") creators.push(splitArr[i-1].trim())
else if(splitArr[i] == "publisher") publishers.push(splitArr[i-1].trim())
}
console.log("creators: ", creators)
console.log("publishers: ", publishers)
I’m using Rails 4.2.3. I’m having trouble passing a variable number of search criteria to my Rails finder method. I have
user = current_user
search_criteria = ["my_objects.user_id = ?"]
search_values = [user.id]
start_date = params[:start_date]
if start_date.present?
start_date_obj = Date.strptime(start_date, "%m/%d/%Y")
search_criteria.push("my_objects.start_date >= ?")
search_values.push(start_date_obj)
else
start_date = my_object.find_user_first_my_object_date(user)
#default_start_date = start_date.to_time.strftime("%m/%d/%Y") if start_date.present?
end
end_date = params[:end_date]
if end_date.present?
end_date_obj = Date.strptime(end_date, "%m/%d/%Y")
search_criteria.push("my_objects.end_date <= ?")
search_values.push(end_date_obj)
else
end_date = my_object.find_user_last_my_object_date(user)
#default_end_date = end_date.to_time.strftime("%m/%d/%Y") if end_date.present?
end
distance = params[:distance]
if distance.present?
distance_parts = distance.split(" ")
search_criteria.push("my_objects.distance = ?")
search_criteria.push("my_objects.distance_unit_id = ?")
search_values.push("#{distance_parts[0]}")
search_values.push("#{distance_parts[1]}")
end
#user_my_objects = MyObjectTime.joins(:my_object).where(search_criteria.join(" AND "), search_values)
.order("my_objects.day")
But this results in the error
wrong number of bind variables (1 for 5) in: my_objects.user_id = ? AND my_objects.start_date >= ? AND my_objects.end_date <= ? AND my_objects.distance = ? AND my_objects.distance_unit_id = ?
I think Rails is treating my “search_values” array as a single value but I want it to pass each value of the array as an argument into the search condition. How do I fix the above?
If I've read the question right, this boils down to
values = ['a', 'b', 'c']
SomeModel.where("foo = ? AND bar = ? AND baz = ?", values)
Throwing an error about an incorrect number of bind variables. To unpack an array and use its values as individual arguments you use the splat operator:
SomeModel.where("foo = ? AND bar = ? AND baz = ?", *values)
models.py
class Restaurant(models.Model)
food_rating = RatingField(range=2, weight=5,can_change_vote = True,allow_delete = True,allow_anonymous = True)
service_rating = RatingField(range=2, weight=5,can_change_vote = True,allow_delete = True,allow_anonymous = True)
ambience_ratiing = RatingField(range=2, weight=5,can_change_vote = True,allow_delete = True,allow_anonymous = True)
view.py code
r = Restaurant.objects.get(pk=1)
r.food_rating.add(score = -1 , user = request.user , ip_address =request.META.get('HTTP_REFERER'))
print r.food_rating.score
error
djangoratings.exceptions.InvalidRating: -1 is not a valid choice for food_rating
doubt
my food_rating field is eligible to take two scores , how am i supposed to change the score so that i can implement vote up and vote down feature , on vote up , i should be able to add 1 to the existing score and on vote down i should be able to subtract a vote , please help , thanks in advance
The problem comes from this script:
if score < 0 or score > self.field.range:
raise InvalidRating("%s is not a valid choice for %s" % (score, self.field.name))
Short answer: convert the [-x:y] interval you want to use for display, into [-x+x:y+x] in your code to avoid this problem. If you wanted [-5:5], then use [-5+5:5+5] which is [0:10]. If you wanted [-50:100] then use [-50+50:100+50] = [0:150] and so on ... It's a simple formula, that shouldn't be a problem for a programer ;)
Long answer: either you fork djangoratings, either you open an issue asking to add a setting enabling negative ratings ... and probably he'll reject it, because of the simple interval conversion workaround, here's some more concrete examples:
class Restaurant(models.Model):
# blabla :)
ambience_rating = RatingField(range=5, weight=5,can_change_vote = True,allow_delete = True,allow_anonymous = True)
def get_adjusted_ambiance_rating(self):
return self.ambience_rating - 3
So, if ambience_rating is "1" (the lowest score), get_adjusted_ambiance_rating() will return -2.
If ambience_rating is "5" (the highest score), get_ambiance_rating_with_negative() will return 2.
Adapt this example/trick to your needs.
You should probably make a single method for all ratings:
def get_adjusted_rating(self, which):
return getattr(self, '%s_rating' % which) - 3
Callable as such:
restaurant.get_adjusted_rating('ambiance')
restaurant.get_adjusted_rating('food')
# etc ...
And maybe a template filter:
#register.filter
def get_adjusted_rating(restaurant, which):
return restaurant.get_adjusted_rating(which)
Usable as such:
{{ restaurant|get_adjusted_rating:"ambiance" }}
{{ restaurant|get_adjusted_rating:"food" }}
{# etc, etc #}
More details about template filters.
I have the models:
class Article(models.Model):
title = models.TextField(blank=True)
keywords = models.ManyToManyField(Keyword, null=True, blank=True)
class Keyword(models.Model):
keyword = models.CharField(max_length=355, blank=True)
I want to get a count of how many articles have each keyword. In essence I want to have a list of keywords where I can get each ones count to give it a relative weighting.
I have tried:
keyword_list=Article.objects.all().annotate(key_count=Count('keywords__keyword'))
but
keyword_list[0].key_count
just seems to give me the number of different keywords each article has? Is it somehow a reverse lookup?
Any help would be much appreciated.
UPDATE
So I got it working:
def keyword_list(request):
MAX_WEIGHT = 5
keywords = Keyword.objects.order_by('keyword')
for keyword in keywords:
keyword.count = Article.objects.filter(keywords=keyword).count()
min_count = max_count = keywords[0].count
for keyword in keywords:
if keyword.count < min_count:
min_count = keyword.count
if max_count > keyword.count:
max_count = keyword.count
range = float(max_count - min_count)
if range == 0.0:
range = 1.0
for keyword in keywords:
keyword.weight = (
MAX_WEIGHT * (keyword.count - min_count) / range
)
return { 'keywords': keywords }
but the view results in a hideous number of queries. I have tried implementing the suggestions given here (thanks) but this is the only methid which seems to work at the moment. However, I must be doing something wrong as I now have 400+ queries!
UPDATE
Wooh! Finally got it working:
def keyword_list(request):
MAX_WEIGHT = 5
keywords_with_article_counts = Keyword.objects.all().annotate(count=Count('keyword_set'))
# get keywords and count limit to top 20 by count
keywords = keywords_with_article_counts.values('keyword', 'count').order_by('-count')[:20]
min_count = max_count = keywords[0]['count']
for keyword in keywords:
if keyword['count'] < min_count:
min_count = keyword['count']
if max_count < keyword['count']:
max_count = keyword['count']
range = float(max_count - min_count)
if range == 0.0:
range = 1.0
for keyword in keywords:
keyword['weight'] = int(
MAX_WEIGHT * (keyword['count'] - min_count) / range
)
return { 'keywords': keywords}
Since you want the number of articles that have each keyword, you have to do it the other way:
>>> Keyword.objects.all().annotate(article_count=models.Count('article'))[0].article_count
2
This is the same as the answer from Vebjorn Ljosa, but with a little context, where article_set is the related_name of the reverse many-to-many relationship object.
keywords_with_article_counts = Keyword.objects.all().annotate(article_count=Count('article_set'))
To illustrate your results, it would be easier to return the .values():
keywords_with_article_counts.values('keyword', 'article_count')
Which would return a list of dictionaries that would look something like this:
[{'article_count': 36, 'keyword': u'bacon'},
{'article_count': 4, 'keyword': u'unicorns'},
{'article_count': 8, 'keyword': u'python'}]
i don't know how you would do it efficiently but if you need to get it done.
keywords = Keyword.objects.all()
for keyword in keywords:
print 'Total Articles: %d' % (Article.objects.filter(keywords=keyword).count())
I've got this complex filtering mechanism...
d = copy(request.GET)
d.setdefault('sort_by', 'created')
d.setdefault('sort_dir', 'desc')
form = FilterShipmentForm(d)
filter = {
'status': ShipmentStatuses.ACTIVE
}
exclude = {}
if not request.user.is_staff:
filter['user__is_staff'] = False
if request.user.is_authenticated():
exclude['user__blocked_by__blocked'] = request.user
if form.is_valid():
d = form.cleaned_data
if d.get('pickup_city'): filter['pickup_address__city__icontains'] = d['pickup_city']
if d.get('dropoff_city'): filter['dropoff_address__city__icontains'] = d['dropoff_city']
if d.get('pickup_province'): filter['pickup_address__province__exact'] = d['pickup_province']
if d.get('dropoff_province'): filter['dropoff_address__province__exact'] = d['dropoff_province']
if d.get('pickup_country'): filter['pickup_address__country__exact'] = d['pickup_country']
if d.get('dropoff_country'): filter['dropoff_address__country__exact'] = d['dropoff_country']
if d.get('min_price'): filter['target_price__gte'] = d['min_price']
if d.get('max_price'): filter['target_price__lte'] = d['max_price']
if d.get('min_distance'): filter['distance__gte'] = d['min_distance'] * 1000
if d.get('max_distance'): filter['distance__lte'] = d['max_distance'] * 1000
if d.get('available_on'): # <--- RELEVANT BIT HERE ---
filter['pickup_earliest__lte'] = d['available_on'] # basically I want "lte OR none"
filter['pickup_latest__gte'] = d['available_on']
if d.get('shipper'): filter['user__username__iexact'] = d['shipper']
order = ife(d['sort_dir'] == 'desc', '-') + d['sort_by']
shipments = Shipment.objects.filter(**filter).exclude(**exclude).order_by(order) \
.annotate(num_bids=Count('bids'), min_bid=Min('bids__amount'), max_bid=Max('bids__amount'))
And now my client tells me he wants pickup/drop-off dates to be 'flexible' as an option. So I've updated the DB to allow dates to be NULL for this purpose, but now the "available for pickup on" filter won't work as expected. It should include NULL/None dates. Is there an easy fix for this?
Flip the logic and use exclude(). What you really want to do is exclude any data that specifies a date that doesn't fit. If pickup_latest and pickup_earliest are NULL it shouldn't match the exclude query and wont be removed. Eg
exclude['pickup_latest__lt'] = d['available_on']
exclude['pickup_earliest__gt'] = d['available_on']
Most database engines don't like relational comparisons with NULL values. Use <field>__isnull to explicitly check if a value is NULL in the database, but you'll need to use Q objects to OR the conditions together.
Don't think that's actually a django-specific question. Variable 'd' is a python dictionary, no? If so, you can use this:
filter['pickup_latest__gte'] = d.get('available_on', None)