Redirect missing translations on Hugo site - internationalization

I have a Hugo site with a few translated pages. Not all the pages are translated, since I don't always have volunteers for every page in every language.
In the menu, I have links to some pages that I'd like to redirect to English if the local translation is not there (so there's always a link, but it might not be translated).
# Force to have /en/my-page and /fr/my-page routes, even for default language.
defaultContentLanguageInSubdir= true
# English is the default language
defaultContentLanguage = "en"
# This page exists in en and fr, but not de
[[menu.shortcuts]]
name = "Licence"
url = "/licence"
[Languages]
[Languages.en]
languageName = "English"
[Languages.fr]
languageName = "Français"
[Languages.de]
languageName = "Deutsch"
On the English and French page, this works fine, the menu link goes to /en/licence and /fr/licence. But on the German page, it goes to /de/licence, which is a 404.
Is there a way to redirect missing pages to the corresponding page in the default language?

Actually there is no default hugo solution.
I've spend a lot of time to figure out how to reach the goal and don't copy data content all the time for all languages, because it's is a way to difficult to controll different versions.
So I simply check if it's an internal link and the page under the current language exists and if so then I create a link for this language if no then I simply assign a default one.
{{ $link := .link }}
{{ if and ( $.Site.GetPage ( substr ( $link ) 0 -1 ) ) ( ne ( $.Site.BaseURL | relLangURL ) "/" ) ( not ( in $link "://" ) ) }}
{{ $link = ( print ( $.Site.BaseURL | relLangURL ) $link ) }}
{{ end }}
All my links have / symbol in the end, so if your links look like /blog and not as /blog/ then just change ( substr ( $link ) 0 -1 ) to just $link.
I'm a hugo newbie, sorry if it's not elegant solution but it works for me so far.

Related

why Php increment count session twice per page load?

My wordpress php script is incremented by two instead one.
++$_SESSION['visitor'] is incremented by two !
In functions.php
if ( !isset( $_SESSION['visitor'] ) ) $_SESSION['visitor'] = 1; else ++$_SESSION['visitor'];
I have to do this in echo to have Session + 1 otherwise I get Session + 2: In any php file
`<?php echo --$_SESSION['visitor'] ; ?>`
I don't know what can cause this.
If I increment when I echo The session is well incremented by 1 , why ?.
if ( !isset( $_SESSION['visitor'] ) ) $_SESSION['visitor'] = 1; else $_SESSION['visitor'];
<?= $_SESSION['visitor'] .' + ' . ++$_SESSION['visitor']; ?>
The increment add well +1 only on any php file inside theme but add +2 every time using it in functions.php. For both I use the same syntax ++$_SESSION['visitor']
I have add params to session to allow subdomains in functions.php:
session_set_cookie_params(0, '/', '.website.com');

Magento 2 - wrong number of digits between separators for prices in Indian Rupees

