oscarale Posted Tuesday at 07:50 PM Share Posted Tuesday at 07:50 PM (edited) Hello everyone, I have some lyrics with chords as text, formatted like this: [Verse] E D G B I'll take you for a ride E D G B On my garbage truck B A Oh no Which I write out like this in html: <div class='lyric'> <div class='section' data-section='verse'> <p class='line'><span class='chord'>E</span>I'll take you <span class='chord'>D</span>for a r<span class='chord'>G</span>ide<span class='chord'>B</span></p> <p class='line'><span class='chord'>E</span>On my ga<span class='chord'>D</span>rbage t<span class='chord'>G</span>ruck<span class='chord'>B</span></p> <p class='line'><span class='chord'>B</span>Oh no<span class='chord'>A</span></p> </div> </div> So that it gets rendered like this: I have a python script which converts my lyric/chord files into the html above, which I then paste into a Textarea field that gets put into my template and rendered out on a page for each song. What I'm wondering is if there's a way to do this through ProcessWire without the python script? So instead of pasting html into the Textarea field, I can type out the lyrics in the field and ProcessWire parses it to output the proper html? I'm thinking I may have to write my own Textformatter but I'm not sure if that's the right solution or where to start. Thanks! Edited Friday at 02:20 PM by oscarale solved Link to comment Share on other sites More sharing options...
diogo Posted Tuesday at 10:42 PM Share Posted Tuesday at 10:42 PM You mean, type them in a text area with the spaces, like in the example above? Seems like it would be a pretty complex PHP script, but possible, I guess... If you don't mind to write something closer to the html code, it would make it really easy. You could simply wrap the notes in an element by making them bold, and make each line a paragraph: EI'll take you Dfor a rGideB EOn my gaDrbage tGruckB BOh noA And then just add something like this to style it. p { position: relative; margin-top: 1.5em; } strong { position: absolute; bottom: 1em; color: red; font-weight: inherit; } Or, if you need exactly the html code from above, do a str_replace in a text formatter from "<strong>" to "<span class='chord'>" and so on... 1 Link to comment Share on other sites More sharing options...
bernhard Posted Tuesday at 10:48 PM Share Posted Tuesday at 10:48 PM If you already have a python script that should be quite easy to do with the help of AI In PW just create a textarea field and make sure to let it use a monospace font so that you can properly paste/write your lyrics. (you can do that in /site/templates/admin.less) Then just grab that content and use your PHP method/function that your AI wrote for you and generate the html that you output on the frontend. PS: Nice idea also by @diogo 🙂 1 Link to comment Share on other sites More sharing options...
oscarale Posted Thursday at 04:45 AM Author Share Posted Thursday at 04:45 AM Got it working! Thanks for that AI suggestion @bernhard it did a lot of the leg work for me, and thanks @diogo for your suggestion as well, though it is easier to read and write the standard format with the chords above the lyrics. While there is software that will do the parsing to the chords within the lyrics for me (there's one called ChordPro) I was trying to remove the "middle man" so to speak and be able to edit and create lyrics directly and easily in ProcessWire. If anyone else is interested below is the code which creates an array with all the columns, sections and lines $started_chords = false; $chord_line = ""; $lyric = [[]]; $column = 0; $section = -1; foreach (explode("\n", $page->psalm_lyrics) as $line) { $stripped = preg_replace('/\s+/', ' ', trim($line)); if ($stripped) { if (array_key_exists($stripped, $sections)) { // START SECTION $section++; $lyric[$column][] = [ "class" => $sections[$stripped], "lines" => [] ]; } elseif (empty(array_diff(explode(" ", $stripped), $chords)) && !$started_chords) { $started_chords = true; $chord_line = $line; } elseif ($stripped === "---") { $lyric[] = []; $column++; $section = -1; } else { if ($started_chords) { $started_chords = false; $chord_line = rtrim($chord_line); $limit = 0; while ($chord_line && $limit < 10) { $i = strrpos($chord_line, " ") ? strrpos($chord_line, " ") + 1 : 0; $stripped = mb_substr($stripped, 0, $i, 'UTF-8') . "<span class='chord'>" . mb_substr($chord_line, $i, null, 'UTF-8') . "</span>" . mb_substr($stripped, $i, null, 'UTF-8'); $chord_line = rtrim(mb_substr($chord_line, 0, $i, 'UTF-8')); $limit++; } } $lyric[$column][$section]["lines"][] = $stripped; } } } Where $sections is a ProcessWire repeater field that parses different starts of sections like [VERSE] and [CHORUS] and then translates those to a class, and $chords is an array of available chords to parse. I can then write out the lyric wherever I need it. <div class="lyrics mt-md"> <?php foreach($lyric as $c) { echo "<div class='column'>"; foreach($c as $s) { echo "<div class='section " . $s['class'] . "'>"; foreach($s["lines"] as $l) { echo "<p class='line'>$l</p>"; } echo "</div>"; } echo "</div>"; } ?> </div> So this lyric for example: [CHORUS] E D G B I'll take you for a ride E D G B On my garbage truck B A Oh no --- [VERSE] E D G B I'll take you to the dump E D G B 'Cuz you're my queen A C Take you uptown A C I'll show you the sights C D You know you wanna ride Will render like this Link to comment Share on other sites More sharing options...
oscarale Posted Thursday at 04:47 AM Author Share Posted Thursday at 04:47 AM On 3/18/2025 at 10:48 PM, bernhard said: In PW just create a textarea field and make sure to let it use a monospace font so that you can properly paste/write your lyrics. (you can do that in /site/templates/admin.less) Expand I can't figure out how to do this, there's not an admin.less file in site/templates, or if I need to create it I'm not sure how to specify that the specific lyric field should use a monospace font Link to comment Share on other sites More sharing options...
bernhard Posted Thursday at 07:26 AM Share Posted Thursday at 07:26 AM On 3/20/2025 at 4:47 AM, oscarale said: I can't figure out how to do this, there's not an admin.less file in site/templates, or if I need to create it I'm not sure how to specify that the specific lyric field should use a monospace font Expand That's just regular HTML/CSS stuff. Inspect the backend page where your textarea is. Get the name of the textarea, then add something like this in admin.less: textarea[name^="your_textarea_field_name"] { // for debugging to make it obvious that this code is active border: 5px solid red; // force a monospace font font-family: monospace; } The ^= selector makes sure that it will also work for repeaters, where your name would be something like your_field_repeater123 Link to comment Share on other sites More sharing options...
oscarale Posted Thursday at 02:51 PM Author Share Posted Thursday at 02:51 PM Forgive my ignorance, but I'm still not sure how site/templates/admin.less will be able to update the styling on my edit page. I did however find in the source that it is pulling from wire/templates-admin/styles/AdminTheme.css, so I added this line to the end and it changed the font, though I'm not sure if this is the correct way to go about this. textarea[name^="song_lyrics"] { font-family: monospace !important; } Thanks for your help! Link to comment Share on other sites More sharing options...
bernhard Posted Thursday at 03:45 PM Share Posted Thursday at 03:45 PM See https://processwire.com/blog/posts/pw-3.0.179/ I think you only need to install the Less module then it should work. Modifying files in /wire is not a good idea as you will lose your changes on the next core update! Link to comment Share on other sites More sharing options...
diogo Posted Friday at 01:38 PM Share Posted Friday at 01:38 PM You can also use the admin.php file to load any css file (you can find it in the templates directory), for instance an admin.css file next to it. You just need to add the line $config->styles->append($config->urls->templates . "admin.css"); right before require($config->paths->core . "admin.php"); 2 Link to comment Share on other sites More sharing options...
oscarale Posted Friday at 02:18 PM Author Share Posted Friday at 02:18 PM Thanks everyone. I ended up using the solution @diogo posted since it seemed the simplest and it works great. I was even able to leave off the '!important'. 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now