first commit

This commit is contained in:
2024-07-15 12:33:27 +02:00
commit ce50ae282b
22084 changed files with 2623791 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
/**
* @file
* Styling for toolbar warning message.
*/
.toolbar-warning {
overflow: hidden;
margin: 0.5em 0;
padding: 0.5em 2em 0.5em 2.3333em;
text-indent: -1000px;
background: url(../../../../core/misc/icons/e29700/warning.svg) no-repeat center center transparent;
background-size: auto 20px;
}
.toolbar-warning:hover {
color: #000;
}
@media only screen and (min-width: 40em) {
.toolbar-warning {
padding-right: 1em; /* LTR */
text-decoration: none;
text-indent: 0;
color: #000;
border-color: #f4daa6;
border-radius: 4px;
background-color: #fdf8ed;
background-position: 0.5em center; /* LTR */
background-size: auto 18px;
font-weight: bold;
}
[dir="rtl"] .toolbar-warning {
padding-right: 2em;
padding-left: 1em;
background-position: right 0.5em center;
}
}

View File

@@ -0,0 +1,56 @@
name: 'Demo: Umami Food Magazine (Experimental)'
type: profile
description: 'Install an example site that shows off some of Drupals capabilities.'
# version: VERSION
install:
- node
- history
- big_pipe
- block
- breakpoint
- ckeditor5
- config
- contextual
- contact
- layout_builder
- layout_discovery
- menu_link_content
- datetime
- block_content
- editor
- help
- image
- media
- media_library
- menu_ui
- options
- path
- page_cache
- dynamic_page_cache
- taxonomy
- dblog
- search
- shortcut
- toolbar
- field_ui
- file
- views
- views_ui
- automated_cron
- responsive_image
- content_moderation
- workflows
- language
- locale
- config_translation
- content_translation
- announcements_feed
themes:
- claro
- umami
keep_english: true
# Information added by Drupal.org packaging script on 2024-07-04
version: '10.3.1'
project: 'drupal'
datestamp: 1720094222

View File

@@ -0,0 +1,61 @@
<?php
/**
* @file
* Install, update and uninstall functions for the demo_umami installation profile.
*/
use Drupal\shortcut\Entity\Shortcut;
/**
* Implements hook_requirements().
*/
function demo_umami_requirements($phase) {
$requirements = [];
if ($phase == 'runtime') {
$profile = \Drupal::installProfile();
$info = \Drupal::service('extension.list.profile')->getExtensionInfo($profile);
$requirements['experimental_profile_used'] = [
'title' => t('Experimental installation profile used'),
'value' => $info['name'],
'description' => t('Experimental profiles are provided for testing purposes only. Use at your own risk. To start building a new site, reinstall Drupal and choose a non-experimental profile.'),
'severity' => REQUIREMENT_WARNING,
];
}
return $requirements;
}
/**
* Implements hook_install().
*
* Perform actions to set up the site for this profile.
*
* @see system_install()
*/
function demo_umami_install() {
// We install some menu links, so we have to rebuild the router, to ensure the
// menu links are valid.
\Drupal::service('router.builder')->rebuildIfNeeded();
// Populate the default shortcut set.
$shortcut = Shortcut::create([
'shortcut_set' => 'default',
'title' => t('Add content'),
'weight' => -20,
'link' => ['uri' => 'internal:/node/add'],
]);
$shortcut->save();
$shortcut = Shortcut::create([
'shortcut_set' => 'default',
'title' => t('All content'),
'weight' => -19,
'link' => ['uri' => 'internal:/admin/content'],
]);
$shortcut->save();
// Enable the demo content module. This can't be specified as a dependency
// in the demo_umami.info.yml file, as it requires configuration provided by
// the profile (fields etc.).
\Drupal::service('module_installer')->install(['demo_umami_content'], TRUE);
}

View File

@@ -0,0 +1,4 @@
toolbar-warning:
css:
component:
css/toolbar-warning.css: {}

View File

@@ -0,0 +1,4 @@
standard.front_page:
title: 'Home'
route_name: '<front>'
menu_name: main

View File

@@ -0,0 +1,106 @@
<?php
/**
* @file
* Enables modules and site configuration for a demo_umami site installation.
*/
use Drupal\contact\Entity\ContactForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
/**
* Implements hook_help().
*/
function demo_umami_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.demo_umami':
$output = '';
$output .= '<h2>' . t('About') . '</h2>';
$output .= '<p>' . t('Umami is an example food magazine website that demonstrates some of the features of Drupal core. It is intended to be used as an example site, rather than as a foundation for building your own site. For more information, see the <a href=":demo_umami">online documentation for the Umami installation profile</a>.', [':demo_umami' => 'https://www.drupal.org/node/2941833']) . '</p>';
$output .= '<h2>' . t('Uses') . '</h2>';
$output .= '<h3>' . t('Demonstrating Drupal core functionality') . '</h3>';
$output .= '<p>' . t('You can look around the site to get ideas for what kinds of features Drupal is capable of, and to see how an actual site can be built using Drupal core.') . '</p>';
$output .= '<h3>' . t('Sample content') . '</h3>';
$output .= '<p>' . t('The Umami profile is very handy if you are developing a feature and need some sample content.') . '</p>';
$output .= '<h2>' . t('What to do when you are ready to build your Drupal website') . '</h2>';
$output .= '<p>' . t("Once you've tried Drupal using Umami and want to build your own site, simply reinstall Drupal and select a different installation profile (such as Standard) from the install screen.") . '</p>';
return $output;
}
}
/**
* Implements hook_form_FORM_ID_alter() for install_configure_form().
*
* Allows the profile to alter the site configuration form.
*/
function demo_umami_form_install_configure_form_alter(&$form, FormStateInterface $form_state) {
$form['site_information']['site_name']['#default_value'] = 'Umami Food Magazine';
$form['#submit'][] = 'demo_umami_form_install_configure_submit';
}
/**
* Submission handler to sync the contact.form.feedback recipient.
*/
function demo_umami_form_install_configure_submit($form, FormStateInterface $form_state) {
$site_mail = $form_state->getValue('site_mail');
ContactForm::load('feedback')->setRecipients([$site_mail])->trustData()->save();
$password = $form_state->getValue('account')['pass'];
demo_umami_set_users_passwords($password);
}
/**
* Sets the password of admin to be the password for all users.
*/
function demo_umami_set_users_passwords(#[\SensitiveParameter] $admin_password) {
// Collect the IDs of all users with roles editor or author.
$ids = \Drupal::entityQuery('user')
->accessCheck(FALSE)
->condition('roles', ['author', 'editor'], 'IN')
->execute();
$users = \Drupal::entityTypeManager()->getStorage('user')->loadMultiple($ids);
foreach ($users as $user) {
$user->setPassword($admin_password);
$user->save();
}
}
/**
* Implements hook_toolbar().
*/
function demo_umami_toolbar() {
// Add a warning about using an experimental profile.
// @todo This can be removed once a generic warning for experimental profiles
// has been introduced. https://www.drupal.org/project/drupal/issues/2934374
$items['experimental-profile-warning'] = [
'#weight' => 3400,
'#cache' => [
'contexts' => ['route'],
],
];
// Show warning only on administration pages.
$admin_context = \Drupal::service('router.admin_context');
if ($admin_context->isAdminRoute()) {
$link_to_help_page = \Drupal::moduleHandler()->moduleExists('help') && \Drupal::currentUser()->hasPermission('access help pages');
$items['experimental-profile-warning']['#type'] = 'toolbar_item';
$items['experimental-profile-warning']['tab'] = [
'#type' => 'inline_template',
'#template' => '<a class="toolbar-warning" href="{{ more_info_link }}">This site is intended for demonstration purposes.</a>',
'#context' => [
// Link directly to the drupal.org documentation if the help pages
// aren't available.
'more_info_link' => $link_to_help_page ? Url::fromRoute('help.page', ['name' => 'demo_umami'])
: 'https://www.drupal.org/node/2941833',
],
'#attached' => [
'library' => ['demo_umami/toolbar-warning'],
],
];
}
return $items;
}

View File

@@ -0,0 +1,11 @@
# Deny all requests from Apache 2.4+.
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
# Deny all requests from Apache 2.0-2.2.
<IfModule !mod_authz_core.c>
Deny from all
</IfModule>
# Turn off all options we don't need.
Options -Indexes -ExecCGI -Includes -MultiViews

View File

@@ -0,0 +1,29 @@
Creative Commons Attribution-ShareAlike 4.0 International License
================================================================================
The following image files:
chili-sauce-umami.jpg by Elliot Ward
chocolate-brownie-umami.jpg by Keith Jay
heritage-carrots.jpg by Keith Jay
home-grown-herbs.jpg by Keith Jay
mediterranean-quiche-umami.jpg by Keith Jay
mushrooms-umami.jpg by Keith Jay
pineapple-placeholder-10.jpg by Keith Jay
pizza-umami.jpg by Keith Jay
supermarket-savvy-umami.jpg by Keith Jay
thai-green-curry-umami.jpg by Keith Jay
vegan-chocolate.jpg by Keith Jay
vegan-chocolate-nut-brownies.jpg by Keith Jay
veggie-pasta-bake-hero-umami.jpg by Keith Jay
veggie-pasta-bake-umami.jpg by Keith Jay
victoria-sponge-umami.jpg by Keith Jay
watercress-soup-umami.jpg by Keith Jay
crema-catalana-umami.jpg by Cristina Chumillas
mojito-mocktail.jpg by Keith Jay
oatmeal-fruit-syrup-topping.jpg by Keith Jay
are all licensed under a http://creativecommons.org/licenses/by-sa/4.0/ Creative
Commons Attribution-ShareAlike 4.0 International License.
================================================================================

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,13 @@
<p>You follow the recipe, you weigh all your ingredients, you use the right oven temperature and you take your time and yet still, your baking comes out with a soggy bottom, fails to rise or just tastes plain horrible. We have come up with a list of the most frustrating baking problems and the techniques you can use to try and avoid them.</p>
<h2>Your cake failed to rise</h2>
<p>Don't under any circumstances open the oven door in the middle of the cooking time. The heat will come whooshing out, destroying the chemical reaction taking place inside your cake. Your raising agent needs the heat to become activated and you might kill it off.</p>
<h2>Your cake is chewy and tough</h2>
<p>If your light sponge is the consistency of a spare tire, you might have over-mixed your batter. Keep the lightness inside your cake mixture by carefully and gently folding in the ingredients and only to the point they are just mixed. If you over-fold, the gluten in the flour will start to come out and you'll be making bread instead of cake.</p>
<h2>Your cookies burned</h2>
<p>A great trick is to use light colored bakeware, rather than black. It is less likely to absorb the heat and transfer it to the bottom of your biscuits. Using baking paper will also help with this. Also, using too much sugar can result in your cookies browning too much and giving them a caramelized look.</p>
<h2>Split top to your cake or bread</h2>
<p>Your oven is very likely too hot. If you suspect your oven doesn't keep to the right temperature, invest in a thermometer and check it regularly throughout the cooking. With bread, over-mixing the dough can result in a cracked or split top.</p>
<h2>The dreaded soggy bottom</h2>
<p>As mentioned above, the color of your pan is important. In this case, a dark pan will increase the heat at the bottom and give you that crisp underneath that you want. If you are using a flaky pastry, you really need to blind bake it. Putting your pie towards the bottom of the oven will increase the heat reaching that part.</p>
<h2>Your pastry has shrunk</h2>
<p>You simply tried to make it stretch too far. When rolling, don't try to make it too thin or too big and when draping over your pan, allow it to settle on its own without stretching it to fit. Or just add more pastry - everyone loves pastry anyway!</p>

View File

@@ -0,0 +1,12 @@
<p>The calendar is full of excuses for chocolate-lovers to indulge, from religious festivals to birthdays - and even World Chocolate Day on the 7th July. But for those who are vegan, or on dairy-free diets, there is no need to miss out, because there are plenty of delicious vegan chocolate varieties on offer.</p>
<p>Dairy-free milk chocolate is made in largely the same way as regular chocolate, until the point when the milk is added. Cacao beans are roasted for a couple of hours until they develop a rich flavor. The outer shells are removed, and the interior nibs are ground to make a paste that can be mixed with cocoa butter to produce the desired percentage of chocolate. Flavorings, sugar and milk are added in different quantities to get the type of chocolate being produced. The chocolate is grainy at this point and needs to be mashed until it is smooth - this can take days! Finally, it is tempered through a process of heating and cooling until it is ready to eat.</p>
<p>So, how do vegan chocolatiers get that creamy milk flavor and texture into their products?</p>
<h2>Rice milk</h2>
<p>The flavor of rice milk perfectly complements the cocoa beans and it was one of the first dairy milk alternatives to be used to create vegan milk chocolate. Rice milk is made from rice powder and is sometimes combined with hazelnut milk to create the correct texture and taste that is ideal for producing all kinds of chocolate bars.</p>
<h2>Coconut milk</h2>
<p>Coconut milk has to be the perfect ingredient for adding creaminess into a chocolate bar. With high fat levels, a sweet, but not overpowering taste and the correct consistency, coconut milk is a great choice for vegan milk chocolate. Chocolate made in this way will melt wonderfully for drizzling or dipping, and the coconut milk adds a slight tropical flavor that works well with other fruit flavors and nuts.</p>
<h2>Soy milk</h2>
<p>Soy has long been the mainstay of vegan and vegetarian diets, as it is rich in protein and is available in a wide variety of textures suitable for all kinds of dishes. Soy milk is widely available and is a great alternative to dairy milk in chocolate. It isn&rsquo;t as rich in fat as some vegan milks, but does have a neutral taste that makes it easy to combine with almost any other flavor.</p>
<h2>Nut milks</h2>
<p>Milks made from almonds and hazelnuts are easy to find on supermarket shelves, and are perfect for chocolate production. Like soy milk, they can be quite low in fat and therefore a little less creamy, but they have that nutty taste that goes so well with chocolate of all kinds.</p>
<p>Many manufacturers will use a combination of the above milks to create the perfect consistency for their product. Using this milk mixture they are able to produce all kinds of milk chocolates, including white chocolate.</p>

View File

@@ -0,0 +1,15 @@
<p>There's nothing like having your own supply of fresh herbs, readily available and close at hand to use while cooking. Whether you have a large garden or a small kitchen window sill, there's always enough room for something home grown.</p>
<h2>Outdoors</h2>
<h3>Mint</h3>
<p>Mint is a great plant to grow as it's hardy and can grow in almost any soil. Mint can grow wild, so keep it contained in a pot or it might spread and take over your whole garden.</p>
<h3>Sage</h3>
<p>Like mint, sage is another prolific growing plant and will take over your garden if you let it. Highly aromatic, the sage plant can be planted in a pot or flower bed in well drained soil. The best way to store the herb is to sun dry the leaves and store in a cool, dark cupboard in a sealed container.</p>
<h3>Rosemary</h3>
<p>Rosemary plants grow into lovely shrubs. Easily grown from cuttings, rosemary plants do not like freezing temperatures so keep pots or planted bushes near the home to shelter them from the cold. It grows well in pots as it likes dry soil, but can survive well in the ground too. If pruning rosemary to encourage it into a better shape, save the branches and hang them upside down to preserve the flavor and use in food.</p>
<h2>Indoors</h2>
<h3>Basil</h3>
<p>Perfect in sunny spot on a kitchen window sill. Basil is an annual plant, so will die off in the autumn, so it's a good idea to harvest it in the summer if you have an abundance and dry it. Picked basil stays fresh longer if it is placed in water (like fresh flowers). A great way to store basil is to make it into pesto!</p>
<h3>Chives</h3>
<p>A versatile herb, chives can grow well indoors. Ensure the plant is watered well, and gets plenty of light. Remember to regularly trim the chives. This prevents the flowers from developing and encourages new growth.</p>
<h3>Coriander (Cilantro)</h3>
<p>Coriander can grow indoors, but unlike the other herbs, it doesn't like full sun. If you have a south facing kitchen window, this isn't the place for it. Although not as thirsty as basil, coriander doesn't like dry soil so don't forget to water it! Cut coriander is best stored in the fridge.</p>

View File

@@ -0,0 +1,43 @@
<p>
It is vegan, gluten-free, low in fat, high in fiber, and can even lower cholesterol - but oatmeal is boring, right? Well, before you write off that boring jar of oats, you might want to take inspiration from our topping ideas that will take your oatmeal from bland to creatively delicious in just a few minutes.
</p>
<p>
Call it oatmeal, porridge, hot cereal, or just plain oats, it is loved the world over; but recently, the humble oat is getting a funky makeover. Long gone are the days of stodgy breakfast bowls of thick gloop, because oats are getting served up as a delicious meal that can suit any time of the day. Trendy build-your-own oatmeal bars are popping up, and they are providing the ultimate oatmeal experience. Diners can choose their oats to be made with milk or water and then go to town with their choice of favorite toppings - sweet, savory, or even spicy.
</p>
<p>
It sounds great, doesnt it? So before you close the cupboard door on that bland-looking jar of oats, we think you should try some of these scrumptious topping ideas to inspire your very own oatmeal makeover.
</p>
<h2>Soaked dried fruit</h2>
<p>
Sometimes plain dried fruit can be a bit chewy and harsh when combined with creamy oats. But if you simply soak your dried fruit in orange juice overnight, they develop a tang, and they swell up, making them softer and even more delicious. Plus the splash of color can really brighten your day.
</p>
<h2>Porridge crème brûlée</h2>
<p>
So simple - but why has no one thought of it before? Put your cooked oatmeal into a ramekin, sprinkle with sugar, and pop under the grill. The sugar will harden, giving you the delight of cracking through the surface and scooping out the creamy deliciousness beneath. If you are really professional, you can use a blow torch.
</p>
<h2>Super seeds</h2>
<p>
For a more savory meal option, cook your oats with water, a little salt, and sprinkle with toasted seeds. You can choose any that you enjoy, but pumpkin seeds, sesame, linseed, and sunflower seeds are especially good. Some supermarkets also sell seed blends to make the job even easier.
</p>
<h2>Deconstructed carrot cake</h2>
<p>
Cook your oats with grated carrots and a little sugar, then top with a sprinkle of cinnamon, chopped walnuts, and a dollop of sweetened cream cheese. If you dont love this, theres something wrong with your taste buds.
</p>
<h2>Dark chocolate</h2>
<p>
This low-sugar delight will meet all of those chocolate cravings and is the perfect dessert. Add a spoonful of cocoa to your oatmeal as it cooks, then top with a few squares of dark chocolate. As it melts, simply swirl into the bowl as artfully as you can. If you are really decadent, a squirt of whipped cream will add further delights.
</p>

View File

@@ -0,0 +1,11 @@
<p>Let's hear it for the humble carrot! This sweet and healthy &lsquo;everyday&rsquo; veg packs it all in. Great flavor, fantastic color, and if you're one for believing the old story, they can even help you to see better in the dark.</p>
<p>Who doesn't love cooking with this super versatile root veg? We roast them, boil them, blend them into soups, and grate them into salads. The humble carrot has to be one of our favorite veg choices and it's been grown for thousands of years. But back then you were more likely to find a purple, red, yellow or white carrot and not the orange one we are all so familiar with today.</p>
<h2>So what happened? When did orange become the preferred color?</h2>
<p>It was the Dutch during the 17th century who cultivated and made popular the orange variety, most likely because of its brilliant color and higher levels of beta carotene. And it has also been suggested that they were cultivated in tribute to William of Orange, who led the struggle during the Dutch battle for independence.</p>
<p>For whatever reason, the orange variety has stuck but look out for the &lsquo;heritage&rsquo; varieties at farmers markets and grocers, their mix of purple, yellow, orange and white are especially appealing to cook with and look absolutely great served as a side dish.</p>
<h2>Nutrition</h2>
<p>Carrots are rich in beta carotene which your body converts into vitamin A. It's often tricky to know whether cooking vegetables will enhance or reduce their nutritious value and unfortunately there's no simple rule. But in the case of carrots, nutrition is enhanced by consuming them cooked. In fact, it only takes 100 grams of carrots to get more than your daily value of vitamin A.</p>
<h2>Get them at their best</h2>
<p>Young carrots, harvested when they are small have an especially sweet flavor and they are absolutely delicious. To cook them you can skip the peeling, give them a good wash and pop them in the steamer for just a few minutes. Carrots will taste the best when they are fresh, so make sure they are firm and bright in color when buying.</p>
<h2>And that thing about carrots helping you see more in the dark?</h2>
<p>Of course it's a myth. During World War II the UK Ministry of Food promoted carrots as a super healthy veggie that would improve your ability to see during the blackouts and as an explanation for the successful night missions of UK fighter pilots. In reality, the only truth in the connection between carrots and improved eye sight is that vitamin A does indeed help to maintain vision.</p>

View File

@@ -0,0 +1,21 @@
<p>Having a cocktail party? Then why not serve up something just as special for those who don't drink alcohol but do want to join in on all the fun? After all, what cocktail party is complete without those incredible looking glasses of mixed fruits, bright colors and of course, the little umbrellas? Do your bit for the environment by ditching the plastic straws and get hold of some great looking alternatives made out of glass, metal, or even bamboo. Don't forget the classic cocktail glasses and cool tumblers to really bring these recipes to life.
</p>
<p>
So, grab the cocktail mixer, skip the spirits, and shake up these deliciously refreshing mocktails that won't leave you or your guests, short on flavor or style.
</p>
<h2>Mango-licious</h2>
<p>This delicious drink has a sophisticated taste that is ideal for adults and the color is perfect for a late summer BBQ.</p>
<h3>Instructions:</h3>
<p>Give a few slices of cucumber and a little honey a good shake in a cocktail shaker. Add a spirit measure of mango puree and the juice of one lime. Add some ice and shake for all you're worth. Using a strainer, pour into a fancy glass and top with ginger beer. A few slices of lime and you're ready to go.</p>
<h2>Mocky Mojito</h2>
<p>There's nothing quite like a Mojito on a warm day and this version is ideal for a relaxing end of the day moment of bliss in the garden.</p>
<h3>Instructions:</h3>
<p>Muddle sugar, a squeeze of lime, and mint leaves in a tall glass, then add a few chunks of ice, top with the juice of a blood orange (for the sunset effect), and add a splash of soda water. Add a few sprigs of mint for an authentic look.</p>
<h2>Sinless Strawberry Martini</h2>
<p>Strawberries add a beautiful rich red to this mocktail, while the ginger gives it a little kick. Serve in a proper martini glass, but maybe avoid the olives.</p>
<h3>Instructions:</h3>
<p>Muddle a strawberry with a dash a ginger beer and some sugar syrup in a cocktail shaker. Add a capful of elderflower cordial and a few mint leaves. Throw in a slice of orange and lemon and shake with ice. Strain into your glass and enjoy the sweet strawberry flavor.</p>
<h2>Coconut Queen</h2>
<p>Crazy about coconuts? Then you'll love the refreshing taste of this coconut based mocktail. The flavors give a hint of the tropical, while the look is grown-up sophistication.</p>
<h3>Instructions:</h3>
<p>Add sliced cucumbers, the juice of a lime or two, and some mint leaves to a pitcher of coconut water and leave to chill and infuse for a few hours in the fridge. You can also add some sugar if you fancy this sweeter. Serve poured into glasses full of ice with sliced cucumber and mint leaves. Simple and beautiful.</p>

View File

