How to use constants in Fluid templates? - templates

I'm using Typo3 version 10+
I created a "Site package extension" to make some nice templates and styles (header / footer / etc)
I'm using constants like this (constants.typoscript):
#cat=My website variables//a; type=string; label=Some id value
config.some_id = 123
BE User can edit the constant in BE.
To use the constant in fluid template, I use this typoscript code (setup.typoscript)
page = PAGE
page {
typeNum = 0
10 = FLUIDTEMPLATE
10 {
variables {
some_id = TEXT
some_id.value = {$config.some_id}
}
}
...
}
In fluid (footer.html) I use this variable:
<f:link.page pageUid="{some_id}">Some link</f:link.page>
Everything works very nice so far.
Now I'm creating a new extension to output some simple events "Events ext" (list / details)
Now question: is it possible to use this constant (some_id from Site package ext) in the Events extension (List.html) as global variable ?
For some reason I can't see any constants in fluid templates of "Event ext". (empty values)
For both extensions I used the code below and included its configs in Typoscript setup
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile(
$extensionKey,
'Configuration/TypoScript',
'My ext'
);

Constants defined through page.10.variable are only available for page template, not in your extension template.
But you can easily access this variable in your extension with some TypoScript.
Add this TS - in your my_ext/TypoScript/setup.typoscript or through BE in template setup field :
plugin.tx_you_ext.settings {
some_id = {$config.some_id}
}
And then, you can access the data in your Fluid Template with :
{settings.some_id}

Related

Pass variable from initializer to handlebars .hbs (Discourse Plugin, maybe Ember in general)

