Thanks for checking out this front-end coding challenge.
Frontend Mentor challenges help you improve your coding skills by building realistic projects.
To do this challenge, you need a basic understanding of HTML and CSS.
The challenge
Your challenge is to build out this social links profile and get it looking as close to the design as possible.
You can use any tools you like to help you complete the challenge. So if you’ve got something you’d like to practice, feel free to give it a go.
Your users should be able to:
See hover and focus states for all interactive elements on the page
Want some support on the challenge? Join our community and ask questions in the #help channel.
Where to find everything
Your task is to build out the project to the designs inside the /design folder. You will find both a mobile and a desktop version of the design.
The designs are in JPG static format. Using JPGs will mean that you’ll need to use your best judgment for styles such as font-size, padding and margin.
If you would like the design files (we provide Sketch & Figma versions) to inspect the design in more detail, you can subscribe as a PRO member.
All the required assets for this project are in the /assets folder. The images are already exported for the correct screen size and optimized.
We also include variable and static font files for the required fonts for this project. You can choose to either link to Google Fonts or use the local font files to host the fonts yourself. Note that we’ve removed the static font files for the font weights that aren’t needed for this project.
There is also a style-guide.md file containing the information you’ll need, such as color palette and fonts.
Building your project
Feel free to use any workflow that you feel comfortable with. Below is a suggested process, but do not feel like you need to follow these steps:
Initialize your project as a public repository on GitHub. Creating a repo will make it easier to share your code with the community if you need help. If you’re not sure how to do this, have a read-through of this Try Git resource.
Configure your repository to publish your code to a web address. This will also be useful if you need some help during a challenge as you can share the URL for your project with your repo URL. There are a number of ways to do this, and we provide some recommendations below.
Look through the designs to start planning out how you’ll tackle the project. This step is crucial to help you think ahead for CSS classes to create reusable styles.
Before adding any styles, structure your content with HTML. Writing your HTML first can help focus your attention on creating well-structured content.
Write out the base styles for your project, including general content styles, such as font-family and font-size.
Start adding styles to the top of the page and work down. Only move on to the next section once you’re happy you’ve completed the area you’re working on.
Deploying your project
As mentioned above, there are many ways to host your project for free. Our recommend hosts are:
We strongly recommend overwriting this README.md with a custom one. We’ve provided a template inside the README-template.md file in this starter code.
The template provides a guide for what to add. A custom README will help you explain your project and reflect on your learnings. Please feel free to edit our template as much as you like.
Once you’ve added your information to the template, delete this file and rename the README-template.md file to README.md. That will make it show up as your repository’s README file.
Remember, if you’re looking for feedback on your solution, be sure to ask questions when submitting it. The more specific and detailed you are with your questions, the higher the chance you’ll get valuable feedback from the community.
Sharing your solution
There are multiple places you can share your solution:
Share your solution page in the #finished-projects channel of our community.
Tweet @frontendmentor and mention @frontendmentor, including the repo and live URLs in the tweet. We’d love to take a look at what you’ve built and help share it around.
Share your solution on other social channels like LinkedIn.
Blog about your experience building your project. Writing about your workflow, technical choices, and talking through your code is a brilliant way to reinforce what you’ve learned. Great platforms to write on are dev.to, Hashnode, and CodeNewbie.
We provide templates to help you share your solution once you’ve submitted it on the platform. Please do edit them and include specific questions when you’re looking for feedback.
The more specific you are with your questions the more likely it is that another member of the community will give you feedback.
Got feedback for us?
We love receiving feedback! We’re always looking to improve our challenges and our platform. So if you have anything you’d like to mention, please email hi[at]frontendmentor[dot]io.
This challenge is completely free. Please share it with anyone who will find it useful for practice.
Tailgate allows you to expose containerized services privately over your Tailnet with automatic HTTPS. It bundles Tailscale, Caddy, and popular plugins into a single, easy-to-deploy container.
Features
Private Ingress: Expose services securely via Tailscale without opening public ports.
Your Tailnet name (required for some MagicDNS setups).
–
Caddy
Variable
Description
Default
CADDY_WATCH
Set to true to auto-reload Caddy when the Caddyfile changes.
false
CADDY_PORT
The port for Caddy’s admin API (used for healthchecks).
2019
CLOUDFLARE_API_TOKEN
Token for Cloudflare DNS challenges.
–
Sablier (Scale-to-Zero)
Only applicable when using the latest-with-sablier image.
Variable
Description
Default
INCLUDE_SABLIER
Set to true to download and start the Sablier binary.
true
SABLIER_VERSION
The version of Sablier to download.
1.10.1
SABLIER_PORT
The port Sablier listens on.
10000
Note on Sablier:
When using the -with-sablier image, the Sablier binary is downloaded at runtime if INCLUDE_SABLIER is set to true. You must mount a configuration file to /etc/sablier/sablier.yml and provide access to the Docker socket.
This script was written by Dominik Rappaport. You can contact me via
email: dominik@rappaport.at.
Introduction
The Strava Segment Downloader is a Python-based script to download the full leaderboard of a
given Strava segment. The data is stored in a CSV file, which is the de facto for exchanging
statistical data.
Why do you want to use this script?
Strava does not provide their uses with advanced analysis methods for the segment leaderboards.
You cannot apply advanced filters or calculate statistical values like mean, median, or standard
deviation. All this can be easily done using software like R or Excel. The CSV file generated by
this script can be easily imported into these tools.
Background details
Strava implements a public API to programmatically interact with their data. That would be the most
natural way of fetching the leaderboard data. Unfortunately, Strava deprecated the API endpoint to
download leaderboards in the year 2020. This link provides you with more information:
As a consequence, traditional Screen scraping is the only way to still get that data. As Strava’s
website make extensive use of JavaScript, libraries like BeautifulSoup are not able to parse the
data, and we have to use Selenium to remote control the browser.
Challenges that come with screen scraping
Screen scraping is a fragile method to get data from a website. The website’s structure may change
anytime and the script may break as a consequence.
In addition, Strava imposes measure to prevent people from doing exactly that. In particular,
they apply a rate limit to the number of requests you can make to their website. If you exceed
that limit, you will be blocked from accessing the leaderboard data for a certain period of time
(typically 24 hours).
To make the script work in such a condition, the user can interrupt the script using Ctrl+C (SIGINT)
and continue another day. With the switch --resume it continues where it left off. Obviously that
may introduce inconsistencies in the data as the leaderboard may have changed in the meantime.
Furthermore, Strava enforces a rate limit to prevent people from accessing their site too frequently. Again, that
works against us. If that rate limit kicks in, the website freezes in state “Loading”. The script will typically
throw the following error message:
Error: Can't navigate to the next page (Element <a href="https://github.com/segments/..."> is not clickable at point (856,935) because another element <div class="loading-panel"> obscures it).
Please refer to section Usage with large segments for further details how to deal with
such challenges.
How to use the script
Installation
The segment_downloader is distributed as a Python package. Several installation methods are available.
Using pip
Executing pip installs the package in your current Python environment. Global installation was once possible, but
modern Linux distributions no longer permit this approach.
pip install segment_downloader
Using pipx or uv
Both pipx and uv enable global tool installation. The package can be installed as follows:
pipx install segment_downloader
or
uv tool install segment_downloader
Usage
Selenium starts the browser with a blank profile, and we therefore have to log in to Strava first.
If you use the script more often Strava may temporarily block your account. To avoid this, we
use an authentication script that logins to Strava and saves the credentials in a cookie file.
This file is then used by the main script to authenticate.
Username and password are stored in environment variables. I decided to use environment variables
instead of command line parameters to make it easier to use the script programmatically like in
GitHub actions together with the GitHub secrets.
The script saves the cookies in a file cookies.pkl. As of today, the filename is hardcoded.
Then you can run the main script passing the segment ID as a command line parameter:
segment_downloader 12345678
The script will download the leaderboard of the segment with the ID 12345678. It creates a CSV file with
the name leaderboard_12345678.csv.
You can interrupt the script at any time using Ctrl+C as described above the paragraph Challenges that come with screen scraping.
If you want to continue where you left off, you can use the --resume switch:
segment_downloader --resume 12345678
Usage with large segments
To work around Strava’s rate limit we recommend the following strategy:
Download the segment in smaller chunks. At the moment, the script throws an error message when it gets blocked by Strava and the
effort to download was in vain.
You can use Ctrl+C and then the resume option to interrupt and resume the download. Then, possibly interrupt again and resume again etc.
This can be automated with a tool like gtimeout. The following example illustrates how to download a large segment in junks of 10 minutes.
# First download
gtimeout -f -s INT 10m python segment_downloader.py 2891805
# Call the script with the resume option as often as needed by repeating the following line:
gtimeout -f -s INT 10m python segment_downloader.py --resume 2891805
Note: By default gtimeout repeats the signal if the script doesn’t exit instantly. As we catch SIGINT and save the data, sending the signal
a second time breaks the script. That will hopefully be fixed in the future. In the meantime, we use the -f option to prevent that. Of course
above mentioned approach could also be implemented manually, without tools like gtimeout.
Notes and Warnings
The script uses the Firefox browser and expects the Strava page to be in English. It may fail if
the pages are in a different language because we identify for examples buttons or the categories
with their labels.
The script tries to compile a single leaderboard list with all data in one table. In Strava for
example age groups, sex and weight groups are not included in the full table. You can only
see if a user is male or female if the leaderboard entry is displayed when the respective filter
is applied. To get the full data, the scripts downloads the leaderboard for each category separately
and joins the tables.
Please note that no user is obliged to specify their sex, weight or age or keep these values up to date.
You may end up with missing data or wrong data in these columns.
AnyKernel3 – Flashable Zip Template for Kernel Releases with Ramdisk Modifications
by osm0sis @ xda-developers
“AnyKernel is a template for an update.zip that can apply any kernel to any ROM, regardless of ramdisk.” – Koush
AnyKernel2 pushed the format further by allowing kernel developers to modify the underlying ramdisk for kernel feature support easily using a number of included command methods along with properties and variables to customize the installation experience to their kernel. AnyKernel3 adds the power of topjohnwu’s magiskboot for wider format support by default, and to automatically detect and retain Magisk root by patching the new Image.*-dtb as Magisk would.
A script based on Galaxy Nexus (tuna) is included for reference. Everything to edit is self-contained in anykernel.sh.
do.devicecheck=1 specified requires at least device.name1 to be present. This should match ro.product.device, ro.build.product, ro.product.vendor.device or ro.vendor.product.device from the build.prop files for your device. There is support for as many device.name# properties as needed. You may remove any empty ones that aren’t being used.
do.modules=1 will push the .ko contents of the modules directory to the same location relative to root (/) and apply correct permissions. On A/B devices this can only be done to the active slot.
do.systemless=1 (with do.modules=1) will instead push the full contents of the modules directory to create a simple “ak3-helper” Magisk module, allowing developers to effectively replace system files, including .ko files. If the current kernel is changed then the kernel helper module automatically removes itself to prevent conflicts.
do.cleanup=0 will keep the zip from removing its working directory in /tmp/anykernel (by default) – this can be useful if trying to debug in adb shell whether the patches worked correctly.
do.cleanuponabort=0 will keep the zip from removing its working directory in /tmp/anykernel (by default) in case of installation abort.
supported.versions= will match against ro.build.version.release from the current ROM’s build.prop. It can be set to a list or range. As a list of one or more entries, e.g. 7.1.2 or 8.1.0, 9 it will look for exact matches, as a range, e.g. 7.1.2 - 9 it will check to make sure the current version falls within those limits. Whitespace optional, and supplied version values should be in the same number format they are in the build.prop value for that Android version.
supported.patchlevels= will match against ro.build.version.security_patch from the current ROM’s build.prop. It can be set as a closed or open-ended range of dates in the format YYYY-MM, whitespace optional, e.g. 2019-04 - 2019-06, 2019-04 - or - 2019-06 where the last two examples show setting a minimum and maximum, respectively.
block=auto instead of a direct block filepath enables detection of the device boot partition for use with broad, device non-specific zips. Also accepts specifically boot, recovery or vendor_boot.
is_slot_device=1 enables detection of the suffix for the active boot partition on slot-based devices and will add this to the end of the supplied block= path. Also accepts auto for use with broad, device non-specific zips.
ramdisk_compression=auto allows automatically repacking the ramdisk with the format detected during unpack. Changing auto to gz, lzo, lzma, xz, bz2, lz4, or lz4-l (for lz4 legacy) instead forces the repack as that format, and using cpio or none will (attempt to) force the repack as uncompressed.
patch_vbmeta_flag=auto allows automatically using the default AVBv2 vbmeta flag on repack, and use the Magisk configuration Canary 23016+. Set to 0 forces keeping whatever is in the original AVBv2 flags, and set to 1 forces patching the flag (only necessary on few devices).
customdd="<arguments>" may be added to allow specifying additional dd parameters for devices that need to hack their kernel directly into a large partition like mmcblk0, or force use of dd for flashing.
slot_select=active|inactive may be added to allow specifying the target slot. If omitted the default remains active.
no_block_display=1 may be added to disable output of the detected final used partition+slot path for zips which choose to include their own custom output instead.
“if search string” is the string it looks for to decide whether it needs to add the tweak or not, so generally something to indicate the tweak already exists. “cmdline entry name” behaves somewhat like this as a match check for the name of the cmdline entry to be changed/added by the patch_cmdline function, followed by the full entry to replace it. “prop name” also serves as a match check in patch_prop for a property in the given prop file, but is only the prop name as the prop value is specified separately.
Similarly, “line match string” and “line replace string” are the search strings that locate where the modification needs to be made for those commands, “begin search string” and “end search string” are both required to select the first and last lines of the script block to be replaced for replace_section, and “mount match name” and “fs match type” are both required to narrow the patch_fstab command down to the correct entry.
“scope” may be specified as “global” to force all instances of the string/line targeted by replace_string, replace_line or remove_line to be replaced/removed accordingly. Omitted or set to anything else and it will perform the default first-match action.
“before|after” requires you simply specify “before” or “after” for the placement of the inserted line, in relation to “line match string”.
“block|mount|fstype|options|flags” requires you specify which part (listed in order) of the fstab entry you want to check and alter.
dump_boot and write_boot are the default method of unpacking/repacking, but for more granular control, or omitting ramdisk changes entirely (“OG AK” mode), these can be separated into split_boot; unpack_ramdisk and repack_ramdisk; flash_boot respectively. flash_generic can be used to flash an image to the corresponding partition. It is automatically included for dtbo and vendor_dlkm in write_boot but can be called separately if using “OG AK” mode or creating a simple partition flashing only zip.
Multi-partition zips can be created by removing the ramdisk and patch folders from the zip and including instead “-files” folders named for the partition (without slot suffix), e.g. boot-files + recovery-files, or kernel-files + ramdisk-files (on some Treble devices). These then contain Image.gz, and ramdisk, patch, etc. subfolders for each partition. To setup for the next partition, simply set block= (without slot suffix) and ramdisk_compression= for the new target partition and use the reset_ak command.
Similarly, multi-slot zips can be created with the normal zip layout for the active (current) slot, then resetting for the inactive slot by setting block= (without slot suffix) again, slot_select=inactive and ramdisk_compression= for the target slot and using the reset_ak keep command, which will retain the patch and any added ramdisk files for the next slot.
backup_file may be used for testing to ensure ramdisk changes are made correctly, transparency for the end-user, or in a ramdisk-only “mod” zip. In the latter case restore_file could also be used to create a “restore” zip to undo the changes, but should be used with caution since the underlying patched files could be changed with ROM/kernel updates.
You may also use ui_print “<text>” to write messages back to the recovery during the modification process, abort “<text>” to abort with optional message, and file_getprop “<file>” “<property>” and contains “<string>” “<substring>” to simplify string testing logic you might want in your script.
// Binary Inclusion
The AK3 repo includes current ARM builds of magiskboot, magiskpolicy and busybox by default to keep the basic package small. Builds for other architectures and optional binaries (see below) are available from the latest Magisk zip, or my latest AIK-mobile and FlashIt packages, respectively, here:
Optional supported binaries which may be placed in /tools to enable built-in expanded functionality are as follows:
mkbootfs – for broken recoveries, or, booted flash support for a script/app via bind mount to /tmp (deprecated/use with caution)
flash_erase, nanddump, nandwrite – MTD block device support for devices where the dd command is not sufficient
dumpimage, mkimage – DENX U-Boot uImage format support
mboot – Intel OSIP Android image format support
unpackelf, mkbootimg – Sony ELF kernel.elf format support, repacking as AOSP standard boot.img for unlocked bootloaders
elftool (with unpackelf) – Sony ELF kernel.elf format support, repacking as ELF for older Sony devices
mkmtkhdr (with unpackelf) – MTK device boot image section headers support for Sony devices
futility + chromeos test keys directory – Google ChromeOS signature support
boot_signer-dexed.jar + avb keys directory – Google Android Verified Boot 1.0 (AVBv1) signature support
rkcrc – Rockchip KRNL ramdisk image support
Optionally moving ARM builds to tools/arm and putting x86 builds in tools/x86 will enable architecture detection for use with broad, device non-specific zips.
// Instructions
Place final kernel build product, e.g. Image.gz-dtb or zImage to name a couple, in the zip root (any separate dt, dtb or recovery_dtbo, dtbo and/or vendor_dlkm should also go here for devices that require custom ones, each will fallback to the original if not included)
Place any required ramdisk files in /ramdisk (/vendor_ramdisk for simple multi-partition vendor_boot support) and module files in /modules (with the full path like /modules/system/lib/modules)
Place any required patch files (generally partial files which go with AK3 file editing commands) in /patch (/vendor_patch for simple multi-partition vendor_boot support)
Modify the anykernel.sh to add your kernel’s name, boot partition location, permissions for any added ramdisk files, and use methods for any required ramdisk modifications (optionally, also place banner and/or version files in the root to have these displayed during flash)
zip -r9 UPDATE-AnyKernel3.zip * -x .git README.md *placeholder
The LICENSE file must remain in the final zip to comply with licenses for binary redistribution and the license of the AK3 scripts.
If supporting a recovery that forces zip signature verification (like Cyanogen Recovery) then you will need to also sign your zip using the method I describe here:
Not required, but any tweaks you can’t hardcode into the source (best practice) should be added with an additional init.tweaks.rc or bootscript.sh to minimize the necessary ramdisk changes. On newer devices Magisk allows these within /overlay.d – see examples.
It is also extremely important to note that for the broadest AK3 compatibility it is always better to modify a ramdisk file rather than replace it.
If running into trouble when flashing an AK3 zip, the suffix -debugging may be added to the zip’s filename to enable creation of a debug .tgz of /tmp for later examination while booted or on desktop.
// Staying Up-To-Date
Now that you’ve got a ready zip for your device, you might be wondering how to keep it up-to-date with the latest AnyKernel commits. AnyKernel2 and AnyKernel3 have been painstakingly developed to allow you to just drop in the latest update-binary and tools directory and have everything “just work” for beginners not overly git or script savvy, but the best practice way is as follows:
Set it up like your zip (i.e. remove any folders you don’t use like ramdisk or patch, delete README.md, and add your anykernel.sh and optionally your Image.*-dtb if you want it up there) then commit all those changes
git push --set-upstream origin <devicename>
git checkout master then repeat steps 4-6 for any other devices you support
Then you should be able to git pull upstream master from your master branch and either merge or cherry-pick the new AK3 commits into your device branches as needed.
As part of the ME-ICA pipeline, Rica (Reports for ICA) provides a reporting tool for ICA decompositions performed with tedana and aroma.
Pronunciation: [หrika]. For an audio recording on how to pronounce Rica see here.
About
Rica originally came out as an alternative to the reports provided by tedana, with the aim of making manual classification of ICA components possible. At the same time, the tool aspires to be of value for ICA decompositions made with tools other than tedana. Rica assumes you’re working with files that mimic the outputs of tedana.
How to use Rica
Even if Rica is designed to be simple to use, you might want to see how you can use the app by watching this tutorial video.
Rica also supports keyboard shortcuts on the ICA components page. You can use the following shortcuts:
Rica can be installed by cloning this repository and executing the following command in the cloned repository:
npm install
In order to run the tool locally, two options exist:
1. Using a localhost
By executing the npm start command in the cloned repository, Rica will open in a new browser tab at http://localhost:3000 and you will be able to use the tool.
2. Compiling the tool
You could also compile the project so that you can use the tool just by opening an HTML file. For that, it is necessary to execute the following commands in the cloned repository.
npm run build
npx gulp
mv build/index.html build/rica.html
open build/rica.html
Pro tip: when you open rica.html for the first time, BOOKMARK IT ๐
Getting involved
Want to learn more about our plans for developing Rica? Have a question, comment, or suggestion? Open or comment on one of our issues!
Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.
The page will reload if you make edits.
You will also see any lint errors in the console.
npm test
Launches the test runner in the interactive watch mode.
See the section about running tests for more information.
npm run build
Builds the app for production to the build folder.
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.
Your app is ready to be deployed!
See the section about deployment for more information.
npm run eject
Note: this is a one-way operation. Once you eject, you canโt go back!
If you arenโt satisfied with the build tool and configuration choices, you can eject at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject will still work, but they will point to the copied scripts so you can tweak them. At this point youโre on your own.
You donโt have to ever use eject. The curated feature set is suitable for small and middle deployments, and you shouldnโt feel obligated to use this feature. However we understand that this tool wouldnโt be useful if you couldnโt customize it when you are ready for it.
A Moodle filter for displaying and optionally interacting with program code by utilising the Moodle CodeRunner question type plugin.
Unlike most Moodle filters, this one is mostly implemented in JavaScript rather than PHP and operates on the rendered HTML rather than the original text. This filter is applied over all HTML elements, therefore can be displayed throughout courses where the user can edit/create HTML elements.
As of Moodle 4.1, the following code adding and editing options are available:
Utilising the new TinyMCE editor’s ‘Code sample’ option (Moodle 4.1+)
This option is recommended for casual code authors, as the editing UI allows direct copying and pasting of code without reformatting. Note: Due to TinyMCE’s quirks, certain options are limited. See further information below.
Utilising Markdown Extra, either in the Moodle editor or externally for importing questions (Moodle 3.11+)
WARNING: Due a bug in Moodle, editing of Ace-inline code using Markdown Extra was unavailable
from around Moodle 4.06 until the bug was fixed in August 2023. You probably
need a recently updated Moodle 4.2 or later for this feature to be usable.
Editing the HTML directly in an HTML editor (Moodle 3.11+)
This option is recommended for code authors who require full functionality/customisation and are comfortable using HTML.
The plugin provides two separate filter operations:
Syntax highlighting (highlight): HTML <pre> elements with an attribute of data-ace-highlight-code are displayed using the JavaScript Ace code editor in read-only mode. This provides syntax colouring of the code.
Code execution (interactive): HTML <pre> elements with an attribute of data-ace-interactive-code are also displayed using the Ace code editor, but with editing enabled. In addition, a button labelled by default Try it! allows the student to execute the current state of the code and observe the outcome. With sufficient ingenuity on the part of the author, graphical output and images can be displayed, too (this option requires the author to edit the raw HTML). By adding additional html elements and linking the <pre> element to them, the author can allow users to enter standard input to the run and even upload files.
It should be noted that the ‘interactive’ elements are interactive only in the sense that the user can edit and run them; the user cannot interact with the code whilst it is running. However, the code can be modified between executions. As this implementation is a filter, data is not stored persistently, and any changes to the code whilst the filter is activated will not be stored.
The plugin requires the CodeRunner plugin to be installed first, since that furnishes the Ace editor required for filter operations. CodeRunner version 4.2.3 and Moodle 3.11 or later is required for basic functionality, although some errors may not display properly.
It is /recommended/ to use CodeRunner version 5.1+ in conjunction with Moodle 4.1 for full functionality.
In addition, the ace-interactive-code filter requires that the system administrator has enabled the CodeRunner sandbox web service which is disabled by default. The Try it! button send the code from the Ace editor to the CodeRunner sandbox (usually a Jobe server) for execution using that web service.
There is a page demonstrating the use of this filter on the CodeRunner site here.
Editor options
To change text editors in Moodle, click on your user icon, and select “Editor preferences”. A drop-down menu can allow a user to switch between editors. Markdown is implemented in “Plain Text Area” and can be selected from a drop-down menu below the implementation of the text editor. TinyMCE referenced is labelled “TinyMCE editor” (not the legacy version) and is available from Moodle version 4.1+.
TinyMCE (Code sample)
This method is recommended for those who want a user-friendly way of implementing code in Moodle 4.1+. This editor-dependent method would suffice for basic use in most circumstances.
How to use:
Click “Insert” > “Code sample”.
Select the programming language you wish to use.
Either write your code normally in the “Code view” area, or copy and paste code into the area.
Click “Save”.
Click “View” > “Source code”.
Locate the code in HTML and add either data-ace-highlight-code or data-ace-interactive-code into the <pre> element. Example:
Add any other desired attributes in the <pre> tag.
Save the question.
To edit the code, double-click on the code block in the editor.
Alternatively, view Source code to edit both code and parameters.
Ace-inline formatting will be viewable outside of the editor; and in-built Prism formatting is visible within.
Caveats:
Currently, the use of <script> tags are not supported by TinyMCE, even when using the Source Code option. Therefore, avoid the use of any <script> tags, and avoid editing code containing any tags in this editor as the HTML is automatically stripped of <script> tags upon editing and saving any material.
Use the ‘data-‘ prefix for every starting parameter. TinyMCE will strip away any non-‘data’ tags upon editing and saving the question.
If the author wants to use another language which is not available through TinyMCE’s “Code sample” drop-down list, then the author should change the language to “HTML/XML” within “Code sample” and add the parameter data-lang=“language” to the <pre> tag, where “language” represents the desired language in quotes; i.e. “java”. Any implemented data-lang will override Code sample selected languages.
Implementing Matplotlib can be done in TinyMCE without the Code mapper, but requires extensive use of HTML-escaped Python. The recommended way of implementing this is under the Demos and samples section.
Markdown Extra editor (Currently unavailable – see above)
This method is recommended for those who want a familiar, consistent way of implementing code in Moodle’s editors or in imported XML files. This method is editor-independent and would suffice for basic use and implementation of code in most circumstances.
How to use:
This filter can recognise both Markdown Extra notation from either imported questions, or from the in-built editor.
Implement the code with standard Markdown Extra. Click here for a reference to Markdown Extra syntax.
Add an attribute of either data-ace-interactive-code= or data-ace-highlight-code=. (Note: the = is necessary as Markdown validates tags by identifying “=”)
Add the attribute of the desired language as data-lang=language.
Add other desired attributes inline (within the {} next to the “`).
Make sure you follow valid Markdown Extra syntax. This means that any extra specified attributes have to be in the same line as the initial backticks (“`) and contain a = between each attribute and its value, and no spaces within either the attribute or the value (spaces are the delimiter for Markdown Extra).
HTML editor
This method is recommended for those who want full functionality and customisation. It allows the use of advanced features which can transform implemented code with the use of JavaScript scripts embedded into the HTML. Basic familiarity with HTML is recommended, although all steps will be outlined below.
How to use:
Write the code that you wish to implement between <pre> tags (in a <pre> element).
Ensure that certain elements are appropriately HTML escaped (see section HTML-escaping of code within the <pre> element section below).
Add either data-ace-interactive-code or data-ace-highlight-code within the initial <pre> tag.
Add any other desired attributes in the <pre> tag.
Example:
<pre data-ace-highlight-code data-lang="java">
public class hello {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
</pre>
Caveats
See the section below on HTML-escaping of code within the <pre> element.
HTML-escaping of code within the <PRE> element
When using ace-highlight-code or ace-interactive-code elements, problems arise when program code contains characters that have special meaning to the browser, i.e. are part of the HTML syntax. For example, in C:
#include <stdio.h>
To ensure characters like ‘<‘, ‘&’ etc are not interpreted by the browser, such special characters should be uri-encoded, e.g. as <, & etc.
For example, an interactive hello world program in C would be defined in HTML as:
Within the Ace editor the student just sees the URI-encoded characters as ‘<‘, ‘&’ etc
Additional Display and Behaviour Attributes
Additional control of the display and behaviour is via attributes of the
<pre> element as follows. All attribute names should start with data- to ensure that the HTML still validates. However, the data- prefix can be dropped if you don’t care about HTML5 validation. For example the data-lang attribute can just be lang. Warning: removing the data- prefix can have unexpected effects, involving stripping of tags in certain editors. It is highly recommended to keep the data prefix in all instances.
Every attribute is supported in HTML.
Prefix Attribute:
Description:
Supported/Available in:
data-lang
This attribute sets the language to be used by the Ace editor for syntax colouring and in the case of interactive, the language for running the code on the Jobe server. A language must be supported in the Jobe server for the interactive code to run. Default: python3.
Highlight, Interactive, TinyMCE, Markdown
data-ace-lang
If set and non-empty, sets the language used by the Ace editor for syntax colouring, independently of data-lang in interactive. This allows the author to have syntax colouring different to the execution language in Jobe. Information on all Ace highlightable languages can be found here .
Highlight, Interactive, TinyMCE, Markdown
data-start-line-number
Sets the line number used for the first displayed line of code, if line numbers are to be shown. Set to none for no line numbers. Default is none for highlight elements and 1 for interactive elements.
Highlight, Interactive, TinyMCE, Markdown
data-font-size
Sets the display font size used by Ace. Default 14px.
Highlight, Interactive, TinyMCE, Markdown
data-min-lines
The minimum number of lines to display in the Ace editor.
Highlight, Interactive, TinyMCE, Markdown
data-max-lines
The maximum number of lines to display in the Ace editor.
Highlight, Interactive, TinyMCE, Markdown
data-dark-theme-mode
Selects when to use a dark mode for the Ace editor. Has values 0, 1 or 2 for no, maybe and yes. If 1 (maybe) is chosen, the dark theme will be used if the browser’s prefers-color-scheme:dark media query returns a match, so this may change with browser, operating system or time of day. The default value is set by the administrator setting for the plugin.
Highlight, Interactive, TinyMCE, Markdown
data-button-name
This sets the text within the Try it! button. Default ‘Try it!’.
Interactive, TinyMCE, Markdown
data-readonly
This disables editing of the code, so students can only run the supplied code without modification. The Try it! button is still displayed and operational.
Interactive, TinyMCE, Markdown
data-hidden
This hides the code, leaving only Try it! visible.
Interactive, TinyMCE, Markdown
data-stdin-taid
This string value specifies the ID of a textarea element and supplies the HTMLelement.innerText attribute as standard input to the program when the Try it! button is clicked. Overrides data-stdin if both are given (and data-stdin is deprecated).
Interactive, TinyMCE, Markdown
data-file-taids
This attribute provides a pseudo-file interface where the user is able to treat one or more supplementary textarea elements like files, entering the pseudo-file contents into the textarea(s) before clicking Try it!. The attribute is a JSON specification that maps from filename(s) to the ID(s) of textarea element(s) and supplies the HTMLelement.innerText attribute that will be used to provide the job with one or more files in the working directory. For each attribute, a file of the specified filename is created and the contents of that file are the contents of the associated textarea at the time Try it! is clicked.
Interactive, TinyMCE
data-file-upload-id
This attribute is the ID of an <input type=”file> element. The user can select one or more files (at 2MB max each) using this element and the files are uploaded into the program’s working space when it is run. Additionally, filenames will be stripped of symbols that throw errors in executing Jobe. These filenames are also implemented on the command line as argv, and can be accessible by parsing the args.
Interactive, TinyMCE, Markdown
data-params
This is a JSON object that defines any Jobe sandbox parameters that are to have non-standard values, such as cputime and memorylimit. This shouldn’t generally be needed. Default: ‘{“cputime”: 5}’. Note that the maximum cputime is set via the administrative interface for the CodeRunner web service and any attempt to exceed that will display an error.
Interactive, TinyMCE
data-code-mapper
This string value must be the name of a global JavaScript function (usually defined in a <script> element preceding the <pre> element) that takes the Ace editor code as a parameter and returns a modified version, e.g. with extra code inserted. If used in conjunction with data-prefix and data-suffix (below), the code-mapper function is applied first and then the prefix and/or suffix code is added.
Interactive, Markdown
data-prefix
This string value is code to be inserted in front of the contents of the ace editor before sending the program to the Jobe server for execution. An extra newline is not inserted between the two strings, so if you want one you must include it explicitly.
Interactive, TinyMCE, Markdown
data-suffix
This string value is code to be inserted after the contents of the ace editor before sending the program to the Jobe server for execution. An extra newline is not inserted between the two strings, so if you want one you must include it explicitly.
Interactive, TinyMCE, Markdown
data-html-output
If this attribute is present (with any value) the output from the run is interpreted as raw HTML. The output from the program is simply wrapped in a <div> element and inserted directly after Try it!. An example of a ace-interactive-code panel that that uses data-prefix, data-suffix and data-html-output to provide Matplotlib graphical output in Python is included in the repo samples folder (the file demoaceinline.xml).
Interactive, TinyMCE, Markdown
data-max-output-length
The maximum length of an output string (more or less). Output greater than this is truncated. Default 30,000 characters.
Interactive, TinyMCE, Markdown
Code examples:
Further code examples can be found in the repo samples folder.
The following code examples all output “Hello world!”.
TinyMCE C program formatting with Code sample.
Open editor and create a new Code sample in C. Copy and paste the corresponding program into the Code view.
#include <stdio.h>
int main() {
printf("Hello world!");
return 0;
}
Then view the HTML from the Source Code editor in TinyMCE and add data-ace-interactive into the <pre> tag.
The HTML should look like this after adding the tag:
Then insert a Code sample in Python, with the code as below:
while 1:
try:
print(input())
except EOFError:
break
Now, inspect the Source Code and add data-ace-interactive-code and data-stdin-taid=”text-demo” into the <pre> tag.
After inserting both attributes, the source code should look like:
There is a page demonstrating most of the capabilities of this filter on the CodeRunner site here. The underlying HTML on that page is mostly the same as in the file [testaceinline.xml](https://github.com/trampgeek/moodle filter_ace_inline/blob/master/tests/fixtures/demoaceinline.xml), which is included in the Github repo, in the samples folder. If you want to experiment yourself, you can download that file and import it as an xml question into the question bank on Moodle. Open it for editing and switch to HTML mode to see how it is set up. It includes a final complex example of a Python3 interactive element that runs numpy and matplotlib, displaying any output graphs as images in addition to any text output. This final example needs to have numpy and matplotlib installed on the Jobe server; they are not there by default, and has to be implemented via an HTML editor which is not TinyMCE in order to avoid <script> stripping.
TinyMCE matplotlib formatting
Due to the <script> stripping, there is a demo of an alternative TinyMCE-friendly matplotlib and numpy implementation, using prefix and suffix code with HTML-escaped Python, in the file [demotinymatplotlib.xml](https://github.com/trampgeek/moodle filter_ace_inline/blob/master/tests/fixtures/demotinymatplotlib.xml), which can be found in the Github repo in the samples folder.
It is highly recommended to import the question into Moodle as above, and then edit the pre-existing code to suit an author’s needs.
Installation and configuration
Download the plugin from the repository, and unzip the code into
<moodlehome>/filter/ace_inline
Then visit Site administration > Notifications. You should receive the usual prompt about updating the database to incorporate the new plugin.
Once installed, visit Site administration > Plugins > Plugins overview > Additional plugins. From this page, click the icon next to “Text filters” and turn “Ace inline” to “Off, but available”.
This allows the individual teacher/administrator to set local settings for each course; if desired. To access individual course settings, click “More” > “Filters” and set Ace inline to “On”.
To use the interactive filter, you will also need to enable the sandbox web service option within the CodeRunner plugin settings. You should read carefully the other related CodeRunner web service settings and consider the various implications. Setting up a separate Jobe server for the web service is recommended if heavy usage of interactive code is likely, in order to mitigate against overload of the main Jobe server.
Note: CodeRunner settings for the web service has a default value for the maximum submission rate (submissions per hour) by any given Moodle user, as this limits the potential for abuse by any student. Use of any interactive execution (running /Try it!/) will contribute towards this limit.
There are two plugin administrator setting provided directly by this plugin:
The default button name for interactive elements can be changed from its default name: Try it! (or whatever was set by the language settings for non-English users) to anything else.
The administrator can set whether to use the Ace editor’s light theme or dark theme by default (although individual filter instances can override this with the data-dark-theme-mode option). There is also an option to use the dark theme ‘sometimes’, meaning whenever the browser’s ‘prefers-color-scheme:dark’ media query returns a match. This may change with browser, operating system or time of day.
Unexpected behaviour in certain areas of Moodle
Currently, in Moodle 4.1, the forum discussion (but not the general description) strips all tags aside from the “class” tag from any HTML elements. This is editor independent. By using the pre-existing [deprecated] method of setting the <pre> class=’ace-interactive-code’ or class=’ace-highlight-code’ basic Python 3 functionality can be implemented.
Alternatively, prefix the desired language with language- and insert this into the <pre> class, alongside with ace-highlight/interactive-code option to implement basic functionality in the selected language.
Example:
Firefox browsers have dynamic scrollbars that hide when the cursor is not hovering over it. To avoid confusion from what may appear as missing code (when in fact, the component is scrollable), the component will expand in width in Firefox browsers to display all code in a line.
This may cause some visual discrepancies between other browsers and Firefox, however functionality remains identical.
It is also recommended to adjust the settings of the scrollbar style in the Firefox browser to allow ease of use.
Change History
Version 1.3.10
Upgrade to Moodle 4.5 compatibility plus various code and test polishing. All thanks to Luca Bรถsch.
Version 1.3.9
Change background colour of read-only ace-inline divs to light grey
to distinguish them for editable ones. Various tweaks to behat tests and style file to
keep the githug CI style checkers happy.
Version 1.3.8
Trivial change: confusing error message ‘User config error’ changed to just ‘Run error’, as could
include submission limit reached, for example.
Version 1.3.7
Bug fix for issue #30: latest update won’t install (due to bad zip uploaded to Moodle plugin repository.)
Version 1.3.6
Update documentation relating to the use of Markdown extra editing.
Version 1.3.5
Bug fix: State of filter reverted to ‘Off but available’ whenever the admin
filter manager was opened.
Version 1.3.4, 1 August 2023.
Adding space after each Try it box
Version 1.3.3, 10 May 2023.
Fix issues with Ace window being far too narrow in many multi-column contexts.
Version 1.3.2, 30 April 2023.
Fixed issue with replacing the wrong node in MarkdownExtra formatting.
Fixed administrator’s default “Try it!” setting to actually work.
Fixed setting minwidth in multichoice so that text will not be truncated.
Added support to allow “style” components to be adapted in. Will be overwritten by Ace Display settings, however, allows other styles such as “min-width” or “margin” to be set with expected results.
Version 1.3.1, 15 February 2023.
Fixed code to adhere to Eslint.
Version 1.3, 7 February 2023.
Changed global dynamic hooks to differentiate between the two.
Version 1.2.2, 19 January 2023.
Updated CI for PHP8 with Moodle 4.1.
Kept Firefox handling code boxes with expansion; changed rest to scrolling.
Checked with Moodle_3x_stable for compatibility.
Updated ReadMe with CodeRunner requirements and Firefox scrollbar issue.
Version 1.2.1, 19 December 2022.
Added a privacy folder with provider.php.
Cleaned up ReadMe.
Version 1.2.0, 15 December 2022.
Added full error handling and file upload size restrictions (2MB).
Mapped files with boxes appropriately.
Version 1.1.1, 13 December 2022.
Changed modules to local, as per Moodle Documentation.
Added file-parsing to JOBE running requirements, including user warnings.
Can now use argv’s to find filenames and run them.
ReadMe and examples to be added tomorrow.
Version 1.1.0, 12 December 2022.
Entire program is now in Vanilla ES.
Decomposed with UiParameters as a class.
ace_inline_code.js is the entry class.
Remaining supporting classes are in modules.
Version 1.0.2, 8 December 2022.
Removed all jQuery from code to prepare for ES6 transition.
Renamed Behat tests for better definition.
Changed Behat tests to insert .txt files from fixtures straight into db instead, to reduce UI dependency.
Implemented CI.
Version 1.0.1, 5 December 2022.
Updated ReadMe fully.
Added demo for Matplotlib in TinyMCE.
Updated demoaceinline.xml.
Patched issue with empty text areas being treated as empty ids. Updated tests accordingly.
Errors now show up consistently in the output area; and output boxes show different error colours and error messages.
Major code refactor, including CSS handling.
Comprehensive Behat tests implemented.
Changed implementation to data-ace-highlight/interactive-code attribute on <pre>.
ReadMe is in process of being rewritten; up to TinyMCE.
Unexpected behaviour in certain areas of Moodle added.
Version 0.8.3, 28 September 2022. Introduce a data-hidden attribute that hides
the code to be executed, allowing authors to set up applet-like elements
that read data from UI elements or files and display output inline when the
button (probably renamed) is clicked. Also set data-min-lines default to 1;
4 was a bad idea.
Version 0.8.2, 25 September 2022. Introduce data-file-upload-id attribute
allowing the user to select files to upload into the workspace on Jobe when
the code is run. Introduce data-max-lines and data-min-lines to set limits
on size of Ace window. Remove old data-files attribute. Plus refactor
code to avoid all use of old-fashioned ‘var’ declarations in JavaScript.
Version 0.7, 21 September 2022. Introduced new attributes stdin-taid and file-taids to allow standard input or file contents to be loaded from
text areas within the same page. Also added the capability of switching
to dark mode both at a system default level and within any particular instance
of the filter.