@@ -0,0 +1,16 @@
<p>This may not surprise you - but your supermarket is a hot bed of marketing mayhem, designed to improve their profit and to encourage the consumer to spend more than they intended. The tricks that all supermarkets employ are sometimes sensible ploys that any retailer should do to improve sales - but some may be more subtle and less obvious than you might think.</p>
<p>With consumer awareness articles and documentaries frequently picking up on this topic, it's likely the case that retailers find it harder to get away with the more obvious ploys. We are becoming ever more savvy consumers and there's probably not a great deal that gets past us. But here's a few retail tricks to keep in mind when you are rushing around the weekly supermarket stock-up.</p>
<h2>Lost essentials</h2>
<p>The layout of your supermarket may make sense to you when you have shopped there for a while. But for newcomers trying to find essentials, it may make very little sense at all. Some supermarkets have noted that people come to their store to buy milk, bread, or eggs and that by hiding these essentials in the far reaches of the store, they encourage the newcomer to wander the aisles - picking up other items as they go.</p>
<p>Sure, this can be great for nudging the memory on essentials you might otherwise forget, but for saving the pennies it's tough to stick to grabbing only the things you came for and the supermarkets know it!</p>
<blockquote>
Our tip: Make your shopping list before leaving the house, checking what you need and sticking to that list. You could be amazed by what you'll save over time.
</blockquote>
<h2>Nonsensical multibuys</h2>
<p>Buy one, get one free; two for &pound;2 and meal deals. They all seem like a great deal. But in some cases these are loss leaders that are positioned to encourage you to take up the deal and buy other stuff while you are there. In other cases, deals for multi-buy or discounts on specific pack sizes might seem like a bargain, until you compare the pricing like-for-like on similar brands or with pack sizes for the same brand. These deals can mean you end up paying less but is it less for something you don't really need and in some cases you can end up paying more for the item. Remember, the supermarkets know you are often in a hurry and might not have the time to take in the full picture.</p>
<blockquote>
<p>Our tip: Don't be rushed, take the time to read the small print. The large print will draw you in but if you read the label small print, you should find the price per 100 grams or per ounce/litre and you'll be surprised how often the headline deals are actually more expensive than just buying a different package type or size of the product.</p>
</blockquote>
<h2>Understanding our shopping habits</h2>
<p>The cheapest products in a supermarket are almost always positioned on the bottom of the shelving where you'll need to bend over to pick it up. You also may not be able to easily read the price ticket. Most people will shop on the middle rows because it is easier and often quicker. These are where the highest profit items are kept and they are the ones the supermarkets want you to buy.</p>
<p>The layout, the music, the colors, and the product types are all decided based on principles laid down by industry experts on people - psychologists and behavioral experts who know how we think. And so the savvy shopper will certainly be able to take advantage of great deals in their weekly shop, but it takes a little time and effort just to be more aware of what we are being encouraged to reach for in the aisles.</p>

View File

@@ -0,0 +1,7 @@
<p>We think mushrooms are one of the most enjoyable ingredients to cook with. There are plenty of edible varieties to try, each with their own distinctive shape, size, and taste. And with curious names such as chanterelle, the gypsy, horn of plenty, or hen of the woods, who wouldn't want to know more about cooking with the mighty mushroom?</p>
<p>One of the best things about mushrooms is their versatility. They can be fried, roasted, grilled, steamed, or even cooked in the microwave. And they can be served as the main ingredient for a dish, or simply added as part of the mix. This makes mushrooms an ideal choice for creating absolutely delicious vegetarian dishes.</p>
<p>So let's take a look at some of our favorite types of mushroom. You might not have tried cooking with them before but don't let that put you off. With their delicious, distinctive flavors you can easily transform soups, starters, sauces and create amazing pasta, or stir-fry dishes.</p>
<p>Try the lovely <strong>shiitake</strong>. Used in Asian cooking, these can be purchased dried and rehydrated for a strong, deep flavor. Or buy fresh and add to soups and stir-fries. Not only does this mushroom have an intense flavor, it looks lovely too. The deep brown and smooth shapes will provide texture to your meal. In their dried form and rehydrated, these are the perfect addition for a deep and flavorful stock for a risotto.</p>
<p>The gorgeous sunny <strong>chanterelle</strong> with its yellow flesh has a fruity flavor - but it is worth mentioning that there are many lookalikes out there and care should be taken to ensure you're eating the right ones. These look great in an omelette or an Asian soup to complement the yellow tones.</p>
<p>The brown <strong>morel</strong> offers a meaty and distinctive flavor and you'll probably love how extraordinary they look in a meal. The morel is a more popular mushroom during the spring, when their availability is high.</p>
<p>For delicacy try the <strong>enoki</strong> with its tiny white heads that grow in a bunch. These can even be eaten raw in salads. Finally, you can choose the popular <strong>oyster</strong> mushroom. They are named thus because they look nothing like a mushroom and resemble the innards of an oyster and their sweet flavor is delicious.</p>

View File

@@ -0,0 +1,3 @@
id,uuid,info,type,field_title,content_type,node_id,field_content_link_title,field_summary,image_reference
umami_home_banner,9aadf4a1-ded6-4017-a10d-a5e043396edf,Umami Home Banner,banner_block,Super easy vegetarian pasta bake,recipe,3,View recipe,A wholesome pasta bake is the ultimate comfort food. This delicious bake is super quick to prepare and an ideal midweek meal for all the family.,18
umami_recipes_banner,4c7d58a3-a45d-412d-9068-259c57e40541,Umami Recipes Banner,banner_block,Vegan chocolate and nut brownies,recipe,2,View recipe,These sumptuous brownies should be gooey on the inside and crisp on the outside. A perfect indulgence!,20
1 id uuid info type field_title content_type node_id field_content_link_title field_summary image_reference
2 umami_home_banner 9aadf4a1-ded6-4017-a10d-a5e043396edf Umami Home Banner banner_block Super easy vegetarian pasta bake recipe 3 View recipe A wholesome pasta bake is the ultimate comfort food. This delicious bake is super quick to prepare and an ideal midweek meal for all the family. 18
3 umami_recipes_banner 4c7d58a3-a45d-412d-9068-259c57e40541 Umami Recipes Banner banner_block Vegan chocolate and nut brownies recipe 2 View recipe These sumptuous brownies should be gooey on the inside and crisp on the outside. A perfect indulgence! 20

View File

@@ -0,0 +1,2 @@
id,uuid,info,type,field_disclaimer,field_copyright
umami_disclaimer,9b4dcd67-99f3-48d0-93c9-2c46648b29de,"Umami Disclaimer",disclaimer_block,"<strong>Umami Magazine & Umami Publications</strong> is a fictional magazine and publisher for illustrative purposes only.","Terms & Conditions"
1 id uuid info type field_disclaimer field_copyright
2 umami_disclaimer 9b4dcd67-99f3-48d0-93c9-2c46648b29de Umami Disclaimer disclaimer_block <strong>Umami Magazine & Umami Publications</strong> is a fictional magazine and publisher for illustrative purposes only. Terms & Conditions

View File

@@ -0,0 +1,2 @@
id,uuid,info,type,field_title,content_type,node_id,field_content_link_title,field_summary,image_reference
umami_footer_promo,924ab293-8f5f-45a1-9c7f-2423ae61a241,Umami footer promo,footer_promo_block,Umami Food Magazine,page,1,Find out more,"Skills and know-how. Magazine exclusive articles, recipes and plenty of reasons to get your copy today.",19
1 id uuid info type field_title content_type node_id field_content_link_title field_summary image_reference
2 umami_footer_promo 924ab293-8f5f-45a1-9c7f-2423ae61a241 Umami footer promo footer_promo_block Umami Food Magazine page 1 Find out more Skills and know-how. Magazine exclusive articles, recipes and plenty of reasons to get your copy today. 19

View File

@@ -0,0 +1,22 @@
id,title,image,alt,author
1,Deep mediterranean quiche,mediterranean-quiche-umami.jpg,A delicious deep layered Mediterranean quiche with basil garnish,Umami
2,Vegan chocolate and nut brownies,vegan-chocolate-nut-brownies.jpg,"A stack of chocolate and pecan brownies, sprinkled with pecan crumbs and crushed walnut, fresh out of the oven",Umami
3,Super easy vegetarian pasta bake,veggie-pasta-bake-umami.jpg,Cheesy pasta dish with vegetarian sausages and topped with mozzarella cheese and basil,Umami
4,Watercress soup,watercress-soup-umami.jpg,Watercress soup with a sprig of coriander as garnish in a white bowl with green trim,Umami
5,Victoria sponge cake,victoria-sponge-umami.jpg,"A classic, uncut Victoria sponge with a deep filling of butter cream and jam",Umami
6,Gluten free pizza,pizza-umami.jpg,"Olives, basil, and mozzarella top a gluten free pizza crust with marinara sauce",Umami
7,Thai green curry,thai-green-curry-umami.jpg,"A traditional bowl of creamy, aromatic Thai green curry with chunks of chicken in a small bowl with jasmine rice",Umami
8,Crema catalana,crema-catalana-umami.jpg,"Typical Catalan dessert made from cream and egg yolks, covered with a traditional layer of caramelized sugar to provide a crispy contrast",Umami
9,Fiery chili sauce,chili-sauce-umami.jpg,"An iridescent array of chilies, onions, and garlic, slowly sweating over a low heat",Umami
10,Home Grown Herbs,home-grown-herbs.jpg,"Fresh cut herbs including mint, parsley, thyme and dill",Holly Foat
11,Vegan Chocolate,vegan-chocolate.jpg,"A delicious bar of dairy-free milk chocolate, broken into pieces",Umami
12,Supermarket Savvy Umami,supermarket-savvy-umami.jpg,Leafy greens presented on supermarket produce shelving,Megan Collins Quinlan
13,Mushrooms Umami,mushrooms-umami.jpg,A delightful selection of mushroom varieties laid out on a simple wooden plate,Umami
14,Heritage Carrots,heritage-carrots.jpg,"Purple, orange, yellow and white heritage carrots",Umami
15,Chocolate Brownie Umami,chocolate-brownie-umami.jpg,A delicious chocolate brownie,Umami
16,Mojito Mocktail,mojito-mocktail.jpg,"Fresh mojito mocktail with garnish of mint leaves, ice, and sliced lime",Megan Collins Quinlan
17,Oatmeal Fruit Syrop Topping,oatmeal-fruit-syrup-topping.jpg,"Oatmeal topped with a vibrant mix of berries, nuts, and seeds",Umami
18,Mouth watering vegetarian pasta bake with rich tomato sauce and cheese toppings,veggie-pasta-bake-hero-umami.jpg,Mouth watering vegetarian pasta bake with rich tomato sauce and cheese toppings,Umami
19,3 issue bundle of the Umami food magazine,umami-bundle.png,3 issue bundle of the Umami food magazine,Umami
20,(Hero) Vegan chocolate and nut brownies,vegan-brownies-hero-umami.jpg,"A stack of chocolate and pecan brownies, sprinkled with pecan crumbs and crushed walnut, fresh out of the oven",Umami
21,Borscht with pork ribs,borscht-with-pork-ribs-umami.jpg,"Traditional Ukrainian soup with beets, tomatoes, and pork ribs",Umami
1 id title image alt author
2 1 Deep mediterranean quiche mediterranean-quiche-umami.jpg A delicious deep layered Mediterranean quiche with basil garnish Umami
3 2 Vegan chocolate and nut brownies vegan-chocolate-nut-brownies.jpg A stack of chocolate and pecan brownies, sprinkled with pecan crumbs and crushed walnut, fresh out of the oven Umami
4 3 Super easy vegetarian pasta bake veggie-pasta-bake-umami.jpg Cheesy pasta dish with vegetarian sausages and topped with mozzarella cheese and basil Umami
5 4 Watercress soup watercress-soup-umami.jpg Watercress soup with a sprig of coriander as garnish in a white bowl with green trim Umami
6 5 Victoria sponge cake victoria-sponge-umami.jpg A classic, uncut Victoria sponge with a deep filling of butter cream and jam Umami
7 6 Gluten free pizza pizza-umami.jpg Olives, basil, and mozzarella top a gluten free pizza crust with marinara sauce Umami
8 7 Thai green curry thai-green-curry-umami.jpg A traditional bowl of creamy, aromatic Thai green curry with chunks of chicken in a small bowl with jasmine rice Umami
9 8 Crema catalana crema-catalana-umami.jpg Typical Catalan dessert made from cream and egg yolks, covered with a traditional layer of caramelized sugar to provide a crispy contrast Umami
10 9 Fiery chili sauce chili-sauce-umami.jpg An iridescent array of chilies, onions, and garlic, slowly sweating over a low heat Umami
11 10 Home Grown Herbs home-grown-herbs.jpg Fresh cut herbs including mint, parsley, thyme and dill Holly Foat
12 11 Vegan Chocolate vegan-chocolate.jpg A delicious bar of dairy-free milk chocolate, broken into pieces Umami
13 12 Supermarket Savvy Umami supermarket-savvy-umami.jpg Leafy greens presented on supermarket produce shelving Megan Collins Quinlan
14 13 Mushrooms Umami mushrooms-umami.jpg A delightful selection of mushroom varieties laid out on a simple wooden plate Umami
15 14 Heritage Carrots heritage-carrots.jpg Purple, orange, yellow and white heritage carrots Umami
16 15 Chocolate Brownie Umami chocolate-brownie-umami.jpg A delicious chocolate brownie Umami
17 16 Mojito Mocktail mojito-mocktail.jpg Fresh mojito mocktail with garnish of mint leaves, ice, and sliced lime Megan Collins Quinlan
18 17 Oatmeal Fruit Syrop Topping oatmeal-fruit-syrup-topping.jpg Oatmeal topped with a vibrant mix of berries, nuts, and seeds Umami
19 18 Mouth watering vegetarian pasta bake with rich tomato sauce and cheese toppings veggie-pasta-bake-hero-umami.jpg Mouth watering vegetarian pasta bake with rich tomato sauce and cheese toppings Umami
20 19 3 issue bundle of the Umami food magazine umami-bundle.png 3 issue bundle of the Umami food magazine Umami
21 20 (Hero) Vegan chocolate and nut brownies vegan-brownies-hero-umami.jpg A stack of chocolate and pecan brownies, sprinkled with pecan crumbs and crushed walnut, fresh out of the oven Umami
22 21 Borscht with pork ribs borscht-with-pork-ribs-umami.jpg Traditional Ukrainian soup with beets, tomatoes, and pork ribs Umami

View File

@@ -0,0 +1,9 @@
id,title,body,author,slug,image_reference,tags
1,Give it a go and grow your own herbs,give-it-a-go-and-grow-your-own-herbs.html,Holly Foat,articles/give-it-a-go-and-grow-your-own-herbs,10,"14,23,16"
2,Dairy-free and delicious milk chocolate,dairy-free-delicious-milk-chocolate.html,Umami,articles/dairy-free-and-delicious-milk-chocolate,11,"27,7"
3,The real deal for supermarket savvy shopping,the-real-deal-for-supermarket-savvy-shopping.html,Megan Collins Quinlan,articles/the-real-deal-for-supermarket-savvy-shopping,12,"26,24"
4,The Umami guide to our favorite mushrooms,the-umami-guide-to-our-favourite-mushrooms.html,Umami,articles/the-umami-guide-to-our-favourite-mushrooms,13,"18,28"
5,Let's hear it for carrots,lets-hear-it-for-carrots.html,Umami,articles/lets-hear-it-for-carrots,14,"6,28,15"
6,Baking mishaps - our troubleshooting tips,baking-mishaps-our-troubleshooting-tips.html,Umami,articles/baking-mishaps-our-troubleshooting-tips,15,"3,17"
7,Skip the spirits with delicious mocktails,skip-the-spirits-with-delicious-mocktails.html,Megan Collins Quinlan,articles/skip-the-spirits-with-delicious-mocktails,16,"1,12,20,8,11"
8,Give your oatmeal the ultimate makeover,give-your-oatmeal-the-ultimate-makeover.html,Umami,articles/give-your-oatmeal-the-ultimate-makeover,17,"27,28,19,4,10"
1 id title body author slug image_reference tags
2 1 Give it a go and grow your own herbs give-it-a-go-and-grow-your-own-herbs.html Holly Foat articles/give-it-a-go-and-grow-your-own-herbs 10 14,23,16
3 2 Dairy-free and delicious milk chocolate dairy-free-delicious-milk-chocolate.html Umami articles/dairy-free-and-delicious-milk-chocolate 11 27,7
4 3 The real deal for supermarket savvy shopping the-real-deal-for-supermarket-savvy-shopping.html Megan Collins Quinlan articles/the-real-deal-for-supermarket-savvy-shopping 12 26,24
5 4 The Umami guide to our favorite mushrooms the-umami-guide-to-our-favourite-mushrooms.html Umami articles/the-umami-guide-to-our-favourite-mushrooms 13 18,28
6 5 Let's hear it for carrots lets-hear-it-for-carrots.html Umami articles/lets-hear-it-for-carrots 14 6,28,15
7 6 Baking mishaps - our troubleshooting tips baking-mishaps-our-troubleshooting-tips.html Umami articles/baking-mishaps-our-troubleshooting-tips 15 3,17
8 7 Skip the spirits with delicious mocktails skip-the-spirits-with-delicious-mocktails.html Megan Collins Quinlan articles/skip-the-spirits-with-delicious-mocktails 16 1,12,20,8,11
9 8 Give your oatmeal the ultimate makeover give-your-oatmeal-the-ultimate-makeover.html Umami articles/give-your-oatmeal-the-ultimate-makeover 17 27,28,19,4,10

View File

@@ -0,0 +1,2 @@
id,title,body,author,slug
1,About Umami,"<p>Umami is a fictional food magazine that has been created to demonstrate how you might build a Drupal site using functionality provided 'out of the box'.</p><p>For more information visit <a href='https://www.drupal.org/docs/umami-drupal-demonstration-installation-profile'>https://www.drupal.org/docs/umami-drupal-demonstration-installation-profile</a>.</p>",Samuel Adamson,about-umami
1 id title body author slug
2 1 About Umami <p>Umami is a fictional food magazine that has been created to demonstrate how you might build a Drupal site using functionality provided 'out of the box'.</p><p>For more information visit <a href='https://www.drupal.org/docs/umami-drupal-demonstration-installation-profile'>https://www.drupal.org/docs/umami-drupal-demonstration-installation-profile</a>.</p> Samuel Adamson about-umami

View File

