I am using the split gem for A/B testing. I have 2 versions of a page for the test. How can our tester test both of these pages without changing the code?
I tested it simply by changing show to show_b in
- if #experiment == 'b'
= render "show_b"
- else
= render "show"
But how can the tester do this?
If you want a tester to be able to force a certain alternative to render a particular template, you can pass a URL parameter to override the normal behavior.
In your controller, you should have something like this to assign the test:
#experiment = ab_test("experiment_name", "a", "b")
For a tester to access a specific version (and not have the test alternative randomly assigned), you can format the URL like so:
http://myawesomesite.com?experiment_name=b
This will always assign the b test alternative, and render the show_b template.
See this section of the Split documentation for more information.
Where you assign #experiment variable? If it from DB you can simple change it via admin panel, before visit page.
Related
I am trying to display my webform in a modal (including error/validation messages inside the modal). I am following this approach for a custom drupal form which is not a webform. I am wondering whether this is possible at all with webforms and in case it is, what I need to take into account to make it run?
The first problem I am having is the following code line from the example's TeacherContactController.php
$modal_form = $this->formBuilder->getForm('Drupal\tl_session\Form\TeacherForm');
When I try to use this in my own controller, I cannot get the webform's proper namespace + id. When I check my webform with devel it says:
[__CLASS__] => Drupal\webform\Entity\Webform
[id] => add_news_webform
But I get a "The form argument Drupal\webform\Entity\Webform\webform-submission-add_news_webform-form is not a valid form" error. I tried many things, but did not succeed.
How can I get the webform with formBuilder and what else am I missing here (like webform specific ajax settings etc.)?
You're trying to hard-code the namespace + ID in a string?
That'd be my first guess as to your problem
try
$modal_form = $this->formBuilder->getForm(Drupal\tl_session\Form\TeacherForm::class);
Or possibly
$modal_form = $this->formBuilder->getForm(\Drupal\tl_session\Form\TeacherForm::class);
If you enable the webform_devel.module you can use the API tab which provides some example code. (/webform/contact/api)
#see \Drupal\webform\WebformSubmissionForm::submitWebformSubmission
I use Postman for REST API testing and parametrize tests with global variables.
I should put a phone number into GET request: /path/get?phone={{phone}} but leading + sign in the phone number is interpreted as a space.
What is the syntax to URL encode global variables in Postman? Is it possible to run JS encodeURIComponent() on variable in URL?
I am late but still worth it:
Just highlight and right click the part of url you want to encode. Select encodeURIComponent
That's it.
Use the Pre-request scripts (it's next to body) for this:
var encoded = encodeURIComponent({{phone number}});
or
var encoded = encodeURIComponent(pm.environment.get("phone number"));
and to proceed, use:
pm.environment.set("encoded phone number", encoded);
And set your URL to /path/get?phone={{encoded phone number}}
Just a shortcut to Mohhamad Hasham' answer.
You can encode and decode direct in the Params Value field:
The trick is to get your environment variable in the pre-request script and then set it after encoding it
var encoded = encodeURIComponent(pm.environment.get("phone"));
pm.environment.set("encoded phone number", encoded);
This will work as well:
var encoded = encodeURIComponent(pm.request.url.query.get("phone"));
pm.request.url.query.remove("phone");
pm.request.url.query.insert("phone", encoded);
I came across this question looking for an answer to a similar question. For me, the variable was a JSON object. The endpoint I needed to hit was expecting an object list as a query parameter and I have no way to change that to be the request body.
As much as some of the answers helped, I ended up coming up with a combined solution. Also, some of the code given in other answers is outdated as Postman has updated their API over the years, so this uses methods that work on 7.22.1.
pm.environment.set("basicJSON", '[{"key1":"value1","key2":"value2"},{"key1":"value1","key2":"value2"}]')
var encoded = encodedURIComponent(pm.environment.get("basicJSON"))
pm.environment.set("encodedJSON", encoded)
This solution requires that both basicJSON and encodedJSON exist as environment variables. But what was important for me was the ease of editing the object. I didn't want to have to decode/encode constantly to change values, and I didn't want to have to open the environment variables dialogue. Also, it's important to note the single-quotes around the object. Excluding them or using double-quotes would cause Postman to send something like "[object Object]" which is useless to an endpoint expecting actual JSON.
I had similar problem with braces { and } in query parameter.
By turning off the following setting it started working for me.
For the postman version 9.28.4 ==>
You can use 2 methods:
By selecting the part of the url in url bar -> right click -> EncodeURLComponent. (screenshot attached)
You can also use "pre-request script" tab of postman and write the script for the variable manually. (screenshot attached)
The problem with right-click => Encode URI Component is that it destroys the raw value of that parameter. You can use the following pre-request script to overcome this (which also works for cases where you have disabled that param):
// queryParam is of type https://www.postmanlabs.com/postman-collection/QueryParam.html
if ((queryParam = pm.request.url.query.one("name_of_your_query_param")) !== undefined
&& queryParam.disabled !== true) {
queryParam.value = encodeURIComponent(queryParam.value);
}
Click the Params button to open the data editor for URL parameters. When you add key-value pairs, Postman combines everything in the query string above. If your URL already has parameters - for example, if you are pasting a URL from some other source. Postman splits the URL into pairs automatically.
https://www.getpostman.com/docs/v6/postman/sending_api_requests/requests
POSTMAN's documentation on building requests in the section "sending parameters" is helpful here. You can encode path data by simply encoding the URL with a colon, listing the key name of the encoded element, and then a new section will appear below the query parameters allowing you to customize values and add a description, just as we do with query params. Here's an example of encoding the URL for a GET request:
https://somesite-api-endpoint/:record/get
And here's what the display looks like after you add path data. Any value you add in the path variables section will automagically update the URL with your data.
I have an html file which is the base,where other html documents extends.Its a static page but i want to have variable in the menu.I don't think it's wise to create a view for it,since i don't intend to let users visit the base alone.So where in my project can I store site-wide dynamic variables that can be called on any page without explicitly stating them in their views.
Thank you in advance.
For user specific variables, use session.
For global constants (not variables!), use settings.py.
For global variables, consider to store it in database so it can be multithreading & multiprocess safe.
I looked around and saw different approaches,but one that doesn't compromise the DRY philosophy the most for me is registering a tag in your project then input it in the base template.Its neater See here https://stackoverflow.com/a/21062774/6629594 for an example
Storage can take any number of places, I put mine in a stats model in the db so you get all the goodness of that (and make it easy to access in views).
I then have a context processor written as so:
#context_processors.py:
def my_custom_context_processor(request):
return {'custom_context_variable1':'foo','custom_context_variable2':'bar'}
Add this to your context processors in settings.py:
TEMPLATE_CONTEXT_PROCESSORS = (
...
"my_app.context_processors.ny_custom_context_processor",
)
Provided you use render() to render your templates you can then you can just use:
{{ custom_context_variable1 }}
to return 'foo' in your template. Obviously returning strings is for example only, you can use anything you like so long as your context processor returns a dict.
you can also try using php pages.
Then acces the variable on each page with an include 'file containing the var.php' on every page.
None of this will be visible in the source html as it is only processed on the server side.
If you you would like to try this, mail me and I will send you some sample code.
I'm using Kohana Framework and this is actually the first framework that I am using. I just wanted to know how to properly add templates in views. What I am doing right now is.
In controller.
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Welcome extends Controller_Template {
public $template = 'site';
public function action_index()
{
$this->template->header = View::factory('templates/header');
$this->template->header->title = 'Page name - Welcome';
$this->template->header->description = 'Blah blah blah.';
}
Now inside view I make a file called site.php (the view) and echo the variable $header on the top so it shows the contents of the page, and it's working fine but is it actually the right way to do it? I mean echoing out the header in every single view? I'm sure there must be a more complex or better way to do that. I have also heard that the use of Kohana Templete is discouraged.
Have a look at the Mustache Plugin KOstache for Kohana. IMO the best way to separate your layout from your logic.
Have a look at Kostache
It allows you to do simple things like
<li>{{kostachevariable}}</li>
You just create the view extending Kostache class and that's it.
Once you do that you can just set variables using
$pagetitle="My Title"
$myview-bind('mypagetitle',$pagetitle)
In your template file you will only need
<head>
<title>{{mypagetitle}}</title>
It has tons of other nice features.
I am trying to write some tests for a Django application I'm working on but I haven't yet decided on the exact urls I want to use for each view. Therefore, I'm using named urls in the tests.
For example, I have a url named dashboard:
c = Client()
resp = c.get(reverse('dashboard'))
This view should only be available to logged in users. If the current user is anonymous, it should redirect them to the login page, which is also a named url. However, when it does this, it uses an additional GET parameter to keep track of the url it just came from, which results in the following:
/login?next=dashboard
When I then try to test this redirect, it fails because of these additional parameters:
# It's expecting '/login' but gets '/login?next=dashboard'
self.assertRedirects(resp, reverse('login'))
Obviously, it works if I hard code them into the test:
self.assertRedirects(resp, '/login?next=dashboard')
But then, if I ever decide to change the URL for my dashboard view, I'd have to update every test that uses it.
Is there something I can do to make it easier to handle these extra parameters?
Any advice appreciated.
Thanks.
As you can see, reverse(...) returns a string. You can use it as:
self.assertRedirects(resp, '%s?next=dashboard' % reverse('login'))