I am using Magento 2.2.3. my default currency is INR, but it shows in the wrong format:
But it should be ₹77,65,000.00. How do we correct price format? Currently its wrong... like USD.
You can set the currency format by following code.
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); // Instance of Object Manager
$priceHelper = $objectManager->create('Magento\Framework\Pricing\Helper\Data'); // Instance of Pricing Helper
$price = 1000; //Your Price
$formattedPrice = $priceHelper->currency($price, true, false);
?>
File path: vendor/magento/zendframework1/library/Zend/Locale/Data/en.xml
On line number 3353, under section currencyFormat and type = "standard", change the pattern from <pattern>¤#,##0.00</pattern> to <pattern>¤ #,##,##0.00</pattern>
Still, on PDP page and cart page summary the price format does not change because the prize format is coming from the JS in which Magento using a RegExp function for only US price format.
For that, please change the code in the below file.
File path: vendor/magento/module-catalog/view/base/web/js/price-utils.js (First extend this file in your theme directory and do the respected changes)
Under the function formatPrice below this line comment all the line in the respective function.
i = parseInt(
amount = Number(Math.round(Math.abs(+amount || 0) + 'e+' + precision) + ('e-' + precision)),
10
) + '';
And add this set of code below the above line.
var x=i;
x=x.toString();
var afterPoint = '';
if(x.indexOf('.') > 0)
afterPoint = x.substring(x.indexOf('.'),x.length);
x = Math.floor(x);
x=x.toString();
var lastThree = x.substring(x.length-3);
var otherNumbers = x.substring(0,x.length-3);
if(otherNumbers != '')
lastThree = ',' + lastThree;
var response = otherNumbers.replace(/\B(?=(\d{2})+(?!\d))/g, ",") + lastThree + afterPoint;
return pattern.replace('%s', response);
deploy and `rm -rf var/cache/*
And then you're done. For Example: A price previously displayed like 453,453, will now display in the Indian manner like 4,53,453.

Remove Header and Footer to add new extra page

I',m using Laravel 5.5 to create a PDF file using barryvdh/laravel-snappy.
I want to generate a PDF with and extra page without header and footer. It is to print terms and conditions at the end of my budget.
I can generate the first 2 page with the products , price, header , footer... but when I add the terms and contiditons I have the footer and header and the pdf options ( marging...)
I have tried to remove header and footer using javascript when I loadView removing header and footer with css but I have a white space in those places but I need all the page.
$presupuesto = ExpedientePresupuesto::findOrFail($id_presupuesto);
$now = Carbon::now('Europe/Madrid');
$header = \View::make('expedientes.pdf.cabeceraPresupuesto', compact('now', 'request', 'presupuesto') )->render();
$footerHTML = Footer::footerHtml($now);
$footer = \View::make('expedientes.pdf.piePresupuesto', compact( 'footerHTML', 'request', 'presupuesto') )->render();
$pdf= \PDF::loadView('expedientes.pdf.cuerpoPresupuesto', compact('presupuesto', 'request'));
return view('expedientes.pdf.cabeceraPresupuesto', compact('now', 'presupuesto', 'request'));
$pdf->setPaper('a4');
$pdf->setOption('header-html', $header );
$pdf->setOption('footer-html', $footer );
$pdf->setOption('footer-spacing', 10 );
My question is it possible to add other page with differents optios in the same PDF? I mean, the first part of the PDF has header footer and anything I want and the last part has no header, other spacing...
Somenting like that ( does not working)
$pdf.= \PDF::loadView('expedientes.pdf.terms', compact('presupuesto', 'request'));
$pdf->setPaper('a4');
$pdf->setOption('header-html', '' );
$pdf->setOption('footer-html', '');
$pdf->setOption('footer-spacing', 10 );
return $pdf->stream( $now . '-PresupuestoFP.pdf');

How to change the language in timespan() function in codeigniter

Im using codeigniter to pull blog posts from my database and I want to display how much time has elapsed since the post is posted. By default codeigniters timespan() function is displaying for example:
1 Year, 10 Months, 2 Weeks, 5 Days, 10 Hours, 16 Minutes
but i want to translate the words Year,Months,Weeks,Days,Hours,Minutes in other language, for example Bosnian,Croatian or Serbian.
How can I translate it?
I found the answer. You need to go to the application/language/english folder and create a file called date_lang.php. In my case I just want to have one language on my website, so i made the file in the default (english) folder. If you have more languages you can change the language in the application/config/config.php and change the $config['language'] = 'english' to whatever language you made in the application/language/YOURLANGUAGE.php file.
I added this piece of code in my date_lang.php file and it works well.
<?php
$lang['date_year'] = 'Godinu';
$lang['date_years'] = 'Godina';
$lang['date_month'] = 'Mjesec';
$lang['date_months'] = 'Mjeseci';
$lang['date_week'] = 'Sedmica';
$lang['date_weeks'] = 'Sedmice';
$lang['date_day'] = 'Dan';
$lang['date_days'] = 'Dana';
$lang['date_hour'] = 'Sat';
$lang['date_hours'] = 'Sat';
$lang['date_minute'] = 'Minute';
$lang['date_minutes'] = 'Minuta';
$lang['date_second'] = 'Sekundu';
$lang['date_seconds'] = 'Sekunde';
?>

Include jekyll / liquid template data in a YAML variable?

I am using the YAML heading of a markdown file to add an excerpt variable to blog posts that I can use elsewhere. In one of these excerpts I refer to an earlier blog post via markdown link markup, and I use the liquid template data variable {{ site.url }} in place of the base URL of the site.
So I have something like (trimmed it somewhat)
---
title: "Decluttering ordination plots in vegan part 2: orditorp()"
status: publish
layout: post
published: true
tags:
- tag1
- tag2
excerpt: In the [earlier post in this series]({{ site.url }}/2013/01/12/
decluttering-ordination-plots-in-vegan-part-1-ordilabel/ "Decluttering ordination
plots in vegan part 1: ordilabel()") I looked at the `ordilabel()` function
----
However, jekyll and the Maruku md parser don't like this, which makes me suspect that you can't use liquid markup in the YAML header.
Is it possible to use liquid markup in the YAML header of pages handled by jekyll?
If it is, what I am I doing wrong in the example shown?
If it is not allowed, who else can I achieve what I intended? I am currently developing my site on my laptop and don't want to hard code the base URL as it'll have to change when I am ready to deploy.
The errors I am getting from Maruku are:
| Maruku tells you:
+---------------------------------------------------------------------------
| Must quote title
| ---------------------------------------------------------------------------
| the [earlier post in this series]({{ site.url }}/2013/01/12/decluttering-o
| --------------------------------------|-------------------------------------
| +--- Byte 40
and
| Maruku tells you:
+---------------------------------------------------------------------------
| Unclosed link
| ---------------------------------------------------------------------------
| the [earlier post in this series]({{ site.url }}/2013/01/12/decluttering-or
| --------------------------------------|-------------------------------------
| +--- Byte 41
and
| Maruku tells you:
+---------------------------------------------------------------------------
| No closing ): I will not create the link for ["earlier post in this series"]
| ---------------------------------------------------------------------------
| the [earlier post in this series]({{ site.url }}/2013/01/12/decluttering-or
| --------------------------------------|-------------------------------------
| +--- Byte 41
Today I ran into a similar problem. As a solution I created the following simple Jekyll filter-plugin which allows to expand nested liquid-templates in (e.g. liquid-variables in the YAML front matter):
module Jekyll
module LiquifyFilter
def liquify(input)
Liquid::Template.parse(input).render(#context)
end
end
end
Liquid::Template.register_filter(Jekyll::LiquifyFilter)
Filters can be added to a Jekyll site by placing them in the '_plugins' sub-directory of the site-root dir. The above code can be simply pasted into a yoursite/_plugins/liquify_filter.rb file.
After that a template like...
---
layout: default
first_name: Harry
last_name: Potter
greetings: Greetings {{ page.first_name }} {{ page.last_name }}!
---
{{ page.greetings | liquify }}
... should render some output like "Greetings Harry Potter!". The expansion works also for deeper nested structures - as long as the liquify filter is also specified on the inner liquid output-blocks. Something like {{ site.url }} works of course, too.
Update - looks like this is now available as a Ruby gem: https://github.com/gemfarmer/jekyll-liquify.
I don't believe it's possible to nest liquid variables inside YAML. At least, I haven't figure out how to do it.
One approach that will work is to use a Liquid's replace filter. Specifically, define a string that you want to use for the variable replacement (e.g. !SITE_URL!). Then, use the replace filter to switch that to your desired Jekyll variable (e.g. site.url) during the output. Here's a cut down .md file that behaves as expected on my jekyll 0.11 install:
---
layout: post
excerpt: In the [earlier post in this series](!SITE_URL!/2013/01/12/)
---
{{ page.excerpt | replace: '!SITE_URL!', site.url }}
Testing that on my machine, the URL is inserted properly and then translated from markdown into an HTML link as expected. If you have more than one item to replace, you can string multiple replace calls together.
---
layout: post
my_name: Alan W. Smith
multi_replace_test: 'Name: !PAGE_MY_NAME! - Site: [!SITE_URL!](!SITE_URL!)'
---
{{ page.multi_replace_test | replace: '!SITE_URL!', site.url | replace: '!PAGE_MY_NAME!', page.my_name }}
An important note is that you must explicitly set the site.url value. You don't get that for free with Jekyll. You can either set it in your _config.yml file with:
url: http://alanwsmith.com
Or, define it when you call jekyll:
jekyll --url http://alanwsmith.com
If you need to replace values in data/yml from another data/yml file, I wrote plugin. It's not so elegant but works :
I did some code improvements. Now it catch all occurrences in one string and work with nested values.
module LiquidReplacer
class Generator < Jekyll::Generator
REGEX = /\!([A-Za-z0-9]|_|\.){1,}\!/
def replace_str(str)
out = str
str.to_s.to_enum(:scan, REGEX).map {
m = Regexp.last_match.to_s
val = m.gsub('!', '').split('.')
vv = $site_data[val[0]]
val.delete_at(0)
val.length.times.with_index do |i|
if val.nil? || val[i].nil? || vv.nil? ||vv[val[i]].nil?
puts "ERROR IN BUILDING YAML WITH KEY:\n#{m}"
else
vv = vv[val[i]]
end
end
out = out.gsub(m, vv)
}
out
end
def deeper(in_hash)
if in_hash.class == Hash || in_hash.class == Array
_in_hash = in_hash.to_a
_out_hash = {}
_in_hash.each do |dd|
case dd
when Hash
_dd = dd.to_a
_out_hash[_dd[0]] = deeper(_dd[1])
when Array
_out_hash[dd[0]] = deeper(dd[1])
else
_out_hash = replace_str(dd)
end
end
else
_out_hash = replace_str(in_hash)
end
return _out_hash
end
def generate(site)
$site_data = site.data
site.data.each do |data|
site.data[data[0]] = deeper(data[1])
end
end
end
end
place this code in site/_plugins/liquid_replacer.rb
in yml file use !something.someval! like as site.data.something.someval but without site.data part.
example :
_data/one.yml
foo: foo
_data/two.yml
bar: "!one.foo!bar"
calling {{ site.data.two.bar }} will produce foobar
=======
OLD CODE
======
module LiquidReplacer
class Generator < Jekyll::Generator
REGEX = /\!([A-Za-z0-9]|_|\.){1,}\!/
def generate(site)
site.data.each do |d|
d[1].each_pair do |k,v|
v.to_s.match(REGEX) do |m|
val = m[0].gsub('!', '').split('.')
vv = site.data[val[0]]
val.delete_at(0)
val.length.times.with_index do |i|
vv = vv[val[i]]
end
d[1][k] = d[1][k].gsub(m[0], vv)
end
end
end
end
end
end
Another approach would be to add an IF statement to your head.html.
Instead of using page.layout like I did on my example below, you could use any variable from the page YAML header.
<title>
{% if page.layout == 'post' %}
Some text with {{ site.url }} variable
{% else %}
{{ site.description | escape }}
{% endif %}
</title>

Resources