@@ -0,0 +1,11 @@
id,title,image_reference,summary,author,recipe_category,preparation_time,cooking_time,total_time,difficulty,ingredients,recipe_instruction,number_of_servings,tags,slug
1,Deep mediterranean quiche,1,An Italian inspired quiche with sun dried tomatoes and courgette. A perfect light meal for a summer's day.,Umami,3,40,30,70,medium,"For the pastry:,280g plain flour,140g butter,Cold water,For the filling:,1 onion,2 garlic cloves,Half a courgette,450ml soya milk,500g grated parmesan,2 eggs,200g sun dried tomatoes,100g feta",mediterranean-quiche-umami.html,8,"22,13",recipes/deep-mediterranean-quiche
2,Vegan chocolate and nut brownies,2,"Scrumptious vegan chocolate brownies that are rich, fudgy, and nutty. These delights have a surprise hint of coconut making them the perfect indulgence. Serve warm with a little vanilla dairy-free ice cream!",Umami,4,20,20,40,medium,"6 tbsp sunflower oil, 80g vegan dark chocolate, 170g plain flour, 80g coconut flour, 1 tsp baking powder, 9 tsp cocoa powder, 100g caster sugar, 3 tbsp of maple syrup, 1/4 tsp sea salt, 1 tsp vanilla extract, 230ml unsweetened organic soya milk, 100g pecan nuts, 80g walnut halves",vegan-chocolate-nut-brownies.html,12,"3,7,27,9",recipes/vegan-chocolate-and-nut-brownies
3,Super easy vegetarian pasta bake,3,A wholesome pasta bake is the ultimate comfort food. This delicious bake is super quick to prepare and an ideal midweek meal for all the family.,Umami,3,5,20,25,easy,"400g wholewheat pasta, 1 onion, 2 garlic cloves, 1 pack vegetarian sausages, 400g chopped tomatoes, 50g sliced sun dried tomatoes, 1 pinch sugar, 3 tbsp red pesto, 50g cheddar cheese, Basil or mixed herbs, 100g mozzarella",veggie-pasta-bake-umami.html,4,"28,21,2",recipes/super-easy-vegetarian-pasta-bake
4,Watercress soup,4,"A wonderfully simple and light soup, making the most of seasonal, local produce. ",Umami,5,10,20,30,easy,"3 bunches watercress,3 potatoes,3 onions,2 leeks,800ml stock,5 tbsp crème fraîche",watercress-soup-umami.html,4,"25,28",recipes/watercress-soup
5,Victoria sponge cake,5,"A traditional Victoria sponge cake, perfect for any afternoon with a cup of tea.",Umami,2,20,20,40,easy,"225g butter or margarine,225g caster sugar,225g self-raising flour,4 eggs,1 tsp baking powder,3 tbsp of jam for the filling,Icing sugar to dust the top,Cream to serve",victoria-sponge-umami.html,10,5,recipes/victoria-sponge-cake
6,Gluten free pizza,6,"A gorgeous and simple gluten free pizza, with deliciously indulgent mozzarella and Parma ham. Can easily be vegetarian by leaving out the ham.",Umami,3,15,15,30,,"400g gluten free flour, 125ml warm water, 125ml milk, 1 sachet dried yeast, 2 tsp sugar, 1 tsp salt, 2 tbsp olive oil, 4 tbsp tomato puree, 1 garlic clove, Fresh basil, 200g mozzarella, 100g rocket, 5 slices Parma ham",pizza-umami.html,4,,recipes/gluten-free-pizza
7,Thai green curry,7,A quick and easy version of the classic Thai green curry. Perfect for a midweek meal!,Umami,3,10,15,25,,"400g coconut milk, 400g chicken or tofu, 1 tbsp Thai green curry paste, 1 garlic clove, 2 tsp fish sauce, 400g mushrooms, 200g green beans, Fresh coriander leaves, Jasmine rice",thai-green-curry-umami.html,4,,recipes/thai-green-curry
8,Crema catalana,8,Enjoy this sweet recipe for one of the oldest desserts in Europe. It requires very few ingredients!,Umami,2,10,20,30,,"1l milk, 200g sugar, 6 egg yolks, 30g cornstarch, 1 cinnamon stick, 1 piece lemon peel",crema-catalana-umami.html,8,"13,28",recipes/crema-catalana
9,Fiery chili sauce,9,A rich and fiery chili sauce. Take care when handling chili peppers. And serve sparingly!,Umami,1,10,50,60,easy,"2 red onions, 1 lemon, 2 limes, 250ml malt vinegar, 7 garlic cloves, 1 green bell pepper, 1 red bell pepper, 800g cherry tomatoes, 30 mixed chilies, Olive oil, 1 tbsp ground black pepper, 1 tbsp brown sugar",chili-sauce-umami.html,60,28,recipes/fiery-chili-sauce
10,Borscht with pork ribs,21,"Every Ukrainian family has a modification; with beans, without cabbage, etc. They are all valid though, theres no unified correct recipe. The one you are about to read and cook is borscht with pork ribs. Youll appreciate its taste and flavor. Youll connect and feel a true Ukrainian soul while savoring!",Umami,3,30,60,90,medium,"400-500g pork ribs,2 beets,2 tomatoes,¼ celery root,¼ cabbage,3-4 medium potatoes,1 carrot,1 onion,1-2 smoked pears,2 bay leaves,3 allspice berries,1 bulb garlic,1 bell pepper,200ml tomato juice,30g butter,2 tbsp tomato paste,3l water,Sour cream,1 can beans (optional),Salt to taste",borscht-with-pork-ribs-umami.html,8,25,recipes/borscht-with-pork-ribs
1 id title image_reference summary author recipe_category preparation_time cooking_time total_time difficulty ingredients recipe_instruction number_of_servings tags slug
2 1 Deep mediterranean quiche 1 An Italian inspired quiche with sun dried tomatoes and courgette. A perfect light meal for a summer's day. Umami 3 40 30 70 medium For the pastry:,280g plain flour,140g butter,Cold water,For the filling:,1 onion,2 garlic cloves,Half a courgette,450ml soya milk,500g grated parmesan,2 eggs,200g sun dried tomatoes,100g feta mediterranean-quiche-umami.html 8 22,13 recipes/deep-mediterranean-quiche
3 2 Vegan chocolate and nut brownies 2 Scrumptious vegan chocolate brownies that are rich, fudgy, and nutty. These delights have a surprise hint of coconut making them the perfect indulgence. Serve warm with a little vanilla dairy-free ice cream! Umami 4 20 20 40 medium 6 tbsp sunflower oil, 80g vegan dark chocolate, 170g plain flour, 80g coconut flour, 1 tsp baking powder, 9 tsp cocoa powder, 100g caster sugar, 3 tbsp of maple syrup, 1/4 tsp sea salt, 1 tsp vanilla extract, 230ml unsweetened organic soya milk, 100g pecan nuts, 80g walnut halves vegan-chocolate-nut-brownies.html 12 3,7,27,9 recipes/vegan-chocolate-and-nut-brownies
4 3 Super easy vegetarian pasta bake 3 A wholesome pasta bake is the ultimate comfort food. This delicious bake is super quick to prepare and an ideal midweek meal for all the family. Umami 3 5 20 25 easy 400g wholewheat pasta, 1 onion, 2 garlic cloves, 1 pack vegetarian sausages, 400g chopped tomatoes, 50g sliced sun dried tomatoes, 1 pinch sugar, 3 tbsp red pesto, 50g cheddar cheese, Basil or mixed herbs, 100g mozzarella veggie-pasta-bake-umami.html 4 28,21,2 recipes/super-easy-vegetarian-pasta-bake
5 4 Watercress soup 4 A wonderfully simple and light soup, making the most of seasonal, local produce. Umami 5 10 20 30 easy 3 bunches watercress,3 potatoes,3 onions,2 leeks,800ml stock,5 tbsp crème fraîche watercress-soup-umami.html 4 25,28 recipes/watercress-soup
6 5 Victoria sponge cake 5 A traditional Victoria sponge cake, perfect for any afternoon with a cup of tea. Umami 2 20 20 40 easy 225g butter or margarine,225g caster sugar,225g self-raising flour,4 eggs,1 tsp baking powder,3 tbsp of jam for the filling,Icing sugar to dust the top,Cream to serve victoria-sponge-umami.html 10 5 recipes/victoria-sponge-cake
7 6 Gluten free pizza 6 A gorgeous and simple gluten free pizza, with deliciously indulgent mozzarella and Parma ham. Can easily be vegetarian by leaving out the ham. Umami 3 15 15 30 400g gluten free flour, 125ml warm water, 125ml milk, 1 sachet dried yeast, 2 tsp sugar, 1 tsp salt, 2 tbsp olive oil, 4 tbsp tomato puree, 1 garlic clove, Fresh basil, 200g mozzarella, 100g rocket, 5 slices Parma ham pizza-umami.html 4 recipes/gluten-free-pizza
8 7 Thai green curry 7 A quick and easy version of the classic Thai green curry. Perfect for a midweek meal! Umami 3 10 15 25 400g coconut milk, 400g chicken or tofu, 1 tbsp Thai green curry paste, 1 garlic clove, 2 tsp fish sauce, 400g mushrooms, 200g green beans, Fresh coriander leaves, Jasmine rice thai-green-curry-umami.html 4 recipes/thai-green-curry
9 8 Crema catalana 8 Enjoy this sweet recipe for one of the oldest desserts in Europe. It requires very few ingredients! Umami 2 10 20 30 1l milk, 200g sugar, 6 egg yolks, 30g cornstarch, 1 cinnamon stick, 1 piece lemon peel crema-catalana-umami.html 8 13,28 recipes/crema-catalana
10 9 Fiery chili sauce 9 A rich and fiery chili sauce. Take care when handling chili peppers. And serve sparingly! Umami 1 10 50 60 easy 2 red onions, 1 lemon, 2 limes, 250ml malt vinegar, 7 garlic cloves, 1 green bell pepper, 1 red bell pepper, 800g cherry tomatoes, 30 mixed chilies, Olive oil, 1 tbsp ground black pepper, 1 tbsp brown sugar chili-sauce-umami.html 60 28 recipes/fiery-chili-sauce
11 10 Borscht with pork ribs 21 Every Ukrainian family has a modification; with beans, without cabbage, etc. They are all valid though, there’s no unified ‘correct’ recipe. The one you are about to read and cook is borscht with pork ribs. You’ll appreciate its taste and flavor. You’ll connect and feel a true Ukrainian soul while savoring! Umami 3 30 60 90 medium 400-500g pork ribs,2 beets,2 tomatoes,¼ celery root,¼ cabbage,3-4 medium potatoes,1 carrot,1 onion,1-2 smoked pears,2 bay leaves,3 allspice berries,1 bulb garlic,1 bell pepper,200ml tomato juice,30g butter,2 tbsp tomato paste,3l water,Sour cream,1 can beans (optional),Salt to taste borscht-with-pork-ribs-umami.html 8 25 recipes/borscht-with-pork-ribs

View File

@@ -0,0 +1,12 @@
<ol>
<li>Preheat the oven to 400°F/200°C. Put pork ribs on the baking dish and bake them for 30 minutes. Wash but dont peel the celery root. Dice the carrot.</li>
<li>Put the baked pork ribs in a pot and add 3 liters of water. Chop the celery root and carrot and add them to the pot, along with half the unpeeled onion. Bring the pot to the boil and simmer for 30 minutes.</li>
<li>The heart of the borscht is sautéed vegetables. Dice the bell pepper, tomatoes, and remainder of the onion. Place the butter in a saucepan and add the vegetables. Cook them over a moderate heat until soft. Add the tomato paste, reduce the heat, and simmer for 5-7 minutes. Grate a beet, add it to the saucepan, and stew for a further 3-4 minutes.</li>
<li>Cut a garlic bulb in a half and add it to the pot. Shred the cabbage and put it aside.</li>
<li>Take the second beet and squeeze all the juice out. If you dont have a juice squeezer, you can grate a beet and pass it through the sieve. Add the juice together with the allspice, bay leaves, and several pinches of salt to taste.</li>
<li>Optionally add the canned beans.</li>
<li>Add the smoked pears to the pot. They will make your dish smell smoky.</li>
<li>Add the shredded cabbage and cook for a further 5 minutes.</li>
<li>Take the borscht off the heat and let it stand for 30 minutes.</li>
</ol>
<p>Serve the borscht with a spoon of sour cream and chopped dill. Put the leftover borscht in the fridge, and remember that it tastes better the next day!</p>

View File

@@ -0,0 +1,14 @@
<ol>
<li>Preheat the oven to 400°F/200°C.</li>
<li>Finely chop the red onions and sweat gently on a low heat in olive oil for 5 minutes.</li>
<li>Peel the garlic and add it to the onions.</li>
<li>Meanwhile, chop the bell peppers to 1 inch pieces. Add the bell peppers and tomatoes to a roasting dish, and rub with lemon juice, olive oil and black pepper. Transfer to the oven and roast for 30 minutes.</li>
<li>Once the onions and garlic have softened, chop and add the chilies, seeds and all. Mix well and continue to gently fry.</li>
<li>Thoroughly wash your hands following handling raw chilies.</li>
<li>Once the tomatoes and bell peppers have finished roasting, add them to the pan. Cook for at least 10 minutes, breaking them up with a masher or a hand blender as they simmer. Once broken up, mix in the sugar.</li>
<li>Transfer the sauce to a blender and blend until smooth.</li>
<li>Return to the pan and add the vinegar and juice of the limes.</li>
<li>Cook through for a further 10 minutes, then leave to cool.</li>
<li>Transfer to sterilized jars and keep refrigerated.</li>
<li>Leave for at least two weeks before tasting.</li>
</ol>

View File

@@ -0,0 +1,9 @@
<ol>
<li>Mix the egg yolks, sugar, and cornstarch with 1/3 of the milk.</li>
<li>In a saucepan, boil 2/3 of the milk with the lemon peel and cinnamon.</li>
<li>After 3 minutes, remove from the heat and take out the lemon and cinnamon.</li>
<li>Slowly add the egg mixture to the hot milk through a strainer to ensure there are no lumps.</li>
<li>Return it to the heat until it boils, stirring constantly.</li>
<li>Once the mixture has begun to thicken, remove from the heat and put it into individual bowls to cool.</li>
<li>For an authentic finish, sprinkle with sugar and brown with a blowtorch or under a preheated broiler to caramelize.</li>
</ol>

View File

@@ -0,0 +1,7 @@
<ol>
<li>Preheat the oven to 400°F/200°C. Starting with the pastry; rub the flour and butter together in a bowl until crumbling like breadcrumbs. Add water, a little at a time, until it forms a dough.</li>
<li>Roll out the pastry on a floured board and gently spread over your tin. Place in the fridge for 20 minutes before blind baking for a further 10.</li>
<li>Whilst the pastry is cooling, chop and gently cook the onions, garlic and courgette.</li>
<li>In a large bowl, add the soya milk, half the parmesan, and the eggs. Gently mix.</li>
<li>Once the pastry is cooked, spread the onions, garlic and sun dried tomatoes over the base and pour the eggs mix over. Sprinkle the remaining parmesan and careful lay the feta over the top. Bake for 30 minutes or until golden brown.</li>
</ol>

View File

@@ -0,0 +1,7 @@
<ol>
<li>Preheat the oven to 425°F/220°C. Mix some of the milk and water in a jug, and add the yeast and sugar, then set aside.</li>
<li>In a bowl, mix the flour, salt and oil. Slowly add the liquid from the jug and form into a dough.</li>
<li>Break the dough in half and shape into two pizza bases. Set aside for about 15 minutes, whilst making the topping.</li>
<li>Spread the tomato puree over the pizza bases, chop the basil and rocket and sprinkle over the tomato. Lay the chopped Parma ham on top and add thick slices of mozzarella across the pizza.</li>
<li>Cook in the oven directly on the top shelf (with a tray underneath) for 10-12 minutes until the mozzarella is bubbling. Season with salt and pepper and serve.</li>
</ol>

View File

@@ -0,0 +1,6 @@
<ol>
<li>In a large wok, brown the chicken until golden, then turn the heat down and gently cook the garlic. Add the chopped green beans and stir.</li>
<li>Add the coconut milk, green curry paste and fish sauce. Mix well and slowly simmer.</li>
<li>Add the chopped mushrooms and simmer until the chicken (or tofu) is cooked.</li>
<li>Serve with jasmine rice and a sprinkle of coriander.</li>
</ol>

View File

@@ -0,0 +1,14 @@
<ol>
<li>Use a little of the sunflower oil to grease an 8 inch square baking tin (or similar size) and line the tin with greaseproof paper.</li>
<li>Preheat the oven to 350°F/180°C.</li>
<li>Break approximately 1/3rd of the chocolate bar off and chop into small pieces. Roughly chop 2/3rds of the pecan nuts and mix together with the chopped chocolate. Set aside.</li>
<li>For finishing the brownies, chop or crush the remaining pecan nuts and walnuts, mix together and set aside.</li>
<li>Melt the remaining chocolate by bringing a couple inches of water to the boil in a small saucepan that is suitably sized for holding a heatproof bowl in the pan opening. Do not allow the bottom of the heatproof bowl to touch the water. Place the chocolate into the bowl to melt, stirring occasionally to ensure the chocolate has fully melted. Once melted, set aside and allow to cool slightly.</li>
<li>Whilst the chocolate is melting, begin to sieve the plain flour, coconut flour, and cocoa powder into a large mixing bowl and mix. Once mixed, stir in the baking powder and sugar.</li>
<li>Once the chocolate has cooled a little, begin to slowly stir the vanilla essence, sunflower oil, soya milk, and melted chocolate into the flour and cocoa mix.</li>
<li>Now stir in the previously chopped chocolate and pecan nuts, ensuring they are stirred evenly into the mixture.</li>
<li>Pour the mixture into the baking tin and spread evenly with a spatula.</li>
<li>Sprinkle the chopped pecan nuts and walnuts across the top and bake in the centre of the oven for 18 to 23 minutes.</li>
<li>Remove from the oven and allow to cool for 45 minutes. Carefully use the edges of the greaseproof paper to lift the brownie out of the tin and place onto a chopping board. With a sharp knife, gently cut into evenly sized pieces.</li>
<li>Serve on their own or with some vegan cream or ice cream.</li>
</ol>

View File

@@ -0,0 +1,8 @@
<ol>
<li>In a large pan, boil the pasta in plenty of water until cooked.</li>
<li>Whilst the pasta is cooking, chop the onion and gently fry it with the garlic in a little oil until soft and the onion looks clear.</li>
<li>Add the vegetarian sausages. Once browned, remove and chop into chunky bites.</li>
<li>Pop the sausages back into the pan and add the tomatoes, sugar, pesto and sun dried tomatoes. Season to taste. Simmer until most of the water from the chopped tomatoes has gone.</li>
<li>Drain the pasta and add to the pan with the sausages and tomatoes. Stir in half of the cheddar and transfer to a shallow dish. Sprinkle with the rest of the cheddar and dot the sliced mozzarella over the top.</li>
<li>Grill for 10 minutes or until the cheese has melted and started to brown. Serve with basil leaves.</li>
</ol>

View File

@@ -0,0 +1,8 @@
<ol>
<li>Preheat the oven to 350°F/180°C and grease two 8 inch cake tins.</li>
<li>In a large bowl, mix the butter and sugar together, then add the eggs, flour and baking powder.</li>
<li>Spread the mix evenly between the 2 cake tins.</li>
<li>Place both tins in the middle of the preheated oven for 20 minutes, before checking with a knife. When the knife comes out clean, it's ready!</li>
<li>Allow to cool in the tins before moving them onto a cooling rack.</li>
<li>Add the jam, stack, dust with icing sugar and serve with a big dollop of cream. Enjoy!</li>
</ol>

View File

@@ -0,0 +1,7 @@
<ol>
<li>Prepare the vegetables by peeling and chopping the potatoes, finely chopping the onions, leeks and garlic.</li>
<li>Heat a little oil in a pan and add the chopped vegetables, gently cooking them for about 5 minutes.</li>
<li>Add the vegetable stock to the same pan and turn up the heat until simmering, adding the watercress after about 10 minutes. Cook until all the vegetables are soft and easily mashed.</li>
<li>Liquidize the soup either with a hand blender or in a mixer, until smooth.</li>
<li>If the soup has cooled too much whilst being liquidized, stir in the crème fraîche and reheat before serving (otherwise serve straight away). Season to taste.</li>
</ol>

View File

@@ -0,0 +1,6 @@
id,term
1,Accompaniments
2,Desserts
3,Main courses
4,Snacks
5,Starters
1 id term
2 1 Accompaniments
3 2 Desserts
4 3 Main courses
5 4 Snacks
6 5 Starters

View File

@@ -0,0 +1,29 @@
id,term
1,Alcohol free
2,Baked
3,Baking
4,Breakfast
5,Cake
6,Carrots
7,Chocolate
8,Cocktail party
9,Dairy-free
10,Dessert
11,Dinner party
12,Drinks
13,Egg
14,Grow your own
15,Healthy
16,Herbs
17,Learn to cook
18,Mushrooms
19,Oats
20,Party
21,Pasta
22,Pastry
23,Seasonal
24,Shopping
25,Soup
26,Supermarkets
27,Vegan
28,Vegetarian
1 id term
2 1 Alcohol free
3 2 Baked
4 3 Baking
5 4 Breakfast
6 5 Cake
7 6 Carrots
8 7 Chocolate
9 8 Cocktail party
10 9 Dairy-free
11 10 Dessert
12 11 Dinner party
13 12 Drinks
14 13 Egg
15 14 Grow your own
16 15 Healthy
17 16 Herbs
18 17 Learn to cook
19 18 Mushrooms
20 19 Oats
21 20 Party
22 21 Pasta
23 22 Pastry
24 23 Seasonal
25 24 Shopping
26 25 Soup
27 26 Supermarkets
28 27 Vegan
29 28 Vegetarian

View File

@@ -0,0 +1,13 @@
<p>Sigues la receta, pesas todos tus ingredientes, usas la temperatura correcta del horno y te tomas tu tiempo y aún así, tu horneado sale con un fondo empapado, no se eleva o simplemente tiene un sabor horrible. Hemos creado una lista de los problemas de horneado más frustrantes y las técnicas que puedes utilizar para tratar de evitarlos.</p>
<h2>Tu pastel no subió</h2>
<p>Bajo ninguna circunstancia abras la puerta del horno en medio del tiempo de cocción. El calor saldrá, destruyendo la reacción química que tiene lugar dentro de tu pastel. Tu agente elevador necesita el calor para activarse y podrías matarlo.</p>
<h2>Tu pastel es chicloso y correoso</h2>
<p>Si tu esponja ligero tiene la consistencia de un neumático de repuesto, es posible que hayas mezclado demasiado la masa. Mantén la ligereza dentro de la mezcla del bizcocho añadiendo cuidadosa y suavemente los ingredientes y sólo hasta el punto en que se mezclen. Si se bate demasiado, el gluten de la harina comenzará a salir y estarás haciendo pan en lugar de pastel.</p>
<h2>Tus galletas se quemaron</h2>
<p>Un gran truco es usar utensilios para hornear de colores claros, en lugar de negros. Es menos probable que absorba el calor y lo transfiera a la parte inferior de tus galletas. Usar papel para hornear también ayudará con esto. Además, usar demasiada azúcar puede provocar que tus galletas se oscurezcan demasiado y les dé un aspecto caramelizado</p>
<h2>Parte superior de tu pastel o pan partida</h2>
<p>Es muy probable que tu horno esté demasiado caliente. Si sospechas que tu horno no mantiene la temperatura correcta, invierte en un termómetro y revísalo regularmente durante la cocción. Con el pan, mezclar la masa demasiado puede resultar en una parte superior agrietada o partida.</p>
<h2>El temido fondo empapado</h2>
<p>Como se mencionó anteriormente, el color de tu sartén es importante. En este caso, una sartén oscura aumentará el calor en la parte inferior y le dará a esa parte inferior el crujiente que deseas. Si estás usando hojaldre, realmente necesitas pre-hornearlo. Poner tu pastel hacia la parte inferior del horno aumentará el calor que llega a esa parte.</p>
<h2>Tu pastel se ha encogido</h2>
<p>Simplemente intentaste hacer que se estirara demasiado. Al laminar, no intentes hacerla demasiado delgada o demasiado grande y al colocarla sobre la sartén, permite que se asiente por sí sola sin estirarla para que encaje. O simplemente añade más masa - ¡a todo el mundo le encantan los pasteles de todos modos!</p>

View File

@@ -0,0 +1,12 @@
<p>El calendario está lleno de excusas para complacer a los amantes del chocolate, desde festividades religiosas a cumpleaños - incluso el Día Internacional del chocolate, el 7 de julio. Pero aquellos que son veganos o no toman lácteos no tienen por qué perdérselo porque hay una gran oferta de chocolates veganos sin lactosa.</p>
<p>El chocolate con leche sin lactosa se fabrica de forma similar al chocolate normal, hasta el momento en el que se añade la leche. Los granos de cacao son tostados durante un par de horas hasta que adquieren su rico sabor. Se elimina la cáscara y se muele el interior del grano hasta conseguir una pasta que pueda mezclarse con la manteca de cacao, produciendo así el porcentaje de cacao deseado. Los saborizantes, el azúcar y la leche son añadidos después en diferentes cantidades dependiendo del tipo de chocolate que se desea realizar. El chocolate es granulado en este punto y se tritura hasta que está suave, ¡esto puede llevar días! Finalmente, se templa mediante un proceso de calentamiento y enfriamiento hasta que está listo para comer.</p>
<p>Entonces, ¿cómo hacen para que los chocolates veganos adquieran ese sabor y esa textura cremosa propias de la leche?</p>
<h2>Leche de arroz</h2>
<p>El sabor de la leche de arroz complementa perfectamente a las semillas de cacao y fue una de las primeras alternativas usadas para crear chocolate con leche vegano. La leche de arroz está hecha de polvo de arroz y algunas veces se combina con leche de avellana para crear la textura y el sabor correctos que son ideales para producir todo tipo de barras de chocolate.</p>
<h2>Leche de coco</h2>
<p>La leche de coco es el ingrediente perfecto para agregar cremosidad a una barra de chocolate. Con altos niveles de grasa, un sabor dulce pero no abrumador y con la consistencia correcta, es una excelente opción para el chocolate con leche vegano. El chocolate hecho de esta manera se derretirá estupendamente para luego rociarlo o mojar en él, y la leche de coco agrega un ligero sabor tropical que funciona bien con otros sabores de frutas y nueces.</p>
<h2>Leche de soja</h2>
<p>La soja ha sido durante mucho tiempo el pilar de las dietas veganas y vegetarianas ya que es rica en proteínas y está disponible en una amplia variedad de texturas adecuadas para todo tipo de platos. La leche de soja está ampliamente disponible y es una excelente alternativa a la leche para el chocolate. No es tan rica en grasa como algunas leches veganas, pero tiene un sabor neutro que facilita su combinación con casi cualquier otro sabor.</p>
<h2>Leche de almendras y avellanas</h2>
<p>Las leches hechas de almendras y avellanas son fáciles de encontrar en los estantes de los supermercados y son perfectas para la producción de chocolate. Al igual que la leche de soja, suelen ser bastante bajas en grasa y, por lo tanto, algo menos cremosas, pero tienen ese sabor a fruto seco que combina muy bien con cualquier tipo de chocolate.</p>
<p>Muchos fabricantes usan una combinación de las leches anteriores citadas para crear la consistencia perfecta para su producto. Usando una mezcla de estas leches, son capaces de producir todo tipo de chocolates con leche (incluido el chocolate blanco).</p>

View File

