I have a question, I have web with modules [client, admin, open]. At first, client visits open module, here is sign in form and some other parts, than he logs. Due to a lot of scripts, each module has own layout.
How to solve reload of whole body and head tag in case of changing the module. Also how to change title of each page? When I add snippet to title tag, it does not work... it is replaced and in the same second replaced back to original page title.
Maybe somehow on success force classic reload? But how to do it except adding data-ajax=false on the sign in button, but adding it into form success action?
Thanks
Hi, I suspect you're doing a redirect after a sign in, correct? If you do, then you can just disable AJAX for the redirect - Nittro will then do a full-page redirect. You can do this by setting $presenter->payload->allowAjax = false;
, which you can shorten to $presenter->disallowAjax();
if you use nittro/nette-bridges
base presenter or PresenterUtils
trait.
As for the page title: this is a long-known issue - Nittro manages the page title on its own and expects to find it in the response payload under the title
key - so while it won't prevent you from making <title>
a snippet, it will ultimately override it by whatever is in payload.title
, defaulting to the current page title. There's currently no easy way to make a <title>
snippet work the way you want it to.. you'll have to assign your title to a variable and add that variable to payload e.g. in afterRender()
.
ad1) thanks, works like a magic
ad2) wtf,... I am screwed,... we have title defined as:
<title>{ifset title}{include title|trim|stripHtml} | {_'IncParadise'}{/ifset}</title>
And the title is set in each latte file as a block,... I will try to create some processing to get the block content in afterrender. Or rewrite the code, but thanks
Well you could also hot-patch the current behaviour in client side code - it's not hard really, but it'd require you to build Nittro yourself - which you might be doing already, in which case you're golden. All you need to do is define a service which listens for the history-save
event of all page transactions and override the title there using whatever is the current document.title
- since snippets are guaranteed to be applied before the history-save
event occurs document.title
will already reflect whatever came in the <title>
snippet. This is how you'd do it: create a file somewhere in your app, let's call it TitleHotPatch.js
:
_context.invoke('App', function() {
var TitleHotPatch = _context.extend(function(page) {
this._ = {
page: page
};
this._.page.on('transaction-created', this._handleTransaction.bind(this));
}, {
_handleTransaction: function(evt) {
evt.data.transaction.on('history-save', this._handleHistorySave.bind(this));
},
_handleHistorySave: function(evt) {
evt.data.title = document.title;
}
});
_context.register(TitleHotPatch, 'TitleHotPatch');
});
Now add titleHotPatch: "App.TitleHotPatch()!"
to the services
section of your bootstrap configuration and rebuild :-)
I have to admit, you are a great developer beyond my comprehension, but I think I may use it. Thank you, also thank you for the workshop last week.
You're welcome 😊 but I'm not that great, if I were I'd have developed a library that people can use without running into issues like these 😄
I have a problem with the script, it is not applied. Actually, the transaction-created event is not called, I added console.log and not a single time it was used. Is there some extension which needs to be enabled?
No, the transaction-created
event is emitted by the page
service which is pretty much a core part of Nittro, nothing would work if this service wasn't running properly - is it possible that you omitted the !
symbol at the end of the service definition in your bootstrap config? It's a shorthand to make the service run at container init; if it's absent the container won't create the service at all, because it's lazy and nothing else depends on it. In your Gulpfile (or wherever you're specifying options for the Nittro builder) you should have an options map with keys like vendor
, base
and so on - along with the key bootstrap
, which specifies bootstrap options. If this were the only service you're registering, your bootstrap
section could look like this:
var builder = new nittro.Builder({
// vendor: ...
// base: ...
bootstrap: {
services: {
titleHotPatch: 'App.TitleHotPatch()!'
}
}
});
It should be ok
const nittroBuilder = new nittro.Builder({
base: {
di: true,
page: true,
forms: true,
flashes: true,
},
extras: {
dialogs: true,
confirm: true,
checklist: true,
paginator: true
},
libraries: {
js: [
'src/assets/js/BootstrapErrorRenderer.js',
'src/assets/js/TitleHotPatch.js'
],
},
bootstrap: {
params: {
dialogs: {
baseZ: 6000
}
},
services: {
formErrorRenderer: 'App.Forms.BootstrapErrorRenderer()',
titleHotPatch: "App.TitleHotPatch()!"
}
},
stack: true
});
gulp.task('nittro:js', function () {
return nittro('js', nittroBuilder)
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(except(/\.min\.js$/i, uglify({ compress: true, mangle: false })))
.pipe(concat('nittro.min.js'))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('public/js'));
});
That's really weird.. Okay, to debug: open your browser's developer tools, switch to Console view, paste the following line and press Enter:
_context.lookup('di')._
You should get an interactive object dump with the keys params
, serviceDefs
, services
and factories
at the top level; you should be able to find the keys page
and titleHotPatch
under the serviceDefs
key as well as under the services
key. If titleHotPatch
is missing in either of those places, then there's an issue with your build somewhere; if it's there then there's something weirder going on.
So, the page is there, also the formErrorRenderer which you send me after the workshop, but titleHotPatch is not present. This is strange, in the build, I can see
_context.invoke("App", function () {
var TitleHotPatch = _context.extend(function (page) {
this._ = {page: page}, this._.page.on("transaction-created", this._handleTransaction.bind(this))
}, {
_handleTransaction: function (evt) {
evt.data.transaction.on("history-save", this._handleHistorySave.bind(this))
}, _handleHistorySave: function (evt) {
evt.data.title = document.title
}
});
_context.register(TitleHotPatch, "TitleHotPatch")
});
_context.invoke(function (Nittro) {
var builder = new Nittro.DI.ContainerBuilder({
params: {dialogs: {baseZ: 6e3}},
extensions: {
ajax: "Nittro.Ajax.Bridges.AjaxDI.AjaxExtension()",
page: "Nittro.Page.Bridges.PageDI.PageExtension()",
forms: "Nittro.Forms.Bridges.FormsDI.FormsExtension()",
flashes: "Nittro.Flashes.Bridges.FlashesDI.FlashesExtension()",
dialogs: "Nittro.Extras.Dialogs.Bridges.DialogsDI.DialogsExtension()",
confirm: "Nittro.Extras.Confirm.Bridges.ConfirmDI.ConfirmExtension()",
checklist: "Nittro.Extras.CheckList.Bridges.CheckListDI.CheckListExtension()",
paginator: "Nittro.Extras.Paginator.Bridges.PaginatorDI.PaginatorExtension()"
},
services: {formErrorRenderer: "App.Forms.BootstrapErrorRenderer()", titleHotPatch: "App.TitleHotPatch()!"},
factories: {}
});
this.di = builder.createContainer(), this.di.runServices()
});
Sign in to post a reply