Basically, I had the same problem as here:
Symfony2 & Translatable : entity's locale is empty
Translations where saved in the ext_translations table, but where not being displayed.
After adding the proposed fix, it DID work.
Today I upgraded from 2.0 to 2.1 I managed to get pretty much everything working so far.
But now my translatables are again not being displayed properly (they ARE still being saved properly).
I think it has something to do with the changes to where and how the users locale is stored in 2.1 compared to 2.0 .. but i cannot figure this one out.
Fixed this by registering a custom listener
namespace XXX;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class LocaleListener implements EventSubscriberInterface
{
private $defaultLocale;
public function __construct($defaultLocale = 'en')
{
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
if (!$request->hasPreviousSession()) {
return;
}
if ($locale = $request->attributes->get('_locale')) {
$request->getSession()->set('_locale', $request->getLocale());
} else {
$request->setDefaultLocale($request->getSession()->get('_locale', $this->defaultLocale));
}
}
static public function getSubscribedEvents()
{
return array(
// must be registered before the default Locale listener
KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
);
}
}
then changed
$request->setDefaultLocale($request->getSession()->get('_locale', $this->defaultLocale));
to
$request->setLocale($request->getSession()->get('_locale'));
and used
$this->getRequest()->getSession()->set('_locale', 'nl');
to set the locale, translations and translatables now work
hope this also helps someone else ..
Related
In my c++ project, I need to create Subjects having an initial value, that may be updated. On each subscription/update, subscribers may trigger then data processing... In a previous Angular (RxJS) project, this kind of behavior was handled with ReplaySubject(1).
I'm not able to reproduce this using c++ rxcpp lib.
I've looked up for documentation, snippets, tutorials, but without success.
Expected pseudocode (typescript):
private dataSub: ReplaySubject<Data> = new ReplaySubject<Data>(1);
private init = false;
// public Observable, immediatly share last published value
get currentData$(): Observable<Data> {
if (!this.init) {
return this.initData().pipe(switchMap(
() => this.dataSub.asObservable()
));
}
return this.dataSub.asObservable();
}
I think you are looking for rxcpp::subjects::replay.
Please try this:
auto coordination = rxcpp::observe_on_new_thread();
rxcpp::subjects::replay<int, decltype(coordination)> test(1, coordination);
// to emit data
test.get_observer().on_next(1);
test.get_observer().on_next(2);
test.get_observer().on_next(3);
// to subscribe
test.get_observable().subscribe([](auto && v)
printf("%d\n", v); // this will print '3'
});
I'm having a Sitecore 8 MVC solution, and I have to extend the behavior of Data Source. It's pretty similar to what other people have done with queryable datasources before (such as http://www.cognifide.com/blogs/sitecore/reduce-multisite-chaos-with-sitecore-queries/ etc), but I've hooked into the <mvc.getXmlBasedLayoutDefinition> pipeline instead. It works fine and my custom data sources are resolved as they are entered in the layouts field on an item or on standard values.
But, when the custom data source is specified as a default data source on a rendering item, things becomes a bit trickier. I could solve it through the same pipeline, but that solution didn't look very nice. It means I'd have to load each rendering that hasn't a data source specified in the layout, and do the processing and resolve it from there. There must be a more natural way of doing this.
Does anyone know where to put such implementation logic for the default data source? (The <resolveRenderingDatasource> pipeline looked promising, but didn't execute in this scenario)
From what I understand, you may want to extend XmlBasedRenderingParser class. Here are the steps that should do the trick:
Create a new file App_Config\include\Sitecore.Mvc.Custom.config:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<initialize>
<processor
patch:after="processor[#type='Sitecore.Mvc.Pipelines.Loader.InitializeRoutes, Sitecore.Mvc']"
type="My.Assembly.Namespace.RegisterCustomXmlBasedRenderingParser, My.Assembly"/>
</initialize>
</pipelines>
</sitecore>
</configuration>
Create CustomXmlBasedRenderingParser class:
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Mvc.Extensions;
using Sitecore.Mvc.Presentation;
namespace My.Assembly.Namespace
{
public class CustomXmlBasedRenderingParser : XmlBasedRenderingParser
{
protected override void AddRenderingItemProperties(Rendering rendering)
{
RenderingItem renderingItem = rendering.RenderingItem;
if (renderingItem != null && !rendering.DataSource.ContainsText())
{
rendering.DataSource = ResolveRenderingItemDataSource(renderingItem);
}
base.AddRenderingItemProperties(rendering);
}
private static string ResolveRenderingItemDataSource(RenderingItem renderingItem)
{
string dataSource = string.Empty;
if (renderingItem.DataSource != null && renderingItem.DataSource.StartsWith("query:"))
{
string query = renderingItem.DataSource.Substring("query:".Length);
Item contextItem = Context.Item;
Item queryItem = contextItem.Axes.SelectSingleItem(query);
if (queryItem != null)
{
dataSource = queryItem.Paths.FullPath;
}
}
return dataSource;
}
}
}
Create RegisterCustomXmlBasedRenderingParser class:
using Sitecore.Mvc.Configuration;
using Sitecore.Mvc.Presentation;
using Sitecore.Pipelines;
namespace My.Assembly.Namespace
{
public class RegisterCustomXmlBasedRenderingParser
{
public virtual void Process(PipelineArgs args)
{
MvcSettings.RegisterObject<XmlBasedRenderingParser>(() => new CustomXmlBasedRenderingParser());
}
}
}
What is more, if you want your code to be executed for DataSource defined on both Rendering and Presentation Details, you should be able to use the code below:
using System.Xml.Linq;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Mvc.Presentation;
namespace My.Assembly.Namespace
{
public class CustomXmlBasedRenderingParser : XmlBasedRenderingParser
{
public override Rendering Parse(XElement node, bool parseChildNodes)
{
Rendering rendering = base.Parse(node, parseChildNodes);
ResolveRenderingItemDataSource(rendering);
return rendering;
}
private static void ResolveRenderingItemDataSource(Rendering rendering)
{
if (rendering.DataSource != null && rendering.DataSource.StartsWith("query:"))
{
string query = rendering.DataSource.Substring("query:".Length);
Item contextItem = Context.Item;
Item queryItem = contextItem.Axes.SelectSingleItem(query);
if (queryItem != null)
{
rendering.DataSource = queryItem.Paths.FullPath;
}
}
}
}
}
Please remember that this code is not tested properly and may not work out of the box in your environment. Anyway I hope it will give you at least a good indication where to start.
I'm trying to get an attribute for it to be listed on list.phtml, the form that is being made is as follows:
I created a module on the Block and created a function which captures the attribute:
protected function getPreOrder()
{
$productId = $this->getRequest()->getParam('id');
$product = Mage::getModel('catalog/product')->load($productId);
$preOrder = $product->getNewsFromDate();
$preOrder = substr($preOrder, 0, 10);
return $preOrder;
}
public function getViewList()
{
if(strtotime(date('Y-m-d')) <= strtotime($this->getPreOrder()))
{
return true;
} else {
return false;
}
}
However, nothing is returned. I also did this same method to view.phtml and it worked perfectly. That goes for a file before the function getChildHtml() phtml, is not being edited list.phtml
That makes sense to create a loop, but the loop is already list.phtml!
What would be the way?
I thank you.
Have you debugged your block function to see if the product id is correct and if its loading the model correctly ??
Also debug the template list.phtml to check if its correctly loading the block type ?
get_class($this);
and see what class type is it.
This code doesn't work. I checked displayLanguage value. Value is right (displayLanguage="Türkçe"). But it doesn't work.
private void setAdvertisement()
{
Locale _locale = Locale.getDefault();
String displayLanguage = _locale.getDisplayLanguage();
if(displayLanguage == "Türkçe")
{
// Create the adView
adView = new AdView(this, AdSize.BANNER, "My Admob ID");
// Lookup your LinearLayout assuming it’s been given
// the attribute android:id="#+id/mainLayout"
// Add the adView to it
linearLayoutAdvertisement.addView(adView);
// Initiate a generic request to load it with an ad
adView.loadAd(new AdRequest());
}
}
But this code works fine:
private void setAdvertisement()
{
// Create the adView
adView = new AdView(this, AdSize.BANNER, "My Admob ID");
// Lookup your LinearLayout assuming it’s been given
// the attribute android:id="#+id/mainLayout"
// Add the adView to it
linearLayoutAdvertisement.addView(adView);
// Initiate a generic request to load it with an ad
adView.loadAd(new AdRequest());
}
I don't understand what the problem is.
This isn't an AdMob issue. But try this:
if ("Türkçe".equals(displayLanguage)) {
..
}
I solved problem. This worked for me:
if(Locale.getDefault().getLanguage().equals("tr"))
{
...
}
I'm having some problems with making my tests insert fake data in my database. I've tried a few approaches, without luck. It seems that Global.onStart is not run when running tests within a FakeApplication, although I think I read that it should work.
object TestGlobal extends GlobalSettings {
val config = Map("global" -> "controllers.TestGlobal")
override def onStart(app: play.api.Application) = {
// load the data ...
}
}
And in my test code:
private def fakeApp = FakeApplication(additionalConfiguration = (
inMemoryDatabase().toSeq +
TestGlobal.config.toSeq
).toMap, additionalPlugins = Seq("plugin.InsertTestDataPlugin"))
Then I use running(fakeApp) within each test.
The plugin.InsertTestDataPlugin was another attempt, but it didn't work without defining the plugin in conf/play.plugins -- and that is not wanted, as I only want this code in the test scope.
Should any of these work? Have anyone succeeded with similar options?
Global.onStart should be executed ONCE (and only once) when the application is launched, whatever mode (dev, prod, test) it is in. Try to follow the wiki on how to use Global.
In that method then you can check the DB status and populate. For example in Test if you use an in-memory db it should be empty so do something akin to:
if(User.findAll.isEmpty) { //code taken from Play 2.0 samples
Seq(
User("guillaume#sample.com", "Guillaume Bort", "secret"),
User("maxime#sample.com", "Maxime Dantec", "secret"),
User("sadek#sample.com", "Sadek Drobi", "secret"),
User("erwan#sample.com", "Erwan Loisant", "secret")
).foreach(User.create)
}
I chose to solve this in another way:
I made a fixture like this:
def runWithTestDatabase[T](block: => T) {
val fakeApp = FakeApplication(additionalConfiguration = inMemoryDatabase())
running(fakeApp) {
ProjectRepositoryFake.insertTestDataIfEmpty()
block
}
}
And then, instead of running(FakeApplication()){ /* ... */}, I do this:
class StuffTest extends FunSpec with ShouldMatchers with CommonFixtures {
describe("Stuff") {
it("should be found in the database") {
runWithTestDatabase { // <--- *The interesting part of this example*
findStuff("bar").size must be(1);
}
}
}
}