@@ -0,0 +1,15 @@
<p>No hay nada como tener tu propio suministro de hierbas frescas a mano y listas para ser usadas mientras cocinas. Tanto si tienes un gran jardín como un pequeño alféizar en la cocina, siempre hay espacio suficiente para un cultivo casero.</p>
<h2>Exteriores</h2>
<h3>Menta</h3>
<p>La menta es una gran planta para cultivo casero ya que es resistente y prácticamente crece en cualquier tipo de tierra. La menta es un cultivo que puede descontrolarse, así que mantenla cercada en una maceta o podría extenderse por todo tu jardín.</p>
<h3>Salvia</h3>
<p>Al igual que la menta, la salvia es otra planta que crece de forma descontrolada y puede hacerse con tu jardín si la dejas. Altamente aromática, la planta de la salvia se puede plantar en una maceta o en un lecho de flores con tierra seca. La mejor forma de almacenar las hierbas es secarlas al sol y guardarlas dentro de un recipiente cerrado en un armario fresco y oscuro.</p>
<h3>Romero</h3>
<p>La planta del romero crece en forma de hermosos arbustos. Se puede cultivar fácilmente a partir de esquejes. No aguanta las temperaturas muy frías así que hay que plantarla cerca de la casa para protegerlas del frío. Crece bien en maceta ya que le gusta el suelo seco, pero puede sobrevivir también sin problema en el suelo. Si vas a podar el romero para mejorar su forma, guarda las ramas y cuélgalas boca abajo para preservar su sabor y usarlas en tus platos.</p>
<h2>Interiores</h2>
<h3>Albahaca</h3>
<p>Perfecta para un lugar al sol en el alféizar de la ventana de la cocina. La albahaca es una planta anual, así que morirá en otoño por lo que es una buena idea recogerla en verano y secarla. Una vez cortada, la albahaca se mantiene fresca más tiempo si se pone en agua (como se hace con las flores frescas). Otra buena manera de almacenar la albahaca es hacer pesto con ella.</p>
<h3>Cebollino</h3>
<p>El cebollino es una hierba versátil, que crece sin problema en interiores. Asegurate de que la planta se riega bien y recibe mucha luz. Recuerda recortar regularmente la planta para prevenir que salgan flores y la planta crezca más.</p>
<h3>Cilantro</h3>
<p>El cilantro puede crecer en interiores, pero a diferencia de otras hierbas, no soporta la luz directa del sol. Si tienes una ventana en la cocina orientada al sur no es un buen lugar para colocarla. Aunque no necesita tanta agua como la albahaca, al cilantro no le gusta la tierra seca así que acuérdate de regarla. El cilantro cortado se almacena mejor en el frigorífico.</p>

View File

@@ -0,0 +1,13 @@
<p>Es vegano, libre de gluten, bajo en grasa, alto en fibra e incluso puede reducir el colesterol, pero la harina de avena es aburrida, ¿verdad? Pero, antes de descartar ese aburrido jarrón de avena, es posible que desee inspirarse en nuestras ideas principales que harán que su avena sea insípida a creativa en sólo unos minutos.</p>
<p>Llámelo avena, avena, cereal caliente o simplemente avena, es amado en todo el mundo; pero recientemente, la avena humilde está recibiendo un cambio de imagen funky. Atrás quedaron los días de tartas de desayuno pesadas y gruesas, porque la avena se sirve como una deliciosa comida que puede adaptarse a cualquier momento del día. Están surgiendo las modernas barras de avena para construir su propia harina de avena, y brindan la mejor experiencia de avena. Los comensales pueden elegir su avena para hacerla con leche o agua y luego ir a la ciudad con sus ingredientes favoritos: dulce, salado o incluso picante.</p>
<p>Suena genial, ¿no es así? Así que antes de cerrar la puerta de la alacena en ese frasco de avena de aspecto insípido, creemos que deberías probar algunas de estas deliciosas ideas para inspirar tu propio cambio de imagen.</p>
<h2>Frutas secas empapadas</h2>
<p>A veces, las frutas secas simples pueden ser un poco blandas y ásperas cuando se combinan con avena cremosa. Pero si simplemente remoja su fruta seca en jugo de naranja durante la noche, desarrollarán una espiga y se hincharán, haciéndolos más suaves y aún más deliciosos. Además, el toque de color realmente puede alegrar su día.</p>
<h2>Crème brûlée gachas</h2>
<p>Tan simple, pero ¿por qué nadie lo ha pensado antes? Ponga su harina de avena cocida en un molde, espolvoree con azúcar y revuelva debajo de la parrilla. El azúcar se endurecerá, lo que te dará el placer de resquebrajarse en la superficie y extraer la deliciosa cremosidad que se encuentra debajo. Si eres realmente profesional, puedes usar un soplete.</p>
<h2>Súper semillas</h2>
<p>Para una opción de comida más sabrosa, cocine su avena con agua, un poco de sal y espolvoree con semillas tostadas. Puede elegir cualquiera que disfrute, pero las semillas de calabaza, sésamo, linaza y girasol son especialmente buenas. Algunos supermercados también venden mezclas de semillas para facilitar aún más el trabajo.</p>
<h2>Torta De Zanahoria Deconstruida</h2>
<p>Cocina la avena con zanahorias ralladas y un poco de azúcar, luego cubre con una pizca de canela, nueces picadas y una cucharada de queso crema endulzado. Si no te gusta esto, hay algo mal con tus papilas gustativas.</p>
<h2>El Chocolate Oscuro</h2>
<p>Esta delicia baja en azúcar cumplirá con todos esos antojos de chocolate y es el postre perfecto. Agregue una cucharada de cacao a su avena mientras se cocina, luego cubra con unos cuadrados de chocolate oscuro. A medida que se derrite, simplemente gíralos en el tazón tan ingeniosamente como puedas. Si eres realmente decadente, un chorrito de crema batida agregará más placeres.</p>

View File

@@ -0,0 +1,11 @@
<p>¡Un aplauso por la humilde zanahoria! Estas verduras «diarias», dulces y saludables tienen todo lo que necesitas. Tienen un gran sabor, un color fantástico y, si eres uno de los que creen en la historia antigua, incluso pueden ayudarte a ver mejor en la oscuridad.</p>
<p>¿A quién no le gusta cocinar con esta raíz super versátil? Las asamos, las hervimos, las trituramos en sopas y las rallamos en ensaladas. La humilde zanahoria tiene que ser una de nuestras opciones favoritas de verduras y se ha cultivado durante miles de años. Pero en ese entonces era más probable que encontraras una zanahoria morada, roja, amarilla o blanca y no la naranja con la que hoy estamos tan familiarizados.</p>
<h2>¿Entonces qué pasó? ¿Cuándo el naranja se convirtió en el color preferido?</h2>
<p>Fueron los holandeses durante el siglo XVII quienes cultivaron e hicieron popular la variedad naranja, probablemente debido a su color brillante y niveles más altos de betacaroteno. También se ha sugerido que fueron cultivadas en homenaje a William de Orange, quien dirigió la lucha durante la batalla holandesa por la independencia.</p>
<p>Por la razón que sea, la versión naranja se ha convertido en la variedad dominante, pero busque variedades &lsquo;tradicionales&rsquo; en los mercados de agricultores y en las tiendas de abarrotes, su mezcla de púrpura, amarillo, naranja y blanco son especialmente atractivas para cocinar y se ven muy bien como guarnición.</p>
<h2>Nutrición</h2>
<p>Zanahorias son ricas en betacaroteno que su cuerpo convierte en vitamina A. A menudo es difícil saber si cocinar verduras aumentará o reducirá su valor nutritivo y, lamentablemente, no hay una regla simple. Pero en el caso de las zanahorias, la nutrición se potencia al consumirlas cocidas. De hecho, solo se necesitan 100 gramos de zanahorias para obtener más que su valor diario de vitamina A.</p>
<h2>Consígalas en su mejor momento</h2>
<p>Las zanahorias jóvenes, cosechadas cuando son pequeñas, tienen un sabor especialmente dulce y son absolutamente deliciosas. Para cocinarlos, puede saltearlos y simplemente lavarlos y cocerlos al vapor durante unos minutos. Las zanahorias sabrán mejor cuando están frescas, así que asegúrese de que sean firmes y de colores brillantes cuando las compre.</p>
<h2>¿Y eso de las zanahorias que te ayudan a ver mejor en la oscuridad?</h2>
<p>Por supuesto que es un mito. Durante la Segunda Guerra Mundial, el Ministerio de Alimentos del Reino Unido promocionó las zanahorias como un vegetal súper saludable que mejoraría su capacidad para ver durante los apagones y como una explicación para las misiones nocturnas exitosas de los pilotos de caza del Reino Unido. En realidad, la única verdad en la conexión entre las zanahorias y la vista mejorada de los ojos es que la vitamina A sí ayuda a mantener la visión.</p>

View File

@@ -0,0 +1,18 @@
<p>¿Tener un cóctel? Entonces, ¿por qué no ofrecer algo tan especial para aquellos que no beben alcohol pero quieren unirse a la diversión? Después de todo, ¿qué cóctel está completo sin esos increíbles vasos de frutas mixtas, colores brillantes y, por supuesto, las pequeñas sombrillas? Haga su esfuerzo por el medio ambiente tirando las pajitas de plástico y adquiera algunas alternativas de gran apariencia, hechas de vidrio, metal o incluso bambú. No se olvide de las clásicas copas de cóctel y los modernos vasos para dar vida a estas recetas.</p>
<p>Entonces, tome la batidora, sáltese los espíritus y mezcle estos cócteles sin alcohol deliciosamente refrescantes que no le dejarán a usted ni a sus invitados, carentes de sabor o estilo.</p>
<h2>Mango-licious</h2>
<p>Esta deliciosa bebida tiene un sabor sofisticado que es ideal para adultos y su color es perfecto para una barbacoa al final del verano.</p>
<h3>Instrucciones:</h3>
<p>Dale unas rodajas de pepino y un poco de miel en una coctelera. Agregue una medida de espíritu de puré de mango y el jugo de una lima. Añadir un poco de hielo y agitar para todo lo que vales. Usando un colador, vierta en un vaso de lujo y cubra con cerveza de jengibre. Unas pocas rodajas de limón y ya está listo para ir.</p>
<h2>Mocky Mojito</h2>
<p>No hay nada como un Mojito en un día caluroso y esta versión es ideal para un relajante momento de felicidad en el jardín.</p>
<h3>Instrucciones:</h3>
<p>Mezcle azúcar, un poco de limón y hojas de menta en un vaso alto, luego agregue unos trozos de hielo, cubra con el jugo de una naranja sanguínea (para el efecto de la puesta del sol) y agregue un chorrito de agua de soda. Agrega unas cuantas ramitas de menta para un look auténtico.</p>
<h2>Fresa Sin Pecado Martini</h2>
<p>Las fresas agregan un hermoso y rico rojo a esta cola de burla, mientras que el jengibre le da una pequeña patada. Servir en un vaso de martini adecuado, pero tal vez evitar las aceitunas.</p>
<h3>Instrucciones:</h3>
<p>Mezcle una fresa con un guión, una cerveza de jengibre y un poco de jarabe de azúcar en una coctelera. Añadir una tapa llena de flor de saúco y unas cuantas hojas de menta. Poner una rodaja de naranja y limón y agitar con hielo. Cuela en tu copa y disfruta del dulce sabor a fresa.</p>
<h2>Reina del Coco</h2>
<p>Loca por los cocos? Entonces te encantará el sabor refrescante de este cóctel a base de coco. Los sabores dan un toque tropical, mientras que el aspecto es la sofisticación del adulto.</p>
<h3>Instrucciones:</h3>
<p>Agregue pepinos en rodajas, el jugo de una lima o dos, y algunas hojas de menta a una jarra de agua de coco y deje enfriar e infundir durante unas horas en la nevera. También puedes agregar un poco de azúcar si te apetece este dulce. Para servir vierte en vasos llenos de hielo con rodajas de pepino y hojas de menta. Sencilla y hermosa.</p>

View File

@@ -0,0 +1,16 @@
<p>Puede que esto no le sorprenda, pero su supermercado es un hervidero de marketing caótico diseñado para mejorar sus ganancias y para alentar al consumidor a gastar más de lo que pretendía. Los trucos que emplean todos los supermercados son a veces tácticas sensatas que cualquier minorista debería hacer para mejorar las ventas, pero algunas de ellas pueden ser más sutiles y menos obvias de lo que cree.</p>
<p>Debido a los artículos y los documentales de sensibilización, los consumidores retoman este tema con frecuencia y es probable que a los minoristas les resulte más difícil salirse con la suya usando solamente los trucos más obvios. Nos estamos convirtiendo en unos consumidores cada vez más inteligentes y probablemente no hay muchas cosas que nos sorprendan. Pero aquí hay algunos trucos para la venta al por menor que debe tener en cuenta cuando se apresura a realizar la compra semanal en el supermercado.</p>
<h2>Productos esenciales escondidos</h2>
<p>La distribución de su supermercado puede tener mucho sentido para usted cuando lleva comprando ahí un tiempo, pero para los nuevos clientes que están intentando encontrar los productos esenciales puede que no tenga ningún sentido. Algunos supermercados han notado como la gente que viene a su tienda a comprar leche, pan o huevos y que, ocultando esos productos esenciales en esquinas recónditas de la tienda, los animan a deambular por ella mientras añaden a la cesta otros productos antes de irse.</p>
<p>Por supuesto, esto puede ser genial para recordar productos esenciales que de otra forma olvidaría, pero no lo es si lo que quiere es ahorrar unas monedas y solo comprar las cosas a por las que vino, y eso lo los supermercados lo saben.</p>
<blockquote>
Nuestro consejo: Realice la lista de la compra antes de salir de casa, revisando que necesita y marcándolo en la lista. Le sorprenderá lo que ahorra con el tiempo.
</blockquote>
<h2>Descuentos por número</h2>
<p>Compre uno y llévese otro gratis; dos por 2&pound; y ofertas en comida. Todo esto descuentos parecen una buena oportunidad, pero en algunos casos son productos vendidos a pérdidas con el único objetivo de atraerle y que compre más cosas mientras está allí. En otros casos, las ofertas para múltiples productos o packs de tamaño específico pueden parecer una ganga hasta que se comparan los precios con marcas similares u otros tamaños de la misma marca. Estos descuentos pueden hacerle pensar que paga menos pero es menos por algo que no necesita e incluso puede terminar pagando más por el artículo. Recuerde, los supermercados saben que a menudo tiene prisa y no tiene tiempo suficiente de considerar la imagen completa del producto.</p>
<blockquote>
<p>Nuestro consejo: No se apresure y tómese el tiempo necesario para leer la letra pequeña. La letra grande le atraerá pero en la letra pequeña encontrará el precio por cada 100g de producto o el precio por litro y se sorprenderá de la de veces que no existe tal oferta o incluso que es más caro que el paquete pequeño.</p>
</blockquote>
<h2>Entendiendo nuestros hábitos de compra</h2>
<p>Los productos más baratos del supermercado casi siempre se colocan en la parte baja de las estanterías, donde tendrá que agacharse para tomarlos. También es posible que no pueda leer fácilmente el precio en el ticket. La mayoría de la gente selecciona los productos de la parte media de las estanterías dado que es más fácil y rápido. Esos productos son los que tienen mayores beneficios y son los que el supermercado quiere que compre.</p>
<p>La distribución de música, colores y tipos de productos está decidido en base a unos principios establecidos por expertos en personas: psicólogos y expertos en comportamiento que saben cómo pensamos. Y así, el comprador inteligente sin duda podrá aprovechar las grandes ofertas en su tienda semanal, pero se necesita un poco de tiempo y esfuerzo para ser más conscientes de lo que se nos incita a escoger en los pasillos.</p>

View File

@@ -0,0 +1,7 @@
<p>Creemos que las setas son uno de los ingredientes que más se pueden disfrutar en la cocina. Hay muchas variedades comestibles para probar, cada una con su propia forma, tamaño y sabor distintivos. Y con curiosos nombres como rebozuelo, seta gitana, trompeta de los muertos o frigola frondosa ¿quién no querría saber más sobre cocinar con las poderosas setas?</p>
<p>Una de las mejoras cosas que tienen las setas son su versatilidad. Pueden ser fritas, tostadas, asadas al horno oa la parrilla e incluso cocinadas en un microondas. Y pueden ser servidas como ingrediente principal del plato como parte de un conjunto mayor. Esto hace a las setas una opción ideal para crear simples y deliciosos platos vegetarianos.</p>
<p>Así que echemos un vistazo a algunos de nuestros tipos preferidos de setas. Es posible que no hayas intentado cocinar con ellas antes, pero no dejes que eso te desanime. Con sus deliciosos y particulares sabores puedes transformar fácilmente sopas, entrantes, salsas y crear increíbles platos de pasta o salteados.</p>
<p>Prueba el adorable <strong>shiitake</strong>. Usadas en la cocina asiática, pueden comprarse secos y rehidratados para obtener un sabor fuerte y profundo. O comprarlo fresco y añadirlo a sopas y sofritos. No solo es una seta de intenso sabor, sino también de encantadora apariencia. Las formas de color marrón oscuro y suave proporcionarán textura a su comida. En su forma rehidratada son el complemento perfecto para un caldo o un risotto.</p>
<p>La hermosa <strong>rebozuelo</strong> (o chantarela) con su pulpa amarilla, tiene un sabor afrutado, pero vale la pena mencionar que hay muchas variedades parecidas por ahí y se ha de tener cuidado para asegurarse de que se está comiendo la correcta. Quedan muy bien en una tortilla o una sopa asiática para complementar los tonos amarillos.</p>
<p>La <strong>morchella</strong> (o morilla) marrón ofrece un sabor carnoso y distintivo y probablemente te encantará lo extraordinaria que se ve en una comida. La morchella es una seta más popular durante la primavera, que es cuando su disponibilidad es más alta.</p>
<p>Para algo delicado, pruebe la <strong>enoki</strong>, con sus diminutas cabezas blancas que crecen en un montón. Incluso se pueden comer crudas en ensaladas. Por último, puedes elegir la popular seta <strong>ostra</strong>. Se nombran porque no se parecen en nada a una seta y se asemejan a las entrañas de una ostra y su sabor dulce es delicioso.</p>

View File

@@ -0,0 +1,3 @@
id,uuid,info,type,field_title,content_type,node_id,field_content_link_title,field_summary,image_reference
umami_home_banner,9aadf4a1-ded6-4017-a10d-a5e043396edf,Umami Casa Pancarta,banner_block,Pasta vegetariana horneada súper fácil,recipe,3,Ver receta,Una pasta al horno es la comida más reconfortante que hay. Este plato al horno es súper rápido de preparar y es ideal para cocinar entre semana para toda la familia.,18
umami_recipes_banner,4c7d58a3-a45d-412d-9068-259c57e40541,Umami Recetas Pancarta,banner_block,Brownies Veganos de Chocolate y Nuez,recipe,2,Ver receta,Estos exquisitos brownies quedarán sabrosos por dentro y crujientes por fuera. ¡La tentación perfecta!,20
1 id uuid info type field_title content_type node_id field_content_link_title field_summary image_reference
2 umami_home_banner 9aadf4a1-ded6-4017-a10d-a5e043396edf Umami Casa Pancarta banner_block Pasta vegetariana horneada súper fácil recipe 3 Ver receta Una pasta al horno es la comida más reconfortante que hay. Este plato al horno es súper rápido de preparar y es ideal para cocinar entre semana para toda la familia. 18
3 umami_recipes_banner 4c7d58a3-a45d-412d-9068-259c57e40541 Umami Recetas Pancarta banner_block Brownies Veganos de Chocolate y Nuez recipe 2 Ver receta Estos exquisitos brownies quedarán sabrosos por dentro y crujientes por fuera. ¡La tentación perfecta! 20

View File

@@ -0,0 +1,2 @@
id,uuid,info,type,field_disclaimer,field_copyright
umami_disclaimer,9b4dcd67-99f3-48d0-93c9-2c46648b29de,"Aviso Legal Umami",disclaimer_block,"<strong>Revista Umami y Publicaciones Umami</strong> es una revista ficticia publicada con propósito ilustrativo sólamente.","Términos y Condiciones"
1 id uuid info type field_disclaimer field_copyright
2 umami_disclaimer 9b4dcd67-99f3-48d0-93c9-2c46648b29de Aviso Legal Umami disclaimer_block <strong>Revista Umami y Publicaciones Umami</strong> es una revista ficticia publicada con propósito ilustrativo sólamente. Términos y Condiciones

View File

@@ -0,0 +1,2 @@
id,uuid,info,type,field_title,content_type,node_id,field_content_link_title,field_summary,image_reference
umami_footer_promo,924ab293-8f5f-45a1-9c7f-2423ae61a241,Umami Pie de Pagina Promocional,footer_promo_block,Revista de Comida Umami,page,1,Más información,"Trucos y consejos. Artículos exclusivos de la revista, recetas y una variedad de razones para conseguir tu copia hoy.",19
1 id uuid info type field_title content_type node_id field_content_link_title field_summary image_reference
2 umami_footer_promo 924ab293-8f5f-45a1-9c7f-2423ae61a241 Umami Pie de Pagina Promocional footer_promo_block Revista de Comida Umami page 1 Más información Trucos y consejos. Artículos exclusivos de la revista, recetas y una variedad de razones para conseguir tu copia hoy. 19

View File