In a .hbs file I am creating a navigation menu with various items. One of the items will only display if a user is a pro (boolean).
var pro is a variable set in my initializer and I need to pass it my .hbs file for the purposes of a conditionally showing one of the menu items.
In Ember, how is this accomplished?
In a such case, we use service to store variables during the application lifecycle. Initializer puts the variables and menu items to service. Menu components retrieve variables from service.
You may also define a helper to retrieve variable from service.
I had quite the same problem : I had to use a language variable that is set in my html and I needed to use this language variable in my template. I used a helper to do so : in the helper you can use the variable pro that is set in your initializer (provided you declared it).
example :
function myInit(pro) {
var template = ...;
var data = ...;
Handlebars.registerHelper('ifProUser', function(item) {
if (pro) {
return "pro menu here";
} else {
return "";
}
}
var html = template(data);
...
}
Then in the template just use :
{{ifProInit}}{{/ifProInit}}

Direct link to language in OpenCart

I have a website(built with OpenCart) with multiple languages, e.g. English, German, French.
Users can change language using default functionality of the OpenCart - clicking on language icons on top.
Is it possible to send users automaticaly (so they don't have to click on the flag) from :
Germany to German version of the website
France to French version of the website
(English language is default)
Is there an URL I can use for these languages if the default page is for example http://mystore.com ?
(I noticed that when I click on the language icon the URL is not changing - it's the same for all languages)
Nowadays opencart doesn't support this function, but in the past , older versions of Opencart did have this function.
If you want to include this function in your website you will have to do the following:
Edit this file:
catalog/controller/module/language.php
find this:
class ControllerModuleLanguage extends Controller {
protected function index() {
if (isset($this->request->post['language_code'])) {
before the "if", you will have to include the following :
if (isset($this->request->get['lang'])) {
$this->session->data['language'] = $this->request->get['lang'];
if (isset($_SERVER['HTTP_REFERER']) && (strpos($_SERVER['HTTP_REFERER'], $this->config->get('config_url')) !== false) ) {
$this->redirect($_SERVER['HTTP_REFERER']);
} else {
$this->redirect($this->url->link('common/home'));
}
} else {
The source
An example of website with this code:
http://incomingtospain.com/madrid&lang=de
http://incomingtospain.com/madrid&lang=ru
This website has 8 idioms and you can access by different url, with this variable "lang" &lang=es &lang=en ... &lang=de &lang=ru
I think language is set in session variable
For the functionality you mentioned will be achive in following way:
Use the HTML5 geolocation to detect the location of user
Research in opencart to set the language function
after all done place your code using VQMOD if you want to do it in proper way
or you can also edit your core opencart files( Not recommended)
if the browser doesn't support geolocation or they refuse to share their location just load the default language.
With OpenCart 2.0, you must work on the file index.php (in your website root) and place this code :
if (isset($request->get['lang']) && array_key_exists($request->get['lang'], $languages)) {
$session->data['language'] = $request->get['lang'];
}
between line 155 and line 157
Line 153 to 154 :
foreach ($query->rows as $result) {
$languages[$result['code']] = $result;
}
(you add here the new code)
Line 157 :
if (isset($session->data['language']) && array_key_exists($session->data['language'], $languages)) {
Line 158 :
$code = $session->data['language'];

How to generate media item link with id instead of path in Sitecore

Anyone knows how to generate links in sitecore with ID instead of item path?
If you use GetMediaUrl method from the API, I can get this URL:
/~/media/Images/Archive/content/News and Events/News_and_Events_Level2/20070419162739/iwhiz3.jpg
The problem with this approach is that if someone changes the media item name, removes it somewhere or deletes it, the above link will break.
I notice if I insert a media link from rich text editor, I get the link as below:
/~/media/14BDED00E4D64DFD8F74019AED4D74EB.ashx
The second link is better because it's using the item id, so if the actual media item is renamed, removed, or deleted, all related links will be updated too. On top of that, when Sitecore renders the page, it will actually convert the above link and display the item path so it's readable.
I'm using Sitecore 6.5 and currently doing content migration so I need to make sure all internal links are updated properly.
May I know if there is a method to generate the second link by using sitecore API?
Thanks!
The GetMediaItemUrl extension method seems to give you what you want.
public static class ItemExtensions
{
public static string GetMediaItemUrl(this Item item)
{
var mediaUrlOptions = new MediaUrlOptions() { UseItemPath = false, AbsolutePath = true };
return Sitecore.Resources.Media.MediaManager.GetMediaUrl(item, mediaUrlOptions);
}
}
[TestFixture]
public class when_using_items_extensions
{
[Test]
public void a_url_based_on_media_item_id_can_be_generated()
{
// Arrange
Database db = global::Sitecore.Configuration.Factory.GetDatabase("master");
Item item = db.GetItem("/sitecore/media library/Images/MyImage");
// Act
var mediaUrl = item.GetMediaItemUrl();
// Assert
Assert.That(mediaUrl, Is.EqualTo("/~/media/17A1341ABEEC46788F2159843DCEAB03.ashx"));
}
}
These are called dynamic links and you can normally generate them using the LinkManager e.g:
Sitecore.Links.LinkManager.GetDynamicUrl(item)
.. but I'm not sure of the method to do this with Media links (there probably is one but I cant seem to find it and its not on MediaManager) but the basic syntax is:
"/~/media/" + item.ID.ToShortID() + ".ashx"
If you always want to use ID's instead of paths, you can change this setting in webconfig to false (like this):
<setting name="Media.UseItemPaths" value="false"/>`
Here is what the webconfig describes about it:
MEDIA - USE ITEM PATHS FOR URLS
This setting controls if item paths are used for constructing media URLs.
If false, short ids will be used.
Default value: true
Then you can use the default implementation (without additional parameters):
Sitecore.Resources.Media.MediaManager.GetMediaUrl(item);
This is what I use:
var imgField = ((Sitecore.Data.Fields.ImageField)currentItem.Fields["Icon"]);
MediaUrlOptions opt = new MediaUrlOptions();
opt.AlwaysIncludeServerUrl = true;
// Absolute Path works as well. So either use AbsolutePath or AlwaysIncludeServerUrl
opt.AbsolutePath = true;
string mediaUrl = MediaManager.GetMediaUrl(imgField.MediaItem, opt);

Rename language after item is created

I'm using sitecore 6.5 with two languages installed, en (default) and fr-CA. There are items in the tree with content in both en and fr-CA.
The problem is that the French url has 'fr-CA' in it and we want that to be 'fr', for example:
http://website.com/fr/page.aspx instead of http://website.com/fr-CA/page.aspx
I tried renaming the language from 'fr-CA' to 'fr' and that fixed the url but the content still points to the old language 'fr-CA', so the item shows three languages: en, fr and fr-CA. It's not recognizing the name change.
Any suggestions are much appreciated.
Thanks,
Tarek
The problem is you have created fr-CA versions of your items which cannot be fixed by renaming the language .. you can now make a fr version but, like you are seeing, this means there are now 3 possible versions.
One suggestion is to leave the languages in Sitecore alone and alter how links are served and processed instead.
You would probably need to look at adding your own method into the httpRequestBegin pipeline in Sitecore. This would follow the LanguageResolver entry. You can then parse the RawUrl and set Sitecore.Context.Langauge' to French if the first element in it matched/fr/`.
Extremely quick & dirty example:
public class MyLanguageResolver : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
string languageText = WebUtil.ExtractLanguageName(args.Context.Request.RawUrl);
if(languageText == "fr")
{
Sitecore.Context.Language = LanguageManager.GetLanguage("fr-CA");
}
}
}
You would probably also have to override the LinkProvider in the <linkManager> section of the web.config to format your URLs when they are resolved by Sitecore.
Another extremely quick & dirty example:
public class MyLinkProvider : LinkProvider
{
public override string GetItemUrl(Sitecore.Data.Items.Item item, UrlOptions options)
{
var url = base.GetItemUrl(item, options);
url = url.Replace("/fr-CA/", "/fr/");
return url;
}
}
Another way (slightly more long-winded as it will need to be executed via a script) is to copy the data from the fr-CA version to the fr version and then delete the fr-CA version of each item.
Rough helper method that encompasses what you're trying to do
private void CopyLanguage(ID id, Language sourceLanguage, Language destinationLanguage)
{
var master = Database.GetDatabase("master");
var sourceLanguageItem = master.GetItem(id, sourceLanguage);
var destinationLanguageItem = master.GetItem(id, destinationLanguage);
using (new SecurityDisabler())
{
destinationLanguageItem.Editing.BeginEdit();
//for each field in source, create in destination if it does not exist
foreach (Field sf in sourceLanguageItem.Fields)
{
if (sf.Name.Contains("_")) continue;
destinationLanguageItem.Fields[sf.Name].Value = sf.Value;
}
destinationLanguageItem.Editing.AcceptChanges();
////Remove the source language version
ItemManager.RemoveVersions(sourceLanguageItem,sourceLanguage, SecurityCheck.Disable);
}
}
Another way to update the languages on your content items is:
Export the fr-CA language to a .xml file (Using the Control Panel)
In the .xml file replace all and tags with the and
Rename fr-CA language in the master database to the fr
Import language from the .xml file
Run Clean Up Databases task (from the Control Panel)
Also you can create a sql script that will change fr-CA language with the fr for all records in the UnversionedFields and VersionedFields tables.
If you need any more information or examples please let me know. :)
I had a similar requirement to rename a language while retaining the content. I decided to migrate content from one language to another by using Unicorn:
1: Create a predicate telling Unicorn to track all of your content. In my case:
<include name="site content" database="master" path="/sitecore/content/mySite" />
Reserialize the content, writing it to disk as YML files
Using a tool that can perform a find & replace in multiple files at once, such as Notepad++, replace all instances of "Language: fr-CA" with "Language: fr" in your yml files.
Run a Unicorn Sync
You will find that all of your content is now associated with the "fr" language instead of "fr-CA".

Why use templates in Kohana?

I don't understand the purpose of using templates in Kohana. I see almost no difference in the process of building a view with a template controller vs a regular controller, except that the template controller is tied to a given template and so is less flexible. What are the advantages?
Building view with regular controller:
Class Controller_Hello extends Controller
{
public function action_index()
{
$view = View::factory('page');
$view->page_title = 'My Hello App';
$view->content = 'hello, world!';
$view->sidebar = View::factory('parts/sidebar');
$this->response->body($view);
}
}
Building view with template controller:
Class Controller_Hello extends Controller_Template
{
public $template = 'page';
public function action_index()
{
$this->template->page_title = 'My Hello App';
$this->template->content = 'hello, world!';
$this->template->sidebar = View::factory('parts/sidebar');
}
}
Controller_Template is just an example of how you can implement your own templating-system.
It is not ready-to-use solution (at least for my projects usually). Check this one controller (it is also not ready-to-use solution but possibly it will help you understand point of extending different controllers for different purposes): http://pastie.org/2563595
I am sure there are other, maybe better solutions for templating systems. But why am I using templates in Kohana?
Think about multiple pages, all based upon one layout/design scheme. So I build a template controller using a certain view, defining layout/design, defining content, header and footer "areas". In the template controller I am loading the CSS files and script files, setting the title and meta values of the website, because every single site is using these CSS/script files with the same meta values and title.
So in every Controller extending the template controller I don't need to load the CSS/script files anew, set the meta values and title etc... But I could change all these values, maybe add a CSS file only for a single site.
Maybe all the mentioned sites have the same footer and/or header: I assign the header/footer view to the template within the template controller, so I don't need to do that in all the controller extending the template controller. Or all actions in one controller have the same header/footer, so I assignt he header and footer few in the before() function of the controller...
For me templates in kohana are a good utility for building small web applications.