I have a guitar lessons site. It has hierarchy categories->lesson->exercise
Currently the urls appear like this:
Category: /category/1/somecat
Lesson: /lesson/1/some-title
Exercise: /exercise/1/some-title
There are a number of places where this naming is hard coded, such as view folder names, views, routes, etc.
This is what I really want:
Category: /guitar-lesson-category/1/somecat
Lesson: /guitar-lesson/1/some-title
Exercise: /guitar-lesson-exercise/1/some-title
I feel this will be better for google search if I am interested in phrase guitar lessons.
Here are some entries from the routes.php file:
Route::get('/category', 'CategoryController#index');
Route::get('/category/{id}/{name?}', 'CategoryController#category');
Route::get('/lesson/{id}/{name?}', 'LessonController#index');
Route::post('/lesson/hit/{id}', 'LessonController#hit');
Route::post('/lesson/progress/{id}', 'LessonController#progress');
Route::post('/lesson/favorite/{id}', 'LessonController#favorite');
Route::get('/exercise/{id}/{name?}', 'ExerciseController#index');
Route::post('/exercise/hit/{id}', 'ExerciseController#hit');
Route::post('/exercise/progress/{id}', 'ExerciseController#progress');
Route::post('/exercise/favorite/{id}', 'ExerciseController#favorite');
Any idea how to do this as painlessly as possible? Specific examples of what to edit and how would be appreciated!
thanks!
////Route Group Example
//Route::prefix('admin')->group(function () {
// Route::get('users', function () {
// // Matches The "/admin/users" URL
// });
//});
//Solution For You
Route::prefix('/category')->group(function () {
Route::get('/', 'CategoryController#index');
// Matches The "/category" URL
Route::get('/{id}/{name?}', 'CategoryController#category');
// Matches The "/category/{id}/{name?}" URL
});
Route::prefix('/lesson')->group(function () {
Route::get('/{id}/{name?}', 'LessonController#index');
// Matches The "/lesson/{id}/{name?}" URL
Route::post('/hit/{id}', 'LessonController#hit');
// Matches The "/lesson/hit/{id}" URL
Route::post('/progress/{id}', 'LessonController#progress');
// Matches The "/lesson/progress/{id}" URL
Route::post('/favorite/{id}', 'LessonController#favorite');
// Matches The "/lesson/favorite/{id}" URL
});
Route::prefix('/exercise')->group(function () {
Route::get('/{id}/{name?}', 'ExerciseController#index');
// Matches The "/exercise/{id}/{name?}" URL
Route::post('/hit/{id}', 'ExerciseController#hit');
// Matches The "/exercise/hit/{id}" URL
Route::post('/progress/{id}', 'ExerciseController#progress');
// Matches The "/exercise/progress/{id}" URL
Route::post('/favorite/{id}', 'ExerciseController#favorite');
// Matches The "/exercise/favorite/{id}" URL
});
Related
I know this should be simple, but a little help would be appreciated; we're all a bit new to using industrial strength typescript packages.
We're building an Angular App and using the #azure/msal-angular library, which for most part works OK; following the tutorials and examples and it generally all make sense.
Apart from what to implement when the "msal:acquireTokenFailure" event is broadcast?
In the ngOnInit() method of our AppComponent we have this line
// Subscriptions and redirects are for jwtTokens
this.subscription = this.broadcastService.subscribe("msal:acquireTokenFailure", () => {
// ToDo: What should be implemented here?
});
In a few posts to the GitHub page for the project contributors have suggested something along the lines of
// Subscriptions and redirects are for jwtTokens
this.subscription = this.broadcastService.subscribe("msal:acquireTokenFailure", () => {
this.subscription.unsubscribe();
this.authService.loginRedirect();
});
Which, as far as I can, will redirect to an AzuerAD login screen but will lose the underlying call details that we trying to get a Token for.
What looks more useful (in pseudo-code) would be something like
// Subscriptions and redirects are for jwtTokens
this.subscription = this.broadcastService.subscribe("msal:acquireTokenFailure", () => {
this.subscription.unsubscribe();
if (isIE) {
this.authService.acquireTokenRedirect(userRequest);
} else {
this.authService.acquireTokenPopup(userRequest);
}
});
The question being, is this a valid approach; and where would we recover the userRequest parameters from?
Please, please, don't redirect me to the Microsoft docs; I've spent hours going round in circles following the same links...
We have a static site using Gatsby and contentful. Now we want to support multi-languages, with localized content from contentful. I am able to populate a graghql query:
query frontpageTeaser($lang: String) {
contentfulFrontpage(node_locale: { eq: "zh-CN" }) {
myArticalContent
...
}
}
This query is able to load the Chinese content from contentful, and English if changed to node_locale: { eq: "en-US" }.
Now the issue is: we want to support a language switch, so that when switching language, the graphql loads corresponding localized content.
We are using gatsby-plugin-react-i18next, which has this great feature:
Support multi-language url routes in a single page component. You don’t have to create separate pages such as pages/en/index.js or pages/es/index.js.
Pages like http://localhost:8000/zh-CN/ does load Chinese from local /locales/zh-CN/translation.json, but how to load localized content when switching language?
Graphql seems providing page query, so i added gatsby-node.js:
exports.createPages = async function ({ actions, graphql }) {
actions.createPage({
path: '/zh-CN/',
component: require.resolve(`./src/pages/index.js`),
context: { lang: 'zh-CN' },
})
}
And use this on page:
export const query = graphql`
query frontpageTeaser($lang: String) {
contentfulFrontpage(node_locale: { eq: $lang }) {
myArticalContent
}
}
`
But it always returns en. Please kindly help :). Thanks.
This can be a complex switch. There is an example project that has smoothly done it with another CMS + Gatsby, here.
Specific places to point out in the codebase:
Configuration of which locales you use, here
A dynamic link depending on the active locale, here
The context for your whole app to know what the active locale is, here
Actually implementing the locale context provider in the higher order component Layout, here
There is also some magic inside of the gatsby-node.js which updates what you've already been working on! You can find that, here.
Hope that helps :)
Before getting a better solution, this one works:
// #todo gatsby plugin https://www.gatsbyjs.org/packages/gatsby-plugin-react-i18next/
// this plugin provides current language `context.i18n.language`, which not know how to pass it to graphql page query.
// This snippet moves it one-level up to `context.locale`.
// #todo need to explore a better solution.
exports.onCreatePage = ({ page, actions }) => {
const { createPage, deletePage } = actions
if (!page.context.locale) {
const language = page.context.i18n.language
const locale = language === 'en' ? 'en-US' : language
deletePage(page)
createPage({
...page,
context: {
...page.context,
locale,
}
})
}
}
How can I repeat the display of response from API in Wix?
I have the following code in my backend module that queries the API for data like so:
export function getTopCoins() {
const url = 'https://api.coinmarketcap.com/v1/ticker/?limit=10';
return fetch(url, {method: 'get'})
.then(response => response.json());
}
and then in the frontend, I want to render it in the browser like so:
export function page1_viewportEnter(event, $w) {
getTopCoins().then(response => {
response.forEach(($w, itemData, index) => {
$w('#coinList').text = itemData.name;
});
});
}
So basically I have a Paragraph element with the ID of name coinList. So as you can see I want to display a list of names of the top 10 coins from coin market cap. How can I achieve this?
A working version of this was one that displayed the name of the first item on the list, this is the code:
export function page1_viewportEnter(event, $w) {
getTopCoins().then(response => {
$w('#coinList').text = "Name: " + response[0].name + "\n";
});
}
You can use the (pretty new) feature of Wix called Repeaters. Its in a Beta phase at the moment. You may find it under Add Panel --> Lists & Grids...
Then, in Wix Code IDE, you may write something like that (assuming you connected all the proper data binding with the connect panel configuration between you dataset and the repeater component:
export function page1_viewportEnter(event, $w) {
getTopCoins().then(response => {
$w('#repeater1').data = response;
});
}
You may refer to the Repeater API here.
One more thing, if I'm allowed to suggest: if you don't have any backend logic when calling getTopCoins from your backend code, you may use Wix Fetch API in you frontend code directly and save a network hop (faster and better performance)
Enjoy!
I'm newbie in Magento. My shop should work with a web service. I have to check availability of products from web service before magento creates a new order. And after creating order successful i have to send the orderId back to web service. All this actions should be execute when a customer confirm a button "place order".
In a picture you see an "Place Order". I not sure how Magento does create a new order. I assume that an action placeOrder() will be call. My aim is to put a method checkAvailability() before this action and and method sendOrderId() after this action. checkAvailability() and SendOrderId() are the methods from webservice.
Has somebody an idea, how and where can i do that?
Sorry about bad english. Thank you
If you need to overwrite a function instead a class method (I used to overwrite Magento_Checkout/js/action/place-order).
requirejs-config.js
var config = {
config: {
mixins: {
'Magento_Checkout/js/action/place-order': {
'My_Module/js/action/place-order': true
}
}
}
};
place-order.js
define(['mage/utils/wrapper'], function (wrapper) {
'use strict';
return function (placeOrderAction) {
return wrapper.wrap(placeOrderAction, function (originalAction, paymentData, redirectOnSuccess) {
// my own code here
return originalAction(paymentData, redirectOnSuccess);
});
};
});
For your requirement, you need to used this event.
Used this event observer to check checkAvailability()
checkout_onepage_controller_success_action
Used this event observer to used SendOrderId()
sales_order_place_after
I had a similar case. I needed to override placeOrder action that was announced in third part module (Amasty_Checkout).
So, my solution was to create mixin in my theme.
1) Announce the mixin in theme with myTheme/Amasty_Checkout/requirejs-config.js:
var config = {
config: {
mixins: {
'Amasty_Checkout/js/view/onepage': {
'Amasty_Checkout/js/view/onepage-extend': true
}
}
}
};
2) Add mixin myTheme/Amasty_Checkout/web/js/view/onepage-extend.js with code:
define(
[
'jquery',
'uiComponent',
'ko',
'uiRegistry',
'Magento_Checkout/js/model/quote',
'Amasty_Checkout/js/action/set-shipping-information',
'Amasty_Checkout/js/model/agreement-validator',
'Amasty_Checkout/js/model/agreement-validator-old',
'Magento_Checkout/js/model/payment/additional-validators',
'Amasty_Checkout/js/model/amalert',
'mage/translate'
],
function (
$,
Component,
ko,
registry,
quote,
setShippingInformationAction,
checkoutValidator,
checkoutValidatorOld,
additionalValidators,
alert,
$t
) {
'use strict';
var mixin = {
placeOrder: function () {
// Here you put your extended code
}
};
return function (target) { // target == Result that Magento_Ui/.../default returns.
return target.extend(mixin); // new result that all other modules receive
};
});
Note that in my case I copied all content in define[...] section from original module script ('Amasty_Checkout/js/view/onepage') that I needed to override.
Here is the resource that helped me with my solution https://github.com/magento/magento2/issues/1864#issuecomment-141112927
I hope this will help someone save time.
I need to search the CouchDB based on several criteria entered in a form. Name, an array of Tags and so on. I would then need various views to index on these fields. Ultimately, all the results will be collated in data.js and provided to mustache.html. Say there are 3 views - docsByName, docsByTags, docsById.
What I don't know is, how to query all these views in query.js. Can this be done and how ?
Or should the approach be of that to write one view that makes multiple emits for each search somehow ?
Thank you.
From what you say I assume you are using Evently, so I will quote from Evently primer:
The async function is the main star, which in this case makes an Ajax request (but it can do anything it wants). Another important thing to note is that the first argument to the async function is a callback which you use to tell Evently when you are done with your asynchronous action. [...] Whatever you pass to the callback function then becomes the first item passed to the data function.
In short: put your Ajax requests in async.js.
As a side note: Evently is only one of the possible choices to write a couchapp and it is not clear if it is maintained. However it works and it is easy to rearrange the code to not use it.
EDIT: here is a sample async function (cut&paste from an old program):
function(cb, e) {
var app = $$(this).app
;
app.db.openDoc('SOMEDOCID', {
error: function(code, error, reason) {
alert("Error("+code+" "+error+"): "+reason);
}
, success: function(doc) {
app.view('SOMEVIEWNAME', {
include_docs: true
, error: function(code, error, reason) {
alert("Error("+code+" "+error+"): "+reason);
}
, success: function(resp) {
resp.doc = doc;
cb(resp);
}
});
}
});
}