@@ -0,0 +1,22 @@
id,title,image,alt,author
1,Quiche mediterráneo profundo,mediterranean-quiche-umami.jpg,Un delicioso quiche mediterráneo de capas profundas con guarnición de albahaca.,Umami
2,Bizcochos veganos de chocolate y nueces,vegan-chocolate-nut-brownies.jpg,"Una pila de brownies de chocolate y nuez, rociados con migas de nuez y nuez triturada, recién sacados del horno",Umami
3,Pasta vegetariana al horno súper fácil,veggie-pasta-bake-umami.jpg,Plato de pasta con salchichas vegetarianas y cubierto con queso mozzarella y albahaca,Umami
4,Sopa de berro,watercress-soup-umami.jpg,Sopa de berros con una ramita de cilantro como guarnición en un tazón blanco con borde verde.,Umami
5,Pastel Victoria,victoria-sponge-umami.jpg,"Una esponja Victoria clásica, sin cortar, con un relleno profundo de crema de mantequilla y mermelada",Umami
6,Pizza sin gluten,pizza-umami.jpg,"Aceitunas, albahaca y mozzarella cubren una masa de pizza sin gluten con salsa de tomate.",Umami
7,Curry verde tailandés,thai-green-curry-umami.jpg,"Un tazón tradicional de curry verde tailandés aromático y cremoso, con trozos de pollo y verduras.",Umami
8,Crema catalana,crema-catalana-umami.jpg,"Postre típico catalán hecho de crema y yemas de huevo, cubierto con una capa tradicional de azúcar caramelizado para proporcionar un contraste crujiente.",Umami
9,Salsa de chile ardiente,chili-sauce-umami.jpg,"Una variedad iridiscente de chiles, cebollas y ajo, que suda lentamente a fuego lento",Umami
10,Prueba y cultiva tus propias hierbas,home-grown-herbs.jpg,"Hierbas frescas cortadas incluyendo menta, perejil, tomillo y eneldo.",Holly Foat
11,Delicioso chocolate sin lactosa,vegan-chocolate.jpg,Deliciosa tableta de chocolate con leche sin lactosa partido en onzas.,Umami
12,El verdadero negocio para comprar en el supermercado,supermarket-savvy-umami.jpg,Verduras de hoja verde presentadas en la estantería del supermercado.,Megan Collins Quinlan
13,Guía Umami de nuestras setas preferidas,mushrooms-umami.jpg,Una deliciosa selección de variedades de setas distribuidas en un sencillo plato de madera.,Umami
14,Un aplauso para las zanahorias,heritage-carrots.jpg,"Zanahorias moradas, naranjas, amarillas y blancas.",Umami
15,Percances al hornear - nuestros consejos para solucionar los problemas,chocolate-brownie-umami.jpg,Un delicioso brownie de chocolate,Umami
16,Salta los espíritus con deliciosos cócteles sin alcohol,mojito-mocktail.jpg,"Mocktail de mojito fresco con guarnición de hojas de menta, hielo y lima en rodajas",Megan Collins Quinlan
17,Dale a tu avena el cambio de imagen definitivo,oatmeal-fruit-syrup-topping.jpg,"Avena con una mezcla vibrante de bayas, nueces y semillas",Umami
18,Pasta vegetariana al horno con una rica salsa de tomate cubierta de queso que hará que se te haga la boca agua.,veggie-pasta-bake-hero-umami.jpg,Pasta vegetariana al horno con una rica salsa de tomate cubierta de queso que hará que se te haga la boca agua.,Umami
19,Paquete de 3 ediciones de la revista de comida Umami,umami-bundle.png,Paquete de 3 ediciones de la revista de comida Umami,Umami
20,(Hero) Bizcochos veganos de chocolate y nueces,vegan-brownies-hero-umami.jpg,"Una pila de brownies de chocolate y nuez, rociados con migas de nuez y nuez triturada, recién sacados del horno",Umami
21,Borscht con costillas de cerdo,borscht-with-pork-ribs-umami.jpg,"Sopa tradicional ucraniana de remolacha, tomates y costillas de cerdo",Umami
1 id title image alt author
2 1 Quiche mediterráneo profundo mediterranean-quiche-umami.jpg Un delicioso quiche mediterráneo de capas profundas con guarnición de albahaca. Umami
3 2 Bizcochos veganos de chocolate y nueces vegan-chocolate-nut-brownies.jpg Una pila de brownies de chocolate y nuez, rociados con migas de nuez y nuez triturada, recién sacados del horno Umami
4 3 Pasta vegetariana al horno súper fácil veggie-pasta-bake-umami.jpg Plato de pasta con salchichas vegetarianas y cubierto con queso mozzarella y albahaca Umami
5 4 Sopa de berro watercress-soup-umami.jpg Sopa de berros con una ramita de cilantro como guarnición en un tazón blanco con borde verde. Umami
6 5 Pastel Victoria victoria-sponge-umami.jpg Una esponja Victoria clásica, sin cortar, con un relleno profundo de crema de mantequilla y mermelada Umami
7 6 Pizza sin gluten pizza-umami.jpg Aceitunas, albahaca y mozzarella cubren una masa de pizza sin gluten con salsa de tomate. Umami
8 7 Curry verde tailandés thai-green-curry-umami.jpg Un tazón tradicional de curry verde tailandés aromático y cremoso, con trozos de pollo y verduras. Umami
9 8 Crema catalana crema-catalana-umami.jpg Postre típico catalán hecho de crema y yemas de huevo, cubierto con una capa tradicional de azúcar caramelizado para proporcionar un contraste crujiente. Umami
10 9 Salsa de chile ardiente chili-sauce-umami.jpg Una variedad iridiscente de chiles, cebollas y ajo, que suda lentamente a fuego lento Umami
11 10 Prueba y cultiva tus propias hierbas home-grown-herbs.jpg Hierbas frescas cortadas incluyendo menta, perejil, tomillo y eneldo. Holly Foat
12 11 Delicioso chocolate sin lactosa vegan-chocolate.jpg Deliciosa tableta de chocolate con leche sin lactosa partido en onzas. Umami
13 12 El verdadero negocio para comprar en el supermercado supermarket-savvy-umami.jpg Verduras de hoja verde presentadas en la estantería del supermercado. Megan Collins Quinlan
14 13 Guía Umami de nuestras setas preferidas mushrooms-umami.jpg Una deliciosa selección de variedades de setas distribuidas en un sencillo plato de madera. Umami
15 14 Un aplauso para las zanahorias heritage-carrots.jpg Zanahorias moradas, naranjas, amarillas y blancas. Umami
16 15 Percances al hornear - nuestros consejos para solucionar los problemas chocolate-brownie-umami.jpg Un delicioso brownie de chocolate Umami
17 16 Salta los espíritus con deliciosos cócteles sin alcohol mojito-mocktail.jpg Mocktail de mojito fresco con guarnición de hojas de menta, hielo y lima en rodajas Megan Collins Quinlan
18 17 Dale a tu avena el cambio de imagen definitivo oatmeal-fruit-syrup-topping.jpg Avena con una mezcla vibrante de bayas, nueces y semillas Umami
19 18 Pasta vegetariana al horno con una rica salsa de tomate cubierta de queso que hará que se te haga la boca agua. veggie-pasta-bake-hero-umami.jpg Pasta vegetariana al horno con una rica salsa de tomate cubierta de queso que hará que se te haga la boca agua. Umami
20 19 Paquete de 3 ediciones de la revista de comida Umami umami-bundle.png Paquete de 3 ediciones de la revista de comida Umami Umami
21 20 (Hero) Bizcochos veganos de chocolate y nueces vegan-brownies-hero-umami.jpg Una pila de brownies de chocolate y nuez, rociados con migas de nuez y nuez triturada, recién sacados del horno Umami
22 21 Borscht con costillas de cerdo borscht-with-pork-ribs-umami.jpg Sopa tradicional ucraniana de remolacha, tomates y costillas de cerdo Umami

View File

@@ -0,0 +1,9 @@
id,title,body,author,slug,image_reference,tags
1,Prueba y cultiva tus propias hierbas,give-it-a-go-and-grow-your-own-herbs.html,Holly Foat,articles/prueba-y-cultiva-tus-propias-hierbas,10,"14,23,16"
2,Delicioso chocolate sin lactosa,dairy-free-delicious-milk-chocolate.html,Umami,articles/delicioso-chocolate-sin-lactosa,11,"27,7"
3,El verdadero negocio para comprar en el supermercado,the-real-deal-for-supermarket-savvy-shopping.html,Gregorio Sánchez,articles/el-verdadeo-negocio-para-comprar-en-el-supermercado,12,"26,24"
4,Guía Umami de nuestras setas preferidas,the-umami-guide-to-our-favourite-mushrooms.html,Umami,articles/guia-umami-de-nuestras-setas-preferidas,13,"18,28"
5,Un aplauso para las zanahorias,lets-hear-it-for-carrots.html,Umami,articles/un-aplauso-para-las-zanahorias,14,"6,28,15"
6,Percances al hornear - nuestros consejos para solucionar los problemas,baking-mishaps-our-troubleshooting-tips.html,Umami,articles/percances-al-hornear-nuestros-consejos-para-solucionar-problemas,15,"3,17"
7,Salta los espíritus con deliciosos cócteles sin alcohol,skip-the-spirits-with-delicious-mocktails.html,Gregorio Sánchez,articles/salta-los-espiritus-con-deliciosos-cocteles-sin-alcohol,16,"1,12,20,8,11"
8,Dale a tu avena el cambio de imagen definitivo,give-your-oatmeal-the-ultimate-makeover.html,Umami,articles/dale-a-tu-avena-el-cambio-de-imagen-definitivo,17,"27,28,19,4,10"
1 id title body author slug image_reference tags
2 1 Prueba y cultiva tus propias hierbas give-it-a-go-and-grow-your-own-herbs.html Holly Foat articles/prueba-y-cultiva-tus-propias-hierbas 10 14,23,16
3 2 Delicioso chocolate sin lactosa dairy-free-delicious-milk-chocolate.html Umami articles/delicioso-chocolate-sin-lactosa 11 27,7
4 3 El verdadero negocio para comprar en el supermercado the-real-deal-for-supermarket-savvy-shopping.html Gregorio Sánchez articles/el-verdadeo-negocio-para-comprar-en-el-supermercado 12 26,24
5 4 Guía Umami de nuestras setas preferidas the-umami-guide-to-our-favourite-mushrooms.html Umami articles/guia-umami-de-nuestras-setas-preferidas 13 18,28
6 5 Un aplauso para las zanahorias lets-hear-it-for-carrots.html Umami articles/un-aplauso-para-las-zanahorias 14 6,28,15
7 6 Percances al hornear - nuestros consejos para solucionar los problemas baking-mishaps-our-troubleshooting-tips.html Umami articles/percances-al-hornear-nuestros-consejos-para-solucionar-problemas 15 3,17
8 7 Salta los espíritus con deliciosos cócteles sin alcohol skip-the-spirits-with-delicious-mocktails.html Gregorio Sánchez articles/salta-los-espiritus-con-deliciosos-cocteles-sin-alcohol 16 1,12,20,8,11
9 8 Dale a tu avena el cambio de imagen definitivo give-your-oatmeal-the-ultimate-makeover.html Umami articles/dale-a-tu-avena-el-cambio-de-imagen-definitivo 17 27,28,19,4,10

View File

@@ -0,0 +1,2 @@
id,title,body,author,slug
1,Acerca de Umami,"<p> Umami es una revista ficticia de alimentos que se ha creado para demostrar cómo se puede construir un sitio de Drupal con la funcionalidad que se proporciona 'fuera de la caja'. </p> <p> Para obtener más información, visite <a href='https://www.drupal.org/docs/umami-drupal-demonstration-installation-profile'>https://www.drupal.org/docs/umami-drupal-demonstration-installation-profile</a>.</p> ",Samuel Adamson,acerca-de-umami
1 id title body author slug
2 1 Acerca de Umami <p> Umami es una revista ficticia de alimentos que se ha creado para demostrar cómo se puede construir un sitio de Drupal con la funcionalidad que se proporciona 'fuera de la caja'. </p> <p> Para obtener más información, visite <a href='https://www.drupal.org/docs/umami-drupal-demonstration-installation-profile'>https://www.drupal.org/docs/umami-drupal-demonstration-installation-profile</a>.</p> Samuel Adamson acerca-de-umami

View File

@@ -0,0 +1,11 @@
id,title,image_reference,summary,author,recipe_category,preparation_time,cooking_time,total_time,difficulty,ingredients,recipe_instruction,number_of_servings,tags,slug
1,Quiche mediterráneo profundo,1,Un quiche de inspiración italiana con tomates secos y calabacín. Una comida ligera perfecta para un día de verano.,Umami,3,40,30,70,medium,"Para la masa:,280g harina normal,140g mantequilla,Agua fría,Para el relleno:,1 cebolla,2 dientes ajo,Medio calabación,450ml leche de soja,500g queso parmesano,2 huevos,200g tomate deshidratado,100g queso feta",mediterranean-quiche-umami.html,8,"22,13",recipes/quiche-mediterráneo-profundo
2,Bizcochos veganos de chocolate y nueces,2,Exquisitos brownies veganos de chocolate con nueces. Estas delicias contienen un toque de coco haciéndolos el placer perfecto. Servir calientes acompañados de un poco de helado de vainilla sin lactosa.,Umami,4,20,20,40,medium,"72g aceite de girasol, 80g de chocolate negro vegano, 170g de harina, 80g de harina de coco, 4g de levadura, 36g de cacao en polvo, 100g de azúcar en polvo, 45g de sirope de arce, 1g cucharadita de sal marina, 5g de extracto de vainilla, 230ml de leche de soja orgánica sin edulcorar, 100g de nueces pecanas, 80g de nueces",vegan-chocolate-nut-brownies.html,12,"3,7,27,9",recipes/bizcochos-veganos-de-chocolate-y-nueces
3,Pasta vegetariana al horno súper fácil,3,Una pasta al horno es la comida más fácil y saludable. Este delicioso plato es súper rápido de preparar y una comida ideal entre semana para toda la familia.,Umami,3,5,20,25,easy,"400g pasta de trigo integral, 1 cebolla, 2 dientes de ajo, 1 paquete de salchichas vegetarianas, 400g tomates picados, 50g rodajas de tomates secados al sol, 1 pizca de azúcar, 45g pesto rojo, 50g queso cheddar, Albahaca o hierbas mixtas, 100g queso mozzarella",veggie-pasta-bake-umami.html,4,"28,21,2",recipes/pasta-vegetariana-horno-super-facil
4,Sopa de berro,4,"Una sopa maravillosamente simple y ligera, que aprovecha al máximo los productos locales de temporada.",Umami,5,10,20,30,easy,"3 racimos de berros,3 patatas,3 cebollas,2 puerros,800ml de caldo,75g de crème fraîche",watercress-soup-umami.html,4,"25,28",recipes/sopa-de-berro
5,Pastel Victoria,5,"Un tradicional bizcocho Victoria, perfecto para cualquier tarde con una taza de té.",Umami,2,20,20,40,easy,"225g mantequilla o margarina,225g azúcar en polvo,225g harina autoniveladora,4 huevos,1 cucharadita polvo de hornear,3 cucharadas mermelada para el relleno,Azúcar glas para espolvorear la parte superior,Crema para servir",victoria-sponge-umami.html,10,5,recipes/pastel-victoria
6,Pizza sin gluten,6,"Una vistosa y simple pizza sin gluten, con deliciosa mozzarella y jamón de Parma. Puede convertirse fácilmente en vegetariana si quitamos el jamón.",Umami,3,15,15,30,,"400g de harina sin gluten, 125ml de agua caliente, 125ml de Leche, 1 de bolsita levadura, 12g de azúcar, 6g de Sal, 32g de aceite de oliva, 75g de tomate triturado, 1 diente de ajo, Albahaca fresca, 200g de mozzarella, 100g de rúcula, 5 lonchas de jamón de Parma",pizza-umami.html,4,,recipes/pizza-sin-gluten
7,Curry verde tailandés,7,Una versión rápida y fácil del clásico curry verde tailandés. ¡Perfecto para una comida entre semana!,Umami,3,10,15,25,,"400g de leche de coco, 400g de pollo o tofu, 15g de pasta de curry verde tailandés, 1 diente de ajo, 10g de salsa de pescado, 400g de champiñones, 200g de judías verdes, Hojas de cilantro fresco, Arroz jazmín",thai-green-curry-umami.html,4,,recipes/curry-verde-tailandes
8,Crema catalana,8,Disfruta de esta dulce receta de uno de los postres más antiguos de Europa. ¡Requiere muy pocos ingredientes!,Umami,2,10,20,30,,"1l de Leche, 200g de azúcar, 6 yemas de huevo, 30g de Maizena, 1 rama de canela, 1 La piel de un limón",crema-catalana-umami.html,8,"13,28",recipes/crema-catalana
9,Salsa de chile ardiente,9,Una rica y ardiente salsa de chile. Tenga cuidado al manejar chiles. ¡Y servir con moderación!,Umami,1,10,50,60,easy,"2 cebollas rojas, 1 limón, 2 limas, 250ml vinagre de malta, 7 dientes de ajo, 1 pimiento verde, 1 pimiento rojo, 800g tomates cherry, 30 chiles mezclados, Aceite de oliva, 1 cucharada pimienta negra molida, 1 cucharada azúcar morena",chili-sauce-umami.html,60,28,recipes/salsa-de-chile-ardiente
10,Borscht con costillas de cerdo,21,"Puedo hablar de borscht todo el día. Cada familia ucraniana tiene su receta: con frijoles, sin repollo, etc. Sin embargo, todas son válidas: no existe una receta 'correcta' unificada. La receta que está a punto de leer y cocinar es borscht con costillas de cerdo. Disfrútala. ¡Este plato le hará sentir una verdadera alma ucraniana!",Umami,1,30,60,90,medium,"400-500g de costillas de cerdo, 2 remolachas, 2 tomates, ¼ de raíz de apio, ¼ de repollo, 3-4 patatas medianas, 1 zanahoria, 1 cebolla, 1-2 peras ahumadas, 2 hojas de laurel, 3 guisantes de pimienta de Jamaica, 1 cabeza de ajo, 1 pimiento morrón, 200ml de jugo de tomate, 30g de mantequilla, 2 cucharadas de pasta de tomate, 3l de agua, Crema agria, 1 lata de alubias, Sal al gusto",borscht-with-pork-ribs-umami.html,8,25,recipes/borscht-con-costillas-de-cerdo
1 id title image_reference summary author recipe_category preparation_time cooking_time total_time difficulty ingredients recipe_instruction number_of_servings tags slug
2 1 Quiche mediterráneo profundo 1 Un quiche de inspiración italiana con tomates secos y calabacín. Una comida ligera perfecta para un día de verano. Umami 3 40 30 70 medium Para la masa:,280g harina normal,140g mantequilla,Agua fría,Para el relleno:,1 cebolla,2 dientes ajo,Medio calabación,450ml leche de soja,500g queso parmesano,2 huevos,200g tomate deshidratado,100g queso feta mediterranean-quiche-umami.html 8 22,13 recipes/quiche-mediterráneo-profundo
3 2 Bizcochos veganos de chocolate y nueces 2 Exquisitos brownies veganos de chocolate con nueces. Estas delicias contienen un toque de coco haciéndolos el placer perfecto. Servir calientes acompañados de un poco de helado de vainilla sin lactosa. Umami 4 20 20 40 medium 72g aceite de girasol, 80g de chocolate negro vegano, 170g de harina, 80g de harina de coco, 4g de levadura, 36g de cacao en polvo, 100g de azúcar en polvo, 45g de sirope de arce, 1g cucharadita de sal marina, 5g de extracto de vainilla, 230ml de leche de soja orgánica sin edulcorar, 100g de nueces pecanas, 80g de nueces vegan-chocolate-nut-brownies.html 12 3,7,27,9 recipes/bizcochos-veganos-de-chocolate-y-nueces
4 3 Pasta vegetariana al horno súper fácil 3 Una pasta al horno es la comida más fácil y saludable. Este delicioso plato es súper rápido de preparar y una comida ideal entre semana para toda la familia. Umami 3 5 20 25 easy 400g pasta de trigo integral, 1 cebolla, 2 dientes de ajo, 1 paquete de salchichas vegetarianas, 400g tomates picados, 50g rodajas de tomates secados al sol, 1 pizca de azúcar, 45g pesto rojo, 50g queso cheddar, Albahaca o hierbas mixtas, 100g queso mozzarella veggie-pasta-bake-umami.html 4 28,21,2 recipes/pasta-vegetariana-horno-super-facil
5 4 Sopa de berro 4 Una sopa maravillosamente simple y ligera, que aprovecha al máximo los productos locales de temporada. Umami 5 10 20 30 easy 3 racimos de berros,3 patatas,3 cebollas,2 puerros,800ml de caldo,75g de crème fraîche watercress-soup-umami.html 4 25,28 recipes/sopa-de-berro
6 5 Pastel Victoria 5 Un tradicional bizcocho Victoria, perfecto para cualquier tarde con una taza de té. Umami 2 20 20 40 easy 225g mantequilla o margarina,225g azúcar en polvo,225g harina autoniveladora,4 huevos,1 cucharadita polvo de hornear,3 cucharadas mermelada para el relleno,Azúcar glas para espolvorear la parte superior,Crema para servir victoria-sponge-umami.html 10 5 recipes/pastel-victoria
7 6 Pizza sin gluten 6 Una vistosa y simple pizza sin gluten, con deliciosa mozzarella y jamón de Parma. Puede convertirse fácilmente en vegetariana si quitamos el jamón. Umami 3 15 15 30 400g de harina sin gluten, 125ml de agua caliente, 125ml de Leche, 1 de bolsita levadura, 12g de azúcar, 6g de Sal, 32g de aceite de oliva, 75g de tomate triturado, 1 diente de ajo, Albahaca fresca, 200g de mozzarella, 100g de rúcula, 5 lonchas de jamón de Parma pizza-umami.html 4 recipes/pizza-sin-gluten
8 7 Curry verde tailandés 7 Una versión rápida y fácil del clásico curry verde tailandés. ¡Perfecto para una comida entre semana! Umami 3 10 15 25 400g de leche de coco, 400g de pollo o tofu, 15g de pasta de curry verde tailandés, 1 diente de ajo, 10g de salsa de pescado, 400g de champiñones, 200g de judías verdes, Hojas de cilantro fresco, Arroz jazmín thai-green-curry-umami.html 4 recipes/curry-verde-tailandes
9 8 Crema catalana 8 Disfruta de esta dulce receta de uno de los postres más antiguos de Europa. ¡Requiere muy pocos ingredientes! Umami 2 10 20 30 1l de Leche, 200g de azúcar, 6 yemas de huevo, 30g de Maizena, 1 rama de canela, 1 La piel de un limón crema-catalana-umami.html 8 13,28 recipes/crema-catalana
10 9 Salsa de chile ardiente 9 Una rica y ardiente salsa de chile. Tenga cuidado al manejar chiles. ¡Y servir con moderación! Umami 1 10 50 60 easy 2 cebollas rojas, 1 limón, 2 limas, 250ml vinagre de malta, 7 dientes de ajo, 1 pimiento verde, 1 pimiento rojo, 800g tomates cherry, 30 chiles mezclados, Aceite de oliva, 1 cucharada pimienta negra molida, 1 cucharada azúcar morena chili-sauce-umami.html 60 28 recipes/salsa-de-chile-ardiente
11 10 Borscht con costillas de cerdo 21 Puedo hablar de borscht todo el día. Cada familia ucraniana tiene su receta: con frijoles, sin repollo, etc. Sin embargo, todas son válidas: no existe una receta 'correcta' unificada. La receta que está a punto de leer y cocinar es borscht con costillas de cerdo. Disfrútala. ¡Este plato le hará sentir una verdadera alma ucraniana! Umami 1 30 60 90 medium 400-500g de costillas de cerdo, 2 remolachas, 2 tomates, ¼ de raíz de apio, ¼ de repollo, 3-4 patatas medianas, 1 zanahoria, 1 cebolla, 1-2 peras ahumadas, 2 hojas de laurel, 3 guisantes de pimienta de Jamaica, 1 cabeza de ajo, 1 pimiento morrón, 200ml de jugo de tomate, 30g de mantequilla, 2 cucharadas de pasta de tomate, 3l de agua, Crema agria, 1 lata de alubias, Sal al gusto borscht-with-pork-ribs-umami.html 8 25 recipes/borscht-con-costillas-de-cerdo

View File

@@ -0,0 +1,11 @@
<ol>
<li>Precaliente el horno a 400°F/200°C, luego coloque las costillas de cerdo en su interior y hornéelas durante 30 min. Lave la raíz del apio, pero no la pele. Coja la zanahoria y córtela en trozos medianos.</li>
<li>Ponga las costillas de cerdo al horno en una olla y añada 3 litros de agua. Agregue la raíz de apio cortada y la zanahoria junto con la mitad de la cebolla sin pelar. Lleve la olla a ebullición. Después de eso, caliente a fuego medio y siga hirviendo durante 30 min.</li>
<li>El corazón del borscht son las verduras asadas previamente. Pique el pimiento morrón y haga lo mismo con los tomates y la cebolla. Coloque la mantequilla en una cacerola y agregue las verduras. Cocínelos a fuego moderado para ablandar los vegetales, luego agregue dos cucharadas de pasta de tomate, baje el fuego y siga guisándolos durante 5 a 7 minutos. Además, ralle una remolacha y póngala en la cacerola también y cocínelas todas juntas durante 3-4 minutos más.</li>
<li>Corte un diente de ajo por la mitad y agréguelo a la olla. Triture el repollo y déjelo a un lado para agregarlo más tarde.</li>
<li>Se necesita jugo de remolacha, así que tome la segunda remolacha y exprima todo el jugo. Si no tiene un exprimidor de jugo, puede rallar una remolacha y exprimirla a través del colador. Luego agregue el jugo junto con la pimienta de Jamaica, las hojas de laurel y varias pizcas de sal (a su gusto).</li>
<li>También puede agregar frijoles enlatados: es una adición opcional.</li>
<li>Ponga las peras ahumadas en una olla. Harán que el plato huela a humo.</li>
<li>Felicitaciones, nuestro borscht está casi listo. Ahora puede agregar repollo rallado y en cinco minutos puede dejar la olla a un lado del fuego. Guarde el borscht durante 30 minutos.</li>
</ol>
<p>Sirva el borscht junto con una cucharada de crema agria y eneldo picado. Ponga el resto del borscht en la nevera y recuerde que sabe mejor al día siguiente.</p>

View File

@@ -0,0 +1,14 @@
<ol>
<li>Precaliente el horno a 400°F/200°C.</li>
<li>Picar finamente las cebollas rojas y sudar suavemente a fuego lento en aceite de oliva durante 5 minutos.</li>
<li>Pelar el ajo y agregarlo a las cebollas.</li>
<li>Mientras tanto, picar los pimientos en trozos de 1 pulgada. Agregue los pimientos y los tomates a un plato para asar, y frote con jugo de limón, aceite de oliva y pimienta negra. Transferir al horno y asar por 30 minutos.</li>
<li>Una vez que las cebollas y el ajo se hayan ablandado, pique y agregue los chiles, las semillas y todo. Mezclar bien y continuar friendo suavemente.</li>
<li>Lávese bien las manos después de manipular los chiles crudos.</li>
<li>Una vez que los tomates y los pimientos hayan terminado de asarse, agréguelos a la sartén. Cocine por al menos 10 minutos, rompiéndolos con un triturador o una batidora de mano mientras se cocinan a fuego lento. Una vez roto, mezclar el azúcar.</li>
<li>Transfiera la salsa a una licuadora y mezcle hasta que quede suave.</li>
<li>Regresa a la sartén y agrega el vinagre y el jugo de las limas.</li>
<li>Cocine por otros 10 minutos, luego deje enfriar.</li>
<li>Transfiera a frascos esterilizados y manténgalos refrigerados.</li>
<li>Dejar por lo menos dos semanas antes de la degustación.</li>
</ol>

View File

@@ -0,0 +1,8 @@
<ol>
<li>Mezcle las yemas de huevo, el azúcar y la harina de maiz con ⅓ de la leche. En un cazo, hierve el resto de la leche con la ralladura de un limón y la canela.</li>
<li>Después de 3 minutos, aparte del fuego y quite el limón y la canela.</li>
<li>Ve añadiendo muy despacio la mezcla del huevo sobre la leche utilizando un colador para asegurarse que no hay grumos.</li>
<li>Coloque el cazo otra vez en el fuego y, sin dejar de remover, espere hasta que hierva.</li>
<li>Una vez que la mezcla ha empezado a espesar, apártalo del fuego y ponlo en recipientes individuales para que enfríe.</li>
<li>Para un resultado auténtico, esparza un poco de azúcar y caramelízalo con un soplete de cocina o bajo el gratinador del horno.</li>
</ol>

View File

@@ -0,0 +1,7 @@
<ol>
<li>Precaliente el horno a 200°C. Empezando por la pastelería; Frote la harina y la mantequilla en un tazón hasta que se desmoronen como migas de pan. Agregue el agua, poco a poco, hasta que forme una masa.</li>
<li>Extiende la masa sobre una tabla enharinada y extiende suavemente sobre tu molde. Coloque en la nevera durante 20 minutos antes de hornear a ciegas durante otros 10.</li>
<li>Mientras la masa se está enfriando, corte y cocine suavemente las cebollas, el ajo y el calabacín.</li>
<li>En un tazón grande, agregue la leche de soya, la mitad del queso parmesano y los huevos. Mezclar suavemente.</li>
<li>Una vez que la masa esté cocida, esparza las cebollas, el ajo y los tomates secos sobre la base y vierta la mezcla de los huevos. Espolvoree el queso parmesano restante y coloque cuidadosamente el feta sobre la parte superior. Hornear durante 30 minutos o hasta que estén doradas.</li>
</ol>

View File

@@ -0,0 +1,7 @@
<ol>
<li>Precaliente el horno a 425 ° F / 220 ° C. Mezcle un poco de la leche y el agua en un jarra. Agregue la levadura y el azúcar y apártalos.</li>
<li>Mezcle la harina, la sal y el aceite en un bol. Agregue lentamente el líquido de la jarra y forme una masa.</li>
<li>Rompa la masa por la mitad y dele forma de dos bases de pizza. Deje reposar durante unos 15 minutos, mientras hace la cobertura.</li>
<li>Extienda el tomate triturado sobre las bases de pizza, corte la albahaca y la rúcula y espolvoree sobre el tomate. Distribuya sobre la masa el jamón de Parma picado y agregue rebanadas gruesas de mozzarella por toda la pizza.</li>
<li>Hornee en la rejilla superior (con una bandeja debajo) de 10 a 12 minutos o hasta que la mozzarella esté burbujeando. Sazone con sal y pimienta y sirva.</li>
</ol>

View File

@@ -0,0 +1,6 @@
<ol>
<li>En un wok grande, dorar el pollo, luego bajar el fuego y cocinar suavemente el ajo. Añadir las judías verdes picadas y revolver.</li>
<li>Añadir la leche de coco, la pasta de curry verde y la salsa de pescado. Mezclar bien y cocinar a fuego lento.</li>
<li>Agregar los champiñones picados y cocinar a fuego lento hasta que el pollo (o tofu) esté cocido.</li>
<li>Servir con arroz jazmín y una pizca de cilantro.</li>
</ol>

View File

@@ -0,0 +1,14 @@
<ol>
<li>Engrasar una bandeja de hornear de unos 20 cm (o tamaño similar) con un poco del aceite de girasol y cubrir con papel de hornear.</li>
<li>Precalentar el horno a 180°C.</li>
<li>Trocear aproximadamente 1/3 del chocolate en pedazos pequeños. Trocear 2/3 de las nueces pecanas y mezclar con el chocolate troceado. Apartar.</li>
<li>Trocear el resto de las nueces pecanas y las avellanas, que se usarán en la parte de arriba de los brownies. Mezclar y apartar.</li>
<li>Derretir el resto del chocolate en un tazón resistente al calor que colocaremos encima de un pequeño cazo con unos 5cm de agua hirviendo. No permitir que el fondo del tazón con el chocolate toque el agua. Remover el chocolate hasta que se derrita completamente. Una vez derretido, apartar y dejar enfriar un poco.</li>
<li>Mientras se derrite el chocolate tamizar la harina, el cacao en polvo y la harina de coco en un tazón grande. Mezclar. Una vez mezclado, agregue el polvo de hornear y el azúcar.</li>
<li>Una vez se haya enfriado un poco el chocolate, añadir lentamente el extracto de vainilla, el aceite de girasol, la leche de soja y el chocolate derretido en la mezcla de harina y cacao.</li>
<li>Añadir el chocolate y las nueces pecanas que habíamos troceado previamente, asegurándonos de que están bien repartidas por toda la mezcla.</li>
<li>Poner la mezcla en el molde de hornear y repartir uniformemente con la ayuda de una espátula.</li>
<li>Esparcir las nueces pecanas y avellanas troceadas por encima y hornear de 18 a 23 minutos en la parte central del horno.</li>
<li>Retirar del horno y dejar enfriar durante unos 45 minutos. Con mucho cuidado usar los bordes del papel de hornear para separar el brownie del molde y depositarlo en una tabla de cortar. Cortar en porciones iguales usando un cuchillo afilado.</li>
<li>Servir los brownies solos o acompañados de crema vegana o helado.</li>
</ol>

View File

@@ -0,0 +1,8 @@
<ol>
<li>En una sartén grande, hervir la pasta en abundante agua hasta que esté cocida.</li>
<li>Mientras se cocina la pasta, pica la cebolla y fríela suavemente con el ajo en un poco de aceite hasta que esté suave y la cebolla se vea clara.</li>
<li>Añadir las salchichas vegetarianas. Una vez dorado, retirar y picar en trozos grandes.</li>
<li>Pon las salchichas en la sartén y agrega los tomates, el azúcar, el pesto y los tomates secos. Sazone al gusto. Cocine a fuego lento hasta que la mayor parte del agua de los tomates picados se haya ido.</li>
<li>Escurrir la pasta y agregar a la sartén con las salchichas y los tomates. Agregue la mitad del queso cheddar y transfierelo a un plato poco profundo. Espolvoree con el resto del queso cheddar y salpique la mozzarella en rodajas por encima.</li>
<li>Asar durante 10 minutos o hasta que el queso se derrita y comience a dorarse. Servir con hojas de albahaca.</li>
</ol>

View File

@@ -0,0 +1,8 @@
<ol>
<li>Precaliente el horno a 350°F/180°C y engrase dos moldes para pasteles de 8 pulgadas.</li>
<li>En un tazón grande, mezcle la mantequilla y el azúcar, luego agregue los huevos, la harina y el polvo para hornear.</li>
<li>Distribuya la mezcla uniformemente entre los 2 moldes para pasteles.</li>
<li>Coloque ambas moldes en el medio del horno precalentado durante 20 minutos, antes de verificar con un cuchillo. Cuando el cuchillo salga limpio, ¡está listo!</li>
<li>Permita que se enfríe en los moldes antes de colocarlos en un estante de enfriamiento.</li>
<li>Agregue la mermelada, apile, espolvoree con azúcar glas y sirva con una cucharada grande de crema. ¡Disfruta!</li>
</ol>

View File

@@ -0,0 +1,7 @@
<ol>
<li>Prepare las verduras pelando y cortando las patatas y picando finamente las cebollas, los puerros y el ajo.</li>
<li>Caliente un poco de aceite en una sartén y agregue las verduras picadas, cocinándolas suavemente durante unos 5 minutos.</li>
<li>Agregue el caldo de verduras a la misma sartén y aumente el fuego hasta que hierva a fuego lento, agregando el berro después de unos 10 minutos. Cocine hasta que todas las verduras estén blandas y se muelan fácilmente.</li>
<li>Licuar la sopa con una batidora de mano o en un mezclador, hasta que esté suave.</li>
<li>Si la sopa se ha enfriado demasiado mientras se está licuando, agregue la crème fraîche y vuelva a calentarla antes de servirla (de lo contrario, sírvala de inmediato). Sazone a su gusto.</li>
</ol>

View File

@@ -0,0 +1,6 @@
id,term
1,Acompañamientos
2,Postres
3,Platos principales
4,Tentempiés
5,Entrantes
1 id term
2 1 Acompañamientos
3 2 Postres
4 3 Platos principales
5 4 Tentempiés
6 5 Entrantes

View File

@@ -0,0 +1,29 @@
id,term
1,Sin alcohol
2,Horneado
3,Cocción
4,Desayuno
5,Pastel
6,Zanahorias
7,Chocolate
8,Fiesta de coctel
9,Sin Lactosa
10,Postre
11,Fiesta de cena
12,Bebidas
13,Huevo
14,Cultiva los tuyos
15,Saludable
16,Hierbas
17,Aprender a cocinar
18,Champiñones
19,Avena
20,Fiesta
21,Pastas
22,Repostería
23,Estacional
24,Compras
25,Sopa
26,Supermercados
27,Vegano
28,Vegetariano
1 id term
2 1 Sin alcohol
3 2 Horneado
4 3 Cocción
5 4 Desayuno
6 5 Pastel
7 6 Zanahorias
8 7 Chocolate
9 8 Fiesta de coctel
10 9 Sin Lactosa
11 10 Postre
12 11 Fiesta de cena
13 12 Bebidas
14 13 Huevo
15 14 Cultiva los tuyos
16 15 Saludable
17 16 Hierbas
18 17 Aprender a cocinar
19 18 Champiñones
20 19 Avena
21 20 Fiesta
22 21 Pastas
23 22 Repostería
24 23 Estacional
25 24 Compras
26 25 Sopa
27 26 Supermercados
28 27 Vegano
29 28 Vegetariano

View File

@@ -0,0 +1,22 @@
name: 'Umami demo: Content'
description: Imports the content for the Umami demo.
type: module
# version: VERSION
package: 'Core (Experimental)'
lifecycle: experimental
hidden: true
dependencies:
- drupal:field
- drupal:file
- drupal:image
- drupal:node
- drupal:options
- drupal:path
- drupal:taxonomy
- drupal:text
- drupal:user
# Information added by Drupal.org packaging script on 2024-07-04
version: '10.3.1'
project: 'drupal'
datestamp: 1720094222

View File

@@ -0,0 +1,28 @@
<?php
/**
* @file
* Install, update and uninstall functions for the module.
*/
use Drupal\demo_umami_content\InstallHelper;
/**
* Implements hook_module_preinstall().
*/
function demo_umami_content_module_preinstall($module) {
if ($module === 'demo_umami_content' && !\Drupal::service('config.installer')->isSyncing()) {
// Run before importing config so blocks are created with the correct
// dependencies.
\Drupal::classResolver(InstallHelper::class)->importContent();
}
}
/**
* Implements hook_uninstall().
*/
function demo_umami_content_uninstall($is_syncing) {
if (!$is_syncing) {
\Drupal::classResolver(InstallHelper::class)->deleteImportedContent();
}
}

View File

@@ -0,0 +1,894 @@
<?php
namespace Drupal\demo_umami_content;
use Drupal\Component\Utility\Html;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\File\Exception\FileException;
use Drupal\Core\File\FileExists;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\State\StateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
// cSpell:ignore María García Gregorio Sánchez
/**
* Defines a helper class for importing default content.
*
* @internal
* This code is only for use by the Umami demo: Content module.
*/
class InstallHelper implements ContainerInjectionInterface {
/**
* Entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* State.
*
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* The file system.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
/**
* Enabled languages.
*
* List of all enabled languages.
*
* @var array
*/
protected $enabledLanguages;
/**
* Term ID map.
*
* Used to store term IDs created in the import process against
* vocabulary and row in the source CSV files. This allows the created terms
* to be cross referenced when creating articles and recipes.
*
* @var array
*/
protected $termIdMap;
/**
* Media Image CSV ID map.
*
* Used to store media image CSV IDs created in the import process.
* This allows the created media images to be cross referenced when creating
* article, recipes and blocks.
*
* @var array
*/
protected $mediaImageIdMap;
/**
* Node CSV ID map.
*
* Used to store node CSV IDs created in the import process. This allows the
* created nodes to be cross referenced when creating blocks.
*
* @var array
*/
protected $nodeIdMap;
/**
* The module's path.
*/
// phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName
protected string $module_path;
/**
* Constructs a new InstallHelper object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* Entity type manager.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
* Module handler.
* @param \Drupal\Core\State\StateInterface $state
* State service.
* @param \Drupal\Core\File\FileSystemInterface $fileSystem
* The file system.
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, ModuleHandlerInterface $moduleHandler, StateInterface $state, FileSystemInterface $fileSystem) {
$this->entityTypeManager = $entityTypeManager;
$this->moduleHandler = $moduleHandler;
$this->state = $state;
$this->fileSystem = $fileSystem;
$this->termIdMap = [];
$this->mediaImageIdMap = [];
$this->nodeIdMap = [];
$this->enabledLanguages = array_keys(\Drupal::languageManager()->getLanguages());
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('module_handler'),
$container->get('state'),
$container->get('file_system')
);
}
/**
* Imports default contents.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function importContent() {
$this->getModulePath()
->importUsers()
->importContentFromFile('taxonomy_term', 'tags')
->importContentFromFile('taxonomy_term', 'recipe_category')
->importContentFromFile('media', 'image')
->importContentFromFile('node', 'recipe')
->importContentFromFile('node', 'article')
->importContentFromFile('node', 'page')
->importContentFromFile('block_content', 'disclaimer_block')
->importContentFromFile('block_content', 'footer_promo_block')
->importContentFromFile('block_content', 'banner_block');
}
/**
* Set module_path variable.
*
* @return $this
*/
protected function getModulePath() {
$this->module_path = $this->moduleHandler->getModule('demo_umami_content')->getPath();
return $this;
}
/**
* Read multilingual content.
*
* @param string $filename
* Filename to import.
*
* @return array
* An array of two items:
* 1. All multilingual content that was read from the files.
* 2. List of language codes that need to be imported.
*/
protected function readMultilingualContent($filename) {
$default_content_path = $this->module_path . "/default_content/languages/";
// Get all enabled languages.
$translated_languages = $this->enabledLanguages;
// Load all the content from any CSV files that exist for enabled languages.
foreach ($translated_languages as $language) {
if (file_exists($default_content_path . "$language/$filename") &&
($handle = fopen($default_content_path . "$language/$filename", 'r')) !== FALSE) {
$header = fgetcsv($handle);
$line_counter = 0;
while (($content = fgetcsv($handle)) !== FALSE) {
$keyed_content[$language][$line_counter] = array_combine($header, $content);
$line_counter++;
}
fclose($handle);
}
else {
// Language directory exists, but the file in this language was not found,
// remove that language from list of languages to be translated.
$key = array_search($language, $translated_languages);
unset($translated_languages[$key]);
}
}
return [$keyed_content, $translated_languages];
}
/**
* Retrieves the Term ID of a term saved during the import process.
*
* @param string $vocabulary
* Machine name of vocabulary to which it was saved.
* @param int $term_csv_id
* The term's ID from the CSV file.
*
* @return int
* Term ID, or 0 if Term ID could not be found.
*/
protected function getTermId($vocabulary, $term_csv_id) {
if (array_key_exists($vocabulary, $this->termIdMap) && array_key_exists($term_csv_id, $this->termIdMap[$vocabulary])) {
return $this->termIdMap[$vocabulary][$term_csv_id];
}
return 0;
}
/**
* Saves a Term ID generated when saving a taxonomy term.
*
* @param string $vocabulary
* Machine name of vocabulary to which it was saved.
* @param int $term_csv_id
* The term's ID from the CSV file.
* @param int $tid
* Term ID generated when saved in the Drupal database.
*/
protected function saveTermId($vocabulary, $term_csv_id, $tid) {
$this->termIdMap[$vocabulary][$term_csv_id] = $tid;
}
/**
* Retrieves the Media Image ID of a media image saved during the import process.
*
* @param int $media_image_csv_id
* The media image's ID from the CSV file.
*
* @return int
* Media Image ID, or 0 if Media Image ID could not be found.
*/
protected function getMediaImageId($media_image_csv_id) {
if (array_key_exists($media_image_csv_id, $this->mediaImageIdMap)) {
return $this->mediaImageIdMap[$media_image_csv_id];
}
return 0;
}
/**
* Saves a Media Image ID generated when saving a media image.
*
* @param int $media_image_csv_id
* The media image's ID from the CSV file.
* @param int $media_image_id
* Media Image ID generated when saved in the Drupal database.
*/
protected function saveMediaImageId($media_image_csv_id, $media_image_id) {
$this->mediaImageIdMap[$media_image_csv_id] = $media_image_id;
}
/**
* Retrieves the node path of node CSV ID saved during the import process.
*
* @param string $langcode
* Current language code.
* @param string $content_type
* Current content type.
* @param string $node_csv_id
* The node's ID from the CSV file.
*
* @return string
* Node path, or 0 if node CSV ID could not be found.
*/
protected function getNodePath($langcode, $content_type, $node_csv_id) {
if (array_key_exists($langcode, $this->nodeIdMap) &&
array_key_exists($content_type, $this->nodeIdMap[$langcode]) &&
array_key_exists($node_csv_id, $this->nodeIdMap[$langcode][$content_type])) {
return $this->nodeIdMap[$langcode][$content_type][$node_csv_id];
}
return 0;
}
/**
* Saves a node CSV ID generated when saving content.
*
* @param string $langcode
* Current language code.
* @param string $content_type
* Current content type.
* @param string $node_csv_id
* The node's ID from the CSV file.
* @param string $node_url
* Node's URL alias when saved in the Drupal database.
*/
protected function saveNodePath($langcode, $content_type, $node_csv_id, $node_url) {
$this->nodeIdMap[$langcode][$content_type][$node_csv_id] = $node_url;
}
/**
* Imports users.
*
* Users are created as their content is imported. However, some users might
* have non-default values (as preferred language), or editors don't have
* their own content so are created here instead.
*
* @return $this
*/
protected function importUsers() {
$user_storage = $this->entityTypeManager->getStorage('user');
$users = [
'Gregorio Sánchez' => [
'preferred_language' => 'es',
'roles' => ['author'],
],
'Margaret Hopper' => [
'preferred_language' => 'en',
'roles' => ['editor'],
],
'Grace Hamilton' => [
'preferred_language' => 'en',
'roles' => ['editor'],
],
'María García' => [
'preferred_language' => 'es',
'roles' => ['editor'],
],
];
foreach ($users as $name => $user_data) {
$user = $user_storage->create([
'name' => $name,
'status' => 1,
'roles' => $user_data['roles'],
'preferred_langcode' => $user_data['preferred_language'],
'preferred_admin_langcode' => $user_data['preferred_language'],
'mail' => \Drupal::transliteration()->transliterate(mb_strtolower(str_replace(' ', '.', $name))) . '@example.com',
]);
$user->enforceIsNew();
$user->save();
$this->storeCreatedContentUuids([$user->uuid() => 'user']);
}
return $this;
}
/**
* Process terms for a given vocabulary and filename.
*
* @param array $data
* Data of line that was read from the file.
* @param string $vocabulary
* Machine name of vocabulary to which we should save terms.
*
* @return array
* Data structured as a term.
*/
protected function processTerm(array $data, $vocabulary) {
$term_name = trim($data['term']);
// Prepare content.
$values = [
'name' => $term_name,
'vid' => $vocabulary,
'path' => ['alias' => '/' . Html::getClass($vocabulary) . '/' . Html::getClass($term_name)],
'langcode' => 'en',
];
return $values;
}
/**
* Process images into media entities.
*
* @param array $data
* Data of line that was read from the file.
*
* @return array
* Data structured as a image.
*/
protected function processImage(array $data) {
// Set article author.
if (!empty($data['author'])) {
$values['uid'] = $this->getUser($data['author']);
}
$image_path = $this->module_path . '/default_content/images/' . $data['image'];
// Prepare content.
$values = [
'name' => $data['title'],
'bundle' => 'image',
'langcode' => 'en',
'field_media_image' => [
'target_id' => $this->createFileEntity($image_path),
'alt' => $data['alt'],
],
];
return $values;
}
/**
* Process pages data into page node structure.
*
* @param array $data
* Data of line that was read from the file.
* @param string $langcode
* Current language code.
*
* @return array
* Data structured as a page node.
*/
protected function processPage(array $data, $langcode) {
// Prepare content.
$values = [
'type' => 'page',
'title' => $data['title'],
'moderation_state' => 'published',
'langcode' => 'en',
];
// Fields mapping starts.
// Set body field.
if (!empty($data['body'])) {
$values['body'] = [['value' => $data['body'], 'format' => 'basic_html']];
}
// Set node alias if exists.
if (!empty($data['slug'])) {
$values['path'] = [['alias' => '/' . $data['slug']]];
}
// Save node alias
$this->saveNodePath($langcode, 'page', $data['id'], $data['slug']);
// Set article author.
if (!empty($data['author'])) {
$values['uid'] = $this->getUser($data['author']);
}
return $values;
}
/**
* Process recipe data into recipe node structure.
*
* @param array $data
* Data of line that was read from the file.
* @param string $langcode
* Current language code.
*
* @return array
* Data structured as a recipe node.
*/
protected function processRecipe(array $data, $langcode) {
$values = [
'type' => 'recipe',
// Title field.
'title' => $data['title'],
'moderation_state' => 'published',
'langcode' => 'en',
];
// Set article author.
if (!empty($data['author'])) {
$values['uid'] = $this->getUser($data['author']);
}
// Set node alias if exists.
if (!empty($data['slug'])) {
$values['path'] = [['alias' => '/' . $data['slug']]];
}
// Save node alias
$this->saveNodePath($langcode, 'recipe', $data['id'], $data['slug']);
// Set field_media_image field.
if (!empty($data['image_reference'])) {
$values['field_media_image'] = [
'target_id' => $this->getMediaImageId($data['image_reference']),
];
}
// Set field_summary field.
if (!empty($data['summary'])) {
$values['field_summary'] = [['value' => $data['summary'], 'format' => 'basic_html']];
}
// Set field_recipe_category if exists.
if (!empty($data['recipe_category'])) {
$values['field_recipe_category'] = [];
$tags = array_filter(explode(',', $data['recipe_category']));
foreach ($tags as $tag_id) {
if ($tid = $this->getTermId('recipe_category', $tag_id)) {
$values['field_recipe_category'][] = ['target_id' => $tid];
}
}
}
// Set field_preparation_time field.
if (!empty($data['preparation_time'])) {
$values['field_preparation_time'] = [['value' => $data['preparation_time']]];
}
// Set field_cooking_time field.
if (!empty($data['cooking_time'])) {
$values['field_cooking_time'] = [['value' => $data['cooking_time']]];
}
// Set field_difficulty field.
if (!empty($data['difficulty'])) {
$values['field_difficulty'] = $data['difficulty'];
}
// Set field_number_of_servings field.
if (!empty($data['number_of_servings'])) {
$values['field_number_of_servings'] = [['value' => $data['number_of_servings']]];
}
// Set field_ingredients field.
if (!empty($data['ingredients'])) {
$ingredients = explode(',', $data['ingredients']);
$values['field_ingredients'] = [];
foreach ($ingredients as $ingredient) {
$values['field_ingredients'][] = ['value' => $ingredient];
}
}
// Set field_recipe_instruction field.
if (!empty($data['recipe_instruction'])) {
$recipe_instruction_path = $this->module_path . '/default_content/languages/' . $langcode . '/recipe_instructions/' . $data['recipe_instruction'];
$recipe_instructions = file_get_contents($recipe_instruction_path);
if ($recipe_instructions !== FALSE) {
$values['field_recipe_instruction'] = [['value' => $recipe_instructions, 'format' => 'basic_html']];
}
}
// Set field_tags if exists.
if (!empty($data['tags'])) {
$values['field_tags'] = [];
$tags = array_filter(explode(',', $data['tags']));
foreach ($tags as $tag_id) {
if ($tid = $this->getTermId('tags', $tag_id)) {
$values['field_tags'][] = ['target_id' => $tid];
}
}
}
return $values;
}
/**
* Process article data into article node structure.
*
* @param array $data
* Data of line that was read from the file.
* @param string $langcode
* Current language code.
*
* @return array
* Data structured as an article node.
*/
protected function processArticle(array $data, $langcode) {
// Prepare content.
$values = [
'type' => 'article',
'title' => $data['title'],
'moderation_state' => 'published',
'langcode' => 'en',
];
// Fields mapping starts.
// Set body field.
if (!empty($data['body'])) {
$body_path = $this->module_path . '/default_content/languages/' . $langcode . '/article_body/' . $data['body'];
$body = file_get_contents($body_path);
if ($body !== FALSE) {
$values['body'] = [['value' => $body, 'format' => 'basic_html']];
}
}
// Set node alias if exists.
if (!empty($data['slug'])) {
$values['path'] = [['alias' => '/' . $data['slug']]];
}
// Save node alias
$this->saveNodePath($langcode, 'article', $data['id'], $data['slug']);
// Set article author.
if (!empty($data['author'])) {
$values['uid'] = $this->getUser($data['author']);
}
// Set field_media_image field.
if (!empty($data['image_reference'])) {
$values['field_media_image'] = [
'target_id' => $this->getMediaImageId($data['image_reference']),
];
}
// Set field_tags if exists.
if (!empty($data['tags'])) {
$values['field_tags'] = [];
$tags = explode(',', $data['tags']);
foreach ($tags as $tag_id) {
if ($tid = $this->getTermId('tags', $tag_id)) {
$values['field_tags'][] = ['target_id' => $tid];
}
}
}
return $values;
}
/**
* Process block_banner data into block_banner block structure.
*
* @param array $data
* Data of line that was read from the file.
* @param string $langcode
* Current language code.
*
* @return array
* Data structured as a block.
*/
protected function processBannerBlock(array $data, $langcode) {
$node_url = $this->getNodePath($langcode, $data['content_type'], $data['node_id']);
$values = [
'uuid' => $data['uuid'],
'info' => $data['info'],
'type' => $data['type'],
'langcode' => 'en',
'field_title' => [
'value' => $data['field_title'],
],
'field_content_link' => [
'uri' => 'internal:/' . $langcode . '/' . $node_url,
'title' => $data['field_content_link_title'],
],
'field_summary' => [
'value' => $data['field_summary'],
],
'field_media_image' => [
'target_id' => $this->getMediaImageId($data['image_reference']),
],
];
return $values;
}
/**
* Process disclaimer_block data into disclaimer_block block structure.
*
* @param array $data
* Data of line that was read from the file.
*
* @return array
* Data structured as a block.
*/
protected function processDisclaimerBlock(array $data) {
$values = [
'uuid' => $data['uuid'],
'info' => $data['info'],
'type' => $data['type'],
'langcode' => 'en',
'field_disclaimer' => [
'value' => $data['field_disclaimer'],
'format' => 'basic_html',
],
'field_copyright' => [
'value' => '&copy; ' . date("Y") . ' ' . $data['field_copyright'],
'format' => 'basic_html',
],
];
return $values;
}
/**
* Process footer_block data into footer_block block structure.
*
* @param array $data
* Data of line that was read from the file.
* @param string $langcode
* Current language code.
*
* @return array
* Data structured as a block.
*/
protected function processFooterPromoBlock(array $data, $langcode) {
$node_url = $this->getNodePath($langcode, $data['content_type'], $data['node_id']);
$values = [
'uuid' => $data['uuid'],
'info' => $data['info'],
'type' => $data['type'],
'langcode' => 'en',
'field_title' => [
'value' => $data['field_title'],
],
'field_content_link' => [
'uri' => 'internal:/' . $node_url,
'title' => $data['field_content_link_title'],
],
'field_summary' => [
'value' => $data['field_summary'],
],
'field_media_image' => [
'target_id' => $this->getMediaImageId($data['image_reference']),
],
];
return $values;
}
/**
* Process content into a structure that can be saved into Drupal.
*
* @param string $bundle_machine_name
* Current bundle's machine name.
* @param array $content
* Current content array that needs to be structured.
* @param string $langcode
* Current language code.
*
* @return array
* Structured content.
*/
protected function processContent($bundle_machine_name, array $content, $langcode) {
switch ($bundle_machine_name) {
case 'recipe':
$structured_content = $this->processRecipe($content, $langcode);
break;
case 'article':
$structured_content = $this->processArticle($content, $langcode);
break;
case 'page':
$structured_content = $this->processPage($content, $langcode);
break;
case 'banner_block':
$structured_content = $this->processBannerBlock($content, $langcode);
break;
case 'disclaimer_block':
$structured_content = $this->processDisclaimerBlock($content);
break;
case 'footer_promo_block':
$structured_content = $this->processFooterPromoBlock($content, $langcode);
break;
case 'image':
$structured_content = $this->processImage($content);
break;
case 'recipe_category':
case 'tags':
$structured_content = $this->processTerm($content, $bundle_machine_name);
break;
default:
break;
}
return $structured_content;
}
/**
* Imports content.
*
* @param string $entity_type
* Entity type to be imported
* @param string $bundle_machine_name
* Bundle machine name to be imported.
*
* @return $this
*/
protected function importContentFromFile($entity_type, $bundle_machine_name) {
$filename = $entity_type . '/' . $bundle_machine_name . '.csv';
// Read all multilingual content from the file.
[$all_content, $translated_languages] = $this->readMultilingualContent($filename);
// English is no longer needed in the list of languages to translate.
$key = array_search('en', $translated_languages);
unset($translated_languages[$key]);
// Start the loop with English (default) recipes.
foreach ($all_content['en'] as $current_content) {
// Process data into its relevant structure.
$structured_content = $this->processContent($bundle_machine_name, $current_content, 'en');
// Save Entity.
$entity = $this->entityTypeManager->getStorage($entity_type)->create($structured_content);
$entity->save();
$this->storeCreatedContentUuids([$entity->uuid() => $entity_type]);
// Save taxonomy entity Drupal ID, so we can reference it in nodes.
if ($entity_type == 'taxonomy_term') {
$this->saveTermId($bundle_machine_name, $current_content['id'], $entity->id());
}
// Save media entity Drupal ID, so we can reference it in nodes & blocks.
if ($entity_type == 'media') {
$this->saveMediaImageId($current_content['id'], $entity->id());
}
// Go through all the languages that have translations.
foreach ($translated_languages as $translated_language) {
// Find the translated content ID that corresponds to original content.
$translation_id = array_search($current_content['id'], array_column($all_content[$translated_language], 'id'));
// Check if translation was found.
if ($translation_id !== FALSE) {
// Process that translation.
$translated_entity = $all_content[$translated_language][$translation_id];
$structured_content = $this->processContent($bundle_machine_name, $translated_entity, $translated_language);
// Save entity's translation.
$entity->addTranslation(
$translated_language,
$structured_content
);
$entity->save();
}
}
}
return $this;
}
/**
* Deletes any content imported by this module.
*
* @return $this
*/
public function deleteImportedContent() {
$uuids = $this->state->get('demo_umami_content_uuids', []);
$by_entity_type = array_reduce(array_keys($uuids), function ($carry, $uuid) use ($uuids) {
$entity_type_id = $uuids[$uuid];
$carry[$entity_type_id][] = $uuid;
return $carry;
}, []);
foreach ($by_entity_type as $entity_type_id => $entity_uuids) {
$storage = $this->entityTypeManager->getStorage($entity_type_id);
$entities = $storage->loadByProperties(['uuid' => $entity_uuids]);
$storage->delete($entities);
}
return $this;
}
/**
* Looks up a user by name, if it is missing the user is created.
*
* @param string $name
* Username.
*
* @return int
* User ID.
*/
protected function getUser($name) {
$user_storage = $this->entityTypeManager->getStorage('user');
$users = $user_storage->loadByProperties(['name' => $name]);
if (empty($users)) {
// Creating user without any password.
$user = $user_storage->create([
'name' => $name,
'status' => 1,
'roles' => ['author'],
'mail' => mb_strtolower(str_replace(' ', '.', $name)) . '@example.com',
]);
$user->enforceIsNew();
$user->save();
$this->storeCreatedContentUuids([$user->uuid() => 'user']);
return $user->id();
}
$user = reset($users);
return $user->id();
}
/**
* Creates a file entity based on an image path.
*
* @param string $path
* Image path.
*
* @return int
* File ID.
*/
protected function createFileEntity($path) {
$filename = basename($path);
try {
$uri = $this->fileSystem->copy($path, 'public://' . $filename, FileExists::Replace);
}
catch (FileException $e) {
$uri = FALSE;
}
$file = $this->entityTypeManager->getStorage('file')->create([
'uri' => $uri,
'status' => 1,
]);
$file->save();
$this->storeCreatedContentUuids([$file->uuid() => 'file']);
return $file->id();
}
/**
* Stores record of content entities created by this import.
*
* @param array $uuids
* Array of UUIDs where the key is the UUID and the value is the entity
* type.
*/
protected function storeCreatedContentUuids(array $uuids) {
$uuids = $this->state->get('demo_umami_content_uuids', []) + $uuids;
$this->state->set('demo_umami_content_uuids', $uuids);
}
}

View File

@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\demo_umami_content\Functional;
use Drupal\Tests\BrowserTestBase;
/**
* Tests that files provided by demo_umami_content are not accessible.
*
* @group demo_umami_content
*/
class DefaultContentFilesAccessTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* Tests that sample images, recipes and articles are not accessible.
*/
public function testAccessDeniedToFiles() {
// The demo_umami profile should not be used because we want to ensure that
// if you install another profile these files are not available.
$this->assertNotSame('demo_umami', \Drupal::installProfile());
$files_to_test = [
'images/heritage-carrots.jpg',
'languages/en/recipe_instructions/mediterranean-quiche-umami.html',
'languages/en/article_body/lets-hear-it-for-carrots.html',
'languages/en/node/article.csv',
];
foreach ($files_to_test as $file) {
// Hard code the path since the demo_umami profile is not installed.
$content_path = "core/profiles/demo_umami/modules/demo_umami_content/default_content/$file";
$this->assertFileExists($this->root . '/' . $content_path);
$this->drupalGet($content_path);
$this->assertSession()->statusCodeEquals(403);
}
}
}

View File

@@ -0,0 +1,193 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\demo_umami_content\Functional;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Tests\BrowserTestBase;
/**
* Tests that uninstalling default content removes created content.
*
* @group demo_umami_content
*/
class UninstallDefaultContentTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected $profile = 'demo_umami';
/**
* Tests uninstalling content removes created entities.
*/
public function testReinstall() {
$module_installer = $this->container->get('module_installer');
// Test imported blocks on profile install.
$block_storage = $this->container->get('entity_type.manager')->getStorage('block_content');
$this->assertImportedCustomBlock($block_storage);
// Test imported nodes on profile install.
$node_storage = $this->container->get('entity_type.manager')->getStorage('node');
$this->assertRecipesImported($node_storage);
$count = $node_storage->getQuery()
->accessCheck(FALSE)
->condition('type', 'article')
->count()
->execute();
$this->assertGreaterThan(0, $count);
// Uninstall the module.
$module_installer->uninstall(['demo_umami_content']);
// Reset storage cache.
$block_storage->resetCache();
$node_storage->resetCache();
// Assert the removal of blocks on uninstall.
foreach ($this->expectedBlocks() as $block_info) {
$count = $block_storage->getQuery()
->accessCheck(FALSE)
->condition('type', $block_info['type'])
->count()
->execute();
$this->assertEquals(0, $count);
$block = $block_storage->loadByProperties(['uuid' => $block_info['uuid']]);
$this->assertCount(0, $block);
}
// Assert the removal of nodes on uninstall.
$count = $node_storage->getQuery()
->accessCheck(FALSE)
->condition('type', 'article')
->count()
->execute();
$this->assertEquals(0, $count);
$count = $node_storage->getQuery()
->accessCheck(FALSE)
->condition('type', 'recipe')
->count()
->execute();
$this->assertEquals(0, $count);
// Re-install and assert imported content.
$module_installer->install(['demo_umami_content']);
$this->assertRecipesImported($node_storage);
$this->assertArticlesImported($node_storage);
$this->assertImportedCustomBlock($block_storage);
}
/**
* Assert recipes are imported.
*
* @param \Drupal\Core\Entity\EntityStorageInterface $node_storage
* Node storage.
*/
protected function assertRecipesImported(EntityStorageInterface $node_storage): void {
$count = $node_storage->getQuery()
->accessCheck(FALSE)
->condition('type', 'recipe')
->count()
->execute();
$this->assertGreaterThan(0, $count);
$nodes = $node_storage->loadByProperties(['title' => 'Gluten free pizza']);
$this->assertCount(1, $nodes);
$node = reset($nodes);
$this->assertStringContainsString('Mix some of the milk and water in a jug', $node->field_recipe_instruction->value);
}
/**
* Assert articles are imported.
*
* @param \Drupal\Core\Entity\EntityStorageInterface $node_storage
* Node storage.
*/
protected function assertArticlesImported(EntityStorageInterface $node_storage): void {
$count = $node_storage->getQuery()
->accessCheck(FALSE)
->condition('type', 'article')
->count()
->execute();
$this->assertGreaterThan(0, $count);
$nodes = $node_storage->loadByProperties(['title' => 'The umami guide to our favorite mushrooms']);
$this->assertCount(1, $nodes);
$node = reset($nodes);
$this->assertStringContainsString('One of the best things about mushrooms is their versatility', $node->body->value);
}
/**
* Assert block content are imported.
*
* @param \Drupal\Core\Entity\EntityStorageInterface $block_storage
* Block storage.
*/
protected function assertImportedCustomBlock(EntityStorageInterface $block_storage): void {
$assert = $this->assertSession();
foreach ($this->expectedBlocks() as $block_info) {
$this->drupalGet($block_info['path']);
// Verify that the block is placed.
$assert->pageTextContains($block_info['unique_text']);
// For blocks that have image alt text, also verify the presence of the
// expected alt text.
if (isset($block_info['image_alt_text'])) {
$img_alt_text = $assert->elementExists('css', $block_info['image_css_selector'])->getAttribute('alt');
$this->assertEquals($block_info['image_alt_text'], $img_alt_text);
}
// Verify that the block can be loaded.
$count = $block_storage->getQuery()
->accessCheck(FALSE)
->condition('type', $block_info['type'])
->count()
->execute();
$this->assertGreaterThan(0, $count);
$block = $block_storage->loadByProperties(['uuid' => $block_info['uuid']]);
$this->assertCount(1, $block);
}
}
/**
* Returns the expected properties of this profile's content blocks.
*/
protected function expectedBlocks() {
return [
[
'path' => '<front>',
'type' => 'banner_block',
'uuid' => '9aadf4a1-ded6-4017-a10d-a5e043396edf',
'unique_text' => 'A wholesome pasta bake is the ultimate comfort food.',
'image_css_selector' => '#block-umami-banner-home img',
'image_alt_text' => 'Mouth watering vegetarian pasta bake with rich tomato sauce and cheese toppings',
],
[
'path' => '/recipes',
'type' => 'banner_block',
'uuid' => '4c7d58a3-a45d-412d-9068-259c57e40541',
'unique_text' => 'These sumptuous brownies should be gooey on the inside and crisp on the outside. A perfect indulgence!',
'image_css_selector' => '#block-umami-banner-recipes img',
'image_alt_text' => 'A stack of chocolate and pecan brownies, sprinkled with pecan crumbs and crushed walnut, fresh out of the oven',
],
[
'path' => '/recipes',
'type' => 'disclaimer_block',
'uuid' => '9b4dcd67-99f3-48d0-93c9-2c46648b29de',
'unique_text' => 'is a fictional magazine and publisher for illustrative purposes only',
],
[
'path' => '/recipes',
'type' => 'footer_promo_block',
'uuid' => '924ab293-8f5f-45a1-9c7f-2423ae61a241',
'unique_text' => 'Magazine exclusive articles, recipes and plenty of reasons to get your copy today.',
'image_css_selector' => '#block-umami-footer-promo img',
'image_alt_text' => '3 issue bundle of the Umami food magazine',
],
];
}
}

View File

@@ -0,0 +1,298 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\demo_umami\Functional;
use Drupal\ckeditor5\Plugin\Editor\CKEditor5;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\InstallStorage;
use Drupal\Core\Config\StorageInterface;
use Drupal\editor\Entity\Editor;
use Drupal\KernelTests\AssertConfigTrait;
use Drupal\Tests\BrowserTestBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\Tests\SchemaCheckTestTrait;
use Symfony\Component\Validator\ConstraintViolation;
/**
* Tests demo_umami profile.
*
* @group demo_umami
* @group #slow
*/
class DemoUmamiProfileTest extends BrowserTestBase {
use AssertConfigTrait;
use SchemaCheckTestTrait;
/**
* {@inheritdoc}
*/
protected function installParameters() {
$parameters = parent::installParameters();
$parameters['forms']['install_configure_form']['site_mail'] = 'admin@example.com';
return $parameters;
}
/**
* {@inheritdoc}
*/
protected $profile = 'demo_umami';
/**
* Tests some features specific to being a demonstration profile.
*/
public function testDemoSpecificFeatures(): void {
// This test coverage is organized into separate protected methods rather
// than individual test methods to avoid having to reinstall Umami for
// a handful of assertions each.
$this->testUser();
$this->testWarningsOnStatusPage();
$this->testAppearance();
$this->testDemonstrationWarningMessage();
}
/**
* Tests demo_umami profile warnings shown on Status Page.
*/
protected function testWarningsOnStatusPage() {
$account = $this->drupalCreateUser(['administer site configuration']);
$this->drupalLogin($account);
// Check the requirements warning for using an experimental profile.
$this->drupalGet('admin/reports/status');
$this->assertSession()->pageTextContains('Experimental profiles are provided for testing purposes only. Use at your own risk. To start building a new site, reinstall Drupal and choose a non-experimental profile.');
}
/**
* Tests the profile supplied configuration is the same after installation.
*/
public function testConfig(): void {
// Just connect directly to the config table so we don't need to worry about
// the cache layer.
$active_config_storage = $this->container->get('config.storage');
$default_config_storage = new FileStorage($this->container->get('extension.list.profile')->getPath('demo_umami') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY, InstallStorage::DEFAULT_COLLECTION);
$this->assertDefaultConfig($default_config_storage, $active_config_storage);
$default_config_storage = new FileStorage($this->container->get('extension.list.profile')->getPath('demo_umami') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY, InstallStorage::DEFAULT_COLLECTION);
$this->assertDefaultConfig($default_config_storage, $active_config_storage);
// Now we have all configuration imported, test all of them for schema
// conformance. Ensures all imported default configuration is valid when
// Demo Umami profile modules are enabled.
$names = $this->container->get('config.storage')->listAll();
/** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config */
$typed_config = $this->container->get('config.typed');
foreach ($names as $name) {
$config = $this->config($name);
$this->assertConfigSchema($typed_config, $name, $config->get());
}
// Validate all configuration.
// @todo Generalize in https://www.drupal.org/project/drupal/issues/2164373
foreach (Editor::loadMultiple() as $editor) {
// Currently only text editors using CKEditor 5 can be validated.
if ($editor->getEditor() !== 'ckeditor5') {
continue;
}
$this->assertSame([], array_map(
function (ConstraintViolation $v) {
return (string) $v->getMessage();
},
iterator_to_array(CKEditor5::validatePair(
$editor,
$editor->getFilterFormat()
))
));
}
}
/**
* Asserts that the default configuration matches active configuration.
*
* @param \Drupal\Core\Config\StorageInterface $default_config_storage
* The default configuration storage to check.
* @param \Drupal\Core\Config\StorageInterface $active_config_storage
* The active configuration storage.
*/
protected function assertDefaultConfig(StorageInterface $default_config_storage, StorageInterface $active_config_storage): void {
/** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
$config_manager = $this->container->get('config.manager');
foreach ($default_config_storage->listAll() as $config_name) {
if ($active_config_storage->exists($config_name)) {
$result = $config_manager->diff($default_config_storage, $active_config_storage, $config_name);
$this->assertConfigDiff($result, $config_name, [
// The filter.format.*:roles key is a special install key.
'filter.format.basic_html' => ['roles:', ' - authenticated'],
'filter.format.full_html' => ['roles:', ' - administrator'],
'filter.format.restricted_html' => ['roles:', ' - anonymous'],
// The system.site config is overwritten during tests by
// FunctionalTestSetupTrait::installParameters().
'system.site' => ['uuid:', 'name:', 'mail:'],
]);
}
else {
$this->fail("$config_name has not been installed");
}
}
}
/**
* Tests that the users can log in with the admin password entered at install.
*/
protected function testUser() {
$password = $this->rootUser->pass_raw;
$ids = \Drupal::entityQuery('user')
->accessCheck(FALSE)
->condition('roles', ['author', 'editor'], 'IN')
->execute();
$users = \Drupal::entityTypeManager()->getStorage('user')->loadMultiple($ids);
foreach ($users as $user) {
$this->drupalLoginWithPassword($user, $password);
}
}
/**
* Tests the successful editing of nodes by admin.
*/
public function testEditNodesByAdmin(): void {
$permissions = [
'administer nodes',
'edit any recipe content',
'use editorial transition create_new_draft',
];
$account = $this->drupalCreateUser($permissions);
$this->drupalLogin($account);
$webassert = $this->assertSession();
// Check that admin is able to edit the node.
$nodes = $this->container->get('entity_type.manager')
->getStorage('node')
->loadByProperties(['title' => 'Deep mediterranean quiche']);
$node = reset($nodes);
$this->drupalGet($node->toUrl('edit-form'));
$webassert->statusCodeEquals(200);
$this->submitForm([], 'Preview');
$webassert->statusCodeEquals(200);
$this->assertSession()->elementsCount('css', 'h1', 1);
$this->clickLink('Back to content editing');
$this->submitForm([], "Save");
$webassert->pageTextContains('Recipe Deep mediterranean quiche has been updated.');
}
/**
* Tests that the Umami theme is available on the Appearance page.
*/
protected function testAppearance() {
$account = $this->drupalCreateUser(['administer themes']);
$this->drupalLogin($account);
$webassert = $this->assertSession();
$this->drupalGet('admin/appearance');
$webassert->pageTextContains('Umami');
}
/**
* Tests that the toolbar warning only appears on the admin pages.
*/
protected function testDemonstrationWarningMessage() {
$permissions = [
'access content overview',
'access toolbar',
'administer nodes',
'edit any recipe content',
'create recipe content',
'use editorial transition create_new_draft',
];
$account = $this->drupalCreateUser($permissions);
$this->drupalLogin($account);
$web_assert = $this->assertSession();
$nodes = $this->container->get('entity_type.manager')
->getStorage('node')
->loadByProperties(['title' => 'Deep mediterranean quiche']);
/** @var \Drupal\node\Entity\Node $recipe_node */
$recipe_node = reset($nodes);
// Check when editing a node, the warning is visible.
$this->drupalGet($recipe_node->toUrl('edit-form'));
$web_assert->statusCodeEquals(200);
$web_assert->pageTextContains('This site is intended for demonstration purposes.');
// Check when adding a node, the warning is visible.
$this->drupalGet('node/add/recipe');
$web_assert->statusCodeEquals(200);
$web_assert->pageTextContains('This site is intended for demonstration purposes.');
// Check when looking at admin/content, the warning is visible.
$this->drupalGet('admin/content');
$web_assert->statusCodeEquals(200);
$web_assert->pageTextContains('This site is intended for demonstration purposes.');
// Check when viewing a node, the warning is not visible.
$this->drupalGet($recipe_node->toUrl());
$web_assert->statusCodeEquals(200);
$web_assert->pageTextNotContains('This site is intended for demonstration purposes.');
// Check when viewing the homepage, the warning is not visible.
$this->drupalGet('<front>');
$web_assert->statusCodeEquals(200);
$web_assert->pageTextNotContains('This site is intended for demonstration purposes.');
}
/**
* Logs in a user using the Mink controlled browser using a password.
*
* If a user is already logged in, then the current user is logged out before
* logging in the specified user.
*
* Note that neither the current user nor the passed-in user object is
* populated with data of the logged in user. If you need full access to the
* user object after logging in, it must be updated manually. If you also need
* access to the plain-text password of the user (set by drupalCreateUser()),
* e.g. to log in the same user again, then it must be re-assigned manually.
* For example:
* @code
* // Create a user.
* $account = $this->drupalCreateUser([]);
* $this->drupalLogin($account);
* // Load real user object.
* $pass_raw = $account->passRaw;
* $account = User::load($account->id());
* $account->passRaw = $pass_raw;
* @endcode
*
* @param \Drupal\Core\Session\AccountInterface $account
* User object representing the user to log in.
* @param string $password
* The password to authenticate the user with.
*
* @see drupalCreateUser()
*/
protected function drupalLoginWithPassword(AccountInterface $account, $password) {
if ($this->loggedInUser) {
$this->drupalLogout();
}
$this->drupalGet('user/login');
$this->submitForm([
'name' => $account->getAccountName(),
'pass' => $password,
], 'Log in');
// @see ::drupalUserIsLoggedIn()
$account->sessionId = $this->getSession()->getCookie(\Drupal::service('session_configuration')->getOptions(\Drupal::request())['name']);
$this->assertTrue($this->drupalUserIsLoggedIn($account), "User {$account->getAccountName()} successfully logged in.");
$this->loggedInUser = $account;
$this->container->get('current_user')->setAccount($account);
}
}

View File

@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\demo_umami\Functional;
use Drupal\FunctionalTests\Installer\InstallerTestBase;
/**
* Tests the multilingual installer installing the Umami profile.
*
* @group Installer
*/
class UmamiMultilingualInstallTest extends InstallerTestBase {
/**
* {@inheritdoc}
*/
protected $profile = 'demo_umami';
/**
* {@inheritdoc}
*/
protected $langcode = 'es';
/**
* Ensures that Umami can be installed with Spanish as the default language.
*/
public function testUmami(): void {
$this->drupalGet('');
// cSpell:disable-next-line
$this->assertSession()->pageTextContains('Quiche mediterráneo profundo');
}
/**
* {@inheritdoc}
*/
protected function setUpLanguage() {
// Place custom local translations in the translations directory to avoid
// getting translations from localize.drupal.org.
mkdir(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
file_put_contents(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.es.po', $this->getPo('es'));
parent::setUpLanguage();
}
/**
* Returns the string for the test .po file.
*
* @param string $langcode
* The language code.
*
* @return string
* Contents for the test .po file.
*/
protected function getPo($langcode) {
return <<<PO
msgid ""
msgstr ""
msgid "Save and continue"
msgstr "Save and continue $langcode"
msgid "Anonymous"
msgstr "Anonymous $langcode"
msgid "Language"
msgstr "Language $langcode"
#: Testing site name configuration during the installer.
msgid "Drupal"
msgstr "Drupal"
PO;
}
}

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\demo_umami\FunctionalJavascript;
use Drupal\FunctionalJavascriptTests\PerformanceTestBase;
use Drupal\Tests\PerformanceData;
/**
* Tests demo_umami profile performance.
*
* @group #slow
*/
class AssetAggregationAcrossPagesTest extends PerformanceTestBase {
/**
* {@inheritdoc}
*/
protected $profile = 'demo_umami';
/**
* Checks the asset requests made when the front and recipe pages are visited.
*/
public function testFrontAndRecipesPages(): void {
$performance_data = $this->doRequests();
$this->assertSame(4, $performance_data->getStylesheetCount());
$this->assertLessThan(80000, $performance_data->getStylesheetBytes());
$this->assertSame(1, $performance_data->getScriptCount());
$this->assertLessThan(7500, $performance_data->getScriptBytes());
}
/**
* Checks the asset requests made when the front and recipe pages are visited.
*/
public function testFrontAndRecipesPagesAuthenticated(): void {
$user = $this->createUser();
$this->drupalLogin($user);
$this->rebuildAll();
$performance_data = $this->doRequests();
$this->assertSame(4, $performance_data->getStylesheetCount());
$this->assertLessThan(87000, $performance_data->getStylesheetBytes());
$this->assertSame(1, $performance_data->getScriptCount());
$this->assertLessThan(133000, $performance_data->getScriptBytes());
}
/**
* Helper to do requests so the above test methods stay in sync.
*/
protected function doRequests(): PerformanceData {
$performance_data = $this->collectPerformanceData(function () {
$this->drupalGet('<front>');
// Give additional time for the request and all assets to be returned
// before making the next request.
sleep(2);
$this->drupalGet('articles');
}, 'umamiFrontAndRecipePages');
return $performance_data;
}
}

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\demo_umami\FunctionalJavascript;
use Drupal\FunctionalJavascriptTests\PerformanceTestBase;
/**
* Tests demo_umami profile performance.
*
* @group OpenTelemetry
* @group #slow
* @requires extension apcu
*/
class OpenTelemetryAuthenticatedPerformanceTest extends PerformanceTestBase {
/**
* {@inheritdoc}
*/
protected $profile = 'demo_umami';
protected function setUp(): void {
parent::setUp();
$user = $this->drupalCreateUser();
$this->drupalLogin($user);
}
/**
* Logs front page tracing data with an authenticated user and warm cache.
*/
public function testFrontPageAuthenticatedWarmCache(): void {
$this->drupalGet('<front>');
$this->drupalGet('<front>');
$performance_data = $this->collectPerformanceData(function () {
$this->drupalGet('<front>');
}, 'authenticatedFrontPage');
$this->assertSame(2, $performance_data->getStylesheetCount());
$this->assertLessThan(44000, $performance_data->getStylesheetBytes());
$this->assertSame(1, $performance_data->getScriptCount());
$this->assertLessThan(133000, $performance_data->getScriptBytes());
$expected_queries = [
'SELECT "session" FROM "sessions" WHERE "sid" = "SESSION_ID" LIMIT 0, 1',
'SELECT * FROM "users_field_data" "u" WHERE "u"."uid" = "10" AND "u"."default_langcode" = 1',
'SELECT "roles_target_id" FROM "user__roles" WHERE "entity_id" = "10"',
'SELECT "config"."name" AS "name" FROM "config" "config" WHERE ("collection" = "") AND ("name" LIKE "language.entity.%" ESCAPE ' . "'\\\\'" . ') ORDER BY "collection" ASC, "name" ASC',
];
$recorded_queries = $performance_data->getQueries();
$this->assertSame($expected_queries, $recorded_queries);
$this->assertSame(4, $performance_data->getQueryCount());
$this->assertSame(43, $performance_data->getCacheGetCount());
$this->assertSame(0, $performance_data->getCacheSetCount());
$this->assertSame(0, $performance_data->getCacheDeleteCount());
$this->assertSame(0, $performance_data->getCacheTagChecksumCount());
$this->assertSame(11, $performance_data->getCacheTagIsValidCount());
$this->assertSame(0, $performance_data->getCacheTagInvalidationCount());
}
}

View File

@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\demo_umami\FunctionalJavascript;
use Drupal\FunctionalJavascriptTests\PerformanceTestBase;
/**
* Tests demo_umami profile performance.
*
* @group OpenTelemetry
* @group #slow
* @requires extension apcu
*/
class OpenTelemetryFrontPagePerformanceTest extends PerformanceTestBase {
/**
* {@inheritdoc}
*/
protected $profile = 'demo_umami';
/**
* Logs front page tracing data with a cold cache.
*/
public function testFrontPageColdCache(): void {
// @todo Chromedriver doesn't collect tracing performance logs for the very
// first request in a test, so warm it up.
// https://www.drupal.org/project/drupal/issues/3379750
$this->drupalGet('user/login');
$this->rebuildAll();
$this->collectPerformanceData(function () {
$this->drupalGet('<front>');
}, 'umamiFrontPageColdCache');
$this->assertSession()->pageTextContains('Umami');
}
/**
* Logs front page tracing data with a hot cache.
*
* Hot here means that all possible caches are warmed.
*/
public function testFrontPageHotCache(): void {
// Request the page twice so that asset aggregates and image derivatives are
// definitely cached in the browser cache. The first response builds the
// file and serves from PHP with private, no-store headers. The second
// request will get the file served directly from disk by the browser with
// cacheable headers, so only the third request actually has the files
// in the browser cache.
$this->drupalGet('<front>');
$this->drupalGet('<front>');
$performance_data = $this->collectPerformanceData(function () {
$this->drupalGet('<front>');
}, 'umamiFrontPageHotCache');
$this->assertSession()->pageTextContains('Umami');
$expected_queries = [];
$recorded_queries = $performance_data->getQueries();
$this->assertSame($expected_queries, $recorded_queries);
$this->assertSame(0, $performance_data->getQueryCount());
$this->assertSame(1, $performance_data->getCacheGetCount());
$this->assertSame(0, $performance_data->getCacheSetCount());
$this->assertSame(0, $performance_data->getCacheDeleteCount());
$this->assertSame(0, $performance_data->getCacheTagChecksumCount());
$this->assertSame(1, $performance_data->getCacheTagIsValidCount());
$this->assertSame(0, $performance_data->getCacheTagInvalidationCount());
$this->assertSame(1, $performance_data->getScriptCount());
$this->assertLessThan(7500, $performance_data->getScriptBytes());
$this->assertSame(2, $performance_data->getStylesheetCount());
$this->assertLessThan(40400, $performance_data->getStylesheetBytes());
}
/**
* Logs front page tracing data with a lukewarm cache.
*
* Cool here means that 'global' site caches are warm but anything
* specific to the front page is cold.
*/
public function testFrontPageCoolCache(): void {
// First of all visit the front page to ensure the image style exists.
$this->drupalGet('<front>');
$this->rebuildAll();
// Now visit a different page to warm non-route-specific caches.
$this->drupalGet('user/login');
$this->collectPerformanceData(function () {
$this->drupalGet('<front>');
}, 'umamiFrontPageCoolCache');
}
}

View File

@@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\demo_umami\FunctionalJavascript;
use Drupal\FunctionalJavascriptTests\PerformanceTestBase;
/**
* Tests demo_umami profile performance.
*
* @group OpenTelemetry
* @group #slow
* @requires extension apcu
*/
class OpenTelemetryNodePagePerformanceTest extends PerformanceTestBase {
/**
* {@inheritdoc}
*/
protected $profile = 'demo_umami';
/**
* Logs node page tracing data with a cold cache.
*/
public function testNodePageColdCache(): void {
// @todo Chromedriver doesn't collect tracing performance logs for the very
// first request in a test, so warm it up.
// https://www.drupal.org/project/drupal/issues/3379750
$this->drupalGet('user/login');
$this->rebuildAll();
$this->collectPerformanceData(function () {
$this->drupalGet('node/1');
}, 'umamiNodePageColdCache');
$this->assertSession()->pageTextContains('quiche');
}
/**
* Logs node page tracing data with a hot cache.
*
* Hot here means that all possible caches are warmed.
*/
public function testNodePageHotCache(): void {
// Request the page twice so that asset aggregates are definitely cached in
// the browser cache.
$this->drupalGet('node/1');
$this->drupalGet('node/1');
$performance_data = $this->collectPerformanceData(function () {
$this->drupalGet('node/1');
}, 'umamiNodePageHotCache');
$this->assertSession()->pageTextContains('quiche');
$this->assertSame($performance_data->getQueryCount(), 0);
$this->assertSame($performance_data->getCacheGetCount(), 1);
$this->assertSame($performance_data->getCacheSetCount(), 0);
$this->assertSame($performance_data->getCacheDeleteCount(), 0);
$this->assertSame(0, $performance_data->getCacheTagChecksumCount());
$this->assertSame(1, $performance_data->getCacheTagIsValidCount());
}
/**
* Logs node/1 tracing data with a cool cache.
*
* Cool here means that 'global' site caches are warm but anything
* specific to the route or path is cold.
*/
public function testNodePageCoolCache(): void {
// First of all visit the node page to ensure the image style exists.
$this->drupalGet('node/1');
$this->rebuildAll();
// Now visit a non-node page to warm non-route-specific caches.
$this->drupalGet('user/login');
$this->collectPerformanceData(function () {
$this->drupalGet('node/1');
}, 'umamiNodePageCoolCache');
$this->assertSession()->pageTextContains('quiche');
}
/**
* Log node/1 tracing data with a warm cache.
*
* Warm here means that 'global' site caches and route-specific caches are
* warm but caches specific to this particular node/path are not.
*/
public function testNodePageWarmCache(): void {
// First of all visit the node page to ensure the image style exists.
$this->drupalGet('node/1');
$this->rebuildAll();
// Now visit a different node page to warm non-path-specific caches.
$this->drupalGet('node/2');
$this->collectPerformanceData(function () {
$this->drupalGet('node/1');
}, 'umamiNodePageWarmCache');
$this->assertSession()->pageTextContains('quiche');
}
}

View File

@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\demo_umami\FunctionalJavascript;
use Drupal\FunctionalJavascriptTests\PerformanceTestBase;
/**
* Tests demo_umami profile performance.
*
* @group Performance
*/
class PerformanceTest extends PerformanceTestBase {
/**
* {@inheritdoc}
*/
protected $profile = 'demo_umami';
/**
* Just load the front page.
*/
public function testPagesAnonymous(): void {
$performance_data = $this->collectPerformanceData(function () {
$this->drupalGet('<front>');
});
$this->assertSession()->pageTextContains('Umami');
$this->assertSame(2, $performance_data->getStylesheetCount());
$this->assertSame(1, $performance_data->getScriptCount());
$performance_data = $this->collectPerformanceData(function () {
$this->drupalGet('node/1');
});
$this->assertSame(2, $performance_data->getStylesheetCount());
$this->assertSame(1, $performance_data->getScriptCount());
}
/**
* Load the front page as a user with access to Toolbar.
*/
public function testFrontPagePerformance(): void {
$admin_user = $this->drupalCreateUser(['access toolbar']);
$this->drupalLogin($admin_user);
$performance_data = $this->collectPerformanceData(function () {
$this->drupalGet('<front>');
});
$this->assertSession()->pageTextContains('Umami');
$this->assertSame(2, $performance_data->getStylesheetCount());
$this->assertSame(2, $performance_data->getScriptCount());
}
}

View File

@@ -0,0 +1,10 @@
ABOUT UMAMI
-----------
Umami is the theme used for the "Umami food magazine" demonstration site.
ABOUT DRUPAL THEMING
--------------------
See https://www.drupal.org/docs/theming-drupal for more information on Drupal
theming.

View File

@@ -0,0 +1,36 @@
# This is so your IDE knows about the syntax for fixes and autocomplete.
$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
# The human readable name.
name: Umami Badge
# Status can be: "experimental", "stable", "deprecated", "obsolete".
status: experimental
# Schema for the props. We support www.json-schema.org. Learn more about the
# syntax there.
props:
# Props are always an object with keys. Each key is a variable in your
# component template.
type: object
properties:
attributes:
type: Drupal\Core\Template\Attribute
title: Attributes
description: Wrapper attributes.
icon:
type: string
description: Icon Name
enum:
- knife
- timer
- serves
- difficulty
slots:
label:
type: string
description: Label text
text:
type: string
description: Text

View File

@@ -0,0 +1,42 @@
.umami-badge__container {
display: flex;
align-items: center;
gap: 0.5rem;
}
/* Large */
@media screen and (min-width: 60rem) {
/* 960px */
.umami-badge__container {
flex-direction: column;
gap: 0;
width: 100%;
padding-block: 0.96em;
}
}
.umami-badge__icon {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
}
/* Large */
@media screen and (min-width: 60rem) {
/* 960px */
.umami-badge__icon {
align-items: start;
width: 56px;
height: 64px;
}
}
.umami-badge__label {
font-weight: bold;
}
.umami-badge__label::after {
content: ":";
}

View File

@@ -0,0 +1,13 @@
<div{{ attributes.addClass('umami-badge') }}>
<div class="umami-badge__container">
{% if icon %}
<div class="umami-badge__icon">
{{ source(componentMetadata.path ~ '/icons/' ~ icon|default('knife') ~ '.svg') }}
</div>
{% endif %}
{% if block('label') is defined and block('label')|trim %}
<div class="umami-badge__label">{% block label %}{% endblock %}</div>
{% endif %}
{% block text %}{% endblock %}
</div>
</div>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="#008068" viewBox="0 0 600 600"><path d="M299.29 118.57c-120.29 0-217.86 97.61-217.86 217.86a215.64 215.64 0 0 0 48.81 137.22 13.8 13.8 0 0 0 19.76 2.12c5.66-5 7.07-14.15 2.12-19.81a187.92 187.92 0 0 1-20.51-31.83l45.27-18.39a14.12 14.12 0 1 0-10.61-26.17l-46 18.39c-5-14.15-8.49-29-9.2-44.56h48.1a14.15 14.15 0 0 0 0-28.29h-48.74a165.28 165.28 0 0 1 8.49-46l43.85 18.39c2.12.71 3.54 1.41 5.66 1.41a14 14 0 0 0 12.73-8.49 14.36 14.36 0 0 0-7.78-18.39l-43.85-18.39A204.84 204.84 0 0 1 155 214.77l32.54 32.54a13.68 13.68 0 0 0 19.81 0 13.68 13.68 0 0 0 0-19.81l-33.24-33.24A211.56 211.56 0 0 1 213 167.38l17.68 42.44c2.12 5.66 7.78 8.49 13.44 8.49 2.12 0 3.54 0 5.66-1.41a15.46 15.46 0 0 0 3.54-2.12c-1.41 12-2.83 30.42-2.83 58 0 33.24.71 74.27 3.54 86.29a49.32 49.32 0 0 0 48.1 38.2 54.6 54.6 0 0 0 10.61-1.41c26.88-5.66 43.85-31.83 38.2-58-2.12-12-18.39-49.51-31.83-79.22-12.73-28.29-21.22-45.27-27.59-55.17 2.12 2.12 5.66 2.83 8.49 2.83a14.19 14.19 0 0 0 14.15-14.15v-44.58a202.27 202.27 0 0 1 46.68 9.2l-17.68 42.44a14.36 14.36 0 0 0 7.78 18.39c2.12.71 3.54 1.41 5.66 1.41a14 14 0 0 0 12.73-8.49L387 168.08a182.4 182.4 0 0 1 38.2 26.17L392 227.5a13.68 13.68 0 0 0 0 19.81 13.68 13.68 0 0 0 19.81 0l32.54-32.54c9.9 12 19.1 25.46 25.46 39.61l-43.85 18.39a14.36 14.36 0 0 0-7.78 18.39c2.12 5.66 7.78 8.49 13.44 8.49 2.12 0 3.54 0 5.66-1.41l43.85-17.68a233 233 0 0 1 8.49 45.27h-48.1a14.15 14.15 0 0 0 0 28.29h48.1a199.17 199.17 0 0 1-9.9 45.27l-45.27-19.1a14.12 14.12 0 0 0-10.61 26.17l44.56 18.39a207.78 207.78 0 0 1-21.93 33.24 13.8 13.8 0 0 0 2.12 19.81c2.83 2.12 5.66 3.54 9.2 3.54a12.73 12.73 0 0 0 10.61-5 217.33 217.33 0 0 0 50.22-139.34c-.76-120.92-99.08-218.53-219.33-218.53zm24 226.35a20.66 20.66 0 0 1-16.27 24c-11.32 2.12-22.63-5-24.76-15.56-2.12-12-3.54-71.44-2.12-110.34 16.32 35.41 40.37 90.58 43.2 101.9zM271.71 188.6h-2.83c-5 .71-8.49 2.83-11.32 9.9l-17.68-42.44a196.33 196.33 0 0 1 46-9.2v46c0 1.41 0 2.83.71 3.54-7.1-7.8-10.59-7.8-14.88-7.8z"/><circle cx="300.24" cy="339.59" r="9.2" transform="rotate(-11.9 300.247 339.58)"/></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

Some files were not shown because too many files have changed in this diff Show More